

現在androidでAPの電波強度を取得するアプリを開発しておりますが、実行したときの電波強度のみしか取得できません。起動中常に電波強度を取得するにはどうしたらよいのでしょうか？  
よろしくお願いします。

[code]

    public class WifiManager02 extends ListActivity {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    
        WifiManager manager = (WifiManager)getSystemService(WIFI_SERVICE);
        if(manager.getWifiState() == WifiManager.WIFI_STATE_ENABLED) {
            // APをスキャン
            manager.startScan();
            // スキャン結果を取得
            List<ScanResult> apList = manager.getScanResults();
            String[] aps = new String[apList.size()];
            for(int i=0; i<apList.size(); i++) {
                aps[i] = "SSID:" + apList.get(i).SSID + "\n"
                + apList.get(i).frequency + "MHz " + apList.get(i).level + "dBm";
                }
            ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, aps);
            setListAdapter(adapter);
            }
        }
    
    @Override
    public boolean onCreateOptionsMenu(android.view.Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.menu_wifi_manager02, menu);
        return true;
    }
    
    @Override
    public boolean onOptionsItemSelected(android.view.MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();
    
        //noinspection SimplifiableIfStatement
        if (id == R.id.action_settings) {
            return true;
        }
    
        return super.onOptionsItemSelected(item);
    }
    
[/code]


CC BY-SA 3.0
2015-10-14T09:19:17.387
17642
2016-06-12T15:46:04.267
12776
question
android java
ライブでアクセスポイントの電波強度を取得するプログラムを作りたいです。


> 起動中常に

という話なので、Activity ではなく Serviceを使ったバックグラウンド常駐アプリは除外するとします。

具体的な実装方法は色々と考えられますが、Thread を使う方向になると思います。

onCreate はアプリの起動過程のあるタイミングで実行されるものなので、Activity
の一回のライフサイクルの中で一度実行されてそれでおしまいです（もちろん、再起動されれば、その時また一度実行されます）。

Thread を定期的に生成・実行するための Java クラスとして、例えば、[Executors
クラス](https://docs.oracle.com/javase/jp/8/api/java/util/concurrent/Executors.html)があります。これを使えば、一定のインターバルで、Thread
を走らせることができます。以下の場合は、10秒間のインターバルで走らせる場合です。

[code]

    scheduledExecutorService = Executors.newSingleThreadScheduledExecutor();
    scheduledExecutorService.scheduleAtFixedRate(new Runnable() {
        @Override
        public void run() {
            getActivity().runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    // Wi-Fiをスキャンするための一連の処理を記述する
                    // (メソッド化して呼び出した方が可読性は良くなるかも)
                    WifiManager manager = (WifiManager)getSystemService(WIFI_SERVICE);
                    if(manager.getWifiState() == WifiManager.WIFI_STATE_ENABLED) {
                        // APをスキャン
                        ...
                    }
                }
            });
        }
    }, 0, 10, TimeUnit.SECONDS);
    
[/code]

Thread 自体は UiThread とは別のスレッドとなります。一方、提示されているコードの場合、UiThread
での処理が必要となるものが主です。そこで、Executors によって生成された Thread の中からさらに、  
`Activity.runOnUiThread` メソッドを実行し、UiThread で走らせる処理を行わせているのがポイントとなります。Runnable
オブジェクトが二重化しているのはそのためです。

Executors の他にも、Timer クラスを使う実装方法もありますが、Thread が基本になっている点は同じでしょう。


CC BY-SA 3.0
2015-10-14T14:12:05.647
17653
2015-10-14T14:12:05.647
7290
17642
answer