android - AlarmManager、BroadcastReceiver 和服务不工作

标签 android broadcastreceiver alarmmanager android-pendingintent

我正在重构一些代码,以便我的应用程序每天在给定时间从网站提取一次数据。根据我的研究,AlarmManager 似乎是最合适的方法。

我一直关注的教程是:http://mobile.tutsplus.com/tutorials/android/android-fundamentals-downloading-data-with-services/

到目前为止,AlarmManagerBroadcastReceiver 似乎在工作,但是 Service 似乎从未启动(即 onStartCommand 好像没有调用)

以下是我目前拥有的代码的重要 fragment :

MyActivity.java

private void setRecurringAlarm(Context context) {
    Calendar updateTime = Calendar.getInstance();
    updateTime.setTimeZone(TimeZone.getDefault());
    updateTime.set(Calendar.HOUR_OF_DAY, 20);
    updateTime.set(Calendar.MINUTE, 30);

    Intent downloader = new Intent(context, AlarmReceiver.class);
    downloader.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, downloader, PendingIntent.FLAG_CANCEL_CURRENT);
    AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
    // should be AlarmManager.INTERVAL_DAY (but changed to 15min for testing)
    alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, updateTime.getTimeInMillis(), AlarmManager.INTERVAL_FIFTEEN_MINUTES, pendingIntent); 
    Log.d("MyActivity", "Set alarmManager.setRepeating to: " + updateTime.getTime().toLocaleString());
}

AlarmReceiver.java

public class AlarmReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        Intent dailyUpdater = new Intent(context, MyService.class);
        context.startService(dailyUpdater);
        Log.d("AlarmReceiver", "Called context.startService from AlarmReceiver.onReceive");
    }
}

MyService.java

public class MyService extends Service {

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Log.d("MyService", "About to execute MyTask");
        new MyTask().execute();
        return Service.START_FLAG_REDELIVERY;
    }

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

    private class MyTask extends AsyncTask<String, Void, boolean> {
        @Override
        protected boolean doInBackground(String... strings) {
            Log.d("MyService - MyTask", "Calling doInBackground within MyTask");
            return false;
        }
    }
}

AndroidManifest.xml

<application ...>
    ...
    <service android:name="MyService"></service>
    <receiver android:name="AlarmReceiver"></receiver>
</application>

当我在 MyActivity 中触发 setRecurringAlarm 时,日志会按预期打印,同样地,每隔 15 分钟就会出现来自 AlarmReceiver 的日志。但是,我从未看到来自 MyService 的日志 :(

我在日志中看到的示例:

DEBUG/MyActivity(688): Set alarmManager.setRepeating to: Jan 29, 2012 8:30:06 PM
DEBUG/AlarmReceiver(688): Called context.startService from AlarmReceiver.onReceive
DEBUG/AlarmReceiver(688): Called context.startService from AlarmReceiver.onReceive

似乎无法弄清楚我做错了什么 - 我对 Android Dev Docs 的理解是在 AlarmReceiver 中,当我调用 context.startService(dailyUpdater) 时,它应该依次调用 MyService 中的 onStartCommand,尽管事实并非如此!

我做错了什么导致 MyService 根本无法启动?

最佳答案

想通了!

MyService 应该扩展 IntentService 而不是 Service!

有了这个变化,这也意味着应该覆盖 onHandleIntent 而不是覆盖 onStartCommand(参见 IntentService 上的文档)

所以 MyService 现在看起来像这样:

public class MyService extends IntentService {

    public MyService() {
        super("MyServiceName");
    }

    @Override
    protected void onHandleIntent(Intent intent) {
        Log.d("MyService", "About to execute MyTask");
        new MyTask().execute();
    }

    private class MyTask extends AsyncTask<String, Void, boolean> {
        @Override
        protected boolean doInBackground(String... strings) {
            Log.d("MyService - MyTask", "Calling doInBackground within MyTask");
            return false;
        }
    }
}

注意:根据文档,onBind 的默认实现返回 null,因此无需覆盖它。

有关扩展 IntentService 的更多信息:http://developer.android.com/guide/topics/fundamentals/services.html#ExtendingIntentService

关于android - AlarmManager、BroadcastReceiver 和服务不工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9053249/

相关文章:

java - NGN 堆栈主叫方 ID/详细信息问题

Android:有时不触发警报

android - 屏幕锁定后更新 UI

android - 我在 Android Studio 中收到广播接收器错误作为空点异常。我想接收 GCM 通知

安卓设计 : background long running service or AlarmManager?

android - 应用程序未运行时的 BroadcastReceiver

android - 如何实现android分秒选择器?

android - APP_STL := gnuSTL_static is broken in Android NDK 8c through 8e

android - 如何将用户的支出与他们在 Firebase 中的个人资料相关联?

android - 警报没有停止