@javascriptcommon/react-native-track-player 1.2.9 → 1.2.23

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (131) hide show
  1. package/android/build.gradle +61 -4
  2. package/android/src/main/AndroidManifest.xml +2 -4
  3. package/android/src/main/ic_home-playstore.png +0 -0
  4. package/android/src/main/ic_repeat-playstore.png +0 -0
  5. package/android/src/main/ic_repeat_50-playstore.png +0 -0
  6. package/android/src/main/ic_shuffle-playstore.png +0 -0
  7. package/android/src/main/ic_shuffle_50-playstore.png +0 -0
  8. package/android/src/main/ic_shuffle_sm-playstore.png +0 -0
  9. package/android/src/main/ic_stop-playstore.png +0 -0
  10. package/android/src/main/ic_test-playstore.png +0 -0
  11. package/android/src/main/java/com/guichaguri/trackplayer/{service/HeadlessJsMediaService.java → HeadlessJsMediaService.java} +84 -33
  12. package/android/src/main/java/com/guichaguri/trackplayer/TrackPlayer.kt +25 -0
  13. package/android/src/main/java/com/guichaguri/trackplayer/extensions/AudioPlayerStateExt.kt +19 -0
  14. package/android/src/main/java/com/guichaguri/trackplayer/kotlinaudio/event/EventHolder.kt +30 -0
  15. package/android/src/main/java/com/guichaguri/trackplayer/kotlinaudio/event/NotificationEventHolder.kt +20 -0
  16. package/android/src/main/java/com/guichaguri/trackplayer/kotlinaudio/event/PlayerEventHolder.kt +111 -0
  17. package/android/src/main/java/com/guichaguri/trackplayer/kotlinaudio/models/AAMediaSessionCallback.kt +10 -0
  18. package/android/src/main/java/com/guichaguri/trackplayer/kotlinaudio/models/AudioContentType.kt +10 -0
  19. package/android/src/main/java/com/guichaguri/trackplayer/kotlinaudio/models/AudioItem.kt +66 -0
  20. package/android/src/main/java/com/guichaguri/trackplayer/kotlinaudio/models/AudioItemTransitionReason.kt +33 -0
  21. package/android/src/main/java/com/guichaguri/trackplayer/kotlinaudio/models/AudioPlayerState.kt +30 -0
  22. package/android/src/main/java/com/guichaguri/trackplayer/kotlinaudio/models/BufferConfig.kt +8 -0
  23. package/android/src/main/java/com/guichaguri/trackplayer/kotlinaudio/models/CacheConfig.kt +17 -0
  24. package/android/src/main/java/com/guichaguri/trackplayer/kotlinaudio/models/Capability.kt +19 -0
  25. package/android/src/main/java/com/guichaguri/trackplayer/kotlinaudio/models/FocusChangeData.kt +3 -0
  26. package/android/src/main/java/com/guichaguri/trackplayer/kotlinaudio/models/MediaSessionCallback.kt +17 -0
  27. package/android/src/main/java/com/guichaguri/trackplayer/kotlinaudio/models/NotificationConfig.kt +43 -0
  28. package/android/src/main/java/com/guichaguri/trackplayer/kotlinaudio/models/NotificationMetadata.kt +8 -0
  29. package/android/src/main/java/com/guichaguri/trackplayer/kotlinaudio/models/NotificationState.kt +8 -0
  30. package/android/src/main/java/com/guichaguri/trackplayer/kotlinaudio/models/PlayWhenReadyChangeData.kt +5 -0
  31. package/android/src/main/java/com/guichaguri/trackplayer/kotlinaudio/models/PlaybackEndedReason.kt +5 -0
  32. package/android/src/main/java/com/guichaguri/trackplayer/kotlinaudio/models/PlaybackError.kt +6 -0
  33. package/android/src/main/java/com/guichaguri/trackplayer/kotlinaudio/models/PlaybackMetadata.kt +200 -0
  34. package/android/src/main/java/com/guichaguri/trackplayer/kotlinaudio/models/PlayerConfig.kt +33 -0
  35. package/android/src/main/java/com/guichaguri/trackplayer/kotlinaudio/models/PlayerOptions.kt +9 -0
  36. package/android/src/main/java/com/guichaguri/trackplayer/kotlinaudio/models/PositionChangedReason.kt +39 -0
  37. package/android/src/main/java/com/guichaguri/trackplayer/kotlinaudio/models/QueuedPlayerOptions.kt +49 -0
  38. package/android/src/main/java/com/guichaguri/trackplayer/kotlinaudio/notification/NotificationManager.kt +678 -0
  39. package/android/src/main/java/com/guichaguri/trackplayer/kotlinaudio/players/AudioPlayer.kt +10 -0
  40. package/android/src/main/java/com/guichaguri/trackplayer/kotlinaudio/players/BaseAudioPlayer.kt +864 -0
  41. package/android/src/main/java/com/guichaguri/trackplayer/kotlinaudio/players/QueuedAudioPlayer.kt +269 -0
  42. package/android/src/main/java/com/guichaguri/trackplayer/kotlinaudio/players/components/MediaSourceExt.kt +35 -0
  43. package/android/src/main/java/com/guichaguri/trackplayer/kotlinaudio/players/components/PlayerCache.kt +26 -0
  44. package/android/src/main/java/com/guichaguri/trackplayer/kotlinaudio/utils/Utils.kt +12 -0
  45. package/android/src/main/java/com/guichaguri/trackplayer/model/MetadataAdapter.kt +224 -0
  46. package/android/src/main/java/com/guichaguri/trackplayer/model/State.kt +13 -0
  47. package/android/src/main/java/com/guichaguri/trackplayer/model/Track.kt +120 -0
  48. package/android/src/main/java/com/guichaguri/trackplayer/model/TrackAudioItem.kt +19 -0
  49. package/android/src/main/java/com/guichaguri/trackplayer/model/TrackType.kt +11 -0
  50. package/android/src/main/java/com/guichaguri/trackplayer/module/AutoConnectionDetector.kt +151 -0
  51. package/android/src/main/java/com/guichaguri/trackplayer/module/MusicEvents.kt +66 -0
  52. package/android/src/main/java/com/guichaguri/trackplayer/module/MusicModule.kt +1177 -0
  53. package/android/src/main/java/com/guichaguri/trackplayer/service/BundleUtils.kt +117 -0
  54. package/android/src/main/java/com/guichaguri/trackplayer/service/MusicBinder.kt +31 -0
  55. package/android/src/main/java/com/guichaguri/trackplayer/service/MusicManager.kt +347 -0
  56. package/android/src/main/java/com/guichaguri/trackplayer/service/MusicService.kt +1254 -0
  57. package/android/src/main/java/com/guichaguri/trackplayer/service/Utils.kt +228 -0
  58. package/android/src/main/java/com/guichaguri/trackplayer/service/metadata/ButtonEvents.kt +141 -0
  59. package/android/src/main/java/com/guichaguri/trackplayer/service/metadata/MetadataManager.kt +396 -0
  60. package/android/src/main/res/drawable-hdpi/ic_home.png +0 -0
  61. package/android/src/main/res/drawable-mdpi/ic_home.png +0 -0
  62. package/android/src/main/res/drawable-xhdpi/ic_home.png +0 -0
  63. package/android/src/main/res/drawable-xxhdpi/ic_home.png +0 -0
  64. package/android/src/main/res/drawable-xxxhdpi/ic_home.png +0 -0
  65. package/android/src/main/res/mipmap-hdpi/ic_arrow_down_circle_foreground.png +0 -0
  66. package/android/src/main/res/mipmap-hdpi/ic_clock_now_foreground.png +0 -0
  67. package/android/src/main/res/mipmap-hdpi/ic_close_foreground.png +0 -0
  68. package/android/src/main/res/mipmap-hdpi/ic_heart_foreground.png +0 -0
  69. package/android/src/main/res/mipmap-hdpi/ic_heart_outlined_foreground.png +0 -0
  70. package/android/src/main/res/mipmap-hdpi/ic_repeat_off_foreground.png +0 -0
  71. package/android/src/main/res/mipmap-hdpi/ic_repeat_on_foreground.png +0 -0
  72. package/android/src/main/res/mipmap-hdpi/ic_shuffle_off_foreground.png +0 -0
  73. package/android/src/main/res/mipmap-hdpi/ic_shuffle_on_foreground.png +0 -0
  74. package/android/src/main/res/mipmap-mdpi/ic_arrow_down_circle_foreground.png +0 -0
  75. package/android/src/main/res/mipmap-mdpi/ic_clock_now_foreground.png +0 -0
  76. package/android/src/main/res/mipmap-mdpi/ic_close_foreground.png +0 -0
  77. package/android/src/main/res/mipmap-mdpi/ic_heart_foreground.png +0 -0
  78. package/android/src/main/res/mipmap-mdpi/ic_heart_outlined_foreground.png +0 -0
  79. package/android/src/main/res/mipmap-mdpi/ic_repeat_off_foreground.png +0 -0
  80. package/android/src/main/res/mipmap-mdpi/ic_repeat_on_foreground.png +0 -0
  81. package/android/src/main/res/mipmap-mdpi/ic_shuffle_off_foreground.png +0 -0
  82. package/android/src/main/res/mipmap-mdpi/ic_shuffle_on_foreground.png +0 -0
  83. package/android/src/main/res/mipmap-xhdpi/ic_arrow_down_circle_foreground.png +0 -0
  84. package/android/src/main/res/mipmap-xhdpi/ic_clock_now_foreground.png +0 -0
  85. package/android/src/main/res/mipmap-xhdpi/ic_close_foreground.png +0 -0
  86. package/android/src/main/res/mipmap-xhdpi/ic_heart_foreground.png +0 -0
  87. package/android/src/main/res/mipmap-xhdpi/ic_heart_outlined_foreground.png +0 -0
  88. package/android/src/main/res/mipmap-xhdpi/ic_repeat_off_foreground.png +0 -0
  89. package/android/src/main/res/mipmap-xhdpi/ic_repeat_on_foreground.png +0 -0
  90. package/android/src/main/res/mipmap-xhdpi/ic_shuffle_off_foreground.png +0 -0
  91. package/android/src/main/res/mipmap-xhdpi/ic_shuffle_on_foreground.png +0 -0
  92. package/android/src/main/res/mipmap-xxhdpi/ic_arrow_down_circle_foreground.png +0 -0
  93. package/android/src/main/res/mipmap-xxhdpi/ic_clock_now_foreground.png +0 -0
  94. package/android/src/main/res/mipmap-xxhdpi/ic_close_foreground.png +0 -0
  95. package/android/src/main/res/mipmap-xxhdpi/ic_heart_foreground.png +0 -0
  96. package/android/src/main/res/mipmap-xxhdpi/ic_heart_outlined_foreground.png +0 -0
  97. package/android/src/main/res/mipmap-xxhdpi/ic_repeat_off_foreground.png +0 -0
  98. package/android/src/main/res/mipmap-xxhdpi/ic_repeat_on_foreground.png +0 -0
  99. package/android/src/main/res/mipmap-xxhdpi/ic_shuffle_off_foreground.png +0 -0
  100. package/android/src/main/res/mipmap-xxhdpi/ic_shuffle_on_foreground.png +0 -0
  101. package/android/src/main/res/mipmap-xxxhdpi/ic_arrow_down_circle_foreground.png +0 -0
  102. package/android/src/main/res/mipmap-xxxhdpi/ic_clock_now_foreground.png +0 -0
  103. package/android/src/main/res/mipmap-xxxhdpi/ic_close_foreground.png +0 -0
  104. package/android/src/main/res/mipmap-xxxhdpi/ic_heart_foreground.png +0 -0
  105. package/android/src/main/res/mipmap-xxxhdpi/ic_heart_outlined_foreground.png +0 -0
  106. package/android/src/main/res/mipmap-xxxhdpi/ic_repeat_off_foreground.png +0 -0
  107. package/android/src/main/res/mipmap-xxxhdpi/ic_repeat_on_foreground.png +0 -0
  108. package/android/src/main/res/mipmap-xxxhdpi/ic_shuffle_off_foreground.png +0 -0
  109. package/android/src/main/res/mipmap-xxxhdpi/ic_shuffle_on_foreground.png +0 -0
  110. package/android/src/main/res/raw/silent_5_seconds.mp3 +0 -0
  111. package/android/src/main/res/strings.xml +6 -0
  112. package/android/src/main/res/values/strings.xml +6 -0
  113. package/index.d.ts +62 -1
  114. package/lib/index.js +10 -9
  115. package/package.json +1 -1
  116. package/android/src/main/java/com/guichaguri/trackplayer/TrackPlayer.java +0 -28
  117. package/android/src/main/java/com/guichaguri/trackplayer/module/MusicEvents.java +0 -55
  118. package/android/src/main/java/com/guichaguri/trackplayer/module/MusicModule.java +0 -298
  119. package/android/src/main/java/com/guichaguri/trackplayer/service/MusicBinder.java +0 -47
  120. package/android/src/main/java/com/guichaguri/trackplayer/service/MusicManager.java +0 -383
  121. package/android/src/main/java/com/guichaguri/trackplayer/service/MusicService.java +0 -271
  122. package/android/src/main/java/com/guichaguri/trackplayer/service/Utils.java +0 -243
  123. package/android/src/main/java/com/guichaguri/trackplayer/service/metadata/ButtonEvents.java +0 -148
  124. package/android/src/main/java/com/guichaguri/trackplayer/service/metadata/MetadataManager.java +0 -379
  125. package/android/src/main/java/com/guichaguri/trackplayer/service/models/Track.java +0 -141
  126. package/android/src/main/java/com/guichaguri/trackplayer/service/models/TrackType.java +0 -35
  127. package/android/src/main/res/drawable-hdpi/ic_logo.png +0 -0
  128. package/android/src/main/res/drawable-mdpi/ic_logo.png +0 -0
  129. package/android/src/main/res/drawable-xhdpi/ic_logo.png +0 -0
  130. package/android/src/main/res/drawable-xxhdpi/ic_logo.png +0 -0
  131. package/android/src/main/res/drawable-xxxhdpi/ic_logo.png +0 -0
