BroadcastReceiver не вызывается после возобновления активности

#android #android-activity #broadcastreceiver #lifecycle

#Android #android-активность #broadcastreceiver #жизненный цикл

Вопрос:

Прежде всего, я новичок в Android, так что это, вероятно, может быть глупой проблемой, тем не менее я уже потратил пару дней, пытаясь найти решение.

Я пытаюсь создать модуль wifi для целей локализации, поэтому я написал BroadcastReceiver для обработки сканирования wifi и локализации. Приложение работает и выполняет свою (довольно простую на данном этапе) работу, с различными проблемами как при изменении ориентации экрана, так и при нажатии кнопки «Назад» на моем Desire HD, а затем снова открывает приложение. Но когда я нажимаю клавишу HOME, переходя на главный экран, а затем снова вхожу в свое приложение, широковещательный приемник, похоже, больше не работает, и если я закрою приложение, я получу сообщение об ошибке.

Вот код, частично адаптированный отсюда.

 public class WiFiDemo extends Activity implements OnClickListener {

private static final String TAG = "WiFiDemo";
WifiManager wifi;
BroadcastReceiver receiver;
WifiManager.WifiLock lock;
boolean wifiPrevState;
boolean scanON = false;
String header;


TextView textStatus;
Button buttonScan;

/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);


    // Setup UI
    textStatus = (TextView) findViewById(R.id.textStatus);
    buttonScan = (Button) findViewById(R.id.buttonScan);
    buttonScan.setOnClickListener(this);

    // Setup WiFi
    if (wifi == null){
        wifi = (WifiManager) getSystemService(Context.WIFI_SERVICE);
    }


    //checking WiFi status, enabling it if needed and locking it.
    wifiPrevState = wifi.isWifiEnabled();
    wifi.setWifiEnabled(true);
    if (lock == null){
        lock = wifi.createWifiLock("lock");
    }

    lock.acquire();

    // Get WiFi status
    WifiInfo info = wifi.getConnectionInfo();
    header="nnWiFi Status: n"   info.toString()   "nnAvailable nets:";
    textStatus.append(header);

    // Register Broadcast Receiver
    if (receiver == null)
        receiver = new WiFiScanReceiver(this);

    registerReceiver(receiver, new IntentFilter(
            WifiManager.SCAN_RESULTS_AVAILABLE_ACTION));
    Log.d(TAG, "onCreate()");

}

/*
@Override
protected void onPause(){
    super.onPause();
    wifi.setWifiEnabled(wifiPrevState);
    lock.release();
    unregisterReceiver(receiver);
    Log.d(TAG, "onPause()");
}

@Override
protected void onResume(){
    super.onResume();
    wifi.setWifiEnabled(true);
    lock.acquire();
    registerReceiver(receiver, new IntentFilter(
            WifiManager.SCAN_RESULTS_AVAILABLE_ACTION));
    Log.d(TAG, "onResume()");

}
*/

@Override
public void onStop() {
    super.onStop();
    wifi.setWifiEnabled(wifiPrevState);
    lock.release();
    unregisterReceiver(receiver);

}

public void onClick(View view) {
    Toast.makeText(this, "On Click Clicked. Toast to that!!!",
            Toast.LENGTH_LONG).show();

    if (view.getId() == R.id.buttonScan) {
        Log.d(TAG, "onClick() wifi.startScan()");
        scanON = !scanON;
        wifi.startScan();
    }
}

}
  

И это BroadcastReceiver

 public class WiFiScanReceiver extends BroadcastReceiver {
  private static final String TAG = "WiFiScanReceiver";
  WiFiDemo wifiDemo;
  ScanResult storedBest;

  public WiFiScanReceiver(WiFiDemo wifiDemo) {
    super();
    this.wifiDemo = wifiDemo;
    storedBest = null;
  }

 @Override
 public void onReceive(Context c, Intent intent) {
    List<ScanResult> results = wifiDemo.wifi.getScanResults();
    ScanResult bestSignal = null;
    wifiDemo.textStatus.setText(wifiDemo.header);

    for (ScanResult result : results) {
      if (bestSignal == null
         || WifiManager.compareSignalLevel(bestSignal.level, result.level) < 0)
         bestSignal = resu<
      wifiDemo.textStatus.append("nn"   result.toString());
    }

      if ( storedBest == null || ((bestSignal.SSID.compareTo(storedBest.SSID)!=0) amp;amp;  bestSignal.level>-50)){
         storedBest = bestSignal;
         String locationMessage = String.format("You are near %s's Access Point",
                 bestSignal.SSID);
         Toast.makeText(wifiDemo, locationMessage, Toast.LENGTH_LONG).show();
      }
      String message = String.format("%s networks found. %s is the strongest. Its level is %s",
         results.size(), bestSignal.SSID, bestSignal.level);
      if (wifiDemo.scanON) wifiDemo.wifi.startScan();
      Log.d(TAG, "onReceive() message: "   message);
  }

}
  

Комментарии:

1. Не могли бы вы также опубликовать свой манифест?

Ответ №1:

При публикации лучше всего опубликовать сообщение об ошибке, которое вы получаете, чтобы мы знали о возникшей у вас проблеме.

При этом причина, по которой он, вероятно, не работает, заключается в том, что вы отменяете регистрацию своего получателя в onStop и регистрируете свой приемник только в onCreate. Обычно вы должны выполнять вызовы такого типа на соответствующих этапах жизненного цикла.

  • onCreate /onDestroy
  • OnStart / onStop
  • onResume / onPause.

Чтобы устранить проблему, попробуйте зарегистрировать приемник в OnStart вместо onCreate.

Комментарии:

1. Лучше зарегистрироваться onResume() и отменить onPause() регистрацию, чтобы избежать трансляции на приостановленные действия (вы все равно не сможете обрабатывать трансляцию во время приостановки).

Ответ №2:

Ваш метод onResume() закомментирован…

Вы уверены, что это правильный IntentFilter?