Merge pull request #172 from OpenSeizureDetector/ble_permissions

Fixed issue with bluetooth permissions
This commit is contained in:
Graham Jones
2024-04-12 20:49:20 +01:00
committed by GitHub
4 changed files with 99 additions and 61 deletions

View File

@@ -5,8 +5,11 @@
android:versionName="4.2.6c"> android:versionName="4.2.6c">
<!-- android:allowBackup="false" --> <!-- android:allowBackup="false" -->
<uses-permission android:name="android.permission.POST_NOTIFICATIONS"/> <uses-permission android:name="android.permission.POST_NOTIFICATIONS"/>
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" /> <uses-permission android:name="android.permission.BLUETOOTH"
android:maxSdkVersion="30" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"
android:maxSdkVersion="30" />
<uses-permission android:name="android.permission.BLUETOOTH_SCAN" /> <uses-permission android:name="android.permission.BLUETOOTH_SCAN" />
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" /> <uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
<uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.INTERNET" />

View File

@@ -29,13 +29,16 @@ import android.bluetooth.le.BluetoothLeScanner;
import android.bluetooth.le.ScanCallback; import android.bluetooth.le.ScanCallback;
import android.bluetooth.le.ScanResult; import android.bluetooth.le.ScanResult;
import android.content.Context; import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent; import android.content.Intent;
import android.content.SharedPreferences; import android.content.SharedPreferences;
import android.content.pm.PackageManager; import android.content.pm.PackageManager;
import android.graphics.Color; import android.graphics.Color;
import android.net.Uri;
import android.os.Bundle; import android.os.Bundle;
import android.os.Handler; import android.os.Handler;
import android.preference.PreferenceManager; import android.preference.PreferenceManager;
import android.text.Html;
import android.util.Log; import android.util.Log;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.Menu; import android.view.Menu;
@@ -48,6 +51,7 @@ import android.widget.ListView;
import android.widget.TextView; import android.widget.TextView;
import android.widget.Toast; import android.widget.Toast;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity; import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat; import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat; import androidx.core.content.ContextCompat;
@@ -66,17 +70,11 @@ public class BLEScanActivity extends ListActivity {
private Handler mHandler; private Handler mHandler;
private boolean bleAvailable = false; private boolean bleAvailable = false;
private OsdUtil mUtil;
private boolean mPermissionsRequested = false; private boolean mPermissionsRequested = false;
private final String TAG = "BLEScanActivity"; private final String TAG = "BLEScanActivity";
private final String[] REQUIRED_PERMISSIONS = {
//Manifest.permission.ACCESS_FINE_LOCATION,
//Manifest.permission.ACCESS_COARSE_LOCATION,
//Manifest.permission.BLUETOOTH,
Manifest.permission.BLUETOOTH_ADMIN,
Manifest.permission.BLUETOOTH_SCAN,
//Manifest.permission.BLUETOOTH_PRIVILEGED,
};
private static final int REQUEST_ENABLE_BT = 1; private static final int REQUEST_ENABLE_BT = 1;
// Stops scanning after 10 seconds. // Stops scanning after 10 seconds.
@@ -98,6 +96,7 @@ public class BLEScanActivity extends ListActivity {
//this.getActionBar().setTitle(R.string.title_devices); //this.getActionBar().setTitle(R.string.title_devices);
this.setTitle(R.string.title_devices); this.setTitle(R.string.title_devices);
mHandler = new Handler(); mHandler = new Handler();
mUtil = new OsdUtil(this, mHandler);
// Use this check to determine whether BLE is supported on the device. Then you can // Use this check to determine whether BLE is supported on the device. Then you can
// selectively disable BLE-related features. // selectively disable BLE-related features.
@@ -205,23 +204,16 @@ public class BLEScanActivity extends ListActivity {
tv.setBackgroundColor(okColour); tv.setBackgroundColor(okColour);
} }
Log.i(TAG,"onResume - calling requestBTPermissions()"); if (!mUtil.areBtPermissionsOk()) {
Log.i(TAG, "onResume - calling requestBTPermissions()");
requestBTPermissions(this); requestBTPermissions(this);
Log.i(TAG,"onResume - checking permissions");
boolean permissionsOk = true;
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 { } else {
Log.e(TAG, "Permission " + REQUIRED_PERMISSIONS[i] + " NOT GRANTED"); Log.i(TAG, "onResume - Bluetooth Permissions OK");
permissionsOk = false;
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); tv = (TextView) findViewById(R.id.ble_perm1_tv);
if (permissionsOk) { if (mUtil.areBtPermissionsOk()) {
tv.setText("Permissions required for Bluetooth Granted OK"); tv.setText("Permissions required for Bluetooth Granted OK");
tv.setBackgroundColor(okColour); tv.setBackgroundColor(okColour);
tv.setTextColor(okTextColour); tv.setTextColor(okTextColour);
@@ -294,17 +286,44 @@ public class BLEScanActivity extends ListActivity {
Log.i(TAG, "requestBTPermissions() - request already sent - not doing anything"); Log.i(TAG, "requestBTPermissions() - request already sent - not doing anything");
} else { } else {
Log.i(TAG, "requestBTPermissions() - showing rationale (if necessary)"); Log.i(TAG, "requestBTPermissions() - showing rationale (if necessary)");
for (int i = 0; i < REQUIRED_PERMISSIONS.length; i++) { boolean showRationale = false;
String btPermissions[] = mUtil.getRequiredBtPermissions();
for (int i = 0; i < btPermissions.length; i++) {
if (ActivityCompat.shouldShowRequestPermissionRationale(activity, if (ActivityCompat.shouldShowRequestPermissionRationale(activity,
REQUIRED_PERMISSIONS[i])) { btPermissions[i])) {
Log.i(TAG, "shouldShowRationale for permission" + REQUIRED_PERMISSIONS[i]); Log.i(TAG, "shouldShowRationale for permission" + btPermissions[i]);
Toast toast = Toast.makeText(this, "Please give us permission! ", Toast.LENGTH_SHORT); showRationale = true;
Toast toast = Toast.makeText(this, "Please give us permission! "+ btPermissions[i], Toast.LENGTH_SHORT);
toast.show(); toast.show();
} }
} }
if (showRationale) {
AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(
this);
alertDialogBuilder
.setTitle(getString(R.string.permissions_required))
.setMessage("Additional Permissions are required to scan for Bluetooth Devices - please grant the permissions in the following dialogs")
.setCancelable(false)
.setNegativeButton(getString(R.string.closeBtnTxt), new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
dialog.cancel();
finish();
}
})
.setPositiveButton("OK", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
dialog.cancel();
}
})
.create()
.show();
} else {
Log.i(TAG,"requestBTPermissions() - rationale display not required");
}
Log.i(TAG, "requestBTPermissions() - requesting permissions"); Log.i(TAG, "requestBTPermissions() - requesting permissions");
ActivityCompat.requestPermissions(activity, ActivityCompat.requestPermissions(activity,
REQUIRED_PERMISSIONS, btPermissions,
42); 42);
mPermissionsRequested = true; mPermissionsRequested = true;
} }
@@ -315,11 +334,11 @@ public class BLEScanActivity extends ListActivity {
try { try {
mBluetoothLeScanner.startScan(mLeScanCallback); mBluetoothLeScanner.startScan(mLeScanCallback);
} catch (SecurityException e) { } catch (SecurityException e) {
Log.e(TAG, "startScan - SecurityException while starting scan"); Log.e(TAG, "startScan - SecurityException while starting scan:" +e.getMessage());
Toast toast = Toast.makeText(this, "ERROR - Security Exception "+e.getMessage(), Toast.LENGTH_SHORT); Toast toast = Toast.makeText(this, "ERROR - Security Exception "+e.getMessage(), Toast.LENGTH_SHORT);
toast.show(); toast.show();
} catch (Exception e) { } catch (Exception e) {
Log.e(TAG,"startScan - Exception while starting scan"); Log.e(TAG,"startScan - Exception while starting scan:"+e.getMessage());
Toast toast = Toast.makeText(this, "ERROR Starting Scan", Toast.LENGTH_SHORT); Toast toast = Toast.makeText(this, "ERROR Starting Scan", Toast.LENGTH_SHORT);
toast.show(); toast.show();
} }

View File

@@ -99,6 +99,21 @@ public class OsdUtil {
private static int mNbound = 0; private static int mNbound = 0;
public final String[] BT_PERMISSIONS_API30 = {
Manifest.permission.ACCESS_FINE_LOCATION,
Manifest.permission.ACCESS_COARSE_LOCATION,
Manifest.permission.BLUETOOTH_SCAN,
//Manifest.permission.BLUETOOTH_ADMIN,
Manifest.permission.BLUETOOTH_CONNECT,
};
public final String[] BT_PERMISSIONS_OLD = {
Manifest.permission.ACCESS_FINE_LOCATION,
Manifest.permission.ACCESS_COARSE_LOCATION,
Manifest.permission.BLUETOOTH,
Manifest.permission.BLUETOOTH_ADMIN,
};
public String[] BT_PERMISSIONS;
public OsdUtil(Context context, Handler handler) { public OsdUtil(Context context, Handler handler) {
mContext = context; mContext = context;
mHandler = handler; mHandler = handler;
@@ -737,4 +752,30 @@ public class OsdUtil {
} }
} }
public String[] getRequiredBtPermissions() {
// API 31 is Android 12 - see https://developer.android.com/develop/connectivity/bluetooth/bt-permissions
if (Build.VERSION.SDK_INT >= 31) {
Log.d(TAG, "getRequiredBtPermissions() - using new Bluetooth Permissions");
BT_PERMISSIONS = BT_PERMISSIONS_API30;
} else {
Log.d(TAG, "getRequiredBtPermissions() - using old Bluetooth Permissions");
BT_PERMISSIONS = BT_PERMISSIONS_OLD;
}
return (BT_PERMISSIONS);
}
public boolean areBtPermissionsOk() {
String[] btPermissions = getRequiredBtPermissions();
boolean allOk = true;
Log.d(TAG, "areBTPermissions OK()");
for (int i = 0; i < btPermissions.length; i++) {
if (ContextCompat.checkSelfPermission(mContext, btPermissions[i])
!= PackageManager.PERMISSION_GRANTED) {
Log.i(TAG, btPermissions[i] + " Permission Not Granted");
allOk = false;
}
}
return allOk;
}
} }

