Issue
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.
Solution
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...");
}
Answered By - Dewey Reed
Answer Checked By - Pedro (JavaFixing Volunteer)