使用 AlarmManager 定期启动服务

Start service periodically with AlarmManager

根据这些示例:here and here,我试图创建定期启动的服务。

首先我创建了服务:

public class MonitorService extends IntentService {

     private static final String TAG = "MonitorService";

     public MonitorService() {
         super(TAG);
     }

     @Override
     protected void onHandleIntent(Intent intent) {
         Log.d("TAG", "Service method was fired.");
     }

}

接下来我创建了 Receiver:

public class MyReceiver extends BroadcastReceiver {

    private static final String TAG = "MyReceiver";

    @Override
    public void onReceive(Context context, Intent intent) {
        Log.d(TAG, "MyReceiver on receive");
        Intent i = new Intent(context, MonitorService.class);
        context.startService(i);
    }

}

我在 MainActivity 中为此添加了启动方法:

public void scheduleAlarm() {
        Intent intent = new Intent(getApplicationContext(), MyReceiver.class);

        final PendingIntent pIntent = PendingIntent.getBroadcast(this, 0,
                intent, PendingIntent.FLAG_UPDATE_CURRENT);

        long firstMillis = System.currentTimeMillis();
        AlarmManager alarm = (AlarmManager) this.getSystemService(Context.ALARM_SERVICE);
        // 1s is only for testing
        alarm.setInexactRepeating(AlarmManager.RTC_WAKEUP, firstMillis, 1000, pIntent);
    }

这当然是在 onCreate 方法中调用的。

而且我没有忘记更改 AndroidManifest:

    <receiver
        android:name=".MyReceiver"
        android:process=":remote" >
    </receiver>
    <service
        android:name=".MonitorService"
        android:exported="false" />

不幸的是,结果是我的日志中没有发生任何事情。

所以我有两个问题。

问题

编辑

根据@Lasse 的提示,我开始调试,发现 Log.d 不工作,当我将其更改为 Log.i 时,记录了来自 MonitorService 的信息。

但是...调试不会在 MyReceiver 中的断点处停止,将 Log.d 更改为 Log.i 也没有帮助。当然 MonitorService 正在触发,这很奇怪。

此外,1000 毫秒的时间会导致每分钟触发一次服务,也许这是最短时间,现在更改为 AlarmManager.INTERVAL 并不重要。

编辑 2

我终于从服务和接收方都获得了日志。我试了很多次,之后就可以了,但我不知道为什么。 但是随之而来的另一个问题出现了——当我的服务是 运行

时我收到警告
 W/art: Suspending all threads took: 21.787ms

我认为服务是 运行 背景,所以不管它有多长,我应该关注这个警告吗?

已编辑

关于第一个问题: 从 developer website

看到这个
  setInexactRepeating(), you have to use       one of the AlarmManager interval constants--in this case, AlarmManager.INTERVAL_DAY.

因此将您的 1000 更改为常量的使用

关于您的其他问题,您可以覆盖应用程序对象并在那里启动它。这样它只会在启动应用程序时被调用。