在Android上设置约会提醒的最佳方法是什么?我希望有比AlarmManager更好的东西。
假设您有一个应用程序,允许用户存储他们下一次牙科预约的提醒(或任何预约 - 这无关紧要 - 但假设每年只有1或2个预约)。当该约会接近时,它应该弹出一个通知,即使应用程序没有运行它也会起作用(假设手机已打开)。
AlarmManager可以执行此操作,但每次设备重新启动时都必须重新激活。这很丑陋有三个原因: -
如果将应用程序安装到SD卡上,它将无效(许多用户将点燃不提供app2sd支持的应用程序)。
如果没有存储提醒,则服务必须仍然在启动时运行才能发现。据我所知,只有在需要时才能以编程方式设置BOOT_COMPLETED监听器。
没有人希望他们的手机在启动时陷入这些类型的服务中。
所以我想知道是否有人知道更好的解决方案?我只想存一个长期约会。最好使用内部Android服务,而不依赖于访问谷歌日历等,或类似的东西。有什么想法吗?
答案 0 :(得分:5)
正确的解决方案是AlarmManager。您可以通过使用PackageManager.setComponentEnabledSetting()以编程方式更改是否在引导时启动,以便仅在安排警报时启用接收器组件。
实际上,AlarmManager在引导期间保留警报是没有用的,因为绝大多数应用程序需要在引导后重新评估警报。例如,日历需要重新同步等等。保留它们有一个很大的缺点:应用程序中的错误可能会在报警管理器中留下垃圾数据,即使重启也无法清除。
对于SD卡,您可以查看http://developer.android.com/reference/android/content/Intent.html#ACTION_EXTERNAL_APPLICATIONS_AVAILABLE以了解何时重新安装外部存储设备并且您的应用可以再次运行。
答案 1 :(得分:1)
不幸的是,实际上没有替代BOOT_COMPLETED意图,SD问题可能不会改变。如果你想要这个功能,你只需要和无知的用户一起生活。如果你做得不错,启动接收器不会显着降低设备速度。
一种替代方案是SMS监听器,您可以在所需的时间发送带有触发信息的SMS:无需启动接收器,如果没有预约,则无活动。对于短信广播接收机而言,有点更具侵入性,但你并不完全有选择的祝福。您也可以以类似的方式使用C2DM,但这些选项(SMS或C2DM)中的任何一个都需要更多的服务器端基础结构(即moe而不是没有)。
就SD问题而言,实际的解决方案是让设备制造商做iphone所做的事情,并在每台设备上放置相对大量的无法移除的闪存:SD疯狂坦率地说完全没必要。我可以以零售价4美元的价格购买4gb sd闪存:如果设备供应商/运营商为了提供卓越的用户体验而过于昂贵,那么他们就应该破产。
答案 2 :(得分:0)
如果没有存储提醒,则服务必须仍然在启动时运行才能发现。据我所知,只有在需要时才能以编程方式设置BOOT_COMPLETED监听器。
当然有。只需使用PackageManager
禁用该组件,并在需要时启用它。例如,这里有OnSharedPreferenceChangeListener
,根据用户是否检查“警报”CheckBoxPreference
启用/禁用启动时接收器:
SharedPreferences.OnSharedPreferenceChangeListener onChange=
new SharedPreferences.OnSharedPreferenceChangeListener() {
public void onSharedPreferenceChanged(SharedPreferences prefs, String key) {
if ("alarm".equals(key)) {
boolean enabled=prefs.getBoolean(key, false);
int flag=(enabled ?
PackageManager.COMPONENT_ENABLED_STATE_ENABLED :
PackageManager.COMPONENT_ENABLED_STATE_DISABLED);
ComponentName component=new ComponentName(EditPreferences.this,
OnBootReceiver.class);
getPackageManager()
.setComponentEnabledSetting(component, flag,
PackageManager.DONT_KILL_APP);
if (enabled) {
OnBootReceiver.setAlarm(EditPreferences.this);
}
else {
OnBootReceiver.cancelAlarm(EditPreferences.this);
}
}
else if ("alarm_time".equals(key)) {
OnBootReceiver.cancelAlarm(EditPreferences.this);
OnBootReceiver.setAlarm(EditPreferences.this);
}
}
};
没有人希望他们的手机在启动时被这些类型的服务陷入困境。
最近的一项测试表明,传统的Android设备上有数十个BOOT_COMPLETED
个侦听器,其中包括来自操作系统的一堆。我同意,如果不需要它,那么禁用组件是一种很好的形式,因为这不是很难实现的。但是,当真正需要它时,我不会担心它。