I have developed an android app that is working perfectly alright on android versions less than 31
. For version 31 or greater I am getting the following error
Targeting S (version 31 and above) requires that one of FLAG_IMMUTABLE or FLAG_MUTABLE be specified when creating a PendingIntent. Strongly consider using FLAG_IMMUTABLE, only use FLAG_MUTABLE if some functionality depends on the PendingIntent being mutable, e.g. if it needs to be used with inline replies or bubbles.
Code
public static void initSyncReceiver(Context context) {
Intent intent = new Intent(context, SyncReciver.class);
AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
boolean alarmUp = (PendingIntent.getBroadcast(context, 23231, intent, PendingIntent.FLAG_NO_CREATE) != null);
if (!Common.SharedPreferenceHelper.getSharedPreference(context, context.getString(R.string.survey_sync_settings_key), true)) {
if (alarmUp) {
//alarm is up but not needed
Log.e(TAG, "sync booking alarm is up but not needed, canceling..");
PendingIntent pendingIntent = PendingIntent.getBroadcast(context,
23231, intent, PendingIntent.FLAG_CANCEL_CURRENT);
pendingIntent.cancel();
alarmManager.cancel(pendingIntent);
} else {
Log.e(TAG, "sync booking alarm neither up nor needed...");
}
return;
}
setAlarm(intent, context, 23231, 5);
Log.e(TAG, "sync booking alarm needed so setting...");
}
I am getting the error on boolean alarmUp = (PendingIntent.getBroadcast(context, 23231, intent, PendingIntent.FLAG_NO_CREATE) != null);
I have already migrated to androidx
. But no result.
Any help would be highly appreciated.
CodePudding user response:
If your app targets Android 12 or higher, you must specify the mutability of each PendingIntent object that your app creates.
Source: https://developer.android.com/guide/components/intents-filters#DeclareMutabilityPendingIntent
In short, add PendingIntent.FLAG_IMMUTABLE
or PendingIntent.FLAG_MUTABLE
to other PendingIntent
flags.
Whether it's mutable or not depends. For alarms, it's normally immutable.
For example, before:
PendingIntent.FLAG_UPDATE_CURRENT
Now:
PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
If you target Android 5 or lower, you need:
PendingIntent.FLAG_UPDATE_CURRENT or
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
PendingIntent.FLAG_IMMUTABLE
} else {
0
}
P.S. I happened to read this commit today. It has a similar modification.
Updated code for the question:
public static void initSyncReceiver(Context context) {
Intent intent = new Intent(context, SyncReciver.class);
AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
boolean alarmUp = (PendingIntent.getBroadcast(context, 23231, intent, PendingIntent.FLAG_NO_CREATE | PendingIntent.FLAG_IMMUTABLE) != null);
if (!Common.SharedPreferenceHelper.getSharedPreference(context, context.getString(R.string.survey_sync_settings_key), true)) {
if (alarmUp) {
//alarm is up but not needed
Log.e(TAG, "sync booking alarm is up but not needed, canceling..");
PendingIntent pendingIntent = PendingIntent.getBroadcast(context,
23231, intent, PendingIntent.FLAG_CANCEL_CURRENT | PendingIntent.FLAG_IMMUTABLE);
pendingIntent.cancel();
alarmManager.cancel(pendingIntent);
} else {
Log.e(TAG, "sync booking alarm neither up nor needed...");
}
return;
}
setAlarm(intent, context, 23231, 5);
Log.e(TAG, "sync booking alarm needed so setting...");
}