mirror of
https://github.com/fr3ts0n/AndrOBD.git
synced 2026-06-03 11:04:38 -04:00
fix: adapt all permissions declarations and runtime requests for full SDK range
- AndroidManifest.xml: add maxSdkVersion=30 to location permissions (not needed on API 31+ with BLUETOOTH_SCAN neverForLocation), add FOREGROUND_SERVICE_CONNECTED_DEVICE permission (required API 34+), add foregroundServiceType=connectedDevice to ObdBackgroundService - MainActivity: replace 4 individual requestPermissions() calls (only last dialog was shown) with a single batched call keyed on SDK version (BLUETOOTH_SCAN+CONNECT on API 31+, ACCESS_FINE_LOCATION on API 23-30); add POST_NOTIFICATIONS runtime request on API 33+; add onRequestPermissionsResult() to retry BT init after grant - BtDeviceListActivity: batch BLUETOOTH_SCAN+BLUETOOTH_CONNECT into one requestPermissions() call - BleDeviceListActivity: same batching fix; guard startScan() behind permission check with early return - ChartActivity: add WRITE_EXTERNAL_STORAGE runtime request before screenshot on API 23-28; add onRequestPermissionsResult() to take screenshot after permission is granted Agent-Logs-Url: https://github.com/fr3ts0n/AndrOBD/sessions/6000e1a5-7568-4451-9a6a-42692a940107 Co-authored-by: fr3ts0n <2822578+fr3ts0n@users.noreply.github.com>
This commit is contained in:
committed by
GitHub
parent
2a7da60254
commit
bfbbffde94
@@ -11,8 +11,11 @@
|
||||
<uses-permission android:name="android.permission.BLUETOOTH_SCAN"
|
||||
android:usesPermissionFlags="neverForLocation" />
|
||||
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
|
||||
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
|
||||
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
|
||||
<!-- location only needed for BT/BLE scan on API 23-30; replaced by BLUETOOTH_SCAN on API 31+ -->
|
||||
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"
|
||||
android:maxSdkVersion="30" />
|
||||
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"
|
||||
android:maxSdkVersion="30" />
|
||||
|
||||
<!-- to keep Bluetooth measurement running even when screen is inactive -->
|
||||
<uses-permission android:name="android.permission.WAKE_LOCK" />
|
||||
@@ -26,6 +29,8 @@
|
||||
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
|
||||
<!-- For foreground service -->
|
||||
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
|
||||
<!-- Required for foreground service of type connectedDevice (API 34+) -->
|
||||
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_CONNECTED_DEVICE" />
|
||||
|
||||
<application
|
||||
android:allowBackup="true"
|
||||
@@ -103,7 +108,8 @@
|
||||
<service
|
||||
android:name=".ObdBackgroundService"
|
||||
android:enabled="true"
|
||||
android:exported="false" />
|
||||
android:exported="false"
|
||||
android:foregroundServiceType="connectedDevice" />
|
||||
</application>
|
||||
|
||||
</manifest>
|
||||
@@ -11,6 +11,7 @@ import android.os.Build;
|
||||
import androidx.annotation.RequiresApi;
|
||||
import androidx.core.app.ActivityCompat;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@RequiresApi (api = Build.VERSION_CODES.LOLLIPOP)
|
||||
@@ -22,11 +23,16 @@ public class BleDeviceListActivity
|
||||
@SuppressLint("InlinedApi")
|
||||
@Override
|
||||
protected void startDeviceScan() {
|
||||
List<String> missingPermissions = new ArrayList<>();
|
||||
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.BLUETOOTH_SCAN) != PackageManager.PERMISSION_GRANTED) {
|
||||
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.BLUETOOTH_SCAN}, 1);
|
||||
missingPermissions.add(Manifest.permission.BLUETOOTH_SCAN);
|
||||
}
|
||||
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.BLUETOOTH_CONNECT) != PackageManager.PERMISSION_GRANTED) {
|
||||
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.BLUETOOTH_CONNECT}, 1);
|
||||
missingPermissions.add(Manifest.permission.BLUETOOTH_CONNECT);
|
||||
}
|
||||
if (!missingPermissions.isEmpty()) {
|
||||
ActivityCompat.requestPermissions(this, missingPermissions.toArray(new String[0]), 1);
|
||||
return;
|
||||
}
|
||||
leScanner = mBtAdapter.getBluetoothLeScanner();
|
||||
leScanner.startScan(scanCallback);
|
||||
|
||||
@@ -41,6 +41,7 @@ import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.core.app.ActivityCompat;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Set;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
@@ -71,11 +72,15 @@ public class BtDeviceListActivity extends Activity
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
|
||||
List<String> missingPermissions = new ArrayList<>();
|
||||
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.BLUETOOTH_SCAN) != PackageManager.PERMISSION_GRANTED) {
|
||||
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.BLUETOOTH_SCAN}, 1);
|
||||
missingPermissions.add(Manifest.permission.BLUETOOTH_SCAN);
|
||||
}
|
||||
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.BLUETOOTH_CONNECT) != PackageManager.PERMISSION_GRANTED) {
|
||||
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.BLUETOOTH_CONNECT}, 1);
|
||||
missingPermissions.add(Manifest.permission.BLUETOOTH_CONNECT);
|
||||
}
|
||||
if (!missingPermissions.isEmpty()) {
|
||||
ActivityCompat.requestPermissions(this, missingPermissions.toArray(new String[0]), 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -18,11 +18,14 @@
|
||||
|
||||
package com.fr3ts0n.ecu.gui.androbd;
|
||||
|
||||
import android.Manifest;
|
||||
import android.annotation.SuppressLint;
|
||||
import android.app.ActionBar;
|
||||
import android.app.Activity;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.Paint.Align;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.os.Message;
|
||||
@@ -34,6 +37,9 @@ import android.view.WindowManager;
|
||||
import android.widget.EditText;
|
||||
import android.widget.ListAdapter;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.core.app.ActivityCompat;
|
||||
|
||||
import com.fr3ts0n.ecu.EcuDataPv;
|
||||
import com.fr3ts0n.ecu.prot.obd.ObdProt;
|
||||
|
||||
@@ -70,6 +76,9 @@ public class ChartActivity extends Activity
|
||||
*/
|
||||
public static final String POSITIONS = "POSITIONS";
|
||||
|
||||
/** Permission request code for WRITE_EXTERNAL_STORAGE (screenshot, API 23-28) */
|
||||
private static final int REQUEST_WRITE_STORAGE = 1;
|
||||
|
||||
/** Map to uniquely collect PID numbers */
|
||||
private final TreeSet<Integer> pidNumbers = new TreeSet<>();
|
||||
|
||||
@@ -248,7 +257,16 @@ public class ChartActivity extends Activity
|
||||
if (itemId == R.id.share) {
|
||||
new ExportTask(this).execute(sensorData);
|
||||
} else if (itemId == R.id.snapshot) {
|
||||
Screenshot.takeScreenShot(this, getWindow().peekDecorView());
|
||||
// WRITE_EXTERNAL_STORAGE is required on API 23-28 for the screenshot
|
||||
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.Q
|
||||
&& ActivityCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE)
|
||||
!= PackageManager.PERMISSION_GRANTED) {
|
||||
ActivityCompat.requestPermissions(this,
|
||||
new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},
|
||||
REQUEST_WRITE_STORAGE);
|
||||
} else {
|
||||
Screenshot.takeScreenShot(this, getWindow().peekDecorView());
|
||||
}
|
||||
}
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
@@ -272,6 +290,22 @@ public class ChartActivity extends Activity
|
||||
super.onDestroy();
|
||||
}
|
||||
|
||||
/**
|
||||
* Take screenshot once WRITE_EXTERNAL_STORAGE permission is granted (API 23-28).
|
||||
*/
|
||||
@Override
|
||||
public void onRequestPermissionsResult(int requestCode,
|
||||
@NonNull String[] permissions,
|
||||
@NonNull int[] grantResults)
|
||||
{
|
||||
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
|
||||
if (requestCode == REQUEST_WRITE_STORAGE
|
||||
&& grantResults.length > 0
|
||||
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
|
||||
Screenshot.takeScreenShot(this, getWindow().peekDecorView());
|
||||
}
|
||||
}
|
||||
|
||||
private final Timer refreshTimer = new Timer();
|
||||
|
||||
/**
|
||||
|
||||
@@ -84,6 +84,7 @@ import java.beans.PropertyChangeListener;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Date;
|
||||
import java.util.HashSet;
|
||||
@@ -163,6 +164,8 @@ public class MainActivity extends PluginManager
|
||||
private static final int REQUEST_SETTINGS = 5;
|
||||
private static final int REQUEST_CONNECT_DEVICE_USB = 6;
|
||||
private static final int REQUEST_GRAPH_DISPLAY_DONE = 7;
|
||||
private static final int REQUEST_BT_PERMISSIONS = 8;
|
||||
private static final int REQUEST_NOTIFICATIONS = 9;
|
||||
/**
|
||||
* app exit parameters
|
||||
*/
|
||||
@@ -641,6 +644,13 @@ public class MainActivity extends PluginManager
|
||||
CommService.medium = CommService.MEDIUM.USB;
|
||||
}
|
||||
|
||||
// Request POST_NOTIFICATIONS permission on API 33+
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
|
||||
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.POST_NOTIFICATIONS) != PackageManager.PERMISSION_GRANTED) {
|
||||
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.POST_NOTIFICATIONS}, REQUEST_NOTIFICATIONS);
|
||||
}
|
||||
}
|
||||
|
||||
initSelectedMode();
|
||||
|
||||
// Bind to background OBD service for continuous monitoring
|
||||
@@ -666,22 +676,28 @@ public class MainActivity extends PluginManager
|
||||
mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
|
||||
log.fine("Adapter: " + mBluetoothAdapter);
|
||||
|
||||
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.BLUETOOTH_SCAN) != PackageManager.PERMISSION_GRANTED) {
|
||||
log.warning("permission.BLUETOOTH_SCAN missing");
|
||||
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.BLUETOOTH_SCAN}, 1);
|
||||
// Collect missing BT/location permissions and request them all at once
|
||||
List<String> missingPermissions = new ArrayList<>();
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
|
||||
// API 31+: new Bluetooth permissions replace location for scanning
|
||||
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.BLUETOOTH_SCAN) != PackageManager.PERMISSION_GRANTED) {
|
||||
log.warning("permission.BLUETOOTH_SCAN missing");
|
||||
missingPermissions.add(Manifest.permission.BLUETOOTH_SCAN);
|
||||
}
|
||||
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.BLUETOOTH_CONNECT) != PackageManager.PERMISSION_GRANTED) {
|
||||
log.warning("permission.BLUETOOTH_CONNECT missing");
|
||||
missingPermissions.add(Manifest.permission.BLUETOOTH_CONNECT);
|
||||
}
|
||||
} else {
|
||||
// API 23-30: location permission required for BT/BLE scan
|
||||
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
|
||||
log.warning("permission.ACCESS_FINE_LOCATION missing");
|
||||
missingPermissions.add(Manifest.permission.ACCESS_FINE_LOCATION);
|
||||
}
|
||||
}
|
||||
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
|
||||
log.warning("permission.ACCESS_FINE_LOCATION missing");
|
||||
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_COARSE_LOCATION}, 1);
|
||||
}
|
||||
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
|
||||
log.warning("permission.ACCESS_FINE_LOCATION missing");
|
||||
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, 1);
|
||||
}
|
||||
|
||||
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.BLUETOOTH_CONNECT) != PackageManager.PERMISSION_GRANTED) {
|
||||
log.warning("permission.BLUETOOTH_CONNECT missing");
|
||||
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.BLUETOOTH_CONNECT}, 1);
|
||||
if (!missingPermissions.isEmpty()) {
|
||||
ActivityCompat.requestPermissions(this, missingPermissions.toArray(new String[0]), REQUEST_BT_PERMISSIONS);
|
||||
return;
|
||||
}
|
||||
|
||||
// If BT is not on, request that it be enabled.
|
||||
@@ -732,6 +748,30 @@ public class MainActivity extends PluginManager
|
||||
super.onStart();
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle permission request results.
|
||||
* Retries BT/BLE mode initialisation once the required permissions are granted.
|
||||
*/
|
||||
@Override
|
||||
public void onRequestPermissionsResult(int requestCode,
|
||||
@androidx.annotation.NonNull String[] permissions,
|
||||
@androidx.annotation.NonNull int[] grantResults)
|
||||
{
|
||||
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
|
||||
if (requestCode == REQUEST_BT_PERMISSIONS) {
|
||||
boolean allGranted = true;
|
||||
for (int result : grantResults) {
|
||||
if (result != PackageManager.PERMISSION_GRANTED) {
|
||||
allGranted = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (allGranted) {
|
||||
initSelectedMode();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override protected void onPause()
|
||||
{
|
||||
super.onPause();
|
||||
|
||||
Reference in New Issue
Block a user