View File

@@ -34,6 +34,7 @@ import android.content.pm.PackageInfo;
import android.content.pm.PackageManager; import android.content.pm.PackageManager;
import android.graphics.Color; import android.graphics.Color;
import android.net.Uri; import android.net.Uri;
import android.os.Build;
import android.os.Bundle; import android.os.Bundle;
import android.os.Handler; import android.os.Handler;
import android.os.PowerManager; import android.os.PowerManager;
@@ -112,14 +113,7 @@ public class StartupActivity extends AppCompatActivity {
Manifest.permission.ACCESS_BACKGROUND_LOCATION, Manifest.permission.ACCESS_BACKGROUND_LOCATION,
}; };
public final String[] BT_PERMISSIONS = { private String[] BT_PERMISSIONS;
Manifest.permission.ACCESS_FINE_LOCATION,
Manifest.permission.ACCESS_COARSE_LOCATION,
//Manifest.permission.BLUETOOTH,
//Manifest.permission.BLUETOOTH_SCAN,
//Manifest.permission.BLUETOOTH_ADMIN,
Manifest.permission.BLUETOOTH_CONNECT,
};
private boolean mBTPermissionsRequested = false; private boolean mBTPermissionsRequested = false;
private String mSdDataSourceName; private String mSdDataSourceName;
private String mBleDeviceAddr; private String mBleDeviceAddr;
@@ -325,7 +319,7 @@ public class StartupActivity extends AppCompatActivity {
pb.setProgressDrawable(getResources().getDrawable(R.drawable.start_server)); pb.setProgressDrawable(getResources().getDrawable(R.drawable.start_server));
if (mSdDataSourceName.equals("BLE") || mSdDataSourceName.equals("BLE2")) { if (mSdDataSourceName.equals("BLE") || mSdDataSourceName.equals("BLE2")) {
if (!areBTPermissionsOK()) { if (!mUtil.areBtPermissionsOk()) {
Log.i(TAG, "Bluetooth permissions NOT OK"); Log.i(TAG, "Bluetooth permissions NOT OK");
tv.setText(getString(R.string.BTPermissionWarning)); tv.setText(getString(R.string.BTPermissionWarning));
tv.setBackgroundColor(alarmColour); tv.setBackgroundColor(alarmColour);
@@ -335,7 +329,7 @@ public class StartupActivity extends AppCompatActivity {
requestBTPermissions(); requestBTPermissions();
allOk = false; allOk = false;
} else if (mBleDeviceAddr.equals("")) { } else if (mBleDeviceAddr.equals("")) {
Log.i(TAG,"BLE daa source selected, but no device address specified"); Log.i(TAG,"BLE data source selected, but no device address specified - starting BLEScanActivity");
Intent i; Intent i;
i = new Intent(getApplicationContext(), BLEScanActivity.class); i = new Intent(getApplicationContext(), BLEScanActivity.class);
startActivity(i); startActivity(i);
@@ -750,19 +744,6 @@ public class StartupActivity extends AppCompatActivity {
return allOk; return allOk;
} }
public boolean areBTPermissionsOK() {
boolean allOk = true;
Log.d(TAG, "areBTPermissions OK()");
for (int i = 0; i < BT_PERMISSIONS.length; i++) {
if (ContextCompat.checkSelfPermission(this, BT_PERMISSIONS[i])
!= PackageManager.PERMISSION_GRANTED) {
Log.d(TAG, BT_PERMISSIONS[i] + " Permission Not Granted");
allOk = false;
}
}
return allOk;
}
public void requestPermissions(AppCompatActivity activity) { public void requestPermissions(AppCompatActivity activity) {
@@ -890,16 +871,10 @@ public class StartupActivity extends AppCompatActivity {
dialog.cancel(); dialog.cancel();
Log.i(TAG, "requestBTPermissions(): Launching ActivityCompat.requestPermissions()"); Log.i(TAG, "requestBTPermissions(): Launching ActivityCompat.requestPermissions()");
ActivityCompat.requestPermissions(StartupActivity.this, ActivityCompat.requestPermissions(StartupActivity.this,
BT_PERMISSIONS, mUtil.getRequiredBtPermissions(),
46); 46);
} }
}) })
//.setNegativeButton(getString(R.string.cancelBtnTxt), new DialogInterface.OnClickListener() {
// public void onClick(DialogInterface dialog, int id) {
// dialog.cancel();
// }
//}
//)
.create().show(); .create().show();
} }
} }