Merge branch 'BLE' into O2SAT

This commit is contained in:
Graham Jones
2021-11-09 21:22:22 +00:00
5 changed files with 126 additions and 52 deletions

3
.gitignore vendored
View File

@@ -3,7 +3,8 @@ build
.idea .idea
local.properties local.properties
*.iml *.iml
app/app-release.apk app/release/app-release.apk
app/build app/build
app/app.iml app/app.iml
app/release/output-metadata.json

Binary file not shown.

View File

@@ -2,11 +2,14 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android" <manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
package="uk.org.openseizuredetector" package="uk.org.openseizuredetector"
android:versionCode="90" android:versionCode="91"
android:versionName="3.7.0a"> android:versionName="3.7.0b">
<!-- android:allowBackup="false" --> <!-- android:allowBackup="false" -->
<uses-permission android:name="android.permission.BLUETOOTH" /> <uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" /> <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<uses-permission android:name="android.permission.BLUETOOTH_PRIVILEGED" />
<uses-permission android:name="android.permission.BLUETOOTH_SCAN" />
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
<uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /> <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
@@ -26,6 +29,9 @@
android:name="android.hardware.telephony" android:name="android.hardware.telephony"
android:required="false" /> android:required="false" />
<uses-feature android:name="android.hardware.bluetooth_le" android:required="false" />
<application <application
android:icon="@drawable/star_of_life_48x48" android:icon="@drawable/star_of_life_48x48"
android:label="@string/app_name" android:label="@string/app_name"

View File

