这次客户反应在晚上有任务来时,提示的铃声太大,能不能够做成铃声渐增的,像闹钟一样。之前因为只考虑了铃声不够大,没有去了解到有
些人是在家做事的。晚上来任务时铃声的问题确实会影响到家人的休息。接下来就来看看铃声渐增的做法。
首先我们知道android中控制声音的类为AudioManager,查看了一下API以及网上搜了一下都没有相关的API能够实现声音渐增的功能,所以接
下来就只有一个办法了:在铃声播放的时候,先将音量初始化为较低的数值然后不断的增加音量,这样就能够达到音量渐增的效果。震动功能
很简单,它的接口也很少,相应的地方加入就是了。
铃声渐增功能我是在服务中实现的,铃声开启时,启动服务,初始化音量,间隔提高音量。间隔提高音量的实现思路:在服务启动时创建一个
Handler对象,初始化初始音量,在handleMessage中提高音量并且延迟固定的时间再sendEmptyMessage,实现消息循环,如果音量已经达
到最大值了,则return并且结束服务。
代码实现:
public class VolumeControlService extends Service{ private final static String TAG = "VolumeControlService"; private AudioManager mAudioManager; private MyHandler mHandler; private int mMaxVolume;//所增加的音量的最大值,超过这个音量则不再增加 private int mIncreaseVolumeDelay;//音量增加的时间间隔,单位:毫秒 private int mStreamType = -1;//铃声类型 public final static int DEFAULT_DELAY_INTERVAL = 6;//默认的音量增加的时间间隔,单位:秒 @Override public IBinder onBind(Intent intent){ Log.i(TAG, "onBind"); return null; } @Override public void onCreate(){ super.onCreate(); Log.i(TAG, "onCreate"); mHandler = new MyHandler(); mAudioManager = (AudioManager) getSystemService(AUDIO_SERVICE); reloadSettings(); if(mStreamType == -1) throw new RuntimeException("Provide valid stream type"); } /** * 初始化默认设置*/ protected void reloadSettings(){ setStreamType(AudioManager.STREAM_MUSIC); setMaxVolume(mAudioManager.getStreamMaxVolume(mStreamType)-5);//设置最大的音量 setCurrentVolume(1);//初始化将音量调到最小 setDelay(DEFAULT_DELAY_INTERVAL); }; /** * 判断音量渐增时候达到最大值*/ protected boolean shouldStop(){ return !isRoomVolumeAvailable(); }; @Override public int onStartCommand(Intent intent, int flags, int startId) { Log.i(TAG, "onStartCommand"); startVolumeIncrease(); return super.onStartCommand(intent, flags, startId); } /** * 停止服务*/ protected void stop() { Log.i(TAG, "stop"); stopSelf(); } protected void startVolumeIncrease() { mHandler.sendEmptyMessageDelayed(0, getDelay()); } /** * 使音量渐增*/ protected void increaseVolume() { if (isRoomVolumeAvailable()) { setCurrentVolume(getCurrentVolume() + 1); android.util.Log.i(TAG, "INCREASE VOLUME " + getCurrentVolume()); } } protected boolean isRoomVolumeAvailable() { return getCurrentVolume() < getMaxVolume(); } /** * 设置音量渐增间隔,每隔多久增加一次音量*/ protected void setDelay(int delay) { if(delay == 0){ delay = DEFAULT_DELAY_INTERVAL; } mIncreaseVolumeDelay = delay * 1000; } protected long getDelay() { return mIncreaseVolumeDelay; } /** * 设置最大音量大小*/ protected void setMaxVolume(int maxVolume) { this.mMaxVolume = maxVolume; } protected int getMaxVolume() { return mMaxVolume; } protected int getStreamMaxVolume(){ return mAudioManager.getStreamMaxVolume(mStreamType); } /** * 设置音频类型*/ protected void setStreamType(int mStreamType) { this.mStreamType = mStreamType; } protected int getStreamType() { return mStreamType; } /** * 设置当前的音量大小*/ protected void setCurrentVolume(int volumeIndex) { mAudioManager.setStreamVolume(mStreamType, volumeIndex, AudioManager.FLAG_REMOVE_SOUND_AND_VIBRATE); Log.i(TAG, "StreamVolume:"+volumeIndex); } protected int getCurrentVolume() { return mAudioManager.getStreamVolume(mStreamType); } class MyHandler extends Handler { @Override public void handleMessage(Message msg) { if (shouldStop()) { stop(); return; } increaseVolume(); sendEmptyMessageDelayed(0, getDelay()); Log.i(TAG, "StreamVolume:"+"音量增加"); } } }
在开启服务时reloadSettings方法初始化了铃声的最小值,铃声类型,铃声增加的频率即时间间隔,然后在onStartCommand方法中启动铃声
渐增功能startVolumeIncrease,这个方法是向Handler的消息队列中发送一个延时的消息,看handleMessage中所执行的动作:shouldStop()
判断铃声是否达到最大值,如果达到就停止服务,然后increaseVolume增加铃声,然后sendEmptyMessageDelayed延时再次执行此这轮动
作。
震动功能的实现方法很简单,首先获取系统的Vibrator服务,这个服务他提供了两个方法:
vibrate(long[] pattern, int repeat) vibrate(long milliseconds)
这两个方法,第一个是自定义震动模式,pattern数组中的数字代表的意思是:暂停,震动,暂停,震动....,repeat为-1代表不重复执行pattern
中的模式,为非-1的数组下标则表示重复执行pattern中的模式,意思就是:repeat不为-1时则只能是pattern数组中下标数中的一个,并且表示
从pattern数组下标开始循环,例如:pattern[2]{700,1000},如果repeat为-1则表示先暂停700毫秒然后震动1秒,如果为0则表示先暂停700然后
震动1秒,然后如此循环,如果为1则震动一次就不会再震动了。
public class MainActivity extends Activity implements OnClickListener{ Button btn; private boolean isStop=true; Vibrator vib; private long pattern[] = {700,1000}; boolean isRepeat = true; AlarmManager am; Handler handler = new Handler(){ public void handleMessage(android.os.Message msg) { if(msg.what==10){ new Thread(new TaskAlarmThread(MainActivity.this)).start(); } }; }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); btn = (Button)findViewById(R.id.button1); btn.setOnClickListener(this); vib = (Vibrator) this.getSystemService(Service.VIBRATOR_SERVICE); } @Override public void onClick(View arg0){ if(isStop){ vib.vibrate(pattern,0);//开启震动 handler.sendEmptyMessageDelayed(10, 2000); isStop = false; }else{ TaskAlarmThread.stopRemind(); vib.cancel(); isStop = true; } }
以上代码是Activity的代码,做了这样的事情:开启震动2秒后才打开铃声,已达到像闹钟一样。
public class TaskAlarmThread extends Thread { public static volatile boolean reminding = false; private Context mContext; public TaskAlarmThread(Context context){ this.mContext = context; TaskAlarmThread.reminding = true; } @Override public void run(){ mContext.startService(new Intent(mContext, VolumeControlService.class)); int n = 0; while(n < 20 && TaskAlarmThread.reminding){ MediaPlayer mpTask = MediaPlayer.create(mContext, R.raw.phonering); mpTask.start(); mpTask.setOnCompletionListener(new OnCompletionListener() { @Override public void onCompletion(MediaPlayer mp) { mp.release(); } }); n++; try{ Thread.sleep(3000); } catch (InterruptedException e) { e.printStackTrace(); } } if(n >= 20){ TaskAlarmThread.stopRemind(); } } public static void stopRemind(){ TaskAlarmThread.reminding = false; } }
上面的代码为铃声播放线程。声音控制服务就是在这个线程中启动的,铃声循环20遍,超过则自动关闭。