diff --git a/android/src/main/java/com/asterinet/react/bgactions/BackgroundTaskOptions.java b/android/src/main/java/com/asterinet/react/bgactions/BackgroundTaskOptions.java index 9951e02..1dcbc00 100644 --- a/android/src/main/java/com/asterinet/react/bgactions/BackgroundTaskOptions.java +++ b/android/src/main/java/com/asterinet/react/bgactions/BackgroundTaskOptions.java @@ -68,6 +68,16 @@ public BackgroundTaskOptions(@NonNull final ReactContext reactContext, @NonNull } catch (Exception e) { extras.putInt("color", Color.parseColor("#ffffff")); } + + // Handle checkLocationPermissions - Arguments.toBundle may not include boolean values properly + try { + if (options.hasKey("checkLocationPermissions")) { + boolean checkLocationPermissions = options.getBoolean("checkLocationPermissions"); + extras.putBoolean("checkLocationPermissions", checkLocationPermissions); + } + } catch (Exception e) { + throw new IllegalArgumentException("checkLocationPermissions not found"); + } } public Bundle getExtras() { @@ -101,4 +111,8 @@ public String getLinkingURI() { public Bundle getProgressBar() { return extras.getBundle("progressBar"); } + + public boolean shouldCheckLocationPermissions() { + return extras.getBoolean("checkLocationPermissions", false); + } } diff --git a/android/src/main/java/com/asterinet/react/bgactions/RNBackgroundActionsTask.java b/android/src/main/java/com/asterinet/react/bgactions/RNBackgroundActionsTask.java index 9900fc0..4db174d 100644 --- a/android/src/main/java/com/asterinet/react/bgactions/RNBackgroundActionsTask.java +++ b/android/src/main/java/com/asterinet/react/bgactions/RNBackgroundActionsTask.java @@ -7,13 +7,17 @@ import android.app.PendingIntent; import android.content.Context; import android.content.Intent; +import android.content.pm.PackageManager; import android.net.Uri; import android.os.Build; import android.os.Bundle; +import android.util.Log; + import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.core.app.NotificationCompat; +import androidx.core.content.ContextCompat; import com.facebook.react.HeadlessJsTaskService; import com.facebook.react.bridge.Arguments; @@ -90,6 +94,15 @@ public int onStartCommand(Intent intent, int flags, int startId) { // Create the notification final Notification notification = buildNotification(this, bgOptions); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q && bgOptions.shouldCheckLocationPermissions()) { + // Android 10+ (API 29+): Check required permissions for location foreground service + // This prevents SecurityException when permissions are revoked while service is running + if (!hasLocationPermissions()) { + stopSelf(); + return START_NOT_STICKY; + } + } + startForeground(SERVICE_NOTIFICATION_ID, notification); return super.onStartCommand(intent, flags, startId); } @@ -103,4 +116,19 @@ private void createNotificationChannel(@NonNull final String taskTitle, @NonNull notificationManager.createNotificationChannel(channel); } } + + /** + * Check if location permissions are granted + */ + private boolean hasLocationPermissions() { + // Check location permissions + boolean hasFineLocation = ContextCompat.checkSelfPermission(this, + android.Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED; + boolean hasCoarseLocation = ContextCompat.checkSelfPermission(this, + android.Manifest.permission.ACCESS_COARSE_LOCATION) == PackageManager.PERMISSION_GRANTED; + boolean hasBackgroundLocation = ContextCompat.checkSelfPermission(this, + android.Manifest.permission.ACCESS_BACKGROUND_LOCATION) == PackageManager.PERMISSION_GRANTED; + + return hasFineLocation && hasCoarseLocation && hasBackgroundLocation; + } } diff --git a/src/index.js b/src/index.js index 3719399..1c0e2bb 100644 --- a/src/index.js +++ b/src/index.js @@ -10,6 +10,7 @@ import EventEmitter from 'eventemitter3'; * color?: string * linkingURI?: string, * progressBar?: {max: number, value: number, indeterminate?: boolean} + * checkLocationPermissions?: boolean * }} BackgroundTaskOptions * @extends EventEmitter<'expiration',any> */ @@ -118,6 +119,7 @@ class BackgroundServer extends EventEmitter { color: options.color || '#ffffff', linkingURI: options.linkingURI, progressBar: options.progressBar, + checkLocationPermissions: options.checkLocationPermissions, }; }