package at.univie.sensorium.sensors; import java.util.LinkedList; import java.util.List; import java.util.Set; import android.bluetooth.BluetoothAdapter; import android.bluetooth.BluetoothDevice; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.os.Handler; import android.util.Log; import at.univie.sensorium.SensorRegistry; public class BluetoothSensor extends AbstractSensor { public static BroadcastReceiver bluetoothReceiver; public static Intent bluetoothIntent; private Handler handler = new Handler(); private BluetoothAdapter bluetoothAdapter; private SensorValue localDeviceName; private SensorValue localMAC; private List<BtDevice> bondedDevices; private SensorValue sBondedDevices; private List<BtDevice> scannedDevices; private SensorValue sScannedDevices; private String bluetooth = ""; // private SensorValue sBluetooth; // private String devices = ""; // private SensorValue sDevices; private int scan_interval = 10; // sec public BluetoothSensor() { super(); setName("Bluetooth Sensor"); localDeviceName = new SensorValue(SensorValue.UNIT.STRING, SensorValue.TYPE.DEVICE_NAME); localMAC = new SensorValue(SensorValue.UNIT.STRING, SensorValue.TYPE.MAC_ADDRESS); bondedDevices = new LinkedList<BtDevice>(); scannedDevices = new LinkedList<BtDevice>(); sBondedDevices = new SensorValue(SensorValue.UNIT.LIST, SensorValue.TYPE.BONDED_DEV); sScannedDevices = new SensorValue(SensorValue.UNIT.LIST, SensorValue.TYPE.SCANNED_DEV); } private Runnable scanTask = new Runnable() { @Override public void run() { IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND); filter.addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED); bluetoothIntent = getContext().getApplicationContext().registerReceiver(bluetoothReceiver, filter); bluetoothAdapter.startDiscovery(); Log.d("scanTask", "restart bluetooth scanning"); handler.postDelayed(this, scan_interval*1000); } }; @Override protected void _enable() { bluetoothAdapter = BluetoothAdapter.getDefaultAdapter(); localDeviceName.setValue(bluetoothAdapter.getName()); localMAC.setValue(bluetoothAdapter.getAddress()); Set<BluetoothDevice> pairedDevices = bluetoothAdapter.getBondedDevices(); String bonded = ""; if (pairedDevices.size() > 0) { for (BluetoothDevice device : pairedDevices) { bondedDevices.add(new BtDevice(device.getName(), device.getAddress())); bonded += device.getName() + "; " + device.getAddress() + "\n"; } } else { bondedDevices.add(new BtDevice("n/a", "n/a")); bonded += "None"; } sBondedDevices.setValue(bonded); if (bluetoothAdapter.isEnabled()){ // only when bluetooth is enabled can we discover devices bluetoothReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { String action = intent.getAction(); if (BluetoothDevice.ACTION_FOUND.equals(action)) { BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); String name = device.getName(); if (name != null && !devices.contains(name)) { short rssi = intent.getShortExtra(BluetoothDevice.EXTRA_RSSI,Short.MIN_VALUE); devices += name + "\t/" + device.getAddress() + "\tRSSI: " + String.valueOf(rssi) + " dBm\n"; scannedDevices.add(new BtDevice(name, device.getAddress(), rssi)); } } else if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)) { context.unregisterReceiver(this); SensorRegistry.getInstance().log("Bluetooth", bluetooth + devices); Log.d("Bluetooth FINISHED", "done"); notifyListeners(); devices = ""; scannedDevices.clear(); } sScannedDevices.setValue(scannedDevices); } }; handler.postDelayed(scanTask, 0); } else // if not enabled, we only get info for local device SensorRegistry.getInstance().log("Bluetooth", bluetooth); } @Override protected void _disable() { if(bluetoothIntent != null) getContext().getApplicationContext().unregisterReceiver(bluetoothReceiver); handler.removeCallbacks(scanTask); scannedDevices.clear(); sScannedDevices.setValue(scannedDevices); // notifyListeners(); } public class BtDevice{ private SensorValue devName = new SensorValue(SensorValue.UNIT.STRING, SensorValue.TYPE.DEVICE_NAME); private SensorValue MACAddr = new SensorValue(SensorValue.UNIT.STRING, SensorValue.TYPE.MAC_ADDRESS); private SensorValue RSSI = new SensorValue(SensorValue.UNIT.NUMBER, SensorValue.TYPE.SIGNALSTRENGTH); public BtDevice() { } public BtDevice(String devName, String MAC){ if (devName != null) this.devName.setValue(devName); if (MAC != null) this.MACAddr.setValue(MAC); this.RSSI.setValue(""); // impossible value for RSSI } public BtDevice(String devName, String MAC, int rssi){ if (devName != null) this.devName.setValue(devName); if (MAC != null) this.MACAddr.setValue(MAC); this.RSSI.setValue(rssi); } public String getDevName(){ return (String) devName.getValue(); } public String getMAC(){ return (String) MACAddr.getValue(); } public Object getRSSI(){ return RSSI.getValue(); } @Override public String toString() { return devName.getValueRepresentation() + "; " + MACAddr.getValueRepresentation() + "; " + RSSI.getValueRepresentation() + " dBm"; } } }