简单的android闹钟

来源:互联网 发布:埃博拉病毒 知乎 编辑:程序博客网 时间:2024/04/28 07:13

对service和date,Calendar的使用一直不是很熟练,今天做了一个简单的闹钟来练习一下,主要思路如下

1.设置日期(年月日),为了熟悉DatePickDialog的使用

2.设置时间(小时,分钟),为了熟悉TimePickDialog的使用(发现其实两个是一样的)

3.开始一个service,在service里面监听时间值,时间好了就使用MediaPlayer来播放

首先是MainActivity

package liuije.exercise.alarmclock;import java.text.SimpleDateFormat;import java.util.Calendar;import java.util.Date;import java.util.Locale;import android.app.Activity;import android.app.DatePickerDialog;import android.app.DatePickerDialog.OnDateSetListener;import android.app.TimePickerDialog;import android.app.TimePickerDialog.OnTimeSetListener;import android.content.Intent;import android.os.Bundle;import android.text.format.DateFormat;import android.view.Menu;import android.view.MenuItem;import android.view.View;import android.widget.DatePicker;import android.widget.TextView;import android.widget.TimePicker;import android.widget.Toast;public class MainActivity extends Activity {Activity tActivity;DatePickerDialog datePickerDialog;TimePickerDialog timePickerDialog;TextView t;Calendar at;Long time;boolean thi = false;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);Calendar c = Calendar.getInstance();t = (TextView) findViewById(R.id.textView1);at = Calendar.getInstance();tActivity = this;datePickerDialog = new DatePickerDialog(this, new OnDateSetListener() {@Overridepublic void onDateSet(DatePicker view, int year, int monthOfYear,int dayOfMonth) {at.set(year, monthOfYear, dayOfMonth);t.append(new SimpleDateFormat("yyyy年MM月dd日", Locale.CHINA).format(at.getTime()));}}, c.get(Calendar.YEAR), c.get(Calendar.MONTH),c.get(Calendar.DAY_OF_MONTH));// 这里的year,monthofyear和dayofmonth是指出现时显示的时间,是int型的,// 但是指定的话需要转换,参数写2的话会出现三月,是因为java月份从0开始timePickerDialog = new TimePickerDialog(tActivity,new OnTimeSetListener() {@Overridepublic void onTimeSet(TimePicker view, int hourOfDay,int minute) {t.append(hourOfDay + ":" + minute + "\n");at.set(Calendar.HOUR_OF_DAY, hourOfDay);at.set(Calendar.MINUTE, minute);}}, c.get(Calendar.HOUR_OF_DAY), c.get(Calendar.MINUTE), true);}public void setDate(View v) {datePickerDialog.show();}public void setTime(View v) {timePickerDialog.show();}public void start(View v) {Intent intent = new Intent();intent.putExtra("time", at.getTimeInMillis());// intent.putExtra("time", System.currentTimeMillis());thi = true;intent.setAction("startAlarmClock");tActivity.startService(intent);}}

注意上面datePickDialog的使用,这个组件的事件处理函数返回的月份是比自然月少一的,是因为java的月份是从零开始的。

然后建立Service类,传入时间参数,判断时间到了之后启动闹钟,主要是用的handler和runnable的回调机制:

实现上述回调检查的方法是:首先new 一个handler,然后在一个runnable的run里面使用这个handlerpostdelay自身,然后使用handler的removeCallback可以除掉回调机制

package liuije.exercise.alarmclock;import java.io.IOException;import android.app.Service;import android.content.Intent;import android.content.res.AssetFileDescriptor;import android.content.res.AssetManager;import android.media.MediaPlayer;import android.os.Handler;import android.os.IBinder;import android.util.Log;public class ClockService extends Service {Long time;MediaPlayer alarm;public ClockService() {}@Overridepublic IBinder onBind(Intent intent) {// TODO Auto-generated method stubreturn null;}@Overridepublic void onCreate() {// TODO Auto-generated method stubsuper.onCreate();alarm = MediaPlayer.create(this, R.raw.alarm);AssetManager am = getAssets();AssetFileDescriptor afd = null;// try {// afd = am.openFd("alarm.mp3");// } catch (IOException e1) {// // TODO Auto-generated catch block// Log.d("服务", "mes");// e1.printStackTrace();// }// try {// alarm.setDataSource(afd.getFileDescriptor());// alarm.prepare();// } catch (IllegalStateException | IOException e) {// Log.d("服务", "me");// e.printStackTrace();// }Log.d("服务", "oncreate");final Handler h = new Handler();Runnable r = new Runnable() {@Overridepublic void run() {Log.d("时间", "time");h.postDelayed(this, 1000);if (System.currentTimeMillis() > time) {h.removeCallbacks(this);alarm.start();}}};h.post(r);// alarm.start();}@Override@Deprecatedpublic void onStart(Intent intent, int startId) {// TODO Auto-generated method stubsuper.onStart(intent, startId);Log.d("服务", "start");time = intent.getLongExtra("time", System.currentTimeMillis());}@Overridepublic void onDestroy() {// TODO Auto-generated method stubsuper.onDestroy();Log.d("服务", "onDestroy");alarm.stop();}}
service要在manifest里面注册,注册的时候可以指定开启的Action

  <service android:name=".ClockService" >            <intent-filter>                <action android:name="startAlarmClock" />            </intent-filter>        </service>
这样就实现了一个简单的闹钟,总结一下几个问题

1.Calendar的getInstance()就可以得到代表当前时间的一个Calendar的对象

2.Calendar的getTime可以返回Date对象,使用SimpleDateFormat可以格式化这个Date

3.SimpleDateFormat的初始化使用的是(String,Locale)两个构造函数的,这样的Locale可以传Locale.CHINA

4.在上面格式化输出的时候年必须传小写y,日期传大写D的话会出错,日期会显示那个是一年中的第几天,比如165天,传小写的就行

5.service使用Context的startService之后调用了Service的OnCreate和OnStart,

0 0
原创粉丝点击