Created
July 14, 2015 14:40
-
-
Save cleac/e1aee66e97178af8beec to your computer and use it in GitHub Desktop.
Code
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class BluetoothService extends Service { | |
private final static String LOG_TAG = BluetoothService.class.getName(); | |
private final static String AUTHORITY = "com.forcemove.forceemotion.bt"; | |
private final int SERVICE_STATUS_ID = 1; | |
private BluetoothGatt mBluetoothGatt; | |
public final static String ACTION_GATT_CONNECTED = AUTHORITY + ".ACTION_GATT_CONNECTED"; | |
public final static String ACTION_GATT_CONNECTING = AUTHORITY + ".ACTION_GATT_CONNECTING"; | |
public final static String ACTION_GATT_DISCONNECTED = AUTHORITY + ".ACTION_GATT_DISCONNECTED"; | |
public final static String ACTION_GATT_SERVICES_DISCOVERED = AUTHORITY + ".ACTION_GATT_SERVICES_DISCOVERED"; | |
public final static String ACTION_GATT_DATA_AVAILABLE = AUTHORITY + ".ACTION_GATT_DATA_AVAILABLE"; | |
public final static String ACTION_GATT_EXTRA_DATA = AUTHORITY + ".ACTION_GATT_EXTRA_DATA"; | |
private int mConnectionState = STATE_DISCONNECTED; | |
private static final int STATE_DISCONNECTED = 0; | |
private static final int STATE_CONNECTING = 1; | |
private static final int STATE_CONNECTED = 2; | |
private final int CHARACTER_NOTI_ID = 2; | |
private final int CONNECTION_STATUS_ID = 3; | |
private final int FOUND_DEVICES_ID = CONNECTION_STATUS_ID + 1; | |
private final int BATTERY_STATE_ID = 5; | |
private final int KEY_NOTI_ID = BATTERY_STATE_ID + 1; | |
/** | |
* Variable that defines interaction with Bluetooth device: gets data from and sends broadcasts | |
* notifications about new data; checks connection state and looks for Bluetooth services that | |
* can be discovered | |
*/ | |
private BluetoothGattCallback mGattCallback = new BluetoothGattCallback() { | |
@Override | |
public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) { | |
String intentAction = null; | |
switch (newState) { | |
case BluetoothProfile.STATE_CONNECTED: | |
intentAction = ACTION_GATT_CONNECTED; | |
mConnectionState = STATE_CONNECTED; | |
gatt.discoverServices(); | |
break; | |
case BluetoothProfile.STATE_DISCONNECTED: | |
intentAction = ACTION_GATT_DISCONNECTED; | |
mConnectionState = STATE_DISCONNECTED; | |
break; | |
case BluetoothProfile.STATE_CONNECTING: | |
intentAction = ACTION_GATT_CONNECTING; | |
mConnectionState = STATE_CONNECTING; | |
} | |
if(intentAction!=null) | |
broadcastUpdate(intentAction); | |
} | |
@Override | |
public void onCharacteristicRead(BluetoothGatt gatt, | |
BluetoothGattCharacteristic characteristic, | |
int status) | |
{ | |
if(status == BluetoothGatt.GATT_SUCCESS) { | |
String uuid = characteristic.getUuid().toString().toUpperCase(); | |
if(uuid.equals(SupportedGattAttributes.Characteristics.Battery)) { | |
sendNotification("Battery level " + characteristic.getIntValue( | |
BluetoothGattCharacteristic.FORMAT_UINT8, 1 | |
) + '%', BATTERY_STATE_ID); | |
} else if(uuid.equals(SupportedGattAttributes.Characteristics.KeyReport)) { | |
sendNotification("Got a key!", KEY_NOTI_ID); | |
} | |
broadcastUpdate(ACTION_GATT_DATA_AVAILABLE, characteristic); | |
} else { | |
Log.e(LOG_TAG,"onCharacteristicRead received : " + status); | |
} | |
} | |
@Override | |
public void onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) { | |
String uuid = characteristic.getUuid().toString().toUpperCase(); | |
if(uuid.equals(SupportedGattAttributes.Characteristics.Battery)) { | |
sendNotification("Battery level " + characteristic.getIntValue( | |
BluetoothGattCharacteristic.FORMAT_UINT8, 1) + '%', BATTERY_STATE_ID); | |
} else if(uuid.equals(SupportedGattAttributes.Characteristics.KeyReport)) { | |
sendNotification("Got a key!", KEY_NOTI_ID); | |
} | |
broadcastUpdate(ACTION_GATT_DATA_AVAILABLE,characteristic); | |
} | |
@Override | |
public void onServicesDiscovered(BluetoothGatt gatt, int status) { | |
if(status == BluetoothGatt.GATT_SUCCESS) { | |
List<BluetoothGattService> services = mBluetoothGatt.getServices(); | |
for(BluetoothGattService service:services) { | |
UUID uuid_current = service.getUuid(); | |
BluetoothGattCharacteristic characteristic; | |
if (uuid_current.equals(UUID.fromString(SupportedGattAttributes.Services.Battery))) { | |
characteristic = service.getCharacteristic( | |
UUID.fromString(SupportedGattAttributes.Characteristics.Battery)); | |
} else if (uuid_current.equals(UUID.fromString(SupportedGattAttributes.Services.HID))) { | |
characteristic = service.getCharacteristic( | |
UUID.fromString(SupportedGattAttributes.Characteristics.KeyReport)); | |
} else { | |
continue; | |
} | |
if(characteristic==null) | |
Log.e(LOG_TAG,"Unable to find characteristic"); | |
else { | |
gatt.readCharacteristic(characteristic); | |
Log.e(LOG_TAG,"READING CHARACTERISTIC"); | |
} | |
} | |
broadcastUpdate(ACTION_GATT_SERVICES_DISCOVERED); | |
} else { | |
Log.e(LOG_TAG, "onServicesDiscovered received: " + status); | |
} | |
} | |
public void broadcastUpdate(String intentAction) { | |
if(intentAction.equals(ACTION_GATT_SERVICES_DISCOVERED)) { | |
NotificationManager notificationManager = | |
(NotificationManager) getSystemService(NOTIFICATION_SERVICE); | |
Notification.Builder notiBuilder = new Notification.Builder(BluetoothService.this) | |
.setSmallIcon(R.drawable.ic_autorenew_white_48dp) | |
.setContentTitle("Force") | |
.setContentText("Found services"); | |
Intent resultIntent = new Intent(BluetoothService.this, BluetoothInfoActivity.class); | |
resultIntent.putExtra(Intent.EXTRA_TEXT, ACTION_GATT_SERVICES_DISCOVERED); | |
TaskStackBuilder stackBuilder = TaskStackBuilder.create(BluetoothService.this); | |
stackBuilder.addParentStack(ScanBluetoothActivity.class); | |
stackBuilder.addNextIntent(resultIntent); | |
PendingIntent resultPendingIntent = stackBuilder.getPendingIntent( | |
0, | |
PendingIntent.FLAG_UPDATE_CURRENT | |
); | |
notiBuilder.setContentIntent(resultPendingIntent); | |
notificationManager.notify(SERVICE_STATUS_ID, notiBuilder.build()); | |
} | |
} | |
public void broadcastUpdate(String intentAction,BluetoothGattCharacteristic characteristic) { | |
sendNotification("Got data", CHARACTER_NOTI_ID); | |
} | |
}; | |
@Override | |
public void onCreate() { | |
super.onCreate(); | |
} | |
@Override | |
public void onDestroy() { | |
super.onDestroy(); | |
sendNotification("Service stopped", SERVICE_STATUS_ID); | |
if(mBluetoothGatt==null) | |
return; | |
mBluetoothGatt.disconnect(); | |
mBluetoothGatt.close(); | |
mBluetoothGatt = null; | |
} | |
private final IBinder mLocalBinder = new LocalBinder(); | |
public class LocalBinder extends Binder { | |
public BluetoothService getService() { | |
return BluetoothService.this; | |
} | |
} | |
@Override | |
public IBinder onBind(Intent intent) { | |
return mLocalBinder; | |
} | |
@Override | |
public int onStartCommand(Intent intent, int flags, int startId) { | |
if(mBluetoothGatt==null) { | |
BluetoothManager mBluetoothManager = (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE); | |
BluetoothAdapter mBluetoothAdapter = mBluetoothManager.getAdapter(); | |
BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(SettingsAccessor.getDeviceAddress(this)); | |
if (device == null) { | |
sendNotification("Device not found",0); | |
} | |
mBluetoothGatt = device.connectGatt(this, true, mGattCallback); | |
} else { | |
mBluetoothGatt.connect(); | |
} | |
return START_STICKY; | |
} | |
private void sendNotification(String message, int id) { | |
NotificationManager notificationManager = | |
(NotificationManager) getSystemService(NOTIFICATION_SERVICE); | |
Notification.Builder notiBuilder = new Notification.Builder(BluetoothService.this) | |
.setSmallIcon(R.drawable.ic_autorenew_white_48dp) | |
.setContentTitle("Force") | |
.setContentText(message); | |
Intent resultIntent = new Intent(BluetoothService.this, BluetoothInfoActivity.class); | |
resultIntent.putExtra(Intent.EXTRA_TEXT, message); | |
TaskStackBuilder stackBuilder = TaskStackBuilder.create(BluetoothService.this); | |
stackBuilder.addParentStack(ScanBluetoothActivity.class); | |
stackBuilder.addNextIntent(resultIntent); | |
PendingIntent resultPendingIntent = stackBuilder.getPendingIntent( | |
0, | |
PendingIntent.FLAG_UPDATE_CURRENT | |
); | |
notiBuilder.setContentIntent(resultPendingIntent); | |
notificationManager.notify(id, notiBuilder.build()); | |
} | |
public List<BluetoothGattService> getGattServices(){ | |
if(mBluetoothGatt!=null) | |
return mBluetoothGatt.getServices(); | |
else | |
return null; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment