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

发布于 2024-11-17 07:51:39 字数 540 浏览 3 评论 0原文

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

假设您有一个应用程序,允许用户存储下一次牙科预约(或任何预约 - 这并不重要 - 但假设每年只有 1 或 2 次预约)的提醒。当约会临近时,它应该会弹出一个通知,即使应用程序没有运行(假设手机已打开),它也会工作。

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

  1. 如果应用程序安装到 SD 卡上,它就不起作用(许多用户会攻击不提供 app2sd 支持的应用程序)。

  2. 如果没有存储提醒,服务仍必须在启动时运行才能发现这一点。据我所知,不可能仅在需要时以编程方式设置 BOOT_COMPLETED 侦听器。

  3. 没有人希望他们的手机在启动时陷入这些类型的服务的困境。

所以我想知道是否有人知道更好的解决方案?我只想存储一个长期约会。最好使用内部 Android 服务,而不依赖于访问 Google 日历等或类似的东西。有什么想法吗?

What is the best way to setup an appointment reminder on Android? I am hoping there is something better than AlarmManager.

Lets say you have an app that allows the user to store a reminder for their next dental appointment (or any appointment - it doesn't matter - but assume there is only 1 or 2 appointments per year). As that appointment approaches it should pop-up a notification, and it will work even if the app isn't running (assuming the phone is switched on).

The AlarmManager could do it, but it would have to be reactivated every time the device reboots. This is ugly for 3 reasons:-

  1. It doesn't work if the app is installed to the SD card (and many users will flame apps that don't provide app2sd support).

  2. If there isn't a reminder stored the service must still run at boot-up to discover that. To my knowledge it's impossible to programmatically setup a BOOT_COMPLETED listener for only when it's needed.

  3. Nobody wants their phone to be bogged down with these types of services at boot-up.

So I was wondering if anyone knew of a better solution? I just want to store a long-term appointment. Preferably using internal Android services without relying on access to Google calender etc, or anything like that. Any ideas?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

水波映月 2024-11-24 07:51:39

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

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

至于SD卡,您可以观看 http://developer.android .com/reference/android/content/Intent.html#ACTION_EXTERNAL_APPLICATIONS_AVAILABLE 了解外部存储何时重新安装以及您的应用程序可以再次运行。

The correct solution is the AlarmManager. You can programmatically change whether you are launched at boot by using PackageManager.setComponentEnabledSetting() to enable your receiver component only when you have an alarm scheduled.

In practice there is no use in the AlarmManager retaining alarms across boots, because the vast majority of apps need to re-evaluate the alarms after a boot. For example, a calendar needs to resync them etc. And retaining them has a big downside: bugs in applications can leave junk data in the alarm manager that even a reboot won't clear out.

As for the SD card, you can watch for http://developer.android.com/reference/android/content/Intent.html#ACTION_EXTERNAL_APPLICATIONS_AVAILABLE to find out when the external storage is re-mounted and your app can run again.

优雅的叶子 2024-11-24 07:51:39

不幸的是,除了 BOOT_COMPLETED 意图之外,确实没有其他选择,并且 SD 问题可能不会改变。如果你想要这个功能,你只需要忍受无知的用户对你的攻击。如果你做得不错,启动接收器不会显着减慢设备速度。

一种替代方案是短信侦听器,您可以在所需的时间发送包含触发信息的短信:无需启动接收器,如果没有预约,则不会进行任何活动。就短信广播接收器而言,更具侵入性,但您并没有足够的选择。您还可以以类似的方式使用 C2DM,但是这些选项(SMS 或 C2DM)中的任何一个都需要更多的服务器端基础设施(即,比没有)。

就SD问题而言,实际的解决方案是设备制造商效仿iPhone,在每台设备上安装相对大量且无法拆卸的闪存:坦率地说,SD疯狂是完全没有必要的。我可以以 4 美元的零售价购买 4GB SD 闪存:如果这对于设备供应商/运营商来说太贵而无法提供卓越的用户体验,那么他们应该倒闭。

Unfortunately there really isn't an alternative to the BOOT_COMPLETED intent, and the SD issue probably won't change. If you want this functionality you will just need to live with ignorant users flaming you. If you do a decent job the boot receiver won't significantly slow the device down.

One alternative would be an SMS listener and you send an SMS with triggering info at the required time: no boot receiver necessary, no activity if they don't hav a appointment. Somewhat more intrusive as far as the SMS broadcast receiver goes, but you're not exactly blessed with choices. You could also use C2DM in a similar fashion, but either of those options (SMS or C2DM) require significantly more server side infrastructure (i.e. moe than none).

As far as the SD issue is concerned, the actual solution is for device manufacturers to do what the iphone does, and put a comparatively massive amount of flash that can't be removed on each device: the SD craziness is quite frankly utterly unnecessary. I can buy a 4gb sd flash for $4 retail: if that is too expensive for the device vendors/carriers to provide a superior user experience then they deserve to go out of business.

寻梦旅人 2024-11-24 07:51:39

如果没有存储提醒,服务仍必须在启动时运行才能发现这一点。据我所知,不可能仅在需要时以编程方式设置 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 侦听器,其中包括一堆来自操作系统的侦听器。我同意,如果不需要组件,则禁用该组件是一种很好的形式,因为这不太难实现。但是,当真正需要它时,我不会担心它。

If there isn't a reminder stored the service must still run at boot-up to discover that. To my knowledge it's impossible to programmatically setup a BOOT_COMPLETED listener for only when it's needed.

Sure there is. Simply disable the component using PackageManager, enabling it when needed. For example, here is an OnSharedPreferenceChangeListener that enables/disables a boot-time receiver based upon whether the user checks an "alarm" 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);
        }
    }
};

Nobody wants their phone to be bogged down with these types of services at boot-up.

A recent test indicated that there are dozens of BOOT_COMPLETED listeners on a conventional Android device, including a bunch from the OS. I agree that it's good form to disable the component if it is not needed, since that's not too tough to implement. However, I wouldn't worry about it when it is truly needed.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文