AlarmManager,BroadcastReceiver和Service无法正常工作

pyk*_*yko 13 android broadcastreceiver alarmmanager android-pendingintent

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

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

到目前为止,AlarmManagerBroadcastReceiver似乎工作,然而Service似乎从来没有开始(即onStartCommand似乎没有被调用)

以下是我到目前为止的代码的重要摘要:

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());
}
Run Code Online (Sandbox Code Playgroud)

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");
    }
}
Run Code Online (Sandbox Code Playgroud)

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;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

AndroidManifest.xml中

<application ...>
    ...
    <service android:name="MyService"></service>
    <receiver android:name="AlarmReceiver"></receiver>
</application>
Run Code Online (Sandbox Code Playgroud)

当我触发setRecurringAlarmMyActivity预期,同样,每次15min的从日志日志打印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
Run Code Online (Sandbox Code Playgroud)

似乎无法找出我错了做-我从了解Android开发文档的是,AlarmReceiver当我叫context.startService(dailyUpdater)应依次调用onStartCommandMyService,尽管这似乎并没有这样的情况!

我做错了什么导致MyService根本没有开始?

pyk*_*yko 15

弄清楚了!

MyService应该扩展IntentService而不是Service!

通过此更改,它还意味着onStartCommand应该覆盖onHandleIntent而不是覆盖(请参阅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;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

注意:从文档中,onBind返回的默认实现null因此无需覆盖它.

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