Skip to content

Commit

Permalink
UI rework, add indoor/outdoor modes, detect rifle/pistol
Browse files Browse the repository at this point in the history
Get rid of separate network buttons and use a popup menu to clean
up the UI a bit.

Found configuration for and implemented a button to select indoor
and outdoor modes. Outdoor mode can be selected with and without
the close range broad area IR cone support. This item is a saved
preference that will reload its previous state each time the app
is opened.

Implemented a method that should hopefully detect if the user has
connected a rifle or a pistol and adjust the battery gauge for
the appropriate blaster.

Implemented a characteristic read queue because it was needed to
allow reading the blaster's ID characteristic during blaster
connection so we can determine if we have a rifle or a pistol.
  • Loading branch information
Dees-Troy committed Jan 23, 2018
1 parent c5c54e2 commit 1460e32
Show file tree
Hide file tree
Showing 8 changed files with 433 additions and 226 deletions.
4 changes: 2 additions & 2 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ android {
applicationId "com.simplecoil.simplecoil"
minSdkVersion 21
targetSdkVersion 26
versionCode 3
versionName "1.2"
versionCode 4
versionName "1.3"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
Expand Down
86 changes: 67 additions & 19 deletions app/src/main/java/com/simplecoil/simplecoil/BluetoothLeService.java
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,10 @@ public class BluetoothLeService extends Service {
"com.example.bluetooth.le.ACTION_GATT_DISCONNECTED";
public final static String ACTION_GATT_SERVICES_DISCOVERED =
"com.example.bluetooth.le.ACTION_GATT_SERVICES_DISCOVERED";
public final static String ACTION_DATA_AVAILABLE =
"com.example.bluetooth.le.ACTION_DATA_AVAILABLE";
public final static String TELEMETRY_DATA_AVAILABLE =
"com.example.bluetooth.le.TELEMETRY_DATA_AVAILABLE";
public final static String ID_DATA_AVAILABLE =
"com.example.bluetooth.le.ID_DATA_AVAILABLE";
public final static String CHARACTERISTIC_WRITE_FINISHED =
"com.example.bluetooth.le.CHARACTERISTIC_WRITE_FINISHED";
public final static String DESCRIPTOR_WRITE_FINISHED =
Expand All @@ -71,10 +73,13 @@ public class BluetoothLeService extends Service {

public final static UUID UUID_RECOIL_TELEMETRY =
UUID.fromString(GattAttributes.RECOIL_TELEMETRY_UUID);
public final static UUID UUID_RECOIL_ID =
UUID.fromString(GattAttributes.RECOIL_ID_UUID);

private boolean mWriteAvailable = true;
private boolean mActionAvailable = true;
private Queue<BluetoothGattCharacteristic> mCharacteristicWriteQueue;
private Queue<BluetoothGattDescriptor> mDescriptorWriteQueue;
private Queue<BluetoothGattCharacteristic> mCharacteristicReadQueue;

// Implements callback methods for GATT events that the app cares about. For example,
// connection change and services discovered.
Expand Down Expand Up @@ -113,7 +118,28 @@ public void onCharacteristicRead(BluetoothGatt gatt,
BluetoothGattCharacteristic characteristic,
int status) {
if (status == BluetoothGatt.GATT_SUCCESS) {
broadcastUpdate(ACTION_DATA_AVAILABLE, characteristic);
Log.d(TAG, "read success!");
broadcastUpdate(characteristic);
} else {
Log.d(TAG, "read failed");
}
if (mCharacteristicWriteQueue.size() > 0) {
if (!mBluetoothGatt.writeCharacteristic(mCharacteristicWriteQueue.peek())) {
Log.e(TAG, "Failed to write queued characteristic " + mCharacteristicWriteQueue.peek().getUuid().toString());
}
mCharacteristicWriteQueue.remove();
} else if (mDescriptorWriteQueue.size() > 0) {
if (!mBluetoothGatt.writeDescriptor(mDescriptorWriteQueue.peek())) {
Log.e(TAG, "Failed to write queued descriptor " + mDescriptorWriteQueue.peek().getUuid().toString());
}
mDescriptorWriteQueue.remove();
} else if (mCharacteristicReadQueue.size() > 0) {
if (!mBluetoothGatt.readCharacteristic(mCharacteristicReadQueue.peek())) {
Log.e(TAG, "Failed to read queued characteristic " + mCharacteristicReadQueue.peek().getUuid().toString());
}
mCharacteristicReadQueue.remove();
} else {
mActionAvailable = true;
}
}

Expand All @@ -136,16 +162,21 @@ public void onCharacteristicWrite(BluetoothGatt gatt,
Log.e(TAG, "Failed to write queued descriptor " + mDescriptorWriteQueue.peek().getUuid().toString());
}
mDescriptorWriteQueue.remove();
} else if (mCharacteristicReadQueue.size() > 0) {
if (!mBluetoothGatt.readCharacteristic(mCharacteristicReadQueue.peek())) {
Log.e(TAG, "Failed to read queued characteristic " + mCharacteristicReadQueue.peek().getUuid().toString());
}
mCharacteristicReadQueue.remove();
} else {
mWriteAvailable = true;
mActionAvailable = true;
}
broadcastUpdate(CHARACTERISTIC_WRITE_FINISHED);
}

@Override
public void onCharacteristicChanged(BluetoothGatt gatt,
BluetoothGattCharacteristic characteristic) {
broadcastUpdate(ACTION_DATA_AVAILABLE, characteristic);
broadcastUpdate(characteristic);
}

@Override
Expand All @@ -167,8 +198,13 @@ public void onDescriptorWrite(BluetoothGatt gatt,
Log.e(TAG, "Failed to write queued descriptor " + mDescriptorWriteQueue.peek().getUuid().toString());
}
mDescriptorWriteQueue.remove();
} else if (mCharacteristicReadQueue.size() > 0) {
if (!mBluetoothGatt.readCharacteristic(mCharacteristicReadQueue.peek())) {
Log.e(TAG, "Failed to read queued characteristic " + mCharacteristicReadQueue.peek().getUuid().toString());
}
mCharacteristicReadQueue.remove();
} else {
mWriteAvailable = true;
mActionAvailable = true;
}
broadcastUpdate(DESCRIPTOR_WRITE_FINISHED);
}
Expand All @@ -179,10 +215,15 @@ private void broadcastUpdate(final String action) {
sendBroadcast(intent);
}

