Android app 的提醒功能
2014-11-11 15:35
369 查看
这篇文章涉及到利用AlarmManager来实现提醒功能以及在锁屏状态下弹出提醒界面的功能。
作为web的补充,移动app也需要有自己的特色功能,两者相辅相成,满足用户不同需求。
我的Android Worktile在大版本3.0.0更新之后,要增加特有功能了——提醒。这也是用户们的呼声。
第一部分 提醒功能
设置提醒时间,时间到时弹出提醒界面
1.首先在配置文件manifest中注册一个receiver来接收AlarmManager发送的广播。
关键点:PendingIntent.getBroadcast方法的第二个参数可以保证设置多个提醒,通过id来区分是新提醒,还是更新提醒,第四个参数可以保证可以更新提醒的时间;AlarmManager的set方法的第二个参数是提醒的时间,当第二个参数的时间到后,RemindReceiver的onReceive方法会被调用。因此在该方法中弹出提醒界面。
3.弹出提醒界面
事情如果如此简单,生活该多美好。
问题1.这种方法在app意外崩溃之后(无法避免简直),或者关机重启后(电量伤不起),所设置的提醒会无效。
问题2.(我们的需求是给日程设置提醒)已经设置过提醒的日程应该显示提醒时间,没有设置过提醒的日程显示“未设置”。而AlarmManager的api方法没有获取所有提醒事件的方法,无从知道哪个日程被设置为提醒了。
问题3.日程有按日/周/月/年重复。AlarmManager可以设置重复提醒。有方法可以调用 日周好说,可月年。。。
由问题1和问题2,想到必须要把设置过的提醒存储起来。Android的轻量数据库方便简洁,而ormlite让存储更简单。
在给日程设置提醒时,在数据库中增加一条记录,记录该日程的相关信息。
在显示日程详情时,去数据库查看是否有记录,有?获取提醒时间:不显示提醒时间(问题2完败)
取消日程的提醒时,取消提醒的同时从数据库删除该条记录。删除该日程时,同理。
在Application类的onCreate方法中遍历数据库的记录,设置提醒。这样,只要用户在使用app,降低了落下提醒的概率。缓解问题1。
另外,app 中有推送,而推送的receiver监听了USER_PRESENT,而application的onCreate方法会在四大组件创建之前调用。
onCreate()
Called when the application is starting, before any activity, service, or receiver objects (excluding content providers) have been created.
也就是说,当用户关机再开机时,会调用推送的receiver的onReceive方法,而在此之前会调用application的onCreate方法,这样看来,应该不会错过提醒了。
关于问题3 ,如何按月按年设置重复提醒。我的解决办法是这样的:
在记录提醒的数据库中会记录初次提醒时间和是否重复的flag。
在application的onCreate方法中设置提醒时比较系统当前时间和提醒的提醒时间。如果系统时间大于提醒时间而且是重复提醒,则设置提醒时间为下一周期(月或年),更新数据库的提醒时间为下一周期。
application的onCreate调用的设置提醒方法
ProjectUtil.remind:
第二部分 弹出提醒界面
提醒界面的注册:
锁屏时 显示壁纸背景+提示框(类似QQ的锁屏通知)
un锁屏时,显示当前显示界面+提示框
利益相关:worktile
搜索IT技术哪家强,Google比百度好的不是一星半点,定位问题快很多。红杏 访问墙外网站更方便。
作为web的补充,移动app也需要有自己的特色功能,两者相辅相成,满足用户不同需求。
我的Android Worktile在大版本3.0.0更新之后,要增加特有功能了——提醒。这也是用户们的呼声。
第一部分 提醒功能
设置提醒时间,时间到时弹出提醒界面
1.首先在配置文件manifest中注册一个receiver来接收AlarmManager发送的广播。
<receiver android:name="com.worktile.core.utils.RemindReceiver" > </receiver>2.设置提醒时间
Intent intent = new Intent(context, RemindReceiver.class); intent.putExtra("data", bundle);//携带提醒界面的信息。 PendingIntent sender = PendingIntent.getBroadcast(context, bundle.getString("xid").hashCode(), intent, PendingIntent.FLAG_UPDATE_CURRENT); AlarmManager manager = (AlarmManager) context.getSystemService(Activity.ALARM_SERVICE); manager.set(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), sender);
关键点:PendingIntent.getBroadcast方法的第二个参数可以保证设置多个提醒,通过id来区分是新提醒,还是更新提醒,第四个参数可以保证可以更新提醒的时间;AlarmManager的set方法的第二个参数是提醒的时间,当第二个参数的时间到后,RemindReceiver的onReceive方法会被调用。因此在该方法中弹出提醒界面。
3.弹出提醒界面
@Override public void onReceive(Context context, Intent intent) { Intent intent_remind = new Intent(context, RemindActivity.class); intent_remind.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); intent_remind.putExtra("data", intent.getBundleExtra("data"));//<span style="font-family: Arial, Helvetica, sans-serif;">提醒界面的信息的相关信息被传递到这里</span> context.startActivity(intent_remind); }
事情如果如此简单,生活该多美好。
问题1.这种方法在app意外崩溃之后(无法避免简直),或者关机重启后(电量伤不起),所设置的提醒会无效。
问题2.(我们的需求是给日程设置提醒)已经设置过提醒的日程应该显示提醒时间,没有设置过提醒的日程显示“未设置”。而AlarmManager的api方法没有获取所有提醒事件的方法,无从知道哪个日程被设置为提醒了。
问题3.日程有按日/周/月/年重复。AlarmManager可以设置重复提醒。有方法可以调用 日周好说,可月年。。。
manager.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), AlarmManager.INTERVAL_DAY, sender);</span>
manager.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), AlarmManager.INTERVAL_DAY*7, sender)
由问题1和问题2,想到必须要把设置过的提醒存储起来。Android的轻量数据库方便简洁,而ormlite让存储更简单。
在给日程设置提醒时,在数据库中增加一条记录,记录该日程的相关信息。
在显示日程详情时,去数据库查看是否有记录,有?获取提醒时间:不显示提醒时间(问题2完败)
取消日程的提醒时,取消提醒的同时从数据库删除该条记录。删除该日程时,同理。
public static void unRemind(Context context, Bundle bundle) {// 取消注册Intent intent = new Intent(context, RemindReceiver.class);PendingIntent sender = PendingIntent.getBroadcast(context, bundle.getString("xid").hashCode(), intent, PendingIntent.FLAG_UPDATE_CURRENT);AlarmManager manager = (AlarmManager) context.getSystemService(Activity.ALARM_SERVICE);manager.cancel(sender);// 数据库删除try {RemindDataUtil util = new RemindDataUtil(RemindDataUtil.getHelper(context).getRemindDataDao(), bundle.getString("xid"));util.delete();} catch (SQLException e) {e.printStackTrace();}}
在Application类的onCreate方法中遍历数据库的记录,设置提醒。这样,只要用户在使用app,降低了落下提醒的概率。缓解问题1。
另外,app 中有推送,而推送的receiver监听了USER_PRESENT,而application的onCreate方法会在四大组件创建之前调用。
onCreate()
Called when the application is starting, before any activity, service, or receiver objects (excluding content providers) have been created.
也就是说,当用户关机再开机时,会调用推送的receiver的onReceive方法,而在此之前会调用application的onCreate方法,这样看来,应该不会错过提醒了。
关于问题3 ,如何按月按年设置重复提醒。我的解决办法是这样的:
在记录提醒的数据库中会记录初次提醒时间和是否重复的flag。
在application的onCreate方法中设置提醒时比较系统当前时间和提醒的提醒时间。如果系统时间大于提醒时间而且是重复提醒,则设置提醒时间为下一周期(月或年),更新数据库的提醒时间为下一周期。
application的onCreate调用的设置提醒方法
private void initRemind() { try { List<Remind> reminds = RemindDataUtil.getHelper(mContext).getRemindDataDao().queryForAll(); for (Remind remind : reminds) { Bundle data = new Bundle(); data.putInt("type", RemindActivity.TYPE_EVENT); data.putString("xid", remind.id); data.putString("projectId", remind.pid); data.putString("name", remind.name); data.putInt("repeat", remind.repeat); Calendar calendar = Calendar.getInstance(); calendar.setTimeInMillis(remind.time); ProjectUtil.remind(mContext, calendar, data); } } catch (SQLException e) { e.printStackTrace(); } }
ProjectUtil.remind:
public static void remind(Context context, Calendar calendar, Bundle bundle) { int rep 4000 eat = bundle.getInt("repeat"); // 进行闹铃注册 Intent intent = new Intent(context, RemindReceiver.class); intent.putExtra("data", bundle); PendingIntent sender = PendingIntent.getBroadcast(context, bundle.getString("xid").hashCode(), intent, PendingIntent.FLAG_UPDATE_CURRENT); AlarmManager manager = (AlarmManager) context.getSystemService(Activity.ALARM_SERVICE); switch (repeat) { case 1:// 天 manager.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), AlarmManager.INTERVAL_DAY, sender); break; case 2:// 周 manager.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), AlarmManager.INTERVAL_DAY * 7, sender); break; case 3:// 月 if (calendar.getTimeInMillis() < System.currentTimeMillis()) calendar.add(Calendar.MONTH, 1); manager.set(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), sender); break; case 4:// 年 if (calendar.getTimeInMillis() < System.currentTimeMillis()) calendar.add(Calendar.YEAR, 1); manager.set(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), sender); break; case 0: manager.set(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), sender); break; } // 存进数据库 try { RemindDataUtil util = new RemindDataUtil(RemindDataUtil.getHelper(context).getRemindDataDao()); Remind remind = new Remind(); remind.id = bundle.getString("xid"); remind.pid = bundle.getString("projectId"); remind.name = bundle.getString("name"); remind.time = calendar.getTimeInMillis(); remind.repeat = repeat; util.add(remind); } catch (SQLException e) { e.printStackTrace(); } }
第二部分 弹出提醒界面
提醒界面的注册:
<activity android:name="com.worktile.ui.uipublic.RemindActivity" android:label="@string/app_name"android:theme="@style/activity_dialog_remind_unlock" ></activity>
<style name="activity_dialog_remind_unlock" parent="@android:style/Theme.Translucent.NoTitleBar"></style>
<style name="activity_dialog_remind_unlock" parent="@android:style/Theme.Translucent.NoTitleBar"></style>
锁屏时 显示壁纸背景+提示框(类似QQ的锁屏通知)
un锁屏时,显示当前显示界面+提示框
@Override protected void onCreate(Bundle savedInstanceState) { KeyguardManager mKeyguardManager = (KeyguardManager) getSystemService(KEYGUARD_SERVICE); if (mKeyguardManager.inKeyguardRestrictedInputMode()) { // 锁屏状态 setTheme(R.style.activity_dialog_remind); } super.onCreate(savedInstanceState); mp = new MediaPlayer(); getWindow().addFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED | WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON); setContentView(R.layout.activity_remind); }
利益相关:worktile
搜索IT技术哪家强,Google比百度好的不是一星半点,定位问题快很多。红杏 访问墙外网站更方便。
相关文章推荐
- android 2.3 app没有 android.permission.MODIFY_PHONE_STATE权限,导致来电自动接听功能难以实现
- android学习—— 简单的实现 android 退出app 的功能, 非 restartPackage
- 在android App中怎样实现对设备重启或者关机功能
- android APP 中微信分享功能实现 的总结
- Android系统的改进(五)-- 没有精确的电量提醒功能
- (转)[教你开启冻酸奶的app2sd] android2.2的APP TO SD功能启动方法
- Android App“记住密码”功能的实现逻辑
- Android 之 自动提醒功能(AutoCompleteTextView)的使用
- Android App开发记录 —配置文件的功能
- android APP 中微信分享功能实现 的总结
- Android中实现Launcher功能之二 ----- 添加窗口小部件以及AppWidget的创建详解
- Android中实现Launcher功能之二 ----- 添加窗口小部件以及AppWidget的创建详解
- Android中实现Launcher功能之二 ----- 添加窗口小部件以及AppWidget的创建详解
- Android APP混淆后,友盟分享功能出错的解决办法
- Android App插件功能实现调研
- Android中给图标加上数字(用于未接来电等等功能的提醒)
- Android app“版本更新”功能的前后端实现
- android-数字提醒,类似邮箱的未读邮件功能
- Android APP中清除缓存功能详解
- android------(桌面小玩意-getBroadcast)AppWidget(功能:可更改桌面图片、文字)