13

私のアプリが特定の時間に1日に1回ウェブサイトからデータを取得するように、いくつかのコードをリファクタリングしています。私の研究からは、AlarmManagerが最も適切なアプローチだと思われます。AlarmManager、BroadcastReceiver、およびService not working

私は、次のされているチュートリアルでは、次のとおりです。これまでのところ、AlarmManagerBroadcastReceiverが働いているように見えるhttp://mobile.tutsplus.com/tutorials/android/android-fundamentals-downloading-data-with-services/

、しかし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; 
     } 
    } 
} 

私はTRのAndroidManifest.xml

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

setRecurringAlarmMyActivityになると、ログが期待通りに印刷されます。同様に、15分ごとにAlarmReceiverのログが表示されます。私の理解Android Dev Docsから -

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 

は私が間違って何をやったかを見つけ出すように見えることはできません。しかし、私は私がログに見るもののMyService :(

例からログを見ることはありませんAlarmReceiverに私はそれが事実ではないようですが、MyServiceでターンコールonStartCommandにすべきcontext.startService(dailyUpdater)を呼び出すときということです!

私はMyServiceは全く?

01を起動しないように引き起こしている間違って何をやっています
+0

+1のおかげで、あなたのコードあなたはまた、アラームに応じてサービスを開始する非自明wakelock行動に実行している – Nirali

+0

..私を助けて。提案のためのhttp://stackoverflow.com/questions/25852309/does-alarmmanager-require-the-pendingintent-to-be-of-type-broadcastreceiver – ctate

答えて

15

それを実感してください!

たMyServiceIntentService代わりのサービスを拡張する必要があります!

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; 
     } 
    } 
} 

注:この変更により

、それはまた、代わりにonStartCommandをオーバーライドするのは、(IntentService上のドキュメントを参照)の代わりに

onHandleIntentをオーバーライドしなければならないことを意味するので、たMyServiceは次のようになります:ドキュメントから、onBindのデフォルトの実装では、それをオーバーライドする必要がnullを返しません。 IntentServiceの延長について

詳細情報:http://developer.android.com/guide/topics/fundamentals/services.html#ExtendingIntentService

+1

+1おかげで、あなたのコードが私を助けた。 – Nirali

+1

+1感謝を!「サービス」クラスは、Android 4.xのデバイス上でうまく動作します私は「IntentService」に変更する場合は、それが魅力のように働いた。教訓。トレーニングそれは、Android 2.xデバイス上で作業されなかった理由ができませんでした! –

0

あなたはこのようなあなたの意図を変更した場合AlarmManagerは、BroadcastReceiverを通過するのではなく、すぐにサービスを実行するために得ることができる:

//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); 

これはあなたの問題を解決することがあります!

+0

おかげで答えではいくつかの詳細と推奨事項があります - 私はこれを試してみました(downloader.addFlagsなしが)前に、それが動作しませんでした - addFlagsで試してみて、それが助けかどうかを確認します!ちょうどあなたがサービスを直接実行できるのであれば、なぜ「BroadcastReceiver」が存在するのでしょうか? – pyko

+0

は、この変更をしようとしました - クマー...運のどちらか – pyko

0

代わりの

Intent dailyUpdater = new Intent(context, MyService.class);

使用

Intent dailyUpdater = new Intent(this, MyService.class);

他の提案を使用しなく放送を送信する放送受信機でサービスを開始するよりも、アラームから直接サービスを開始することです。

+0

あなたはdownloader.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)なしでウルのコードを試してみましたによって示唆されているようにもthis' 'に' context'を変更しようとした:(動作しませんでした!; –

+0

HIクマーは、はい、私はどちらか動作しませんでした、だけでなくaddFlags' 'なしでそれを試してなかったと信じています。 – pyko

関連する問題