private void broadcastUpdate(final String action,
final BluetoothGattCharacteristic characteristic) {
private void broadcastUpdate(final BluetoothGattCharacteristic characteristic) {
if (UUID_RECOIL_TELEMETRY.equals((characteristic.getUuid()))) {
final Intent intent = new Intent(action);
final Intent intent = new Intent(TELEMETRY_DATA_AVAILABLE);
sendBroadcast(intent);
} else if (UUID_RECOIL_ID.equals((characteristic.getUuid()))) {
// This gets the blaster type, 1 for rifle and 2 for pistol
final Intent intent = new Intent(ID_DATA_AVAILABLE);
final byte[] data = characteristic.getValue();
intent.putExtra(EXTRA_DATA, data[10]);
sendBroadcast(intent);
} else {
Log.e(TAG, "unexpected characteristic data from " + characteristic.getUuid().toString());
Expand Down Expand Up @@ -234,6 +275,7 @@ public boolean initialize() {
}

mCharacteristicWriteQueue = new LinkedList<>();
mCharacteristicReadQueue = new LinkedList<>();
mDescriptorWriteQueue = new LinkedList<>();

return true;
Expand Down Expand Up @@ -319,26 +361,32 @@ public void readCharacteristic(BluetoothGattCharacteristic characteristic) {
Log.w(TAG, "BluetoothAdapter not initialized");
return;
}
mBluetoothGatt.readCharacteristic(characteristic);
}

public boolean isWriteAvailable() {
return mWriteAvailable;
if ((!mActionAvailable)) {
Log.d(TAG, "Reading not available yet, queuing...");
mCharacteristicReadQueue.add(characteristic);
return;
}
if (mBluetoothGatt.readCharacteristic(characteristic)) {
Log.d(TAG, "read the char");
mActionAvailable = false;
} else {
Log.d(TAG, "failed to read the char");
}
}

public void writeCharacteristic(BluetoothGattCharacteristic characteristic) {
if (mBluetoothAdapter == null || mBluetoothGatt == null) {
Log.w(TAG, "BluetoothAdapter not initialized");
return;
}
if ((!mWriteAvailable)) {
if ((!mActionAvailable)) {
Log.d(TAG, "Writing not available yet, queuing...");
mCharacteristicWriteQueue.add(characteristic);
return;
}
if (mBluetoothGatt.writeCharacteristic(characteristic)) {
//Log.d(TAG, "wrote char");
mWriteAvailable = false;
mActionAvailable = false;
} else {
Log.d(TAG, "failed to write char");
}
Expand All @@ -349,14 +397,14 @@ public void writeDescriptor(BluetoothGattDescriptor descriptor) {
Log.w(TAG, "BluetoothAdapter not initialized");
return;
}
if (!mWriteAvailable) {
if (!mActionAvailable) {
Log.d(TAG, "Writing not available yet, queuing...");
mDescriptorWriteQueue.add(descriptor);
return;
}
if (mBluetoothGatt.writeDescriptor(descriptor)) {
//Log.d(TAG, "wrote descriptor success");
mWriteAvailable = false;
mActionAvailable = false;
} else {
Log.d(TAG, "wrote descriptor FAIL");
}
Expand Down
Loading

0 comments on commit 1460e32

Please sign in to comment.