2

呼ば届かないSCAN_RESULTS_AVAILABLE_ACTIONためBroadcastReceiverは、ここに私のコードです:AndroidのWifiのスキャン -

public class FloatWifiManager implements IWifiManager { 

    private WifiManager wifiManager; 

    private BroadcastReceiver wifiScanReceiver; 

    public FloatWifiManager(Context context) { 
     ... 
     wifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE); 

     // Registering Wifi Receiver 
     wifiScanReceiver = new BroadcastReceiver() { 
      @Override 
      public void onReceive(Context c, Intent intent) { 
       if (intent.getAction().equals(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION)) { 
        // not getting called, only after running app and manually going to the wifi settings in android 
       } 
      } 
     }; 

     IntentFilter intentFilter = new IntentFilter(); 
     intentFilter.addAction(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION); 
     context.registerReceiver(wifiScanReceiver, intentFilter); 
     wifiManager.startScan(); 
    } 

私はすべての例で見た、とstartScanをまったく同じように、私はBroadcastReceiverを登録しました。

wifiのリストは変更されていますが(確かにテストしましたが)、ただアプリにとどまっているとonReceiveは呼び出されません。

onReceiveが最終的に呼ばれるようになりますこと - 実行中のままにしておき、アプリを起動することであり、設定するには、Androidの携帯電話に行く - >無線LANの設定。そこに行くと、突然Listが更新され、onReceiveが呼び出されます。

ここで問題は何ですか?

  1. wifiManager.startScan();はスキャンを1回だけ実行しますか?受信した「スキャン結果」を聞き続ける機能ですか?

  2. 明らかに、なぜ受信機が呼び出されないのですか?

答えて

3

はい、startScan()は、1回のスキャンのみを要求します。

if (intent.getAction().equals(..))の状態を取り除くことができます。他のものは大丈夫と思われる。

ちょうどそれを明確にする - 私の目標は、WiFiネットワークリストが変更されるたびに呼び出さ を取得する受信機を持っているために、「スタートスキャン」ボタンをクリックする を持たずに。

AFAIK Wi-Fiネットワークのいずれかが変更されたときに通知を受けることはできません。 startScanでのみスキャンをリクエストできます。もちろん、スレッドまたはハンドラを使用してstartScanを繰り返し呼び出すことができます。

docs

ときSCAN_RESULTS_AVAILABLE_ACTIONが呼ばれると言う「アクセスポイントのスキャンが完了した、との結果がサプリカントから入手できます」。スキャンがいつ、どのように行われるかは、サプリカントの実装によって異なります。 Elenkovには、 "Androidデバイスには元のwpa_supplicantコードはほとんど含まれていません。含まれている実装は、基礎となるSoCとの互換性を改善するために変更されることがよくあります"


アクセスポイントのスキャン

この例では、利用可能なアクセスポイントおよびアドホックネットワークをスキャンします。 btnScanは、WifiManager.startScan()メソッドによって開始されたスキャンを有効にします。スキャンの後、WifiManagerSCAN_RESULTS_AVAILABLE_ACTIONインテントを呼び出し、WifiScanReceiverクラスはスキャン結果を処理します。結果はTextViewに表示されます。

public class MainActivity extends AppCompatActivity { 

    private final static String TAG = "MainActivity"; 

    TextView txtWifiInfo; 
    WifiManager wifi; 
    WifiScanReceiver wifiReceiver; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 

     wifi=(WifiManager)getSystemService(Context.WIFI_SERVICE); 
     wifiReceiver = new WifiScanReceiver(); 

     txtWifiInfo = (TextView)findViewById(R.id.txtWifiInfo); 
     Button btnScan = (Button)findViewById(R.id.btnScan); 
     btnScan.setOnClickListener(new View.OnClickListener() { 
      @Override 
      public void onClick(View v) { 
       Log.i(TAG, "Start scan..."); 
       wifi.startScan(); 
      } 
     }); 
    } 

    protected void onPause() { 
     unregisterReceiver(wifiReceiver); 
     super.onPause(); 
    } 

    protected void onResume() { 
     registerReceiver(
      wifiReceiver, 
      new IntentFilter(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION) 
     ); 
     super.onResume(); 
    } 

    private class WifiScanReceiver extends BroadcastReceiver { 
     public void onReceive(Context c, Intent intent) { 
      List<ScanResult> wifiScanList = wifi.getScanResults(); 
      txtWifiInfo.setText(""); 
      for(int i = 0; i < wifiScanList.size(); i++){ 
       String info = ((wifiScanList.get(i)).toString()); 
       txtWifiInfo.append(info+"\n\n"); 
      } 
     } 
    } 
} 

権限

次の権限がのAndroidManifest.xmlで定義する必要があります。

<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /> 
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" /> 

android.permission.ACCESS_WIFI_STATEWifiManager.getScanResults()を呼び出すために必要です。 android.permission.CHANGE_WIFI_STATEがなければ、WifiManager.startScan()でスキャンを開始することはできません。

APIレベル23以上(Android 6.0以上)のプロジェクトをコンパイルする場合は、android.permission.ACCESS_FINE_LOCATIONまたはandroid.permission.ACCESS_COARSE_LOCATIONのいずれかを挿入する必要があります。さらに、許可を要求する必要があります。あなたの主な活動のonCreate方法で:

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    ... 
    String[] PERMS_INITIAL={ 
      Manifest.permission.ACCESS_FINE_LOCATION, 
    }; 
    ActivityCompat.requestPermissions(this, PERMS_INITIAL, 127); 
} 
+0

が、私はその場合は、「単一のスキャン」を尋ねることによって何を意味するのかをだった - WiFiネットワークを更新しているとき、私はonResponseに通知し続けるのだろうか?コードを実行して「設定」 - >「Wifi設定」に移動すると、onResponseが複数回呼び出されるためです。ですから、startScan()を何度も呼び出す必要はありません。 –

+0

ちょうどそれを明確にする - 私の目標は、 "スキャンを開始"ボタンをクリックすることなく、Wifiネットワークのリストが変化しているたびに呼び出される受信機を持つことです。 –

+0

答えを更新しました。 – gus27

関連する問題