Skip to content

Commit 7c1759a

Browse files
Fixed(NotificationAPI): Fix termux-notification actions not updating or conflicting between notifications due to same request code being used for the PendingIntent of all actions and also specify PendingIntent.FLAG_IMMUTABLE to prevent any modification
- https://developer.android.com/about/versions/12/behavior-changes-12#pending-intent-mutability Closes #677, Closes #764
1 parent 02b1c66 commit 7c1759a

File tree

3 files changed

+77
-1
lines changed

3 files changed

+77
-1
lines changed

app/src/main/java/com/termux/api/apis/NotificationAPI.java

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@
2222
import com.termux.api.R;
2323
import com.termux.api.TermuxAPIConstants;
2424
import com.termux.api.TermuxApiReceiver;
25+
import com.termux.api.util.PendingIntentUtils;
26+
import com.termux.api.util.PluginUtils;
2527
import com.termux.api.util.ResultReturner;
2628
import com.termux.shared.logger.Logger;
2729
import com.termux.shared.shell.command.ExecutionCommand;
@@ -421,6 +423,10 @@ static Intent createExecuteIntent(String action){
421423

422424
static PendingIntent createAction(final Context context, String action){
423425
Intent executeIntent = createExecuteIntent(action);
424-
return PendingIntent.getService(context, 0, executeIntent, 0);
426+
// Use unique request code for each action created so that pending intent extras are updated
427+
// and do not conflict when same action is recreated or between actions of different notifications.
428+
return PendingIntent.getService(context,
429+
PluginUtils.getLastPendingIntentRequestCode(context), executeIntent,
430+
PendingIntentUtils.getPendingIntentImmutableFlag());
425431
}
426432
}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
package com.termux.api.util;
2+
3+
import android.app.PendingIntent;
4+
import android.os.Build;
5+
6+
public class PendingIntentUtils {
7+
8+
/**
9+
* Get {@link PendingIntent#FLAG_IMMUTABLE} flag.
10+
*
11+
* - https://developer.android.com/guide/components/intents-filters#DeclareMutabilityPendingIntent
12+
* - https://developer.android.com/about/versions/12/behavior-changes-12#pending-intent-mutability
13+
*/
14+
public static int getPendingIntentImmutableFlag() {
15+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M)
16+
return PendingIntent.FLAG_IMMUTABLE;
17+
else
18+
return 0;
19+
}
20+
21+
/**
22+
* Get {@link PendingIntent#FLAG_MUTABLE} flag.
23+
*
24+
* - https://developer.android.com/guide/components/intents-filters#DeclareMutabilityPendingIntent
25+
* - https://developer.android.com/about/versions/12/behavior-changes-12#pending-intent-mutability
26+
*/
27+
public static int getPendingIntentMutableFlag() {
28+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S)
29+
return PendingIntent.FLAG_MUTABLE;
30+
else
31+
return 0;
32+
}
33+
34+
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
package com.termux.api.util;
2+
3+
import android.app.PendingIntent;
4+
import android.content.Context;
5+
6+
import com.termux.shared.termux.settings.preferences.TermuxPreferenceConstants.TERMUX_API_APP;
7+
import com.termux.shared.termux.settings.preferences.TermuxAPIAppSharedPreferences;
8+
9+
public class PluginUtils {
10+
11+
/**
12+
* Try to get the next unique {@link PendingIntent} request code that isn't already being used by
13+
* the app and which would create a unique {@link PendingIntent} that doesn't conflict with that
14+
* of any other execution commands.
15+
*
16+
* @param context The {@link Context} for operations.
17+
* @return Returns the request code that should be safe to use.
18+
*/
19+
public synchronized static int getLastPendingIntentRequestCode(final Context context) {
20+
if (context == null) return TERMUX_API_APP.DEFAULT_VALUE_KEY_LAST_PENDING_INTENT_REQUEST_CODE;
21+
22+
TermuxAPIAppSharedPreferences preferences = TermuxAPIAppSharedPreferences.build(context);
23+
if (preferences == null) return TERMUX_API_APP.DEFAULT_VALUE_KEY_LAST_PENDING_INTENT_REQUEST_CODE;
24+
25+
int lastPendingIntentRequestCode = preferences.getLastPendingIntentRequestCode();
26+
27+
int nextPendingIntentRequestCode = lastPendingIntentRequestCode + 1;
28+
29+
if (nextPendingIntentRequestCode == Integer.MAX_VALUE || nextPendingIntentRequestCode < 0)
30+
nextPendingIntentRequestCode = TERMUX_API_APP.DEFAULT_VALUE_KEY_LAST_PENDING_INTENT_REQUEST_CODE;
31+
32+
preferences.setLastPendingIntentRequestCode(nextPendingIntentRequestCode);
33+
return nextPendingIntentRequestCode;
34+
}
35+
36+
}

0 commit comments

Comments
 (0)