Request only the Bluetooth permission the app actually uses
Lint flagged ACCESS_FINE_LOCATION declared without ACCESS_COARSE_LOCATION, which Android 12 requires to be requested together. Rather than add the missing one, drop location entirely: the Bluetooth transport only talks to already-paired devices, enumerating bonded devices and opening an RFCOMM socket. Neither is a scan, so no location access is needed. BLUETOOTH_SCAN and BLUETOOTH_ADVERTISE go for the same reason — nothing was using them. Discovery of unpaired devices would bring all of these back; the manifest notes what that would require. Co-Authored-By: Claude Opus 5 <[email protected]> Claude-Session: https://claude.ai/code/session_015qjfMiPUDshdKEUa6vxqzN
This commit is contained in:
@@ -10,25 +10,22 @@
|
|||||||
<!-- Lets the app hand a downloaded APK to the system installer. -->
|
<!-- Lets the app hand a downloaded APK to the system installer. -->
|
||||||
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />
|
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />
|
||||||
|
|
||||||
<!-- Bluetooth. Android 12 (API 31) split the old catch-all permissions into
|
<!-- Bluetooth. Android 12 (API 31) replaced the catch-all BLUETOOTH
|
||||||
explicit SCAN/CONNECT/ADVERTISE, so the legacy pair is capped below 31
|
permission with explicit ones, so the legacy pair is capped below 31
|
||||||
and the new trio is requested at runtime above it. neverForLocation
|
and BLUETOOTH_CONNECT is requested at runtime above it.
|
||||||
tells the system we aren't deriving physical location from scans, which
|
|
||||||
avoids dragging in the location permission on 12+. -->
|
Only CONNECT is declared because the transport talks exclusively to
|
||||||
|
devices that are already paired: it enumerates bonded devices and
|
||||||
|
opens an RFCOMM socket, neither of which is a scan. Adding discovery
|
||||||
|
of unpaired devices later would mean declaring BLUETOOTH_SCAN here
|
||||||
|
(and, below API 31, both ACCESS_FINE_LOCATION and
|
||||||
|
ACCESS_COARSE_LOCATION, which Android requires together). -->
|
||||||
<uses-permission android:name="android.permission.BLUETOOTH"
|
<uses-permission android:name="android.permission.BLUETOOTH"
|
||||||
android:maxSdkVersion="30" />
|
android:maxSdkVersion="30" />
|
||||||
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"
|
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"
|
||||||
android:maxSdkVersion="30" />
|
android:maxSdkVersion="30" />
|
||||||
<uses-permission android:name="android.permission.BLUETOOTH_SCAN"
|
|
||||||
android:usesPermissionFlags="neverForLocation"
|
|
||||||
tools:targetApi="s" />
|
|
||||||
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT"
|
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT"
|
||||||
tools:targetApi="s" />
|
tools:targetApi="s" />
|
||||||
<uses-permission android:name="android.permission.BLUETOOTH_ADVERTISE"
|
|
||||||
tools:targetApi="s" />
|
|
||||||
<!-- Pre-31, Bluetooth discovery is gated behind location access. -->
|
|
||||||
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"
|
|
||||||
android:maxSdkVersion="30" />
|
|
||||||
|
|
||||||
<!-- Both radios are optional: the app is fully playable against AI without them. -->
|
<!-- Both radios are optional: the app is fully playable against AI without them. -->
|
||||||
<uses-feature android:name="android.hardware.bluetooth" android:required="false" />
|
<uses-feature android:name="android.hardware.bluetooth" android:required="false" />
|
||||||
|
|||||||
@@ -47,14 +47,10 @@ class MainActivity : ComponentActivity() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun requestBluetoothPermissions() {
|
private fun requestBluetoothPermissions() {
|
||||||
|
// Only CONNECT: the transport reaches paired devices and never scans.
|
||||||
|
// See the manifest for what discovery of unpaired devices would add.
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
|
||||||
bluetoothPermissions.launch(
|
bluetoothPermissions.launch(arrayOf(Manifest.permission.BLUETOOTH_CONNECT))
|
||||||
arrayOf(
|
|
||||||
Manifest.permission.BLUETOOTH_CONNECT,
|
|
||||||
Manifest.permission.BLUETOOTH_SCAN,
|
|
||||||
Manifest.permission.BLUETOOTH_ADVERTISE,
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user