android震动伴随铃声渐增功能的实现

这次客户反应在晚上有任务来时,提示的铃声太大,能不能够做成铃声渐增的,像闹钟一样。之前因为只考虑了铃声不够大,没有去了解到有

些人是在家做事的。晚上来任务时铃声的问题确实会影响到家人的休息。接下来就来看看铃声渐增的做法。

首先我们知道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遍,超过则自动关闭。

你可能感兴趣的:(android震动伴随铃声渐增功能的实现)