在Android上创建约会提醒的最佳方式是什么?

在Android上创建约会提醒的最佳方式是什么?,android,alarmmanager,Android,Alarmmanager,在Android上设置约会提醒的最佳方式是什么?我希望有比AlarmManager更好的东西 假设你有一个应用程序,允许用户为他们的下一次牙科预约(或任何预约——没关系——但假设每年只有1到2次预约)存储提醒。当约会临近时,它会弹出一个通知,即使应用程序没有运行(假设手机已打开),它也会工作 AlarmManager可以做到这一点,但每次设备重新启动时都必须重新激活它。这是丑陋的,原因有三:- 如果将应用程序安装到SD卡上,它将不起作用(许多用户会使用不支持app2sd的应用程序) 如果没有存储

在Android上设置约会提醒的最佳方式是什么?我希望有比AlarmManager更好的东西

假设你有一个应用程序,允许用户为他们的下一次牙科预约(或任何预约——没关系——但假设每年只有1到2次预约)存储提醒。当约会临近时,它会弹出一个通知,即使应用程序没有运行(假设手机已打开),它也会工作

AlarmManager可以做到这一点,但每次设备重新启动时都必须重新激活它。这是丑陋的,原因有三:-

  • 如果将应用程序安装到SD卡上,它将不起作用(许多用户会使用不支持app2sd的应用程序)

  • 如果没有存储提醒,则服务必须在启动时仍运行才能发现。据我所知,仅在需要时才以编程方式设置引导完成的侦听器是不可能的

  • 没有人希望他们的手机在开机时被这些类型的服务困住


  • 所以我想知道是否有人知道更好的解决方案?我只想储存一个长期约会。最好使用内部安卓服务,而不依赖谷歌日历等,或诸如此类的访问。有什么想法吗?

    不幸的是,除了BOOT_COMPLETED意图之外,真的没有其他选择,SD问题可能不会改变。如果你想要这个功能,你只需要和无知的用户一起生活。如果你做得很好,引导接收器不会显著降低设备的速度

    另一种选择是SMS侦听器,您在所需时间发送带有触发信息的SMS:不需要启动接收器,如果他们没有预约,则不需要活动。就短信广播接收器而言,它更具侵扰性,但你并没有足够的选择。您也可以以类似的方式使用C2DM,但这些选项(SMS或C2DM)中的任何一个都需要大量的服务器端基础设施(即moe,而不是无)


    就SD问题而言,实际的解决方案是让设备制造商像iphone一样,在每台设备上都安装大量无法移除的闪存:坦率地说,SD的疯狂是完全没有必要的。我可以以4美元的零售价购买4gb sd闪存:如果这对于设备供应商/运营商来说太贵,无法提供卓越的用户体验,那么他们应该停业。

    正确的解决方案是AlarmManager。您可以通过使用PackageManager.setComponentEnabledSetting()以编程方式更改是否在启动时启动,以便仅在计划报警时启用接收器组件

    实际上,AlarmManager在引导过程中保留警报是没有用的,因为绝大多数应用程序在引导后都需要重新评估警报。例如,日历需要重新同步它们等等,保留它们有一个很大的缺点:应用程序中的bug会在alarm manager中留下垃圾数据,即使重新启动也无法清除

    至于SD卡,你可以观察外部存储何时重新安装,你的应用程序何时可以再次运行

    如果没有存储提醒,则服务必须在启动时仍运行才能发现。据我所知,仅在需要时才以编程方式设置引导完成的侦听器是不可能的

    当然有。只需使用
    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);
            }
        }
    };
    
    没有人希望他们的手机在开机时被这些类型的服务困住


    最近的一项测试表明,在传统的安卓设备上有几十个
    BOOT_完成的
    监听器,包括一堆来自操作系统的监听器。我同意,如果不需要组件,最好禁用它,因为实现起来并不太困难。不过,如果真的需要,我不会担心的。

    非常感谢Dianne,我真的很感谢你抽出时间回答。这让我更好地理解了为什么在重新启动时清除AlarmManager。我将坚持使用AlarmManager,因为我现在更加相信它适合此任务。我打算在不需要启动接收器时使用PackageManager来禁用它,因为这似乎是正确的做法,所以很高兴知道这是可能的。监听外部应用程序意味着我可以为错过启动完成事件的app2sd用户设置AlarmManager。看来一切都很好。再次非常感谢,非常感谢菲米。我对C2DM选项很感兴趣,但它只能从Android 2.2开始使用,我必须支持1.5版本。短信对我来说太贵了。因此,我现在将坚持使用AlarmManager,但我真的很欣赏其他的想法。在SD卡问题上,我完全同意你的看法,我迫不及待地想让大多数设备都有更好的内部存储,这样当前对SD卡的狂热就会消失。非常感谢马克。很高兴知道它可以通过编程方式禁用。我错误地认为它是硬连线的,因为我在清单中声明了它,但是你让我意识到我仍然可以通过PackageManager禁用它。我很感谢你抽出时间回答我的问题,因为我非常珍视你在安卓领域的书籍、教诲和知识。