@@ -0,0 +1,120 @@
1
+ package com.guichaguri.trackplayer.model
2
+
3
+ import android.content.Context
4
+ import android.net.Uri
5
+ import android.os.Bundle
6
+ import android.support.v4.media.MediaDescriptionCompat
7
+ import android.support.v4.media.MediaMetadataCompat
8
+ import android.support.v4.media.RatingCompat
9
+ import android.support.v4.media.session.MediaSessionCompat
10
+ import android.util.Log
11
+ import com.guichaguri.trackplayer.kotlinaudio.models.AudioItemOptions
12
+ import com.guichaguri.trackplayer.kotlinaudio.models.MediaType
13
+ import com.guichaguri.trackplayer.service.Utils
14
+ import com.guichaguri.trackplayer.service.Utils.bundleToJson
15
+ import org.json.JSONObject
16
+
17
+ /**
18
+ * @author Guichaguri
19
+ */
20
+ class Track(context: Context?, bundle: Bundle, ratingType: Int) {
21
+ var url: String = ""
22
+ var id: String?
23
+ var resourceId: Int? = null // leave it null, not 0
24
+ var type = MediaType.DEFAULT
25
+ var contentType: String?
26
+ var userAgent: String?
27
+ var artwork: Uri? = null
28
+ var title: String? = null
29
+ var artist: String? = null
30
+ var album: String? = null
31
+ var date: String? = null
32
+ var genre: String? = null
33
+ var duration: Long = 0
34
+ var originalItem: Bundle?
35
+ var json: JSONObject
36
+ var rating: RatingCompat? = null
37
+ var headers: MutableMap<String, String>? = null
38
+ val queueId: Long
39
+
40
+ init {
41
+ id = bundle.getString("mediaId")
42
+ val trackType = bundle.getString("type", "default")
43
+ for (t in MediaType.values()) {
44
+ if (t.name.equals(trackType, ignoreCase = true)) {
45
+ type = t
46
+ break
47
+ }
48
+ }
49
+ if (bundle.getString("sourceData") != null) {
50
+ url = bundle.getString("sourceData").toString()
51
+ }
52
+ contentType = bundle.getString("contentType")
53
+ userAgent = bundle.getString("userAgent")
54
+ val httpHeaders = bundle.getBundle("headers")
55
+ if (httpHeaders != null) {
56
+ headers = HashMap()
57
+ for (header in httpHeaders.keySet()) {
58
+ (headers as HashMap<String, String?>)[header] = httpHeaders.getString(header)
59
+ }
60
+ }
61
+ setMetadata(context, bundle, ratingType)
62
+ queueId = System.currentTimeMillis()
63
+ json = bundleToJson(bundle)
64
+ originalItem = bundle
65
+ }
66
+
67
+ fun setMetadata(context: Context?, bundle: Bundle, ratingType: Int) {
68
+ artwork = context?.let { Utils.getUri(it, bundle, "artwork") }
69
+ title = bundle.getString("title")
70
+ artist = bundle.getString("artist")
71
+ album = bundle.getString("album")
72
+ date = bundle.getString("date")
73
+ genre = bundle.getString("genre")
74
+ duration = try {
75
+ Utils.toMillis(bundle.getDouble("duration", 0.0))
76
+ } catch (ex: Exception) {
77
+ val durationInt = bundle.getInt("duration", 0)
78
+ Utils.toMillis(durationInt.toDouble())
79
+ }
80
+ rating = Utils.getRating(bundle, "rating", ratingType)
81
+ if (originalItem != null && originalItem != bundle) originalItem!!.putAll(bundle)
82
+ }
83
+
84
+ fun toMediaMetadata(): MediaMetadataCompat.Builder {
85
+ val builder = MediaMetadataCompat.Builder()
86
+ builder.putString(MediaMetadataCompat.METADATA_KEY_TITLE, title)
87
+ builder.putString(MediaMetadataCompat.METADATA_KEY_ARTIST, artist)
88
+ builder.putString(MediaMetadataCompat.METADATA_KEY_ALBUM, album)
89
+ builder.putString(MediaMetadataCompat.METADATA_KEY_DATE, date)
90
+ builder.putString(MediaMetadataCompat.METADATA_KEY_GENRE, genre)
91
+ //builder.putString(METADATA_KEY_MEDIA_URI, uri.toString());
92
+ builder.putString(MediaMetadataCompat.METADATA_KEY_MEDIA_ID, id)
93
+ if (duration > 0) {
94
+ builder.putLong(MediaMetadataCompat.METADATA_KEY_DURATION, duration)
95
+ }
96
+ // if (artwork != null) {
97
+ // builder.putString(MediaMetadataCompat.METADATA_KEY_ART_URI, artwork.toString())
98
+ // }
99
+ if (rating != null) {
100
+ builder.putRating(MediaMetadataCompat.METADATA_KEY_RATING, rating)
101
+ }
102
+ return builder
103
+ }
104
+
105
+ fun toQueueItem(): MediaSessionCompat.QueueItem {
106
+ val descr = MediaDescriptionCompat.Builder()
107
+ .setTitle(title)
108
+ .setSubtitle(artist)
109
+ .setMediaId(id) //.setMediaUri(uri)
110
+ .setIconUri(artwork)
111
+ .build()
112
+ return MediaSessionCompat.QueueItem(descr, queueId)
113
+ }
114
+
115
+ fun toAudioItem(): TrackAudioItem {
116
+ return TrackAudioItem(this, type, url, artist, title, album, artwork.toString(), duration,
117
+ AudioItemOptions(headers, userAgent, resourceId)
118
+ )
119
+ }
120
+ }
@@ -0,0 +1,19 @@
1
+ package com.guichaguri.trackplayer.model
2
+
3
+ import android.graphics.Bitmap
4
+ import com.guichaguri.trackplayer.kotlinaudio.models.AudioItem
5
+ import com.guichaguri.trackplayer.kotlinaudio.models.AudioItemOptions
6
+ import com.guichaguri.trackplayer.kotlinaudio.models.MediaType
7
+
8
+ data class TrackAudioItem(
9
+ val track: Track,
10
+ override val type: MediaType,
11
+ override var audioUrl: String,
12
+ override var artist: String? = null,
13
+ override var title: String? = null,
14
+ override var albumTitle: String? = null,
15
+ override val artwork: String? = null,
16
+ override val duration: Long = 0,
17
+ override val options: AudioItemOptions? = null,
18
+ override var artworkBitmap: Bitmap? = null
19
+ ): AudioItem
@@ -0,0 +1,11 @@
1
+ package com.guichaguri.trackplayer.model
2
+
3
+ enum class TrackType(val typeName: String) {
4
+ DEFAULT("default"),
5
+
6
+ DASH("dash"),
7
+
8
+ HLS("hls"),
9
+
10
+ SMOOTH_STREAMING("smoothstreaming")
11
+ }
@@ -0,0 +1,151 @@
1
+ package com.guichaguri.trackplayer.module
2
+
3
+ import android.annotation.SuppressLint
4
+ import android.content.AsyncQueryHandler
5
+ import android.content.BroadcastReceiver
6
+ import android.content.ContentResolver
7
+ import android.content.Context
8
+ import android.content.Intent
9
+ import android.content.IntentFilter
10
+ import android.database.Cursor
11
+ import android.net.Uri
12
+ import android.os.Build
13
+ import com.facebook.react.bridge.Arguments
14
+ import com.facebook.react.bridge.ReactContext
15
+ import com.facebook.react.bridge.WritableMap
16
+ import com.facebook.react.modules.core.DeviceEventManagerModule
17
+
18
+ class AutoConnectionDetector(
19
+ val context: ReactContext,
20
+ private val onConnectionChange: ((Boolean) -> Unit)? = null
21
+ ) {
22
+
23
+ companion object {
24
+ const val TAG = "AutoConnectionDetector"
25
+
26
+ // columnName for provider to query on connection status
27
+ const val CAR_CONNECTION_STATE = "CarConnectionState"
28
+
29
+ // auto app on your phone will send broadcast with this action when connection state changes
30
+ const val ACTION_CAR_CONNECTION_UPDATED = "androidx.car.app.connection.action.CAR_CONNECTION_UPDATED"
31
+
32
+ // phone is not connected to car
33
+ const val CONNECTION_TYPE_NOT_CONNECTED = 0
34
+
35
+ // phone is connected to Automotive OS
36
+ const val CONNECTION_TYPE_NATIVE = 1
37
+
38
+ // phone is connected to Android Auto
39
+ const val CONNECTION_TYPE_PROJECTION = 2
40
+
41
+ private const val QUERY_TOKEN = 42
42
+
43
+ private const val CAR_CONNECTION_AUTHORITY = "androidx.car.app.connection"
44
+
45
+ private val PROJECTION_HOST_URI = Uri.Builder().scheme("content").authority(CAR_CONNECTION_AUTHORITY).build()
46
+
47
+ private const val CAR_CONNECTION_UPDATE = "car-connection-update"
48
+ }
49
+
50
+ var isCarConnected = false
51
+
52
+ private val carConnectionReceiver = CarConnectionBroadcastReceiver()
53
+ private val carConnectionQueryHandler = CarConnectionQueryHandler(context.contentResolver, context, this, onConnectionChange)
54
+ private var isReceiverRegistered = false
55
+
56
+ fun registerCarConnectionReceiver() {
57
+ if (!isReceiverRegistered) {
58
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
59
+ context.registerReceiver(carConnectionReceiver, IntentFilter(ACTION_CAR_CONNECTION_UPDATED), Context.RECEIVER_NOT_EXPORTED)
60
+ } else @SuppressLint("UnspecifiedRegisterReceiverFlag") {
61
+ context.registerReceiver(carConnectionReceiver, IntentFilter(ACTION_CAR_CONNECTION_UPDATED))
62
+ }
63
+ isReceiverRegistered = true
64
+ }
65
+ queryForState()
66
+ }
67
+
68
+ fun unRegisterCarConnectionReceiver() {
69
+ if (isReceiverRegistered) {
70
+ context.unregisterReceiver(carConnectionReceiver)
71
+ isReceiverRegistered = false
72
+ }
73
+ }
74
+
75
+ private fun queryForState() {
76
+ carConnectionQueryHandler.startQuery(
77
+ QUERY_TOKEN,
78
+ null,
79
+ PROJECTION_HOST_URI,
80
+ arrayOf(CAR_CONNECTION_STATE),
81
+ null,
82
+ null,
83
+ null
84
+ )
85
+ }
86
+
87
+ inner class CarConnectionBroadcastReceiver : BroadcastReceiver() {
88
+ // query for connection state every time the receiver receives the broadcast
89
+ override fun onReceive(context: Context?, intent: Intent?) {
90
+ queryForState()
91
+ }
92
+ }
93
+
94
+ internal class CarConnectionQueryHandler(
95
+ resolver: ContentResolver?,
96
+ private val context: ReactContext?,
97
+ private val autoConnectionDetector: AutoConnectionDetector,
98
+ private val onConnectionChange: ((Boolean) -> Unit)? = null,
99
+ ) : AsyncQueryHandler(resolver) {
100
+
101
+ private fun emitConnectionUpdate(params: WritableMap) {
102
+ context?.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)?.emit(
103
+ CAR_CONNECTION_UPDATE, params
104
+ )
105
+ }
106
+
107
+ private fun notifyCarConnected() {
108
+ autoConnectionDetector.isCarConnected = true
109
+ val params = Arguments.createMap()
110
+ params.putBoolean("connected", true)
111
+ emitConnectionUpdate(params)
112
+ onConnectionChange?.invoke(true)
113
+ }
114
+
115
+ private fun notifyCarDisconnected() {
116
+ autoConnectionDetector.isCarConnected = false
117
+ val params = Arguments.createMap()
118
+ params.putBoolean("connected", false)
119
+ emitConnectionUpdate(params)
120
+ onConnectionChange?.invoke(false)
121
+ }
122
+
123
+ // notify new queryed connection status when query complete
124
+ override fun onQueryComplete(token: Int, cookie: Any?, response: Cursor?) {
125
+ if (response == null) {
126
+ // Null response from content provider when checking connection to the car, treating as disconnected
127
+ notifyCarDisconnected()
128
+ return
129
+ }
130
+ val carConnectionTypeColumn = response.getColumnIndex(CAR_CONNECTION_STATE)
131
+ if (carConnectionTypeColumn < 0) {
132
+ // Connection to car response is missing the connection type, treating as disconnected
133
+ notifyCarDisconnected()
134
+ return
135
+ }
136
+ if (!response.moveToNext()) {
137
+ // Connection to car response is empty, treating as disconnected
138
+ notifyCarDisconnected()
139
+ return
140
+ }
141
+ val connectionState = response.getInt(carConnectionTypeColumn)
142
+ if (connectionState == CONNECTION_TYPE_NOT_CONNECTED) {
143
+ // Android Auto disconnected
144
+ notifyCarDisconnected()
145
+ } else {
146
+ // Android Auto connected
147
+ notifyCarConnected()
148
+ }
149
+ }
150
+ }
151
+ }
@@ -0,0 +1,66 @@
1
+ package com.guichaguri.trackplayer.module
2
+
3
+ import android.content.BroadcastReceiver
4
+ import android.content.Context
5
+ import android.content.Intent
6
+ import com.facebook.react.bridge.Arguments
7
+ import com.facebook.react.bridge.ReactContext
8
+ import com.facebook.react.modules.core.DeviceEventManagerModule.RCTDeviceEventEmitter
9
+
10
+ /**
11
+ * @author Milen Pivchev @mpivchev
12
+ */
13
+ class MusicEvents(private val reactContext: ReactContext) : BroadcastReceiver() {
14
+ override fun onReceive(context: Context, intent: Intent) {
15
+ val event = intent.getStringExtra("event")
16
+ val data = intent.getBundleExtra("data")
17
+ val map = if (data != null) Arguments.fromBundle(data) else null
18
+ reactContext.getJSModule(RCTDeviceEventEmitter::class.java).emit(
19
+ event!!, map
20
+ )
21
+ }
22
+
23
+ companion object {
24
+ // Media Control Events
25
+ const val BUTTON_PLAY = "remote-play"
26
+ const val BUTTON_PLAY_FROM_ID = "remote-play-id"
27
+ const val SEARCH = "remote-search"
28
+ const val BUTTON_PLAY_FROM_SEARCH = "remote-play-search"
29
+ const val BUTTON_PLAY_FROM_QUEUE = "remote-play-queue"
30
+ const val BUTTON_PAUSE = "remote-pause"
31
+ const val BUTTON_STOP = "remote-stop"
32
+ const val BUTTON_SKIP = "remote-skip"
33
+ const val BUTTON_SKIP_NEXT = "remote-next"
34
+ const val BUTTON_SKIP_PREVIOUS = "remote-previous"
35
+ const val BUTTON_SEEK_TO = "remote-seek"
36
+ const val BUTTON_SET_RATING = "remote-set-rating"
37
+ const val BUTTON_JUMP_FORWARD = "remote-jump-forward"
38
+ const val BUTTON_JUMP_BACKWARD = "remote-jump-backward"
39
+ const val BUTTON_DUCK = "remote-duck"
40
+ const val BUTTON_BROWSE = "remote-browse"
41
+ const val BUTTON_SHUFFLE = "remote-shuffle"
42
+ const val BUTTON_REPEAT = "remote-repeat"
43
+ const val BUTTON_TRACK_STATUS = "remote-track-status"
44
+
45
+ // Playback Events
46
+ const val PLAYBACK_PLAY_WHEN_READY_CHANGED = "playback-play-when-ready-changed"
47
+ const val PLAYBACK_STATE = "playback-state"
48
+ const val PLAYBACK_TRACK_CHANGED = "playback-track-changed"
49
+ const val PLAYBACK_ACTIVE_TRACK_CHANGED = "playback-active-track-changed"
50
+ const val PLAYBACK_QUEUE_ENDED = "playback-queue-ended"
51
+ const val PLAYBACK_METADATA = "playback-metadata-received"
52
+ const val PLAYBACK_PROGRESS_UPDATED = "playback-progress-updated"
53
+ const val PLAYBACK_ERROR = "playback-error"
54
+
55
+ // Metadata Events
56
+ const val METADATA_CHAPTER_RECEIVED = "metadata-chapter-received"
57
+ const val METADATA_TIMED_RECEIVED = "metadata-timed-received"
58
+ const val METADATA_COMMON_RECEIVED = "metadata-common-received"
59
+ const val METADATA_PAYLOAD_KEY = "metadata"
60
+
61
+ // Other
62
+ const val PLAYER_ERROR = "player-error"
63
+
64
+ const val EVENT_INTENT = "com.doublesymmetry.trackplayer.event"
65
+ }
66
+ }