Skip to content

Commit f92de60

Browse files
committed
add BLUETOOTH_CONNECT permission
fixes #62
1 parent 1f17e35 commit f92de60

File tree

13 files changed

+68
-28
lines changed

13 files changed

+68
-28
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,7 @@ After you have imported your client certificate, you will be able to choose it f
110110
* ACCESS_WIFI_STATE: necessary to retrieve SSID of connected Wi-Fi
111111
* BLUETOOTH: necessary up to Android 11 to communicate with beacons
112112
* BLUETOOTH_ADMIN: necessary up to Android 11 to discover beacons
113+
* BLUETOOTH_CONNECT: on Android 12+, necessary to read beacon names
113114
* BLUETOOTH_SCAN: on Android 12+, necessary to discover beacons
114115
* INTERNET: only necessary if your MQTT server is not running locally
115116
* RECEIVE_BOOT_COMPLETED: necessary to start service on start-up

app/build.gradle.kts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,8 +47,8 @@ android {
4747
multiDexEnabled = true
4848
targetSdk = 33
4949
vectorDrawables.useSupportLibrary = true
50-
versionCode = 49
51-
versionName = "2.5.1"
50+
versionCode = 50
51+
versionName = "2.5.2"
5252
javaCompileOptions {
5353
annotationProcessorOptions {
5454
argument("room.schemaLocation", "$projectDir/schemas")

app/src/main/AndroidManifest.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"
2121
android:maxSdkVersion="30" />
2222
<!-- Request Bluetooth permissions on Android 12+ -->
23+
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT"/>
2324
<uses-permission android:name="android.permission.BLUETOOTH_SCAN"/>
2425
<uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
2526
<uses-permission android:name="android.permission.INTERNET" />

app/src/main/java/org/ostrya/presencepublisher/initialization/EnsureBluetoothPermission.java

Lines changed: 25 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -15,20 +15,25 @@
1515
import org.ostrya.presencepublisher.dialog.ConfirmationDialogFragment;
1616
import org.ostrya.presencepublisher.log.DatabaseLogger;
1717

18+
import java.util.Map;
1819
import java.util.Queue;
1920

20-
public class EnsureBluetoothPermission extends AbstractChainedHandler<String, Boolean> {
21+
public class EnsureBluetoothPermission
22+
extends AbstractChainedHandler<String[], Map<String, Boolean>> {
2123
protected EnsureBluetoothPermission(MainActivity activity, Queue<HandlerFactory> handlerChain) {
22-
super(activity, new ActivityResultContracts.RequestPermission(), handlerChain);
24+
super(activity, new ActivityResultContracts.RequestMultiplePermissions(), handlerChain);
2325
}
2426

2527
@Override
2628
protected void doInitialize() {
2729
if (activity.isLocationPermissionNeeded()
2830
&& activity.isBluetoothBeaconConfigured()
2931
&& Build.VERSION.SDK_INT >= Build.VERSION_CODES.S
30-
&& ContextCompat.checkSelfPermission(activity, Manifest.permission.BLUETOOTH_SCAN)
31-
!= PackageManager.PERMISSION_GRANTED) {
32+
&& (ContextCompat.checkSelfPermission(activity, Manifest.permission.BLUETOOTH_SCAN)
33+
!= PackageManager.PERMISSION_GRANTED
34+
|| ContextCompat.checkSelfPermission(
35+
activity, Manifest.permission.BLUETOOTH_CONNECT)
36+
!= PackageManager.PERMISSION_GRANTED)) {
3237
DatabaseLogger.i(TAG, "Bluetooth scan permission not yet granted, asking user ...");
3338
FragmentManager fm = activity.getSupportFragmentManager();
3439
ConfirmationDialogFragment fragment =
@@ -45,19 +50,28 @@ protected void doInitialize() {
4550
@RequiresApi(api = Build.VERSION_CODES.S)
4651
private void onResult(Activity parent, boolean ok) {
4752
if (ok) {
48-
getLauncher().launch(Manifest.permission.BLUETOOTH_SCAN);
53+
getLauncher()
54+
.launch(
55+
new String[] {
56+
Manifest.permission.BLUETOOTH_SCAN,
57+
Manifest.permission.BLUETOOTH_CONNECT
58+
});
4959
} else {
5060
finishInitialization();
5161
}
5262
}
5363

5464
@Override
55-
protected void doHandleResult(Boolean result) {
56-
if (result) {
57-
DatabaseLogger.i(TAG, "Successfully granted bluetooth permission");
58-
} else {
59-
DatabaseLogger.w(TAG, "Bluetooth permission not granted, continuing anyway");
60-
}
65+
protected void doHandleResult(Map<String, Boolean> result) {
66+
result.forEach(
67+
(permission, enabled) ->
68+
DatabaseLogger.i(
69+
TAG,
70+
"Result for "
71+
+ permission
72+
+ ": "
73+
+ (enabled ? "granted" : "not granted")));
74+
DatabaseLogger.i(TAG, "Continuing initialization");
6175
finishInitialization();
6276
}
6377

app/src/main/java/org/ostrya/presencepublisher/preference/ConditionFragment.java

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@
2626
import org.ostrya.presencepublisher.preference.condition.SendViaMobileNetworkPreference;
2727
import org.ostrya.presencepublisher.preference.condition.WifiCategorySupport;
2828

29+
import java.util.Map;
30+
2931
public class ConditionFragment extends AbstractConfigurationFragment {
3032
private static final String TAG = "ConditionFragment";
3133

@@ -41,15 +43,15 @@ public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
4143

4244
WifiCategorySupport wifiSupport = new WifiCategorySupport(this);
4345
ActivityResultLauncher<String> serviceStartLauncher;
44-
ActivityResultLauncher<String> permissionRequestLauncher;
46+
ActivityResultLauncher<String[]> permissionRequestLauncher;
4547
// to make linter happy
4648
if (beaconsSupported) {
4749
serviceStartLauncher =
48-
registerForActivityResult(new IntentActionContract(), this::onActivityResult);
50+
registerForActivityResult(new IntentActionContract(), this::onServiceStart);
4951
permissionRequestLauncher =
5052
registerForActivityResult(
51-
new ActivityResultContracts.RequestPermission(),
52-
this::onActivityResult);
53+
new ActivityResultContracts.RequestMultiplePermissions(),
54+
this::onPermissionsGranted);
5355
} else {
5456
serviceStartLauncher = null;
5557
permissionRequestLauncher = null;
@@ -98,11 +100,19 @@ protected void onPreferencesChanged(SharedPreferences sharedPreferences, String
98100
}
99101
}
100102

101-
private void onActivityResult(boolean result) {
103+
private void onServiceStart(boolean result) {
102104
DatabaseLogger.d(TAG, "Received result " + result);
103105
if (result && beaconSupport != null) {
104106
DatabaseLogger.i(TAG, "Start scanning after enabling bluetooth");
105107
beaconSupport.clickAdd();
106108
}
107109
}
110+
111+
private void onPermissionsGranted(Map<String, Boolean> result) {
112+
DatabaseLogger.d(TAG, "Received result " + result);
113+
if (result.values().stream().allMatch(b -> b) && beaconSupport != null) {
114+
DatabaseLogger.i(TAG, "Start scanning after enabling bluetooth");
115+
beaconSupport.clickAdd();
116+
}
117+
}
108118
}

app/src/main/java/org/ostrya/presencepublisher/preference/condition/AddBeaconChoicePreferenceDummy.java

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -29,13 +29,13 @@ public class AddBeaconChoicePreferenceDummy extends ClickDummy {
2929
private static final String TAG = "AddBeaconChoicePreferenceDummy";
3030

3131
private final ActivityResultLauncher<String> serviceStartLauncher;
32-
private final ActivityResultLauncher<String> permissionRequestLauncher;
32+
private final ActivityResultLauncher<String[]> permissionRequestLauncher;
3333

3434
public AddBeaconChoicePreferenceDummy(
3535
Context context,
3636
Fragment fragment,
3737
ActivityResultLauncher<String> serviceStartLauncher,
38-
ActivityResultLauncher<String> permissionRequestLauncher) {
38+
ActivityResultLauncher<String[]> permissionRequestLauncher) {
3939
super(
4040
context,
4141
R.drawable.baseline_playlist_add_24,
@@ -49,10 +49,16 @@ public AddBeaconChoicePreferenceDummy(
4949
@Override
5050
protected void onClick() {
5151
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S
52-
&& ContextCompat.checkSelfPermission(
53-
getContext(), Manifest.permission.BLUETOOTH_SCAN)
54-
!= PackageManager.PERMISSION_GRANTED) {
55-
permissionRequestLauncher.launch(Manifest.permission.BLUETOOTH_SCAN);
52+
&& (ContextCompat.checkSelfPermission(
53+
getContext(), Manifest.permission.BLUETOOTH_SCAN)
54+
!= PackageManager.PERMISSION_GRANTED
55+
|| ContextCompat.checkSelfPermission(
56+
getContext(), Manifest.permission.BLUETOOTH_CONNECT)
57+
!= PackageManager.PERMISSION_GRANTED)) {
58+
permissionRequestLauncher.launch(
59+
new String[] {
60+
Manifest.permission.BLUETOOTH_SCAN, Manifest.permission.BLUETOOTH_CONNECT
61+
});
5662
return;
5763
}
5864
BluetoothManager bluetoothManager =

app/src/main/java/org/ostrya/presencepublisher/preference/condition/BeaconCategorySupport.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ public class BeaconCategorySupport extends AbstractDynamicPreferenceCategorySupp
2020
public BeaconCategorySupport(
2121
AbstractConfigurationFragment fragment,
2222
@Nullable ActivityResultLauncher<String> serviceStartLauncher,
23-
@Nullable ActivityResultLauncher<String> permissionRequestLauncher) {
23+
@Nullable ActivityResultLauncher<String[]> permissionRequestLauncher) {
2424
super(
2525
fragment,
2626
R.string.category_beacon_regions,
@@ -35,7 +35,7 @@ private static Preference createAdderEntry(
3535
Context context,
3636
Fragment fragment,
3737
@Nullable ActivityResultLauncher<String> serviceStartLauncher,
38-
@Nullable ActivityResultLauncher<String> permissionRequestLauncher) {
38+
@Nullable ActivityResultLauncher<String[]> permissionRequestLauncher) {
3939
if (serviceStartLauncher != null && permissionRequestLauncher != null) {
4040
return new AddBeaconChoicePreferenceDummy(
4141
context, fragment, serviceStartLauncher, permissionRequestLauncher);

app/src/main/play/listings/de-DE/full-description.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ Datenschutzerklärung unter <a href="https://ostrya.github.io/PresencePublisher/
2828
• ACCESS_WIFI_STATE: notwendig, um den Namen des verbundenen WLANs zu erfassen
2929
• BLUETOOTH: notwendig bis Android 11, um mit Bluetooth-Beacons zu kommunizieren
3030
• BLUETOOTH_ADMIN: notwendig bis Android 11, um unbekannte Bluetooth-Beacons zu finden
31+
• BLUETOOTH_CONNECT: notwendig ab Android 12, um Namen von unbekannten Bluetooth-Beacons zu lesen
3132
• BLUETOOTH_SCAN: notwendig ab Android 12, um unbekannte Bluetooth-Beacons zu finden
3233
• FOREGROUND_SERVICE: notwendig ab Android 9, damit die App zuverlässig laufen kann
3334
• INTERNET: nur notwendig, wenn dein MQTT-Broker nicht im lokalen Netzwerk läuft

app/src/main/play/listings/en-US/full-description.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ please have a look at the privacy policy at <a href="https://ostrya.github.io/Pr
2525
• ACCESS_WIFI_STATE: necessary to retrieve SSID of connected Wi-Fi
2626
• BLUETOOTH: necessary up to Android 11 to communicate with beacons
2727
• BLUETOOTH_ADMIN: necessary up to Android 11 to discover beacons
28+
• BLUETOOTH_CONNECT: on Android 12+, necessary to read beacon names
2829
• BLUETOOTH_SCAN: on Android 12+, necessary to discover beacons
2930
• FOREGROUND_SERVICE: necessary on Android 9+ to run the app reliably
3031
• INTERNET: only necessary if your MQTT server is not running locally

app/src/main/play/release-notes/de-DE/default.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
v2.5.2
2+
• weitere fehlende Bluetooth-Berechtigung hinzugefügt
3+
14
v2.5.1
25
• Hell- und Dunkelmodus
36
• neue Berechtigungen für Bluetooth-Erkennung mit Android 12+

0 commit comments

Comments
 (0)