AndroidでWiFi、Bluetoothビーコン、センサー情報を取得するサンプル

はじめに
--------------------

Androidから下記３情報を取得するサンプルです。BSDライセンスです。（念のため）

- WiFi接続情報 (周囲のAPと接続中のAP)
- BLEビーコン配信情報
- センサー情報


MainActivity
--------------------
下記クラスの中身はご想像におまかせします。（I/F見ればだいたい想像つくかと）

- Data : 取得したデータを格納するクラス
- DataList : Dataのリスト
- GuiHandler : GUIに結果を描画するクラス

```java:MainActivity.java
public class MainActivity extends AppCompatActivity {

    private Monitor mWifiMonitor;
    private Monitor mIBeaconMonitor;
    private Monitor mSensorMonitor;

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

        GuiHandler mGuiHandler = new GuiHandler(this);

        SensorManager mSensorManager = (SensorManager)getSystemService(Context.SENSOR_SERVICE);
        mSensorMonitor = new SensorMonitor(
                mGuiHandler,
                mSensorManager,
                SensorManager.SENSOR_DELAY_FASTEST);

        if (getPackageManager().hasSystemFeature(PackageManager.FEATURE_WIFI)) {
            ConnectivityManager mConnectivityManager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
            WifiManager mWifiManager = (WifiManager) getSystemService(Context.WIFI_SERVICE);
            mWifiMonitor = new WifiMonitor(
                    mGuiHandler,
                    mConnectivityManager,
                    mWifiManager,
                    500);
        }

        if (getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE)) {
            BluetoothManager mBluetoothManager = (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
            BluetoothAdapter mBluetoothAdapter = mBluetoothManager.getAdapter();
            mIBeaconMonitor = new IBeaconMonitor(
                    mGuiHandler,
                    mBluetoothAdapter);
        }
    }

    @Override
    protected void onResume() {
        super.onResume();
        if(mIBeaconMonitor != null) { mIBeaconMonitor.start(); }
        if(mSensorMonitor != null) { mSensorMonitor.start(); }
        if(mWifiMonitor != null) { mWifiMonitor.start(); }
    }

    @Override
    protected void onPause() {
        super.onPause();
        if(mIBeaconMonitor != null) { mIBeaconMonitor.stop(); }
        if(mSensorMonitor != null) { mSensorMonitor.stop(); }
        if(mWifiMonitor != null) { mWifiMonitor.stop(); }
    }
}
```

モニターの共通インターフェース
--------------------

```java:Monitor.java
public interface Monitor {
    public void start();
    public void stop();
}
```

センサーのモニター
--------------------

```java:SensorMonitor.java
public class SensorMonitor implements SensorEventListener, Monitor {

    static final String TAG = "Sensor";
    private SensorManager mSensorManager;
    private GuiHandler mGuiHandler;
    private int samplingPeriodUs;

    @Override
    public void onAccuracyChanged(Sensor sensor, int accuracy) {
        Log.d(TAG, "accuracy changed");
    }

    @Override
    public void onSensorChanged(SensorEvent event) {
        String sensor = null;
        DataList dataList = new DataList();
        switch(event.sensor.getType()) {
            case Sensor.TYPE_ACCELEROMETER:
                sensor = ":acc";
                dataList.add(new Data("Sensor:acc-x", event.values[0]));
                dataList.add(new Data("Sensor:acc-y", event.values[1]));
                dataList.add(new Data("Sensor:acc-z", event.values[2]));
                break;

            case Sensor.TYPE_ROTATION_VECTOR:
                sensor = ":rot";
                dataList.add(new Data("Sensor:rot-x", event.values[0]));
                dataList.add(new Data("Sensor:rot-y", event.values[1]));
                dataList.add(new Data("Sensor:rot-z", event.values[2]));
                break;

            case Sensor.TYPE_GRAVITY:
                sensor = ":grav";
                dataList.add(new Data("Sensor:grv-x", event.values[0]));
                dataList.add(new Data("Sensor:grv-y", event.values[1]));
                dataList.add(new Data("Sensor:grv-z", event.values[2]));
                break;
        }

        mGuiHandler.setTextAsync(TAG+sensor, dataList);
    }

    public SensorMonitor(
            GuiHandler mGuiHandler,
            SensorManager mSensorManager,
            int samplingPeriodUs) {

        this.mGuiHandler = mGuiHandler;
        this.mSensorManager = mSensorManager;
        this.samplingPeriodUs = samplingPeriodUs;
    }

    public void start() {
        Log.d(TAG, "start");
        List<Sensor> sensors = mSensorManager.getSensorList(Sensor.TYPE_ALL);
        for(Sensor sensor : sensors) {
            mSensorManager.registerListener(this, sensor, samplingPeriodUs);
        }
    }

    public void stop() {
        Log.d(TAG, "stop");
        mSensorManager.unregisterListener(this);
    }

}
```

