Android AlarmManager、广播接收器和服务不工作

Android AlarmManager、广播接收器和服务不工作,android,broadcastreceiver,alarmmanager,android-pendingintent,Android,Broadcastreceiver,Alarmmanager,Android Pendingintent,我正在重构一些代码,以便我的应用程序每天在给定的时间从网站上提取数据一次。根据我的研究,似乎AlarmManager是最合适的方法 我一直遵循的教程是: 到目前为止,AlarmManager和BroadcastReceiver似乎正在工作,但是服务似乎从未启动(即,onStartCommand似乎没有被调用) 以下是到目前为止我掌握的重要代码片段: MyActivity.java private void setRecurringAlarm(上下文){ Calendar updateTime=C

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

我一直遵循的教程是:

到目前为止,
AlarmManager
BroadcastReceiver
似乎正在工作,但是
服务似乎从未启动(即,
onStartCommand
似乎没有被调用)

以下是到目前为止我掌握的重要代码片段:

MyActivity.java

private void setRecurringAlarm(上下文){
Calendar updateTime=Calendar.getInstance();
setTimeZone(TimeZone.getDefault());
updateTime.set(Calendar.HOUR\u OF_DAY,20);
updateTime.set(Calendar.MINUTE,30);
意向下载器=新意向(上下文,AlarmReceiver.class);
downloader.addFlags(Intent.FLAG\u ACTIVITY\u NEW\u TASK);
PendingEvent PendingEvent=PendingEvent.getBroadcast(上下文,0,下载程序,PendingEvent.FLAG_CANCEL_CURRENT);
AlarmManager AlarmManager=(AlarmManager)getSystemService(Context.ALARM\u服务);
//应为AlarmManager.INTERVAL_DAY(但测试更改为15分钟)
alarmManager.setRepeating(alarmManager.RTC_唤醒,updateTime.getTimeInMillis(),alarmManager.INTERVAL_十五分钟,挂起内容);
Log.d(“MyActivity”,“将alarmManager.setRepeating设置为:”+updateTime.getTime().toLocaleString());
}
AlarmReceiver.java

公共类AlarmReceiver扩展了BroadcastReceiver{
@凌驾
公共void onReceive(上下文、意图){
Intent dailyUpdater=新的Intent(上下文,MyService.class);
startService(dailyUpdater);
Log.d(“AlarmReceiver”,“从AlarmReceiver.onReceive调用context.startService”);
}
}
MyService.java

公共类MyService扩展服务{
@凌驾
公共int onStartCommand(Intent Intent、int标志、int startId){
Log.d(“MyService”,“即将执行MyTask”);
新建MyTask().execute();
退货服务。开始\标志\重新交付;
}
@凌驾
公共IBinder onBind(意向){
返回null;
}
私有类MyTask扩展了AsyncTask{
@凌驾
受保护的布尔doInBackground(字符串…字符串){
d(“MyService-MyTask”,“在MyTask中调用doInBackground”);
返回false;
}
}
}
AndroidManifest.xml

是在
AlarmReceiver
中,当我调用
context.startService(dailyUpdater)
时,它应该依次调用
MyService
中的
onStartCommand
,尽管情况似乎并非如此


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

如果您这样改变您的意图,您可以让AlarmManager立即运行服务,而不是通过广播接收器:

//Change the intent
Intent downloader = new Intent(context, MyService.class);
    downloader.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

//Change to getService()
PendingIntent pendingIntent = PendingIntent.getService(context, 0, downloader, PendingIntent.FLAG_CANCEL_CURRENT);
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;
        }
    }
}
这可能会解决你的问题

而不是使用

Intent dailyUpdater=newintent(上下文,MyService.class)

使用

Intent dailyUpdater=newintent(这个,MyService.class)

另一个建议是直接从警报启动服务,而不是发送广播并在广播接收器中启动服务。

明白了

MyService应该扩展IntentService而不是服务

有了此更改,还意味着除了覆盖
onStartCommand
之外,还应该覆盖
onhandlecontent
(请参见上的文档)

因此,MyService现在看起来是这样的:

//Change the intent
Intent downloader = new Intent(context, MyService.class);
    downloader.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

//Change to getService()
PendingIntent pendingIntent = PendingIntent.getService(context, 0, downloader, PendingIntent.FLAG_CANCEL_CURRENT);
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;
        }
    }
}
公共类MyService扩展了IntentService{
公共MyService(){
超级(“我的服务名”);
}
@凌驾
受保护的手部内容无效(意图){
Log.d(“MyService”,“即将执行MyTask”);
新建MyTask().execute();
}
私有类MyTask扩展了AsyncTask{
@凌驾
受保护的布尔doInBackground(字符串…字符串){
d(“MyService-MyTask”,“在MyTask中调用doInBackground”);
返回false;
}
}
}
注意:从文档中,
onBind
的默认实现返回
null
,因此无需覆盖它


有关扩展
IntentService
的更多信息:

感谢您的建议-我以前尝试过这个方法(虽然没有downloader.addFlags),但它不起作用-将尝试使用addFlags,看看是否有帮助!只是想知道,如果你可以直接运行服务,“BroadcastReceiver”为什么会存在?尝试了此更改-不起作用:(还尝试了按照kumar的建议将
上下文更改为
。。也不走运!你试过没有下载程序的代码吗?addFlags(Intent.FLAG\u ACTIVITY\u NEW\u TASK);嗨,库马尔,是的,我相信我在没有添加标志的情况下也尝试过,但也没有成功。+1谢谢!在Android 4.x设备上,“服务”类运行得很好,但我无法解释为什么它在Android 2.x设备上不起作用。当改为“IntentService”时它就像一个魔咒。经验教训!您还遇到了一种不明显的唤醒锁定行为,即启动服务以响应警报。下面的答案中有一些详细信息和建议