同様のシナリオがあります-アラームで目が覚め、アラームのBroadcastReceiverがWakefulIntentServiceを起動し、サービスがネットワークのスキャンを開始します。私はロックを保持する愚かな方法を使用します1 - これをラッチに置き換えるつもりです。「AsyncTask」を WakefulIntentService に置き換えることをお勧めします。AsyncTask が起動されない可能性があります。WakefulIntentServiceでは、wifi ロックを取得して保持する必要があります - これを YourWakefulIntentService の静的フィールドにします - これについては完全には明確ではありません - 少し前のことです。これが機能しない場合は、 YourWakefulIntentService でラッチを使用します。
// register an alarm
Intent i = new Intent(context, YourReceiver.class);
PendingIntent alarmPendingIntent= PendingIntent.getBroadcast(context, 0, i,
PendingIntent.FLAG_UPDATE_CURRENT);
public class YourReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
WakefulIntentService.sendWakefulWork(context, YourWIS.class);
}
}
//pseudocode !
public class YourWIS extends WakefulIntentService { // you must add a cstor !
@Override
doWakefulWork() {
acquireWifiLock();
enableScanReceiver();
startScan();
serviceLatch.wait();
releaseWifiLock();
}
}
// in YourScanReceiver
onReceive() {
if(action.equals(SCAN_RESULTS) {
// do something that does not take time or start another/the same
// WakefulIntentService
serviceLatch.notify();
}
}
最初に WakefulIntentService を試してください (アラーム レシーバーから AsyncTask を起動すると思います)。スキャン レシーバーは、スキャン結果を受信するために登録されたレシーバーです (WifiManager のドキュメントを参照してください - スリープの問題については、リスナーよりもレシーバーを優先してください)。
1 : これはワーキング クラスです - 私は 2 番目のウェイクフル インテント サービスを使用してウェイク ロックを維持するだけです - ラッチを使用するようにリファクタリングする必要がありますが、このアプローチは少なくとも機能します (2 番目のサービス (ゲートキーパー) をモニターで待機させます)ゲートキーパー内にウェイクロックを持っています.ゲートキーパーはCPUロックも保持しているので、すべて問題ありません(そして醜いです)