From 7a7d015f8a68f5e0d06fe6e3d9422d5f418f653d Mon Sep 17 00:00:00 2001 From: Trygve Laugstøl Date: Sun, 30 Nov 2014 23:55:54 +0100 Subject: o Initial import of Fiken Status Display app. --- .../topi/fiken/display/DefaultDisplayService.java | 255 +++++++++++++++++++++ 1 file changed, 255 insertions(+) create mode 100644 app/src/main/java/no/topi/fiken/display/DefaultDisplayService.java (limited to 'app/src/main/java/no/topi/fiken/display/DefaultDisplayService.java') diff --git a/app/src/main/java/no/topi/fiken/display/DefaultDisplayService.java b/app/src/main/java/no/topi/fiken/display/DefaultDisplayService.java new file mode 100644 index 0000000..b1aa2e7 --- /dev/null +++ b/app/src/main/java/no/topi/fiken/display/DefaultDisplayService.java @@ -0,0 +1,255 @@ +package no.topi.fiken.display; + +import android.app.Service; +import android.bluetooth.BluetoothAdapter; +import android.bluetooth.BluetoothDevice; +import android.bluetooth.BluetoothGatt; +import android.bluetooth.BluetoothGattCallback; +import android.bluetooth.BluetoothGattCharacteristic; +import android.bluetooth.BluetoothGattDescriptor; +import android.bluetooth.BluetoothGattService; +import android.bluetooth.BluetoothManager; +import android.content.Context; +import android.content.Intent; +import android.os.Handler; +import android.os.IBinder; +import android.util.Log; +import android.widget.Toast; + +public class DefaultDisplayService extends Service implements DisplayService { + private final Context context = DefaultDisplayService.this; + private final static String TAG = DefaultDisplayService.class.getSimpleName(); + + private final IBinder binder = new LocalBinder(this); + + private BluetoothManager mBluetoothManager; + private BluetoothAdapter mBluetoothAdapter; + private BluetoothGattService displayService; + private BluetoothGatt gatt; + + private Handler handler; + private int UPDATE_RSSI_DELAY = 1000; + + private Runnable updateRssi = new Runnable() { + @Override + public void run() { + if(gatt != null) { + gatt.readRemoteRssi(); + } + + handler.postDelayed(this, UPDATE_RSSI_DELAY); + } + }; + + public static enum ServiceState { + BROKEN, + IDLE, + SCANNING, + CONNECTED, + } + + private ServiceState serviceState = ServiceState.BROKEN; + + @Override + public IBinder onBind(Intent intent) { + return binder; + } + + @Override + public void onCreate() { + handler = new Handler(); + + handler.postDelayed(updateRssi, UPDATE_RSSI_DELAY); + } + + public boolean initialize() { + // For API level 18 and above, get a reference to BluetoothAdapter through + // BluetoothManager. + if (mBluetoothManager == null) { + mBluetoothManager = (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE); + if (mBluetoothManager == null) { + Log.e(TAG, "Unable to initialize BluetoothManager."); + return false; + } + } + + mBluetoothAdapter = mBluetoothManager.getAdapter(); + if (mBluetoothAdapter == null) { + Log.e(TAG, "Unable to obtain a BluetoothAdapter."); + return false; + } + + Log.e(TAG, "Bluetooth initialized"); + + serviceState = ServiceState.IDLE; + + return true; + } + + @Override + public boolean connect(final String address) { + if (serviceState != ServiceState.IDLE) { + if (!(serviceState == ServiceState.CONNECTED && gatt.getDevice().getAddress().equals(address))) { + Log.e(TAG, "connect(): Not idle: " + serviceState); + return false; + } + + Log.i(TAG, "connect(): already connected: " + serviceState); + return true; + } + + BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(address); + + gatt = device.connectGatt(this, false, new BluetoothGattCallback() { + @Override + public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) { +// Toast.makeText(context, "Connected", Toast.LENGTH_SHORT).show(); + if (status == BluetoothGatt.GATT_SUCCESS && newState == BluetoothGatt.STATE_CONNECTED) { + boolean ok = gatt.discoverServices(); + + if (!ok) { + disconnect(); + } else { + Intent intent = IntentAction.DEVICE_UPDATE.intent(); + intent.putExtra(IntentExtra.DEVICE_ADDRESS.name(), address); + intent.putExtra(IntentExtra.CONNECTED.name(), true); + sendBroadcast(intent); + } + } else { + Log.w(TAG, "Could not connect to device"); +// Toast.makeText(context, "Could not connect to device", Toast.LENGTH_SHORT).show(); + } + } + + @Override + public void onServicesDiscovered(BluetoothGatt gatt, int status) { + Log.i(TAG, "onServicesDiscovered"); + + Log.i(TAG, "Constants.TRYGVIS_IO_FIKEN_STATUS_PANEL_UUID = " + Constants.TRYGVIS_IO_FIKEN_STATUS_PANEL_UUID); + + for (BluetoothGattService bluetoothGattService : gatt.getServices()) { + Log.i(TAG, "bluetoothGattService.getUuid() = " + bluetoothGattService.getUuid()); + } + + displayService = gatt.getService(Constants.TRYGVIS_IO_FIKEN_STATUS_PANEL_UUID); + + Log.i(TAG, "service=" + displayService); + + Intent intent = IntentAction.DEVICE_UPDATE.intent(); + intent.putExtra(IntentExtra.DEVICE_ADDRESS.name(), address); + intent.putExtra(IntentExtra.DEVICE_IS_DISPLAY.name(), displayService != null); + sendBroadcast(intent); + } + + @Override + public void onCharacteristicRead(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) { + Log.i(TAG, "onCharacteristicRead"); + } + + @Override + public void onCharacteristicWrite(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) { + Log.i(TAG, "onCharacteristicWrite"); + } + + @Override + public void onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) { + Log.i(TAG, "onCharacteristicChanged"); + } + + @Override + public void onDescriptorRead(BluetoothGatt gatt, BluetoothGattDescriptor descriptor, int status) { + Log.i(TAG, "onDescriptorRead"); + } + + @Override + public void onDescriptorWrite(BluetoothGatt gatt, BluetoothGattDescriptor descriptor, int status) { + Log.i(TAG, "onDescriptorWrite"); + } + + @Override + public void onReliableWriteCompleted(BluetoothGatt gatt, int status) { + Log.i(TAG, "onReliableWriteCompleted"); + } + + @Override + public void onReadRemoteRssi(BluetoothGatt gatt, int rssi, int status) { + Log.i(TAG, "onReadRemoteRssi, status=" + status + ", rssi=" + rssi); + if (status == BluetoothGatt.GATT_SUCCESS) { + Intent intent = IntentAction.DEVICE_UPDATE.intent(); + intent.putExtra(IntentExtra.DEVICE_ADDRESS.name(), gatt.getDevice().getAddress()); + intent.putExtra(IntentExtra.RSSI.name(), rssi); + sendBroadcast(intent); + } + } + }); + + if (gatt != null) { + serviceState = ServiceState.CONNECTED; + return true; + } else { + return false; + } + } + + @Override + public void disconnect() { + if (serviceState != ServiceState.CONNECTED) { + Log.d(TAG, "disconnect(): Not connected: " + serviceState); + return; + } + + serviceState = ServiceState.IDLE; + + if (gatt != null) { + try { + gatt.disconnect(); + } catch (Exception e) { + Log.w(TAG, "gatt.disconnect()", e); + } + try { + gatt.close(); + } catch (Exception e) { + Log.w(TAG, "gatt.close()", e); + } + gatt = null; + } + + displayService = null; + } + + @Override + public void startScan() { + if (serviceState != ServiceState.IDLE) { + Toast.makeText(context, "startScan(): Not idle", Toast.LENGTH_SHORT).show(); + return; + } + + serviceState = ServiceState.SCANNING; + + mBluetoothAdapter.startLeScan(leScanCallback); + } + + @Override + public void stopScan() { + Log.d(TAG, "stopScan(): stopping scanning"); + + if (serviceState != ServiceState.SCANNING) { + Log.d(TAG, "stopScan(): not scanning"); + return; + } + mBluetoothAdapter.stopLeScan(leScanCallback); + serviceState = ServiceState.IDLE; + } + + private BluetoothAdapter.LeScanCallback leScanCallback = new BluetoothAdapter.LeScanCallback() { + @Override + public void onLeScan(final BluetoothDevice device, final int rssi, final byte[] scanRecord) { + Log.i(TAG, "onLeScan()"); + Intent intent = IntentAction.DEVICE_UPDATE.intent(); + intent.putExtra(IntentExtra.DEVICE_ADDRESS.name(), device.getAddress()); + intent.putExtra(IntentExtra.DEVICE_NAME.name(), device.getName()); + intent.putExtra(IntentExtra.RSSI.name(), rssi); + sendBroadcast(intent); + } + }; +} -- cgit v1.2.3