Skip to content

Commit efc9531

Browse files
committed
feat(android): add configurable notification click behavior
1 parent c46c8fb commit efc9531

File tree

6 files changed

+124
-3
lines changed

6 files changed

+124
-3
lines changed

android/src/main/java/com/doublesymmetry/trackplayer/service/MusicService.kt

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -223,11 +223,19 @@ class MusicService : HeadlessJsTaskService() {
223223
}
224224
}
225225

226+
val notificationClickBehavior = androidOptions?.getBundle(NOTIFICATION_CLICK_BEHAVIOR_KEY)
227+
val enableUriData = notificationClickBehavior?.getBoolean(NOTIFICATION_CLICK_ENABLED_KEY, true) ?: true
228+
226229
val openAppIntent = packageManager.getLaunchIntentForPackage(packageName)?.apply {
227230
flags = Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_SINGLE_TOP
228-
// Add the Uri data so apps can identify that it was a notification click
229-
data = Uri.parse("trackplayer://notification.click")
230-
action = Intent.ACTION_VIEW
231+
232+
if (enableUriData) {
233+
val customUri = notificationClickBehavior?.getString(NOTIFICATION_CLICK_CUSTOM_URI_KEY)
234+
data = Uri.parse(customUri ?: "trackplayer://notification.click")
235+
236+
val customAction = notificationClickBehavior?.getString(NOTIFICATION_CLICK_CUSTOM_ACTION_KEY)
237+
action = customAction ?: Intent.ACTION_VIEW
238+
}
231239
}
232240

233241
val accentColor = BundleUtils.getIntOrNull(options, "color")
@@ -847,6 +855,12 @@ class MusicService : HeadlessJsTaskService() {
847855
const val ANDROID_AUDIO_CONTENT_TYPE = "androidAudioContentType"
848856
const val IS_FOCUS_LOSS_PERMANENT_KEY = "permanent"
849857
const val IS_PAUSED_KEY = "paused"
858+
859+
// Notification click behavior keys
860+
const val NOTIFICATION_CLICK_BEHAVIOR_KEY = "notificationClickBehavior"
861+
const val NOTIFICATION_CLICK_ENABLED_KEY = "enabled"
862+
const val NOTIFICATION_CLICK_CUSTOM_URI_KEY = "customUri"
863+
const val NOTIFICATION_CLICK_CUSTOM_ACTION_KEY = "action"
850864

851865
const val DEFAULT_JUMP_INTERVAL = 15.0
852866
const val DEFAULT_STOP_FOREGROUND_GRACE_PERIOD = 5

docs/docs/api/objects/android-options.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,4 @@ Options available for the android player. All options are optional.
77
| `appKilledPlaybackBehavior` | [`AppKilledPlaybackBehavior`](../constants/app-killed-playback-behavior.md) | [`ContinuePlayback`](../constants/app-killed-playback-behavior.md#continueplayback-default) | Define how the audio playback should behave after removing the app from recents (killing it). |
88
| `alwaysPauseOnInterruption` | `boolean` | `false` | Whether the `remote-duck` event will be triggered on every interruption |
99
| `stopForegroundGracePeriod` | `number` | `5` | Time in seconds to wait once the player should transition to not considering the service as in the foreground. If playback resumes within this grace period, the service remains in the foreground state. |
10+
| `notificationClickBehavior` | [`NotificationClickBehavior`](./notification-click-behavior.md) | [`Default Value`](./notification-click-behavior.md) | Configuration for notification click behavior |
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
# NotificationClickBehavior
2+
3+
Configuration for notification click behavior on Android.
4+
5+
| Param | Type | Default | Description |
6+
|-------|-------|---------|-------------|
7+
| `enabled` | `boolean` | `true` | Whether to add URI data to the notification click intent. When disabled, the app will launch without any URI information. |
8+
| `customUri` | `string` | `"trackplayer://notification.click"` | Custom URI to use instead of the default. Only used when `enabled` is `true`. |
9+
| `action` | `string` | `"android.intent.action.VIEW"` | Custom action to use for the notification click intent. Only used when `enabled` is `true`. |
10+
11+
## Default Value
12+
13+
```typescript
14+
{
15+
enabled: true,
16+
customUri: "trackplayer://notification.click",
17+
action: "android.intent.action.VIEW"
18+
}
19+
```
20+
21+
## Examples
22+
23+
### Disable URI data (launch app without notification click detection)
24+
```typescript
25+
await TrackPlayer.updateOptions({
26+
android: {
27+
notificationClickBehavior: {
28+
enabled: false
29+
}
30+
}
31+
});
32+
```
33+
34+
### Use custom URI
35+
```typescript
36+
await TrackPlayer.updateOptions({
37+
android: {
38+
notificationClickBehavior: {
39+
enabled: true,
40+
customUri: "myapp://notification.click"
41+
}
42+
}
43+
});
44+
```
45+
46+
### Use custom action
47+
```typescript
48+
await TrackPlayer.updateOptions({
49+
android: {
50+
notificationClickBehavior: {
51+
enabled: true,
52+
action: "android.intent.action.MAIN"
53+
}
54+
}
55+
});
56+
```
57+
58+
### Complete configuration
59+
```typescript
60+
await TrackPlayer.updateOptions({
61+
android: {
62+
notificationClickBehavior: {
63+
enabled: true,
64+
customUri: "myapp://player.notification",
65+
action: "android.intent.action.VIEW"
66+
}
67+
}
68+
});
69+
```

example/android/app/src/main/AndroidManifest.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
22

33
<uses-permission android:name="android.permission.INTERNET" />
4+
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
45

56
<application
67
android:name=".MainApplication"

example/src/services/SetupService.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,17 @@ export const SetupService = async () => {
3333
await TrackPlayer.updateOptions({
3434
android: {
3535
appKilledPlaybackBehavior: DefaultAudioServiceBehaviour,
36+
// Example: Configure notification click behavior
37+
// You can disable URI data to launch app without notification click detection
38+
// notificationClickBehavior: {
39+
// enabled: false
40+
// },
41+
// Or use custom URI and action
42+
// notificationClickBehavior: {
43+
// enabled: true,
44+
// customUri: "example://notification.click",
45+
// action: "android.intent.action.VIEW"
46+
// }
3647
},
3748
// This flag is now deprecated. Please use the above to define playback mode.
3849
// stoppingAppPausesPlayback: true,

src/interfaces/AndroidOptions.ts

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,25 @@
11
import type { AppKilledPlaybackBehavior } from '../constants';
22

3+
export interface NotificationClickBehavior {
4+
/**
5+
* Whether to add URI data to the notification click intent
6+
* @default true
7+
*/
8+
enabled?: boolean;
9+
10+
/**
11+
* Custom URI to use instead of the default "trackplayer://notification.click"
12+
* Only used when enabled is true
13+
*/
14+
customUri?: string;
15+
16+
/**
17+
* Custom action to use for the notification click intent
18+
* @default "android.intent.action.VIEW"
19+
*/
20+
action?: string;
21+
}
22+
323
export interface AndroidOptions {
424
/**
525
* Whether the audio playback notification is also removed when the playback
@@ -20,4 +40,9 @@ export interface AndroidOptions {
2040
* Defaults to 5 seconds.
2141
*/
2242
stopForegroundGracePeriod?: number;
43+
44+
/**
45+
* Configuration for notification click behavior
46+
*/
47+
notificationClickBehavior?: NotificationClickBehavior;
2348
}

0 commit comments

Comments
 (0)