Wi-Fiのモニター
--------------------

```java:WifiMonitor.java
public class WifiMonitor implements Monitor {

    static final String TAG = "Wifi";
    private ConnectivityManager mConnectivityManager;
    private WifiManager mWifiManager;
    private GuiHandler mGuiHandler;
    private int interval;

    private Timer mTimer;
    private TimerTask wifiMonitorTask = new TimerTask() {
        @Override
        public void run() {
            if(mWifiManager.isWifiEnabled()) {
                scanSurroundedAPs();

                NetworkInfo mNetworkInfo = mConnectivityManager.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
                if(mNetworkInfo!=null && mNetworkInfo.isConnected()) {
                    checkCurrentAP();
                }
            }
        }
    };

    private void scanSurroundedAPs() {
        mWifiManager.startScan();

        List<ScanResult> mScanResults = mWifiManager.getScanResults();
        for(ScanResult mScanResult : mScanResults) {
            DataList dataList = new DataList();
            dataList.add(new Data("Wifi:BSSID", mScanResult.BSSID));
            dataList.add(new Data("Wifi:SSID", mScanResult.SSID));
            dataList.add(new Data("Wifi:level", mScanResult.level));
            dataList.add(new Data("Wifi:frequency", mScanResult.frequency));
            dataList.add(new Data("Wifi:channelWidth", mScanResult.channelWidth));

            mGuiHandler.setTextAsync(TAG, dataList);
        }
    }

    private void checkCurrentAP() {
        WifiInfo mWifiInfo = mWifiManager.getConnectionInfo();

        DataList dataList = new DataList();
        dataList.add(new Data("Wifi:BSSID", mWifiInfo.getBSSID()));
        dataList.add(new Data("Wifi:SSID", mWifiInfo.getSSID()));
        dataList.add(new Data("Wifi:MacAddress", mWifiInfo.getMacAddress()));
        dataList.add(new Data("Wifi:IpAddress", mWifiInfo.getIpAddress()));
        dataList.add(new Data("Wifi:LinkSpeed", mWifiInfo.getLinkSpeed()));
        dataList.add(new Data("Wifi:RSSI", mWifiInfo.getRssi()));
        dataList.add(new Data("Wifi:frequency", mWifiInfo.getFrequency()));

        mGuiHandler.setTextAsync(TAG, dataList);
    }

    public WifiMonitor(
            GuiHandler mGuiHandler,
            ConnectivityManager mConnectivityManager,
            WifiManager mWifiManager,
            int interval) {

        this.mConnectivityManager = mConnectivityManager;
        this.mWifiManager = mWifiManager;
        this.mGuiHandler = mGuiHandler;
        this.interval = interval;
    }

    public void start() {
        Log.d(TAG, "start");
        mTimer = new Timer();
        mTimer.schedule(wifiMonitorTask, 0, interval);
    }

    public void stop() {
        Log.d(TAG, "stop");
        mTimer.cancel();
    }

}
```

iBeaconのモニター
--------------------
IBeaconクラスの変換はご想像におまかせします。

```java:IBeaconMonitor.java
public class IBeaconMonitor implements Monitor {

    static final String TAG = "BLE";
    private BluetoothAdapter mBluetoothAdapter;
    private GuiHandler mGuiHandler;

    private BluetoothAdapter.LeScanCallback mLeScanCallback = new BluetoothAdapter.LeScanCallback() {
        @Override
        public void onLeScan(BluetoothDevice device, int rssi, byte[] scanRecord) {
            IBeacon mIBeacon = new IBeacon(scanRecord);
            if(mIBeacon.getUuid()==null) { return; }

            DataList dataList = new DataList();
            dataList.add(new Data("BLE:Name", device.getName()));
            dataList.add(new Data("BLE:BondState", device.getBondState()));
            dataList.add(new Data("BLE:Address", device.getAddress()));
            dataList.add(new Data("BLE:Type", device.getType()));
            dataList.add(new Data("BLE:Uuid", mIBeacon.getUuid()));
            dataList.add(new Data("BLE:Major", mIBeacon.getMajor()));
            dataList.add(new Data("BLE:Minor", mIBeacon.getMinor()));
            dataList.add(new Data("BLE:Rssi", rssi));

            mGuiHandler.setTextAsync(TAG, dataList);
        }
    };

    public IBeaconMonitor(
            GuiHandler mGuiHandler,
            BluetoothAdapter mBluetoothAdapter) {

        this.mBluetoothAdapter = mBluetoothAdapter;
        this.mGuiHandler = mGuiHandler;
    }

    public void start() {
        Log.d(TAG, "start");
        mBluetoothAdapter.startLeScan(mLeScanCallback);
    }

    public void stop() {
        Log.d(TAG, "stop");
        mBluetoothAdapter.stopLeScan(mLeScanCallback);
    }

}
```