AlarmManager、BroadcastReceiver 和 Service 不工作
我正在重构一些代码,以便我的应用程序每天在给定时间从网站提取数据一次。根据我的研究,AlarmManager
似乎是最合适的方法。
我一直在关注的教程是: http://mobile.tutsplus.com /tutorials/android/android-fundamentals-downloading-data-with-services/
到目前为止,AlarmManager
和 BroadcastReceiver
似乎正在工作,但是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());
}
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>
当我触发 中的
日志按预期打印,类似地,每 15 分钟就会显示一次来自 setRecurringAlarm
时MyActivityAlarmReceiver
的日志。但是,我从未看到来自 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 根本无法启动?
I'm refactoring some code so that my app will pull data from a website once a day at a given time. From my research, it seems like AlarmManager
is the most appropriate approach.
The tutorial I have been following is: http://mobile.tutsplus.com/tutorials/android/android-fundamentals-downloading-data-with-services/
So far, AlarmManager
and the BroadcastReceiver
seem to be working, however the Service
never seems to start (ie. onStartCommand
doesn't seem to be called)
Here are the important snippets of the code I have so far:
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>
When I trigger the setRecurringAlarm
in MyActivity
the log prints as expected, similarly, every 15min the log from AlarmReceiver
appears. However, I never see the log from MyService
:(
Example of what I see in the logs:
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
Can't seem to figure out what I've done wrong - my understanding from the Android Dev Docs is that in AlarmReceiver
when I call context.startService(dailyUpdater)
that should in turn call onStartCommand
in MyService
, though that doesn't seem to be the case!
What am I doing wrong that is causing MyService
to not start at all?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
想通了!
MyService 应该扩展 IntentService 而不是 Service!
通过此更改,这也意味着不应重写
onStartCommand
,而应重写onHandleIntent
(请参阅 IntentService)所以MyService现在看起来像这样:
注意:从文档中,
onBind
的默认实现返回null
所以不需要覆盖它。有关扩展
IntentService
的更多信息:http://developer.android.com /guide/topics/fundamentals/services.html#ExtendingIntentServiceFigured it out!
MyService should be extending IntentService instead of Service!
With this change, it also means that instead of overriding
onStartCommand
should be overridingonHandleIntent
instead (see docs on IntentService)So MyService now looks like this:
Note: From the docs, the default implementation of
onBind
returnsnull
so no need to override it.More information about extending
IntentService
: http://developer.android.com/guide/topics/fundamentals/services.html#ExtendingIntentService如果您像这样改变您的意图,您可以让 AlarmManager 立即运行该服务,而不是通过 BroadcastReceiver:
这可能会解决您的问题!
You could get AlarmManager to run the Service straight away rather than going through a BroadcastReceiver, if you change your intent like this:
This may solve your problem!
不要使用
Intent dailyUpdater = new Intent(context, MyService.class);
使用
Intent dailyUpdater = new Intent(this, MyService.class);
其他建议是启动服务直接来自警报,而不是发送广播并在广播接收器中启动服务。
Instead of using
Intent dailyUpdater = new Intent(context, MyService.class);
use
Intent dailyUpdater = new Intent(this, MyService.class);
Other suggestion is to start service directly from alarm rather than sending a broadcast and starting the service in broadcast receiver.