Skip to content

Commit 71f80f4

Browse files
Add notification to remind user to allow bluetooth permissions
1 parent a76ac65 commit 71f80f4

2 files changed

Lines changed: 86 additions & 5 deletions

File tree

android/sdl_android/src/main/java/com/smartdevicelink/transport/SdlRouterService.java

Lines changed: 85 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@
7070
import android.os.ParcelFileDescriptor;
7171
import android.os.Parcelable;
7272
import android.os.RemoteException;
73+
import android.provider.Settings;
7374
import android.util.AndroidRuntimeException;
7475
import android.util.SparseArray;
7576
import android.util.SparseIntArray;
@@ -217,6 +218,10 @@ public class SdlRouterService extends Service {
217218
private boolean startSequenceComplete = false;
218219
private VehicleType receivedVehicleType;
219220
private boolean isConnectedOverUSB;
221+
private boolean waitingForBTRuntimePermissions = false;
222+
private Handler btPermissionsHandler;
223+
private Runnable btPermissionsRunnable;
224+
private final static int BT_PERMISSIONS_CHECK_FREQUENCY = 1000;
220225

221226
private ExecutorService packetExecutor = null;
222227
ConcurrentHashMap<TransportType, PacketWriteTaskMaster> packetWriteTaskMasterMap = null;
@@ -1098,11 +1103,27 @@ private boolean initCheck() {
10981103
return false;
10991104
}
11001105

1101-
//If Android 12 or newer make sure we have BT Runtime permissions
1102-
boolean supportsBTPermissions = AndroidTools.areBtPermissionsGranted(this, this.getPackageName());
1103-
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S && !supportsBTPermissions) {
1104-
DebugTool.logError(TAG, "Bluetooth Runtime Permissions are not granted. Shutting down");
1105-
return false;
1106+
// If Android 12 or newer make sure we have BT Runtime permissions
1107+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S && !AndroidTools.areBtPermissionsGranted(this, this.getPackageName())) {
1108+
if (isConnectedOverUSB) {
1109+
waitingForBTRuntimePermissions = true;
1110+
btPermissionsHandler = new Handler(Looper.myLooper());
1111+
btPermissionsRunnable = new Runnable() {
1112+
@Override
1113+
public void run() {
1114+
if (!AndroidTools.areBtPermissionsGranted(SdlRouterService.this, SdlRouterService.this.getPackageName())) {
1115+
btPermissionsHandler.postDelayed(btPermissionsRunnable, BT_PERMISSIONS_CHECK_FREQUENCY);
1116+
} else {
1117+
waitingForBTRuntimePermissions = false;
1118+
initBluetoothSerialService();
1119+
}
1120+
}
1121+
};
1122+
btPermissionsHandler.postDelayed(btPermissionsRunnable, BT_PERMISSIONS_CHECK_FREQUENCY);
1123+
showBTPermissionsNotification();
1124+
} else {
1125+
return false;
1126+
}
11061127
}
11071128

11081129
if (!AndroidTools.isServiceExported(this, new ComponentName(this, this.getClass()))) { //We want to check to see if our service is actually exported
@@ -1776,6 +1797,10 @@ public void closeSelf() {
17761797
}
17771798

17781799
private synchronized void initBluetoothSerialService() {
1800+
if (waitingForBTRuntimePermissions) {
1801+
return;
1802+
}
1803+
17791804
if (legacyModeEnabled) {
17801805
DebugTool.logInfo(TAG, "Not starting own bluetooth during legacy mode");
17811806
return;
@@ -3885,4 +3910,59 @@ private void notifySppError() {
38853910
DebugTool.logError(TAG, "notifySppError: Unable to retrieve notification Manager service");
38863911
}
38873912
}
3913+
3914+
private void showBTPermissionsNotification() {
3915+
Notification.Builder builder;
3916+
if (android.os.Build.VERSION.SDK_INT < Build.VERSION_CODES.O) {
3917+
builder = new Notification.Builder(getApplicationContext());
3918+
} else {
3919+
builder = new Notification.Builder(getApplicationContext(), TransportConstants.SDL_ERROR_NOTIFICATION_CHANNEL_ID);
3920+
}
3921+
3922+
ComponentName name = new ComponentName(this, this.getClass());
3923+
if (0 != (getApplicationInfo().flags & ApplicationInfo.FLAG_DEBUGGABLE)) { //If we are in debug mode, include what app has the router service open
3924+
builder.setContentTitle("SDL: " + name.getPackageName());
3925+
} else {
3926+
builder.setContentTitle(getString(R.string.notification_title));
3927+
}
3928+
builder.setTicker(getString(R.string.sdl_error_notification_channel_name));
3929+
builder.setContentText(getString(R.string.allow_bluetooth_permissions));
3930+
3931+
//We should use icon from library resources if available
3932+
int trayId = getResources().getIdentifier("sdl_tray_icon", "drawable", getPackageName());
3933+
3934+
builder.setSmallIcon(trayId);
3935+
Bitmap icon = BitmapFactory.decodeResource(getResources(), R.drawable.spp_error);
3936+
builder.setLargeIcon(icon);
3937+
3938+
builder.setOngoing(false);
3939+
builder.setAutoCancel(true);
3940+
3941+
// Create an intent that will be fired when the user clicks the notification.
3942+
Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
3943+
Uri uri = Uri.fromParts("package", getPackageName(), null);
3944+
intent.setData(uri);
3945+
int flag = android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.S ? PendingIntent.FLAG_IMMUTABLE : 0;
3946+
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent, flag);
3947+
builder.setContentIntent(pendingIntent);
3948+
3949+
final String tag = "SDL";
3950+
//Now we need to add a notification channel
3951+
final NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
3952+
if (notificationManager != null) {
3953+
notificationManager.cancel(tag, TransportConstants.SDL_ERROR_NOTIFICATION_CHANNEL_ID_INT);
3954+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
3955+
NotificationChannel notificationChannel = new NotificationChannel(TransportConstants.SDL_ERROR_NOTIFICATION_CHANNEL_ID, getString(R.string.sdl_error_notification_channel_name), NotificationManager.IMPORTANCE_HIGH);
3956+
notificationChannel.enableLights(true);
3957+
notificationChannel.enableVibration(true);
3958+
notificationChannel.setShowBadge(false);
3959+
notificationManager.createNotificationChannel(notificationChannel);
3960+
builder.setChannelId(notificationChannel.getId());
3961+
}
3962+
Notification notification = builder.build();
3963+
notificationManager.notify(tag, TransportConstants.SDL_ERROR_NOTIFICATION_CHANNEL_ID_INT, notification);
3964+
} else {
3965+
DebugTool.logError(TAG, "Unable to retrieve notification Manager service");
3966+
}
3967+
}
38883968
}

android/sdl_android/src/main/res/values/strings.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
<string name="lockscreen_device_image_description">Device Icon</string>
66
<string name="default_lockscreen_warning_message">Swipe down to dismiss, acknowledging that you are not the driver.</string>
77
<string name="spp_out_of_resource">Too many apps are using Bluetooth</string>
8+
<string name="allow_bluetooth_permissions">Please click here and allow the app to use bluetooth permissions</string>
89
<string name="notification_title">SmartDeviceLink</string>
910
<string name="sdl_error_notification_channel_name">SDL Error</string>
1011
</resources>

0 commit comments

Comments
 (0)