Android开发之倒计时应用(三)

来源:互联网 发布:用ps做淘宝产品图片 编辑:程序博客网 时间:2024/05/21 06:45

如需转载,请注明出处,谢谢!



这篇文章是主要是把剩下的Service和BroadcastReceiver讲完,即倒计时的具体实现。因为代码中有一些比较细节的地方,我讲得不够清楚的欢迎提问。

我写了一个继承自Service的TimerService类,除了默认要实现的onBind方法外,还重写了onCreate、onStartCommand、onDestroy方法。

onCreate方法中主要做一些初始化的操作:

@Overridepublic void onCreate() {super.onCreate();mTimer = new Timer();preferences = getSharedPreferences(ConstantUtil.PREFERENCE, Context.MODE_PRIVATE);}

需要注意的是,这里的preference与MainActivity中的preference不是同一个。在这里顺带讲一下Sharedpreferences:

Sharedpreferences本身是一个接口,可通过以下几个方法获得:

getPreferences(int mode);  // 只属于该Activity,一个Activity只有一个PreferenceManager.getDefaultSharedPreferences(this); // 属于整个应用程序,只有一个getSharedpreferences(String name, int mode); // 属于整个应用程序,可以有多个

这里用到preference的原因下面会讲到。


onDestroy方法主要做一些变量的销毁,没什么好讲的。

@Overridepublic void onDestroy() {super.onDestroy();if (mTimer != null) {mTimer = null;}if (mTask != null) {mTask.cancel();mTask = null;}if (preferences != null) {preferences = null;}}

主要的代码在 onStartCommand中:

@Overridepublic int onStartCommand(Intent intent, int flags, int startId) {// 必须判断一下,否则可能导致程序无法运行if (intent == null) {return super.onStartCommand(intent, flags, startId);}String action = intent.getAction();if (action.equals(ConstantUtil.START)) {currentProgress = intent.getIntExtra(ConstantUtil.CURRENT_PROGRESS, 0);progress = intent.getIntExtra(ConstantUtil.PROGRESS, 0);start();} else if (action.equals(ConstantUtil.PAUSE)) {pause();} else if (action.equals(ConstantUtil.STOP)) {stop();}return super.onStartCommand(intent, flags, startId);}


接下来分别讲start、pause和stop方法。

程序中可能会出现这种情况:倒计时任务正在进行,但用户继续点击开始按钮,因此在这里先判断一下mTask是否为空再进一步操作。(为了防止这种情况出现,也可以让任务在进行的时候讲开始按钮设置为不可点击。)然后再通过mTimer启动mTask任务进行倒计时。关于Timer和TimerTask,这里就不做介绍了。

private void start() {// 有任务正在进行,发送广播通知Activityif (mTask != null) {Intent intent = new Intent(ConstantUtil.ALREADY_RUN);sendBroadcast(intent);return;}mTask = new MyTimerTask();mTimer.schedule(mTask, 1000, 1000);}

pause方法中,我没找到可以使TimerTask暂停的方法,所以就直接cancel掉了,然后把状态保存下来。

private void pause() {if (mTask != null) {mTask.cancel();mTask = null;}// 将当前进度发回activity保存Intent intent = new Intent(ConstantUtil.PAUSE);intent.putExtra(ConstantUtil.CURRENT_PROGRESS, currentProgress);sendBroadcast(intent);}

关于stop方法,这里指的是点击停止按钮强行停止倒计时。
/** * 人为停止计时器 */private void stop() {if (mTask != null) {mTask.cancel();mTask = null;}}


说了那么久的TimerTask在这里终于要来啦!这也是倒计时的主要实现,但其实代码很简单的!

private class MyTimerTask extends TimerTask {@Overridepublic void run() {if (++currentProgress >= progress) {timeout();} else {running();}}}

running方法中,只是向Activity发送广播,通知Activity更新UI

private void running() {// 发送广播使activity更新UIIntent intent = new Intent(ConstantUtil.RUNNING);intent.putExtra(ConstantUtil.CURRENT_PROGRESS, currentProgress);sendBroadcast(intent);}

timeout方法中要做的工作就比较多了,上面在onCreate方法中声明的preferences在这里就要用到了。
/** * 倒计时完成,停止计时器 */private void timeout() {if (mTask != null) {mTask.cancel();mTask = null;}Intent intent = new Intent(ConstantUtil.TIMEOUT);sendBroadcast(intent);// 当activity无法收到倒计时完成的消息时,将停止状态保存在sharedpreference中// activity再次启动时便可以判断倒计时是否已完成Editor editor = preferences.edit();editor.putBoolean(ConstantUtil.STOP, true);editor.commit();// 创建通知createNotification();}private void createNotification() {Intent contentIntent = new Intent();contentIntent.setClass(this, MainActivity.class);PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, contentIntent, 0);if (MainActivity.isDestroy) {NotificationManager mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);Notification notification = new Notification.Builder(getApplicationContext()).setContentTitle("Timeout").setContentText("恭喜你,消耗了" +progress +"秒").setSmallIcon(R.drawable.ic_launcher).setContentIntent(pendingIntent).setAutoCancel(true).build();mNotificationManager.notify(0, notification);}// 发出系统通知声音和调用震动ringAndVibrator();}private void ringAndVibrator() {// 控制震动Vibrator vibrator = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE);long pattern[] = {100, 300, 100, 400};vibrator.vibrate(pattern, -1);// 获取系统通知声音Uri alert = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);          MediaPlayer player = new MediaPlayer();          try {player.setDataSource(this, alert);} catch (Exception e) {e.printStackTrace();}         final AudioManager audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);          if (audioManager.getStreamVolume(AudioManager.STREAM_NOTIFICATION) != 0) {          player.setAudioStreamType(AudioManager.STREAM_NOTIFICATION);          player.setLooping(false);          try {        player.prepare();        } catch (Exception e) {        e.printStackTrace();        }        player.start();          }  }

在service中发送的广播都是发给Activity的,因此,在Activity中创建一个BroadcastReceiver,然后在onCreate中注册并在onDestroy中注销掉。

private class ServiceReceiver extends BroadcastReceiver {@Overridepublic void onReceive(Context context, Intent intent) {String action = intent.getAction();if (action.equals(ConstantUtil.ALREADY_RUN)) {toast = Toast.makeText(getApplicationContext(), "任务正在进行中...", SHORT);toast.show();} else if (action.equals(ConstantUtil.PAUSE)) {int data = intent.getIntExtra(ConstantUtil.CURRENT_PROGRESS, 0);currentProgress = data;} else if (action.equals(ConstantUtil.RUNNING)) {int data = intent.getIntExtra(ConstantUtil.CURRENT_PROGRESS, 0);currentProgress = data;showView.setText((progress - currentProgress) + "");} else if (action.equals(ConstantUtil.TIMEOUT)) {currentProgress = 0;showView.setText(getResources().getString(R.string.default_text));AlertDialog dialog = new AlertDialog.Builder(MainActivity.this).setTitle("Timeout").setMessage("恭喜你消耗了" + progress + "秒").setPositiveButton("好的", null).create();dialog.show();}}}

好了,到了这里,整个应用就算完成了!

附上源码链接:源码下载

如果发现Bug或者是对代码的实现有什么建议,欢迎大家指出来~~

0 0
原创粉丝点击