关于日程提醒,用Android系统的AlarmManager,将提醒时间加入系统闹钟并同广播关联,在闹钟到点提醒时,触发广播,然后弹出通知栏通知日程,以下为设置闹钟的代码
private void addRemind(){
//得到日历实例,主要是为了下面的获取时间
Calendar mCalendar1 = Calendar.getInstance();
mCalendar1.setTimeInMillis(System.currentTimeMillis());
//获取当前毫秒值
long systemTime = System.currentTimeMillis();
//是设置日历的时间,主要是让日历的年月日和当前同步
mCalendar1.setTimeInMillis(System.currentTimeMillis());
// 这里时区需要设置一下,不然可能个别手机会有8个小时的时间差
mCalendar1.setTimeZone(TimeZone.getTimeZone("GMT+8"));
//设置在几点提醒 设置的为13点
mCalendar1.set(Calendar.HOUR_OF_DAY, 15);
//设置在几分提醒 设置的为25分
mCalendar1.set(Calendar.MINUTE, 21);
//下面这两个看字面意思也知道
mCalendar1.set(Calendar.SECOND, 0);
mCalendar1.set(Calendar.MILLISECOND, 0);
/**
* 若感觉上面的设置过于繁琐,则可如此设置
* mCalendar1.setTimeInMillis(System.currentTimeMillis()+60*1000);
* 表示于当前时间1分钟后提醒
*/
Log.i("MainActivity","提醒时间1-->"+Utils.getCustonFormatTime(mCalendar1.getTimeInMillis(),"yyyy/MM/dd/HH/mm"));
//上面设置的就是15点21分0秒的时间点
//获取上面设置的15点21分0秒的时间点
long selectTime = mCalendar1.getTimeInMillis();
// 如果当前时间大于设置的时间,那么就从第二天的设定时间开始
if(systemTime > selectTime) {
mCalendar1.add(Calendar.DAY_OF_MONTH, 1);
}
//AlarmReceiver.class为广播接受者
Intent intent = new Intent(MainActivity.this, AlarmReceiver.class);
PendingIntent pi = PendingIntent.getBroadcast(MainActivity.this, 0, intent, 0);
//得到AlarmManager实例
AlarmManager am = (AlarmManager)getSystemService(ALARM_SERVICE);
//**********注意!!下面的两个根据实际需求任选其一即可*********
/**
* 单次提醒
* mCalendar.getTimeInMillis() 上面设置的15点21分0秒的时间点
*/
am.set(AlarmManager.RTC_WAKEUP, mCalendar1.getTimeInMillis(), pi);
/**
* 重复提醒
* 第一个参数是警报类型;下面有介绍
* 第二个参数网上说法不一,很多都是说的是延迟多少毫秒执行这个闹钟
* 第三个参数是重复周期,也就是下次提醒的间隔 毫秒值 我这里是一天后提醒
*/
am.setRepeating(AlarmManager.RTC_WAKEUP, mCalendar1.getTimeInMillis(), (1000 * 60 * 60 * 24), pi);
}
开发时可能需要向广播传递数据,这时需要更改PendingIntent的参数,如下:
Intent intent = new Intent(MainActivity.this, AlarmReceiver.class); intent.putExtra("name","向广播的传值"); //sendBroadcast(intent); PendingIntent pi = PendingIntent.getBroadcast(MainActivity.this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
第二个参数为requestCode,标识不同的闹钟服务,若需要添加多个闹铃,则该值需要该不同,负责会覆盖原来的值,其中若使用sendBroadcast(intent),则会在代码执行时,立即向广播发送数据,而不会等到提醒时间点发送;若每一次打开app时,addRemind()都执行,则无论提醒时间是否已经过时(<当前时间),都会提醒,因此需要再加判断,若需要添加
多个闹钟,代码如下(添加了两个闹钟):
for (int i=0;i<2;i++){ Calendar calendar=Calendar.getInstance(); calendar.setTimeInMillis(System.currentTimeMillis()); //获取当前毫秒值 long systemTime = System.currentTimeMillis(); //是设置日历的时间,主要是让日历的年月日和当前同步 calendar.setTimeInMillis(System.currentTimeMillis()); // 这里时区需要设置一下,不然可能个别手机会有8个小时的时间差 calendar.setTimeZone(TimeZone.getTimeZone("GMT+8")); //设置在几点提醒 设置的为15点 calendar.set(Calendar.HOUR_OF_DAY, 15); //设置在几分提醒 设置的为50分 calendar.set(Calendar.MINUTE, 50); calendar.set(Calendar.SECOND, 40); calendar.set(Calendar.MILLISECOND, 0); Log.i("MainActivity","提醒时间-->"+Utils.getCustonFormatTime(calendar.getTimeInMillis(),"yyyy/MM/dd/HH/mm")); Intent intent = new Intent(MainActivity.this, AlarmReceiver.class); intent.putExtra("name","向广播的传值"+i); //sendBroadcast(intent); PendingIntent pi = PendingIntent.getBroadcast(MainActivity.this, i, intent, PendingIntent.FLAG_UPDATE_CURRENT); // sendBroadcast(intent); AlarmManager am = (AlarmManager)getSystemService(ALARM_SERVICE); am.set(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), pi); //am.cancel(pi); }
取消闹钟的代码:/** * 关闭提醒 */ private void stopRemind(){ Intent intent = new Intent(MainActivity.this, AlarmReceiver.class); PendingIntent pi = PendingIntent.getBroadcast(MainActivity.this, 0, intent, 0); AlarmManager am = (AlarmManager)getSystemService(ALARM_SERVICE); //取消警报 am.cancel(pi); Toast.makeText(this, "关闭了提醒", Toast.LENGTH_SHORT).show(); }
其中PendingIntent的参数需要相同以下为广播的代码:
public class AlarmReceiver extends BroadcastReceiver{ @Override public void onReceive(Context context, Intent intent) { Toast.makeText(context, "闹钟响了", Toast.LENGTH_SHORT).show(); Log.i("AlarmReceiver","闹钟响了"); Bundle bundle=intent.getExtras(); Log.i("AlarmReceiver","接收传值"+bundle.getString("name")); //从系统服务中获得通知管理器 Intent it=new Intent(context,MainActivity.class); PendingIntent pi=PendingIntent.getActivity(context,0,it, PendingIntent.FLAG_CANCEL_CURRENT); Resources res=context.getResources(); Bitmap bmp= BitmapFactory.decodeResource(res,R.mipmap.icon); NotificationManager manager_notifica=(NotificationManager)context.getSystemService(Context.NOTIFICATION_SERVICE); //定义notification NotificationCompat.Builder builder = new NotificationCompat.Builder(context); builder.setContentTitle("日程通知") .setSmallIcon(R.mipmap.ic_launcher) .setLargeIcon(bmp) .setContentText("这是通知的内容") .setTicker("日程通知") // 单机 面板自动取消通知 .setAutoCancel(true) .setDefaults(Notification.DEFAULT_SOUND);// 设置通知响应方式 // .setContentIntent(pi); manager_notifica.notify(1, builder.build());// 通过管理器发送通知(通知的id,Notification对象) } }若不通过bundle接收值,则会获得空值,另外还有一点需要注意,在定义通知栏时,如果没有设置小图标(setSmallIcon(R.mipmap.ic_launcher)),通知栏只会出现声音提示,不会弹出提示框(设置大图标亦无效),若更改图标,会发现弹出的测提示框图标未更改,重新安装也不行(使用魅族note3手机如此,不知其他有没有这样的情况),后经查询
app保留原来的图标,导致新的图标无法使用,这时更换手机主题设置即可出现新设置的图标。
仍需要在清单文件中,注册广播服务:
以上整个闹钟添加与取消就可以了,源代码也已经上传,可以到资源页面下载<receiver android:name=".AlarmReceiver" android:process=":remote"></receiver>