--> -->
#blog2navi() *WakeLockじゃなくてAlarmManagerを使って定期的な処理を継続する [#g3b90759] バックグラウンドで処理を行いたい場合、Sleepしてしまうと処理が止まってしまうため、WakeLockを使うといいように書いてあったりします。~ [[http://techbooster.org/android/application/4429/:http://techbooster.org/android/application/4429/]]~ 私もSleep中に処理が止まってしまうのに悩んでいたので、「これだっ」と思って早速実装してみましたが、どうも一度寝てしまうと起きてくれません。~ 同じ事に悩んでいる人はいるらしく、検索していると&color(red){WakeLockはWake状態をLockするためのもので、SleepをWakeするためのものではない};事が分かりました。~ [[http://stackoverflow.com/questions/16450947/how-to-wake-the-android-device-from-deep-sleep-using-wake-lock:http://stackoverflow.com/questions/16450947/how-to-wake-the-android-device-from-deep-sleep-using-wake-lock]]~ 上記の記事ではAlarmManagerを使えとあり、試してみたところうまくいったので簡単にまとめてみます。~ ~ 概要としては、ServiceからAlarmを仕掛け、Alarmが起動したらcallbackしてService内の処理を実行します。~ ~ まずはService内からAlarmを仕掛けます。~ ~ InfoTransferService.java((ソースは様々なサイトの記述を参考にさせていただいています(部分部分は結構そのままだったりします、ごめんなさい)。~でも大変助かっています、ありがとうございます。)) InfoTransferService.java((ソースは様々なサイトの記述を参考にさせていただいています(部分部分は結構そのままだったりします、ごめんなさい)。&br;でも大変助かっています、ありがとうございます。)) #code(java){{ private InfoTransferBroadcastReceiver ibr; private Integer interval = 0; // Interval @Override public void onCreate() { :(略) // AlarmのListener & broadcastを仕掛ける ibr = new InfoTransferBroadcastReceiver(); IntentFilter alarmFilter = new IntentFilter(); this.registerReceiver(ibr, alarmFilter); ibr.setListener(this); // callback用のリスナー :(略) } @Override public int onStartCommand(Intent intent, int flags, int startId) { :(略) interval = Integer.parseInt(intent.getStringExtra("interval")); // intervalをUIから受け取る例 createTimer(); // intervalを受け取った後に実行 :(略) } @Override public void onDestroy() { :(略) // Alarmのキャンセル cancelTimer(); // AlarmのListenerを外す ibr.removeListener(); // Alarm用Broadcast解除 unregisterReceiver(ibr); :(略) } // Alarmセット private void createTimer() { Intent i = new Intent(this, InfoTransferBroadcastReceiver.class); // Receiverを呼び出すインテントを作成 PendingIntent sender = PendingIntent.getBroadcast(this, 0, i, PendingIntent.FLAG_CANCEL_CURRENT); // 既存の仕掛けがあったらCancel long firstTime = SystemClock.elapsedRealtime(); firstTime += interval*1000; // 本当は、intervalがヘンな値だったら仕掛けないようにした方が良い AlarmManager am = (AlarmManager)getSystemService(Context.ALARM_SERVICE); // AlramManager取得 // 繰り返し設定 am.setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP, firstTime, interval*1000, sender); } private void cancelTimer() { Log.d(TAG,"cancelTimer"); //タイマーのキャンセル処理 Intent i = new Intent(this, InfoTransferBroadcastReceiver.class); // Receiverを呼び出すインテントを作成 PendingIntent sender = PendingIntent.getBroadcast(this, 0, i, PendingIntent.FLAG_CANCEL_CURRENT); // 既存の仕掛けがあったらCancel AlarmManager am = (AlarmManager)getSystemService(Context.ALARM_SERVICE); // AlramManager取得 am.cancel(sender); } /** * WakeUp時の処理。Receiverからcallbackで呼ばれる。 */ public void wakeupAlarm() { Log.d(TAG,"wakeupAlarm"); // 処理を書く } }} InfoTransferBroadcastReceiver.java #code(java){{ public class InfoTransferBroadcastReceiver extends BroadcastReceiver { static private InfoTransferBroadcastReceiverInterface listener = null; static final String TAG = "InfoTransferBroadcastReceiver"; @Override public void onReceive(Context context, Intent intent) { Log.d(TAG,"onReceive"); listener.wakeupAlarm(); } // Listener set public void setListener( InfoTransferBroadcastReceiverInterface listener ){ Log.d(TAG,"setListener"); InfoTransferBroadcastReceiver.listener = listener; } // Listener delete public void removeListener(){ Log.d(TAG,"removeListener"); InfoTransferBroadcastReceiver.listener = null; } } }} InfoTransferBroadcastReceiverInterface.java #code(java){{ public interface InfoTransferBroadcastReceiverInterface extends EventListener { public void wakeupAlarm(); } }} これでソースの実装は完了です。~ しかし、実はここまで書いてもAlarmは起動してくれません。色々調べてみると、manifestファイルにReceiverの記述が必要なことが分かりました。~ ~ AndroidManifest.xml #code(xml){{ :(略) <receiver android:name="InfoTransferBroadcastReceiver" /> :(略) }} ここについうっかり''android:process=":remote"''とか書いてしまうと、Alarmで起動されるたびにlistenerがnullになってしまい、callbackできません。android:processはしていしないようにしましょう。 ---- #htmlinsert(20130818_alarm.html) ---- RIGHT:Category: [[[android>日記/Category/android]]] - 06:18:55 ~ RIGHT:&blog2trackback(); #comment(above) #blog2navi()