我们的Sprint3冲刺——闹钟的添加和管理(刘铸辉,何晓楠)
闹钟是我们生活中常用的工具。由于我们的软件是学生日程管理系统,所以必须有提醒功能,在android系统中提供了强大的闹钟接口,并且使用起来也非常简单。AlarmManager是android提供的闹铃管理接口。我们想创建一个闹铃程序就需要通过它来完成。那么接下来就看一下创建闹钟的过程:
1. 获取AlarmManager对象
1 public class AlarmHelper { 2 3 private Context c; 4 private AlarmManager mAlarmManager; 5 6 public AlarmHelper(Context c) { 7 this.c = c; 8 mAlarmManager = (AlarmManager) c 9 .getSystemService(Context.ALARM_SERVICE); 10 } 11 12 public void openAlarm(int id,String content,long time) { 13 Intent intent = new Intent(); 14 intent.putExtra("content", content); 15 intent.putExtra("time", time); 16 intent.setClass(c,CallAlarm.class); 17 PendingIntent pi = PendingIntent.getBroadcast(c, id, intent, 18 PendingIntent.FLAG_UPDATE_CURRENT); 19 mAlarmManager.set(AlarmManager.RTC_WAKEUP, time, pi); 20 } 21 22 public void closeAlarm(int id, String title, String content) { 23 Intent intent = new Intent(); 24 intent.putExtra("_id", id); 25 intent.putExtra("title", title); 26 intent.putExtra("content", content); 27 intent.setClass(c, CallAlarm.class); 28 PendingIntent pi = PendingIntent.getBroadcast(c, id, intent, 0); 29 mAlarmManager.cancel(pi); 30 } 31 }
2.为AlarmManager建立一个receiver类,这个类是用来接收广播的闹铃事件的,我们也可以看作是闹铃的处理程序吧。
1 public class BootReceiver extends BroadcastReceiver { 2 public void onReceive(Context context, Intent intent) { 3 String action = intent.getAction(); 4 if (action.equals(Intent.ACTION_BOOT_COMPLETED)) { 5 ScheduleViewAddActivity.setAlart(context); 6 } 7 } 8 }
这个类需要继承自BroadcastReceiver类,这里有两种方式来接收Intent的广播事件,一是动态注册一个Receiver;二是创建一个继承自BroadcastReceiver的类
3. 创建两个Intent,一个是用于AlarmReceiver类处理的,一个是用于广播的
1 public class CallAlarm extends BroadcastReceiver { 2 @Override 3 public void onReceive(Context context, Intent intent) { 4 String content=intent.getExtras().getString("content"); 5 intent.putExtra("content", content); 6 intent.putExtra("time", intent.getExtras().getLong("time")); 7 intent.setClass(context,AlarmAlert.class); 8 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 9 context.startActivity(intent); 10 }
4. 要设置它震动和要响应的铃声
1 public class AlarmAlert extends Activity { 2 private Dialog builder; 3 private MediaPlayer mp; 4 private Vibrator vibrator; 5 @Override 6 protected void onCreate(Bundle savedInstanceState) { 7 super.onCreate(savedInstanceState); 8 requestWindowFeature(Window.FEATURE_NO_TITLE); 9 setContentView(R.layout.tixing); 10 mp = new MediaPlayer(); 11 //控制响铃震动时长 12 new Thread(){ 13 public void run(){ 14 try { 15 Thread.sleep(53000); 16 if(mp!=null){ 17 mp.stop(); 18 vibrator.cancel(); 19 }else if(vibrator!=null){ 20 vibrator.cancel(); 21 } 22 } catch (InterruptedException e) { 23 // TODO Auto-generated catch block 24 e.printStackTrace(); 25 } 26 } 27 }.start(); 28 try { 29 //播放当前默认铃声 30 mp.setDataSource(this, RingtoneManager.getDefaultUri(RingtoneManager.TYPE_RINGTONE)); 31 mp.prepare(); 32 mp.setLooping(true); 33 mp.start(); 34 } catch (IllegalArgumentException e) { 35 // TODO Auto-generated catch block 36 e.printStackTrace(); 37 } catch (SecurityException e) { 38 // TODO Auto-generated catch block 39 e.printStackTrace(); 40 } catch (IllegalStateException e) { 41 // TODO Auto-generated catch block 42 e.printStackTrace(); 43 } catch (IOException e) { 44 // TODO Auto-generated catch block 45 e.printStackTrace(); 46 } 47 //设置震动 48 vibrator = (Vibrator)getSystemService(Context.VIBRATOR_SERVICE); 49 long [] pattern = {700,1300,700,1300}; 50 vibrator.vibrate(pattern,2); 51 String content=getIntent().getExtras().getString("content"); 52 TextView dialog_content=(TextView) findViewById(R.id.dialog_content); 53 Button dialog_button_cancel=(Button)findViewById(R.id.dialog_button_cancel); 54 dialog_content.setText(content); 55 dialog_button_cancel.setOnClickListener(new OnClickListener() { 56 57 public void onClick(View v) { 58 finish(); 59 } 60 }); 61 } 62 @Override 63 protected void onStop() { 64 ScheduleViewAddActivity.setAlart(AlarmAlert.this); 65 if(mp!=null){ 66 mp.stop(); 67 vibrator.cancel(); 68 }else if(vibrator!=null){ 69 vibrator.cancel(); 70 } 71 super.onStop(); 72 } 73 74 }
5.然后我们还要设置真正能让alarm起作用的参数
1 //设置闹钟,只能设置一个闹铃时间,所以在响铃过后要重新判断最近的时间重新设置闹铃 2 public static void setAlart(Context context){ 3 ScheduleDAO dao1=new ScheduleDAO(context); 4 ArrayList<ScheduleVO> arrSch=dao1.getAllSchedule(); 5 Calendar mCalendar = Calendar.getInstance(); 6 mCalendar.setTimeInMillis(System.currentTimeMillis()); 7 long time; 8 String content=arrSch.get(0).getScheduleContent(); 9 time=arrSch.get(0).getAlartime(); 10 for (ScheduleVO vo : arrSch) { 11 if(vo.getAlartime()>mCalendar.getTimeInMillis()){ 12 if(time<mCalendar.getTimeInMillis()){ 13 time=vo.getAlartime(); 14 content=vo.getScheduleContent(); 15 if(time>vo.getAlartime()){ 16 time=vo.getAlartime(); 17 content=vo.getScheduleContent(); 18 } 19 }else{ 20 if(time>vo.getAlartime()){ 21 time=vo.getAlartime(); 22 content=vo.getScheduleContent(); 23 } 24 } 25 } 26 } 27 if(time>mCalendar.getTimeInMillis()){ 28 } 29 }
6.最后绑定到每个日历事件中
1 /** 2 * 通过选择提醒次数来处理最后的显示结果 3 * @param year 4 * @param month 5 * @param day 6 * @param hour 7 * @param minute 8 * @param week 9 * @param remindID 10 */ 11 public String handleInfo(int year, int month, int day, int hour, int minute, String week, int remindID){ 12 String remindType = remind[remindID]; //提醒类型 13 String show = ""; 14 if(0 <= remindID && remindID <= 4){ 15 //提醒一次,隔10分钟,隔30分钟,隔一小时 16 show = year+"-"+month+"-"+day+" "+hour+":"+minute+" "+week+" "+remindType; 17 }else if(remindID == 5){ 18 //每周 19 show = "每周"+week+" "+hour+":"+minute; 20 }else if(remindID == 6){ 21 //每月 22 show = "每月"+day+"号"+" "+hour+":"+minute; 23 }else if(remindID == 7){ 24 //每年 25 show = "每年"+month+"-"+day+" "+hour+":"+minute; 26 } 27 return show; 28 } 29
1 /** 2 * 设置日程标记日期 3 * @param remindID 4 * @param year 5 * @param month 6 * @param day 7 */ 8 public void setScheduleDateTag(int remindID, String year, String month, String day,int scheduleID){ 9 SimpleDateFormat format = new SimpleDateFormat("yyyy-M-d"); 10 String d = year+"-"+month+"-"+day; 11 Calendar cal = Calendar.getInstance(); 12 try { 13 cal.setTime(format.parse(d)); 14 } catch (ParseException e) { 15 // TODO Auto-generated catch block 16 e.printStackTrace(); 17 } 18 //封装要标记的日期 19 if(remindID >= 0 && remindID <= 3){ 20 //"提醒一次","隔10分钟","隔30分钟","隔一小时"(只需标记当前这一天) 21 ScheduleDateTag dateTag = new ScheduleDateTag(); 22 dateTag.setYear(Integer.parseInt(year)); 23 dateTag.setMonth(Integer.parseInt(month)); 24 dateTag.setDay(Integer.parseInt(day)); 25 dateTag.setScheduleID(scheduleID); 26 dateTagList.add(dateTag); 27 }else if(remindID == 4){ 28 //每天重复(从设置的日程的开始的之后每一天多要标记) 29 for(int i =0; i <= (2049-Integer.parseInt(year))*12*4*7; i++){ 30 if( i==0 ){ 31 cal.add(Calendar.DATE, 0); 32 }else{ 33 cal.add(Calendar.DATE, 1); 34 } 35 handleDate(cal,scheduleID); 36 } 37 }else if(remindID == 5){ 38 //每周重复(从设置日程的这天(星期几),接下来的每周的这一天多要标记) 39 for(int i =0; i <= (2049-Integer.parseInt(year))*12*4; i++){ 40 if( i==0 ){ 41 cal.add(Calendar.WEEK_OF_MONTH, 0); 42 }else{ 43 cal.add(Calendar.WEEK_OF_MONTH, 1); 44 } 45 handleDate(cal,scheduleID); 46 } 47 }else if(remindID == 6){ 48 //每月重复(从设置日程的这天(几月几号),接下来的每月的这一天多要标记) 49 for(int i =0; i <= (2049-Integer.parseInt(year))*12; i++){ 50 if( i==0 ){ 51 cal.add(Calendar.MONTH, 0); 52 }else{ 53 cal.add(Calendar.MONTH, 1); 54 } 55 handleDate(cal,scheduleID); 56 } 57 }else if(remindID == 7){ 58 //每年重复(从设置日程的这天(哪一年几月几号),接下来的每年的这一天多要标记) 59 for(int i =0; i <= 2049-Integer.parseInt(year); i++){ 60 if( i==0 ){ 61 cal.add(Calendar.YEAR, 0); 62 }else{ 63 cal.add(Calendar.YEAR, 1); 64 } 65 handleDate(cal,scheduleID); 66 } 67 } 68 //将标记日期存入数据库中 69 dao.saveTagDate(dateTagList); 70 }