我正在重构一些代码,以便我的应用程序每天在给定时间从网站提取一次数据。根据我的研究,AlarmManager
似乎是最合适的方法。
我一直关注的教程是:http://mobile.tutsplus.com/tutorials/android/android-fundamentals-downloading-data-with-services/
到目前为止,AlarmManager
和 BroadcastReceiver
似乎在工作,但是 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/