@@ -23,6 +23,9 @@ import android.app.ListActivity;
import android.bluetooth.BluetoothAdapter; import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice; import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothManager; import android.bluetooth.BluetoothManager;
import android.bluetooth.le.BluetoothLeScanner;
import android.bluetooth.le.ScanCallback;
import android.bluetooth.le.ScanResult;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.content.SharedPreferences; import android.content.SharedPreferences;
@@ -31,6 +34,7 @@ import android.os.Bundle;
import android.os.Handler; import android.os.Handler;
import android.preference.PreferenceManager; import android.preference.PreferenceManager;
import android.support.v4.app.ActivityCompat; import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.util.Log; import android.util.Log;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.Menu; import android.view.Menu;
@@ -46,12 +50,15 @@ import android.widget.Toast;
import java.util.ArrayList; import java.util.ArrayList;
import static android.support.v4.content.PermissionChecker.PERMISSION_GRANTED;
/** /**
* Activity for scanning and displaying available Bluetooth LE devices. * Activity for scanning and displaying available Bluetooth LE devices.
*/ */
public class BLEScanActivity extends ListActivity { public class BLEScanActivity extends ListActivity {
private LeDeviceListAdapter mLeDeviceListAdapter; private LeDeviceListAdapter mLeDeviceListAdapter;
private BluetoothAdapter mBluetoothAdapter; private BluetoothAdapter mBluetoothAdapter;
private BluetoothLeScanner mBluetoothLeScanner;
private boolean mScanning; private boolean mScanning;
private Handler mHandler; private Handler mHandler;
private boolean bleAvailable = false; private boolean bleAvailable = false;
@@ -60,9 +67,11 @@ public class BLEScanActivity extends ListActivity {
private final String TAG = "BLEScanActivity"; private final String TAG = "BLEScanActivity";
private final String[] REQUIRED_PERMISSIONS = { private final String[] REQUIRED_PERMISSIONS = {
Manifest.permission.ACCESS_FINE_LOCATION,
Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION,
Manifest.permission.BLUETOOTH, Manifest.permission.BLUETOOTH,
Manifest.permission.BLUETOOTH_ADMIN, Manifest.permission.BLUETOOTH_ADMIN,
//Manifest.permission.BLUETOOTH_PRIVILEGED,
}; };
private static final int REQUEST_ENABLE_BT = 1; private static final int REQUEST_ENABLE_BT = 1;
@@ -98,6 +107,8 @@ public class BLEScanActivity extends ListActivity {
finish(); finish();
return; return;
} }
mBluetoothLeScanner = mBluetoothAdapter.getBluetoothLeScanner();
} }
@Override @Override
@@ -145,11 +156,11 @@ public class BLEScanActivity extends ListActivity {
String bleAddr = SP.getString("BLE_Device_Addr", "none"); String bleAddr = SP.getString("BLE_Device_Addr", "none");
String bleName = SP.getString("BLE_Device_Name", "none"); String bleName = SP.getString("BLE_Device_Name", "none");
tv.setText("Current Device=" + bleName + " (" + bleAddr + ")"); tv.setText("Current Device=" + bleName + " (" + bleAddr + ")");
} catch(Exception e) { } catch (Exception e) {
tv.setText("Current Device=" + "none" + " (" + "none" + ")"); tv.setText("Current Device=" + "none" + " (" + "none" + ")");
} }
tv = (TextView)findViewById(R.id.ble_present_tv); tv = (TextView) findViewById(R.id.ble_present_tv);
if (mBluetoothAdapter == null) { if (mBluetoothAdapter == null) {
tv.setText("ERROR - Bluetooth Adapter Not Present"); tv.setText("ERROR - Bluetooth Adapter Not Present");
} else { } else {
@@ -157,7 +168,7 @@ public class BLEScanActivity extends ListActivity {
} }
// Ensures Bluetooth is enabled on the device. If Bluetooth is not currently enabled, // Ensures Bluetooth is enabled on the device. If Bluetooth is not currently enabled,
// fire an intent to display a dialog asking the user to grant permission to enable it. // fire an intent to display a dialog asking the user to grant permission to enable it.
tv = (TextView)findViewById(R.id.ble_adapter_tv); tv = (TextView) findViewById(R.id.ble_adapter_tv);
if (!mBluetoothAdapter.isEnabled()) { if (!mBluetoothAdapter.isEnabled()) {
tv.setText("ERROR - Bluetoot NOT Enabled"); tv.setText("ERROR - Bluetoot NOT Enabled");
Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE); Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
@@ -166,6 +177,43 @@ public class BLEScanActivity extends ListActivity {
tv.setText("Bluetooth Adapter Enabled OK"); tv.setText("Bluetooth Adapter Enabled OK");
} }
requestBTPermissions(this);
for (int i = 0; i < REQUIRED_PERMISSIONS.length; i++) {
if (ContextCompat.checkSelfPermission(this, REQUIRED_PERMISSIONS[i]) == PERMISSION_GRANTED) {
Log.i(TAG, "Permission " + REQUIRED_PERMISSIONS[i] + " OK");
} else {
Log.e(TAG, "Permission " + REQUIRED_PERMISSIONS[i] + " NOT GRANTED");
Toast.makeText(this, "ERROR - Permission " + REQUIRED_PERMISSIONS[i] + " not Granted - this will not work!!!!!", Toast.LENGTH_SHORT).show();
}
}
tv = (TextView) findViewById(R.id.ble_perm1_tv);
if (ContextCompat.checkSelfPermission(this, REQUIRED_PERMISSIONS[0]) == PERMISSION_GRANTED) {
tv.setText("Permission " + REQUIRED_PERMISSIONS[0] + " OK");
} else {
tv.setText("ERROR: Permission " + REQUIRED_PERMISSIONS[0] + " NOT GRANTED");
}
tv = (TextView) findViewById(R.id.ble_perm2_tv);
if (ContextCompat.checkSelfPermission(this, REQUIRED_PERMISSIONS[1]) == PERMISSION_GRANTED) {
tv.setText("Permission " + REQUIRED_PERMISSIONS[1] + " OK");
} else {
tv.setText("ERROR: Permission " + REQUIRED_PERMISSIONS[1] + " NOT GRANTED");
}
tv = (TextView) findViewById(R.id.ble_perm3_tv);
if (ContextCompat.checkSelfPermission(this, REQUIRED_PERMISSIONS[2]) == PERMISSION_GRANTED) {
tv.setText("Permission " + REQUIRED_PERMISSIONS[2] + " OK");
} else {
tv.setText("ERROR: Permission " + REQUIRED_PERMISSIONS[2] + " NOT GRANTED");
}
tv = (TextView) findViewById(R.id.ble_perm4_tv);
if (ContextCompat.checkSelfPermission(this, REQUIRED_PERMISSIONS[3]) == PERMISSION_GRANTED) {
tv.setText("Permission " + REQUIRED_PERMISSIONS[3] + " OK");
} else {
tv.setText("ERROR: Permission " + REQUIRED_PERMISSIONS[3] + " NOT GRANTED");
}
// Initializes list view adapter. // Initializes list view adapter.
mLeDeviceListAdapter = new LeDeviceListAdapter(); mLeDeviceListAdapter = new LeDeviceListAdapter();
setListAdapter(mLeDeviceListAdapter); setListAdapter(mLeDeviceListAdapter);
@@ -196,10 +244,10 @@ public class BLEScanActivity extends ListActivity {
if (device == null) return; if (device == null) return;
Log.v(TAG, "onListItemClick: Device=" + device.getName() + ", Addr=" + device.getAddress()); Log.v(TAG, "onListItemClick: Device=" + device.getName() + ", Addr=" + device.getAddress());
if (mScanning) { if (mScanning) {
mBluetoothAdapter.stopLeScan(mLeScanCallback); mBluetoothLeScanner.stopScan(mLeScanCallback);
mScanning = false; mScanning = false;
} }
Log.v(TAG,"Saving Device Details"); Log.v(TAG, "Saving Device Details");
SharedPreferences.Editor SPE = PreferenceManager SharedPreferences.Editor SPE = PreferenceManager
.getDefaultSharedPreferences(this).edit(); .getDefaultSharedPreferences(this).edit();
try { try {
@@ -208,50 +256,69 @@ public class BLEScanActivity extends ListActivity {
SPE.apply(); SPE.apply();
SPE.commit(); SPE.commit();
Log.v(TAG, "Saved Device Name="+device.getName()+" and Address="+device.getAddress()); Log.v(TAG, "Saved Device Name=" + device.getName() + " and Address=" + device.getAddress());
} catch (Exception ex) { } catch (Exception ex) {
Log.e(TAG, "Error Saving Devie Name and Address!"); Log.e(TAG, "Error Saving Device Name and Address!");
Toast toast = Toast.makeText(this, "Problem Saving Device Name and Address", Toast.LENGTH_SHORT); Toast toast = Toast.makeText(this, "Problem Saving Device Name and Address", Toast.LENGTH_SHORT);
toast.show(); toast.show();
} }
SharedPreferences SP = PreferenceManager.getDefaultSharedPreferences((this)); SharedPreferences SP = PreferenceManager.getDefaultSharedPreferences((this));
Log.v(TAG,"Check of saved values - Name="+SP.getString("BLE_Device_Name","NOT SET")+", Addr="+SP.getString("BLE_Device_Addr","NOT SET")); Log.v(TAG, "Check of saved values - Name=" + SP.getString("BLE_Device_Name", "NOT SET") + ", Addr=" + SP.getString("BLE_Device_Addr", "NOT SET"));
finish(); finish();
} }
public void requestBTPermissions(Activity activity) {
if (mPermissionsRequested) {
Log.i(TAG, "requestPermissions() - request already sent - not doing anything");
} else {
Log.i(TAG, "requestPermissions() - requesting permissions");
for (int i = 0; i < REQUIRED_PERMISSIONS.length; i++) {
if (ActivityCompat.shouldShowRequestPermissionRationale(activity,
REQUIRED_PERMISSIONS[i])) {
Log.i(TAG, "shouldShowRationale for permission" + REQUIRED_PERMISSIONS[i]);
}
}
ActivityCompat.requestPermissions(activity,
REQUIRED_PERMISSIONS,
42);
mPermissionsRequested = true;
}
}
private void scanLeDevice(final boolean enable) { private void scanLeDevice(final boolean enable) {
TextView tv; TextView tv;
requestPermissions(this);
if (enable) { if (enable) {
// Stops scanning after a pre-defined scan period. // Stops scanning after a pre-defined scan period.
mHandler.postDelayed(new Runnable() { mHandler.postDelayed(new Runnable() {
@Override @Override
public void run() { public void run() {
mScanning = false; mScanning = false;
mBluetoothAdapter.stopLeScan(mLeScanCallback); mBluetoothLeScanner.stopScan(mLeScanCallback);
invalidateOptionsMenu(); invalidateOptionsMenu();
TextView tv = (TextView)(findViewById(R.id.ble_scan_status_tv)); TextView tv = (TextView) (findViewById(R.id.ble_scan_status_tv));
tv.setText("Stopped"); tv.setText("Stopped");
Button b = (Button)findViewById(R.id.startScanButton); Button b = (Button) findViewById(R.id.startScanButton);
b.setEnabled(true); b.setEnabled(true);
} }
}, SCAN_PERIOD); }, SCAN_PERIOD);
mScanning = true; mScanning = true;
mBluetoothAdapter.startLeScan(mLeScanCallback); mBluetoothLeScanner.startScan(mLeScanCallback);
tv = (TextView)(findViewById(R.id.ble_scan_status_tv)); tv = (TextView) (findViewById(R.id.ble_scan_status_tv));
tv.setText("Scanning"); tv.setText("Scanning");
Button b = (Button)findViewById(R.id.startScanButton); Button b = (Button) findViewById(R.id.startScanButton);
b.setEnabled(false); b.setEnabled(false);
} else { } else {
mScanning = false; mScanning = false;
mBluetoothAdapter.stopLeScan(mLeScanCallback); mBluetoothLeScanner.stopScan(mLeScanCallback);
tv = (TextView)(findViewById(R.id.ble_scan_status_tv)); tv = (TextView) (findViewById(R.id.ble_scan_status_tv));
tv.setText("Stopped"); tv.setText("Stopped");
Button b = (Button)findViewById(R.id.startScanButton); Button b = (Button) findViewById(R.id.startScanButton);
b.setEnabled(true); b.setEnabled(true);
} }
invalidateOptionsMenu(); invalidateOptionsMenu();
@@ -270,7 +337,7 @@ public class BLEScanActivity extends ListActivity {
public void addDevice(BluetoothDevice device) { public void addDevice(BluetoothDevice device) {
if (!mLeDevices.contains(device)) { if (!mLeDevices.contains(device)) {
Log.v(TAG,"addDevice - "+device.getName()); Log.v(TAG, "addDevice - " + device.getName());
mLeDevices.add(device); mLeDevices.add(device);
} }
} }
@@ -301,7 +368,7 @@ public class BLEScanActivity extends ListActivity {
@Override @Override
public View getView(int i, View view, ViewGroup viewGroup) { public View getView(int i, View view, ViewGroup viewGroup) {
ViewHolder viewHolder; ViewHolder viewHolder;
Log.v(TAG,"scanner getView i="+i); Log.v(TAG, "scanner getView i=" + i);
// General ListView optimization code. // General ListView optimization code.
if (view == null) { if (view == null) {
view = mInflator.inflate(R.layout.ble_list_item_device, null); view = mInflator.inflate(R.layout.ble_list_item_device, null);
@@ -326,20 +393,15 @@ public class BLEScanActivity extends ListActivity {
} }
// Device scan callback. // Device scan callback.
private BluetoothAdapter.LeScanCallback mLeScanCallback = private ScanCallback mLeScanCallback =
new BluetoothAdapter.LeScanCallback() { new ScanCallback() {
@Override @Override
public void onLeScan(final BluetoothDevice device, int rssi, byte[] scanRecord) { public void onScanResult(int callbackType, ScanResult result) {
Log.v(TAG,"LEScanCallback - device="+device.getName()); //super.onScanResult(callbackType, result);
runOnUiThread(new Runnable() { Log.v(TAG, "ScanCallback - " + result.getDevice().getName());
@Override mLeDeviceListAdapter.addDevice(result.getDevice());
public void run() {
mLeDeviceListAdapter.addDevice(device);
mLeDeviceListAdapter.notifyDataSetChanged(); mLeDeviceListAdapter.notifyDataSetChanged();
} }
});
}
}; };
static class ViewHolder { static class ViewHolder {
@@ -348,21 +410,4 @@ public class BLEScanActivity extends ListActivity {
} }
public void requestPermissions(Activity activity) {
if (mPermissionsRequested) {
Log.i(TAG, "requestPermissions() - request already sent - not doing anything");
} else {
Log.i(TAG, "requestPermissions() - requesting permissions");
for (int i = 0; i < REQUIRED_PERMISSIONS.length; i++) {
if (ActivityCompat.shouldShowRequestPermissionRationale(activity,
REQUIRED_PERMISSIONS[i])) {
Log.i(TAG, "shouldShowRationale for permission" + REQUIRED_PERMISSIONS[i]);
}
}
ActivityCompat.requestPermissions(activity,
REQUIRED_PERMISSIONS,
42);
mPermissionsRequested = true;
}
}
} }

View File

@@ -42,6 +42,28 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="current_ble_device_tv" /> android:text="current_ble_device_tv" />
<TextView
android:id="@+id/ble_perm1_tv"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="ble_perm1_tv" />
<TextView
android:id="@+id/ble_perm2_tv"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="ble_perm2_tv" />
<TextView
android:id="@+id/ble_perm3_tv"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="ble_perm3_tv" />
<TextView
android:id="@+id/ble_perm4_tv"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="ble_perm4_tv" />
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="fill_parent" android:layout_height="fill_parent"