【问题标题】:How to ensure AlarmManager survives phone restart and application kill如何确保 AlarmManager 在手机重启和应用程序终止后幸存下来
【发布时间】:2012-07-18 01:43:15
【问题描述】:

我有一个 Android 应用程序,我想在一天中的固定时间向用户发送通知

为此,我使用 AlarmManager 来安排警报,然后使用它来生成通知

但我面临的问题是,如果用户“强制关闭”应用程序,警报会被重置,因此我不会收到任何通知。这是正常行为吗?有没有办法解决这个问题?

此外,如果手机重启,闹钟也会取消。我该如何控制它?我是否需要收听电话重启事件并在那里再次安排警报?这是这里唯一的选择吗?

【问题讨论】:

  • 显示你的代码,因为alarmManager允许你发出警报,如果你重启手机仍然可以工作。

标签: android alarmmanager


【解决方案1】:

我的数据库中有一个表来存储我所有待处理的警报,以防重启。如果手机重新启动,我有一个重置警报的服务类。

private AppDatabase mDbHelper;
public class BootService extends Service {

    @Override
    public IBinder onBind(final Intent intent) {
            return null;
    }

    @Override
    public void onCreate() {
            super.onCreate();
            mDbHelper = new AppDatabase(this);
            mDbHelper.open();
    }

    @Override
    public void onStart(final Intent intent, final int startId) {
            super.onStart(intent, startId);
            LoadNotificationsFromDB();             
    }

    private void LoadNotificationsFromDB() {
            Cursor c = mDbHelper.getPendingNotifications();
            if (c.moveToFirst()) {
                    do {

                            int id = c.getInt(AppDatabase.ID_COLUMN);
                            String date = c.getString(AppDatabase.DATE_COLUMN);
                            addNotification(id, date);
                    } while (c.moveToNext());
            }
            c.close();
    }

    private void addNotification(int id, String date) {
            Intent intent = new Intent(BootService.this,    
                           NotificationBroadcastReceiver.class);

            PendingIntent mAlarmSender = PendingIntent.getBroadcast(
                            BootService.this, id, intent, 0);

            long alarmDate = Long.valueOf(date);

            AlarmManager am = (AlarmManager) getSystemService(ALARM_SERVICE);
            am.set(AlarmManager.RTC_WAKEUP, date, mAlarmSender);
    }
}

然后创建一个Receiver类:

public class BootReceiver extends BroadcastReceiver {

    @Override
    public void onReceive(final Context context, final Intent intent) {
            if ("android.intent.action.BOOT_COMPLETED".equals(intent.getAction())) {
                    Intent mServiceIntent = new Intent();
                    mServiceIntent.setAction("<package name>.BootService");
                    ComponentName service = context.startService(mServiceIntent);
                    if (null == service) {
                            // something really wrong here
                    }
            } 
    }
}

并且将以下行添加到Manifest.xml

    <receiver android:name=".BootReceiver" android:enabled="true">
            <intent-filter>
                    <action android:name ="android.intent.action.BOOT_COMPLETED"></action>
            </intent-filter>
    </receiver>
</application>
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />

【讨论】:

  • 嘿,这篇文章对我来说真的很有用,但我有一个问题......你为什么需要这项服务?如果我从引导接收器的 onReceive 重新加载警报是否相同??
  • IMO,广播接收器和服务都在 UI 线程上运行。所以在其中一个上创建它是相同的效果。如果你真的想将它移出 UI 线程,请考虑使用 IntentService,它适用于一个单独的线程。
【解决方案2】:

您将需要设置与此类似的内容以连接到启动完成的意图。

<receiver android:name="MyStartupIntentReceiver">
<intent-filter>
<action
  android:name="android.intent.action.BOOT_COMPLETED" />
<category android:name="android.intent.category.HOME" />
</intent-filter>
</receiver>

一旦你有了它,你将需要启动一个服务或做一些事情

public void onReceive(Context context, Intent intent) {
    Intent serviceIntent = new Intent();
    serviceIntent.setAction("com.yourapp.yourservice");
    context.startService(serviceIntent);
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-28
    • 1970-01-01
    相关资源
    最近更新 更多