capacitor-plugin-playlist 0.5.1 → 0.6.0
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.
- package/README.md +29 -23
- package/android/build.gradle +1 -3
- package/android/src/main/java/org/dwbn/plugins/playlist/App.kt +0 -43
- package/android/src/main/java/org/dwbn/plugins/playlist/PlaylistPlugin.kt +217 -153
- package/android/src/main/java/org/dwbn/plugins/playlist/RmxAudioPlayer.java +4 -2
- package/android/src/main/java/org/dwbn/plugins/playlist/manager/PlaylistManager.kt +8 -6
- package/android/src/main/java/org/dwbn/plugins/playlist/playlist/AudioApi.kt +20 -11
- package/android/src/main/java/org/dwbn/plugins/playlist/playlist/AudioPlaylistHandler.java +1 -46
- package/android/src/main/java/org/dwbn/plugins/playlist/playlist/BaseMediaApi.kt +4 -8
- package/android/src/main/java/org/dwbn/plugins/playlist/service/MediaService.kt +17 -0
- package/package.json +1 -1
- package/android/.gradle/8.0.2/checksums/checksums.lock +0 -0
- package/android/.gradle/8.0.2/checksums/md5-checksums.bin +0 -0
- package/android/.gradle/8.0.2/checksums/sha1-checksums.bin +0 -0
- package/android/.gradle/8.0.2/dependencies-accessors/dependencies-accessors.lock +0 -0
- package/android/.gradle/8.0.2/dependencies-accessors/gc.properties +0 -0
- package/android/.gradle/8.0.2/executionHistory/executionHistory.bin +0 -0
- package/android/.gradle/8.0.2/executionHistory/executionHistory.lock +0 -0
- package/android/.gradle/8.0.2/fileChanges/last-build.bin +0 -0
- package/android/.gradle/8.0.2/fileHashes/fileHashes.bin +0 -0
- package/android/.gradle/8.0.2/fileHashes/fileHashes.lock +0 -0
- package/android/.gradle/8.0.2/fileHashes/resourceHashesCache.bin +0 -0
- package/android/.gradle/8.0.2/gc.properties +0 -0
- package/android/.gradle/8.2.1/checksums/checksums.lock +0 -0
- package/android/.gradle/8.2.1/checksums/md5-checksums.bin +0 -0
- package/android/.gradle/8.2.1/checksums/sha1-checksums.bin +0 -0
- package/android/.gradle/8.2.1/dependencies-accessors/dependencies-accessors.lock +0 -0
- package/android/.gradle/8.2.1/dependencies-accessors/gc.properties +0 -0
- package/android/.gradle/8.2.1/executionHistory/executionHistory.bin +0 -0
- package/android/.gradle/8.2.1/executionHistory/executionHistory.lock +0 -0
- package/android/.gradle/8.2.1/fileChanges/last-build.bin +0 -0
- package/android/.gradle/8.2.1/fileHashes/fileHashes.bin +0 -0
- package/android/.gradle/8.2.1/fileHashes/fileHashes.lock +0 -0
- package/android/.gradle/8.2.1/gc.properties +0 -0
- package/android/.gradle/buildOutputCleanup/buildOutputCleanup.lock +0 -0
- package/android/.gradle/buildOutputCleanup/cache.properties +0 -2
- package/android/.gradle/buildOutputCleanup/outputFiles.bin +0 -0
- package/android/.gradle/config.properties +0 -2
- package/android/.gradle/file-system.probe +0 -0
- package/android/.gradle/vcs-1/gc.properties +0 -0
- package/android/.idea/compiler.xml +0 -6
- package/android/.idea/gradle.xml +0 -19
- package/android/.idea/kotlinc.xml +0 -6
- package/android/.idea/migrations.xml +0 -10
- package/android/.idea/misc.xml +0 -9
- package/android/.idea/vcs.xml +0 -6
- package/android/bin/.gradle/8.0.2/checksums/checksums.lock +0 -0
- package/android/bin/.gradle/8.0.2/checksums/md5-checksums.bin +0 -0
- package/android/bin/.gradle/8.0.2/checksums/sha1-checksums.bin +0 -0
- package/android/bin/.gradle/8.0.2/dependencies-accessors/dependencies-accessors.lock +0 -0
- package/android/bin/.gradle/8.0.2/dependencies-accessors/gc.properties +0 -0
- package/android/bin/.gradle/8.0.2/executionHistory/executionHistory.bin +0 -0
- package/android/bin/.gradle/8.0.2/executionHistory/executionHistory.lock +0 -0
- package/android/bin/.gradle/8.0.2/fileChanges/last-build.bin +0 -0
- package/android/bin/.gradle/8.0.2/fileHashes/fileHashes.bin +0 -0
- package/android/bin/.gradle/8.0.2/fileHashes/fileHashes.lock +0 -0
- package/android/bin/.gradle/8.0.2/fileHashes/resourceHashesCache.bin +0 -0
- package/android/bin/.gradle/8.0.2/gc.properties +0 -0
- package/android/bin/.gradle/8.2.1/checksums/checksums.lock +0 -0
- package/android/bin/.gradle/8.2.1/checksums/md5-checksums.bin +0 -0
- package/android/bin/.gradle/8.2.1/checksums/sha1-checksums.bin +0 -0
- package/android/bin/.gradle/8.2.1/dependencies-accessors/dependencies-accessors.lock +0 -0
- package/android/bin/.gradle/8.2.1/dependencies-accessors/gc.properties +0 -0
- package/android/bin/.gradle/8.2.1/executionHistory/executionHistory.bin +0 -0
- package/android/bin/.gradle/8.2.1/executionHistory/executionHistory.lock +0 -0
- package/android/bin/.gradle/8.2.1/fileChanges/last-build.bin +0 -0
- package/android/bin/.gradle/8.2.1/fileHashes/fileHashes.bin +0 -0
- package/android/bin/.gradle/8.2.1/fileHashes/fileHashes.lock +0 -0
- package/android/bin/.gradle/8.2.1/gc.properties +0 -0
- package/android/bin/.gradle/buildOutputCleanup/buildOutputCleanup.lock +0 -0
- package/android/bin/.gradle/buildOutputCleanup/cache.properties +0 -2
- package/android/bin/.gradle/buildOutputCleanup/outputFiles.bin +0 -0
- package/android/bin/.gradle/config.properties +0 -2
- package/android/bin/.gradle/file-system.probe +0 -0
- package/android/bin/.gradle/vcs-1/gc.properties +0 -0
- package/android/bin/.idea/compiler.xml +0 -6
- package/android/bin/.idea/gradle.xml +0 -19
- package/android/bin/.idea/kotlinc.xml +0 -6
- package/android/bin/.idea/migrations.xml +0 -10
- package/android/bin/.idea/misc.xml +0 -9
- package/android/bin/.idea/vcs.xml +0 -6
- package/android/bin/.project +0 -34
- package/android/bin/build.gradle +0 -79
- package/android/bin/gradle/wrapper/gradle-wrapper.jar +0 -0
- package/android/bin/gradle/wrapper/gradle-wrapper.properties +0 -7
- package/android/bin/gradle.properties +0 -22
- package/android/bin/gradlew +0 -248
- package/android/bin/gradlew.bat +0 -92
- package/android/bin/local.properties +0 -8
- package/android/bin/proguard-rules.pro +0 -21
- package/android/bin/settings.gradle +0 -2
- package/android/bin/src/androidTest/java/com/getcapacitor/android/ExampleInstrumentedTest.class +0 -0
- package/android/bin/src/main/AndroidManifest.xml +0 -4
- package/android/bin/src/main/java/org/dwbn/plugins/playlist/App.kt +0 -62
- package/android/bin/src/main/java/org/dwbn/plugins/playlist/FakeR.kt +0 -39
- package/android/bin/src/main/java/org/dwbn/plugins/playlist/OnStatusCallback.kt +0 -34
- package/android/bin/src/main/java/org/dwbn/plugins/playlist/OnStatusReportListener.class +0 -0
- package/android/bin/src/main/java/org/dwbn/plugins/playlist/PlaylistItemOptions.class +0 -0
- package/android/bin/src/main/java/org/dwbn/plugins/playlist/PlaylistPlugin.kt +0 -356
- package/android/bin/src/main/java/org/dwbn/plugins/playlist/RmxAudioErrorType.class +0 -0
- package/android/bin/src/main/java/org/dwbn/plugins/playlist/RmxAudioPlayer.class +0 -0
- package/android/bin/src/main/java/org/dwbn/plugins/playlist/RmxAudioStatusMessage.class +0 -0
- package/android/bin/src/main/java/org/dwbn/plugins/playlist/RmxConstants.class +0 -0
- package/android/bin/src/main/java/org/dwbn/plugins/playlist/TrackRemovalItem.class +0 -0
- package/android/bin/src/main/java/org/dwbn/plugins/playlist/data/AudioTrack.kt +0 -94
- package/android/bin/src/main/java/org/dwbn/plugins/playlist/manager/MediaControlsListener.kt +0 -13
- package/android/bin/src/main/java/org/dwbn/plugins/playlist/manager/Options.kt +0 -77
- package/android/bin/src/main/java/org/dwbn/plugins/playlist/manager/PlaylistManager.kt +0 -286
- package/android/bin/src/main/java/org/dwbn/plugins/playlist/notification/PlaylistNotificationProvider.kt +0 -26
- package/android/bin/src/main/java/org/dwbn/plugins/playlist/playlist/AudioApi.kt +0 -101
- package/android/bin/src/main/java/org/dwbn/plugins/playlist/playlist/AudioPlaylistHandler$Builder.class +0 -0
- package/android/bin/src/main/java/org/dwbn/plugins/playlist/playlist/AudioPlaylistHandler.class +0 -0
- package/android/bin/src/main/java/org/dwbn/plugins/playlist/playlist/BaseMediaApi.kt +0 -40
- package/android/bin/src/main/java/org/dwbn/plugins/playlist/service/MediaImageProvider.kt +0 -79
- package/android/bin/src/main/java/org/dwbn/plugins/playlist/service/MediaService.kt +0 -53
- package/android/bin/src/main/res/.gitkeep +0 -0
- package/android/bin/src/main/res/drawable/ic_closed_caption_white_24dp.xml +0 -9
- package/android/bin/src/main/res/drawable/ic_demo_icon_adaptive.xml +0 -15
- package/android/bin/src/main/res/drawable/ic_launcher_background.xml +0 -48
- package/android/bin/src/main/res/drawable/ic_launcher_foreground.xml +0 -22
- package/android/bin/src/main/res/drawable/ic_notification_icon.png +0 -0
- package/android/bin/src/main/res/layout/bridge_layout_main.xml +0 -15
- package/android/bin/src/main/res/values/colors.xml +0 -3
- package/android/bin/src/main/res/values/strings.xml +0 -3
- package/android/bin/src/main/res/values/styles.xml +0 -3
- package/android/bin/src/test/java/com/getcapacitor/ExampleUnitTest.class +0 -0
- package/android/local.properties +0 -8
|
@@ -1,286 +0,0 @@
|
|
|
1
|
-
package org.dwbn.plugins.playlist.manager
|
|
2
|
-
|
|
3
|
-
import android.app.Application
|
|
4
|
-
import android.util.Log
|
|
5
|
-
import androidx.annotation.FloatRange
|
|
6
|
-
import androidx.annotation.IntRange
|
|
7
|
-
import com.devbrackets.android.exomedia.listener.OnErrorListener
|
|
8
|
-
import com.devbrackets.android.playlistcore.api.MediaPlayerApi
|
|
9
|
-
import com.devbrackets.android.playlistcore.manager.ListPlaylistManager
|
|
10
|
-
import org.dwbn.plugins.playlist.PlaylistItemOptions
|
|
11
|
-
import org.dwbn.plugins.playlist.TrackRemovalItem
|
|
12
|
-
import org.dwbn.plugins.playlist.data.AudioTrack
|
|
13
|
-
import org.dwbn.plugins.playlist.playlist.AudioApi
|
|
14
|
-
import org.dwbn.plugins.playlist.service.MediaService
|
|
15
|
-
import java.lang.ref.WeakReference
|
|
16
|
-
import java.util.*
|
|
17
|
-
|
|
18
|
-
/**
|
|
19
|
-
* A PlaylistManager that extends the [ListPlaylistManager] for use with the
|
|
20
|
-
* [MediaService] which extends [com.devbrackets.android.playlistcore.service.BasePlaylistService].
|
|
21
|
-
*/
|
|
22
|
-
class PlaylistManager(application: Application) :
|
|
23
|
-
ListPlaylistManager<AudioTrack>(application, MediaService::class.java), OnErrorListener {
|
|
24
|
-
private val audioTracks: MutableList<AudioTrack> = ArrayList()
|
|
25
|
-
private var volumeLeft = 1.0f
|
|
26
|
-
private var volumeRight = 1.0f
|
|
27
|
-
private var playbackSpeed = 1.0f
|
|
28
|
-
var loop = false
|
|
29
|
-
var isShouldStopPlaylist = false
|
|
30
|
-
var currentErrorTrack: AudioTrack? = null
|
|
31
|
-
|
|
32
|
-
// Really need a way to propagate the settings through the app
|
|
33
|
-
var resetStreamOnPause = true
|
|
34
|
-
var options: Options
|
|
35
|
-
private var mediaControlsListener = WeakReference<MediaControlsListener?>(null)
|
|
36
|
-
private var errorListener = WeakReference<OnErrorListener?>(null)
|
|
37
|
-
private var currentMediaPlayer: WeakReference<MediaPlayerApi<AudioTrack>?>? =
|
|
38
|
-
WeakReference(null)
|
|
39
|
-
|
|
40
|
-
fun setOnErrorListener(listener: OnErrorListener?) {
|
|
41
|
-
errorListener = WeakReference(listener)
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
fun setMediaControlsListener(listener: MediaControlsListener?) {
|
|
45
|
-
mediaControlsListener = WeakReference(listener)
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
val isPlaying: Boolean
|
|
49
|
-
get() = playlistHandler != null && playlistHandler!!.currentMediaPlayer != null && playlistHandler!!.currentMediaPlayer!!.isPlaying
|
|
50
|
-
|
|
51
|
-
override fun onError(e: Exception): Boolean {
|
|
52
|
-
Log.i(TAG, "onError: $e")
|
|
53
|
-
if (errorListener.get() != null) {
|
|
54
|
-
errorListener.get()!!.onError(e)
|
|
55
|
-
}
|
|
56
|
-
return true
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
/*
|
|
60
|
-
* isNextAvailable, getCurrentItem, and next() are overridden because there is
|
|
61
|
-
* a glaring bug in playlist core where when an item completes, isNextAvailable and
|
|
62
|
-
* getCurrentItem return wildly contradictory things, resulting in endless repeat
|
|
63
|
-
* of the last item in the playlist.
|
|
64
|
-
*/
|
|
65
|
-
override val isNextAvailable: Boolean
|
|
66
|
-
get() {
|
|
67
|
-
if (itemCount <= 1) {
|
|
68
|
-
return false;
|
|
69
|
-
}
|
|
70
|
-
val isAtEnd = currentPosition + 1 >= itemCount
|
|
71
|
-
val isConstrained = currentPosition + 1 in 0 until itemCount
|
|
72
|
-
return if (isAtEnd) {
|
|
73
|
-
loop
|
|
74
|
-
} else isConstrained
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
override operator fun next(): AudioTrack? {
|
|
78
|
-
if (isNextAvailable) {
|
|
79
|
-
val isAtEnd = currentPosition + 1 >= itemCount
|
|
80
|
-
if (isAtEnd && loop) {
|
|
81
|
-
currentPosition = 0
|
|
82
|
-
} else {
|
|
83
|
-
currentPosition = (currentPosition + 1).coerceAtMost(itemCount)
|
|
84
|
-
}
|
|
85
|
-
} else {
|
|
86
|
-
if (loop) {
|
|
87
|
-
currentPosition = INVALID_POSITION
|
|
88
|
-
} else {
|
|
89
|
-
isShouldStopPlaylist = true
|
|
90
|
-
return null
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
return currentItem
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
/*
|
|
99
|
-
* List management
|
|
100
|
-
*/
|
|
101
|
-
fun setAllItems(items: List<AudioTrack>?, options: PlaylistItemOptions) {
|
|
102
|
-
clearItems()
|
|
103
|
-
addAllItems(items)
|
|
104
|
-
currentPosition = 0
|
|
105
|
-
// If the options said to start from a specific position, do so.
|
|
106
|
-
var seekStart: Long = 0
|
|
107
|
-
if (options.playFromPosition > 0) {
|
|
108
|
-
seekStart = options.playFromPosition
|
|
109
|
-
} else if (options.retainPosition) {
|
|
110
|
-
val progress = currentProgress
|
|
111
|
-
if (progress != null) {
|
|
112
|
-
seekStart = progress.position
|
|
113
|
-
}
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
// If the options said to start from a specific id, do so.
|
|
117
|
-
var idStart: String? = null
|
|
118
|
-
if (options.playFromId != null) {
|
|
119
|
-
idStart = options.playFromId
|
|
120
|
-
}
|
|
121
|
-
if (idStart != null && "" != idStart) {
|
|
122
|
-
val code = idStart.hashCode()
|
|
123
|
-
setCurrentItem(code.toLong())
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
// We assume that if the playlist is fully loaded in one go,
|
|
127
|
-
// that the next thing to happen will be to play. So let's start
|
|
128
|
-
// paused, which will allow the player to pre-buffer until the
|
|
129
|
-
// user says Go.
|
|
130
|
-
beginPlayback(seekStart, options.startPaused)
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
fun addItem(item: AudioTrack?) {
|
|
134
|
-
if (item == null) {
|
|
135
|
-
return
|
|
136
|
-
}
|
|
137
|
-
val countBefore = audioTracks.size;
|
|
138
|
-
audioTracks.add(item)
|
|
139
|
-
items = audioTracks
|
|
140
|
-
if (countBefore == 0) {
|
|
141
|
-
currentPosition = 0
|
|
142
|
-
beginPlayback(1, true)
|
|
143
|
-
}
|
|
144
|
-
if (this.playlistHandler != null) {
|
|
145
|
-
this.playlistHandler!!.updateMediaControls()
|
|
146
|
-
}
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
fun addAllItems(its: List<AudioTrack>?) {
|
|
150
|
-
val currentItem = currentItem // may be null
|
|
151
|
-
audioTracks.addAll(its!!)
|
|
152
|
-
items =
|
|
153
|
-
audioTracks // not *strictly* needed since they share the reference, but for good measure..
|
|
154
|
-
currentPosition = audioTracks.indexOf(currentItem)
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
fun removeItem(index: Int, itemId: String): AudioTrack? {
|
|
158
|
-
val wasPlaying = isPlaying
|
|
159
|
-
if (playlistHandler != null) {
|
|
160
|
-
playlistHandler!!.pause(true)
|
|
161
|
-
}
|
|
162
|
-
var currentPosition = currentPosition
|
|
163
|
-
var foundItem: AudioTrack? = null
|
|
164
|
-
var removingCurrent = false
|
|
165
|
-
|
|
166
|
-
// If isPlaying is true, and currentItem is not null,
|
|
167
|
-
// that implies that currentItem is the currently playing item.
|
|
168
|
-
// If removingCurrent gets set to true, we are removing the currently playing item,
|
|
169
|
-
// and we need to restart playback once we do.
|
|
170
|
-
val resolvedIndex = resolveItemPosition(index, itemId)
|
|
171
|
-
if (resolvedIndex >= 0) {
|
|
172
|
-
foundItem = audioTracks[resolvedIndex]
|
|
173
|
-
if (foundItem == currentItem) {
|
|
174
|
-
removingCurrent = true
|
|
175
|
-
}
|
|
176
|
-
audioTracks.removeAt(resolvedIndex)
|
|
177
|
-
}
|
|
178
|
-
items = audioTracks
|
|
179
|
-
currentPosition = if (removingCurrent) currentPosition else audioTracks.indexOf(currentItem)
|
|
180
|
-
beginPlayback(currentPosition.toLong(), !wasPlaying)
|
|
181
|
-
if (this.playlistHandler != null) {
|
|
182
|
-
this.playlistHandler!!.updateMediaControls()
|
|
183
|
-
}
|
|
184
|
-
return foundItem
|
|
185
|
-
}
|
|
186
|
-
|
|
187
|
-
fun removeAllItems(its: ArrayList<TrackRemovalItem>): ArrayList<AudioTrack> {
|
|
188
|
-
val removedTracks = ArrayList<AudioTrack>()
|
|
189
|
-
val wasPlaying = isPlaying
|
|
190
|
-
if (playlistHandler != null) {
|
|
191
|
-
playlistHandler!!.pause(true)
|
|
192
|
-
}
|
|
193
|
-
var currentPosition = currentPosition
|
|
194
|
-
val currentItem = currentItem // may be null
|
|
195
|
-
var removingCurrent = false
|
|
196
|
-
for (item in its) {
|
|
197
|
-
val resolvedIndex = resolveItemPosition(item.trackIndex, item.trackId)
|
|
198
|
-
if (resolvedIndex >= 0) {
|
|
199
|
-
val foundItem = audioTracks[resolvedIndex]
|
|
200
|
-
if (foundItem == currentItem) {
|
|
201
|
-
removingCurrent = true
|
|
202
|
-
}
|
|
203
|
-
removedTracks.add(foundItem)
|
|
204
|
-
audioTracks.removeAt(resolvedIndex)
|
|
205
|
-
}
|
|
206
|
-
}
|
|
207
|
-
items = audioTracks
|
|
208
|
-
currentPosition = if (removingCurrent) currentPosition else audioTracks.indexOf(currentItem)
|
|
209
|
-
beginPlayback(currentPosition.toLong(), !wasPlaying)
|
|
210
|
-
return removedTracks
|
|
211
|
-
}
|
|
212
|
-
|
|
213
|
-
fun clearItems() {
|
|
214
|
-
if (playlistHandler != null) {
|
|
215
|
-
playlistHandler!!.stop()
|
|
216
|
-
}
|
|
217
|
-
audioTracks.clear()
|
|
218
|
-
items = audioTracks
|
|
219
|
-
currentPosition = INVALID_POSITION
|
|
220
|
-
}
|
|
221
|
-
|
|
222
|
-
private fun resolveItemPosition(trackIndex: Int, trackId: String): Int {
|
|
223
|
-
var resolvedPosition = -1
|
|
224
|
-
if (trackIndex >= 0 && trackIndex < audioTracks.size) {
|
|
225
|
-
resolvedPosition = trackIndex
|
|
226
|
-
} else if ("" != trackId) {
|
|
227
|
-
val itemPos = getPositionForItem(trackId.hashCode().toLong())
|
|
228
|
-
if (itemPos != INVALID_POSITION) {
|
|
229
|
-
resolvedPosition = itemPos
|
|
230
|
-
}
|
|
231
|
-
}
|
|
232
|
-
return resolvedPosition
|
|
233
|
-
}
|
|
234
|
-
|
|
235
|
-
fun getVolumeLeft(): Float {
|
|
236
|
-
return volumeLeft
|
|
237
|
-
}
|
|
238
|
-
|
|
239
|
-
fun getVolumeRight(): Float {
|
|
240
|
-
return volumeRight
|
|
241
|
-
}
|
|
242
|
-
|
|
243
|
-
fun setVolume(
|
|
244
|
-
@FloatRange(from = 0.0, to = 1.0) left: Float,
|
|
245
|
-
@FloatRange(from = 0.0, to = 1.0) right: Float
|
|
246
|
-
) {
|
|
247
|
-
volumeLeft = left
|
|
248
|
-
volumeRight = right
|
|
249
|
-
if (currentMediaPlayer != null && currentMediaPlayer!!.get() != null) {
|
|
250
|
-
Log.i("PlaylistManager", "setVolume completing with volume = $left")
|
|
251
|
-
currentMediaPlayer!!.get()!!.setVolume(volumeLeft, volumeRight)
|
|
252
|
-
}
|
|
253
|
-
}
|
|
254
|
-
|
|
255
|
-
fun getPlaybackSpeed(): Float {
|
|
256
|
-
return playbackSpeed
|
|
257
|
-
}
|
|
258
|
-
|
|
259
|
-
fun setPlaybackSpeed(@FloatRange(from = 0.0, to = 1.0) speed: Float) {
|
|
260
|
-
playbackSpeed = speed
|
|
261
|
-
if (playlistHandler!!.currentMediaPlayer != null && playlistHandler!!.currentMediaPlayer!! is AudioApi) {
|
|
262
|
-
Log.i(TAG, "setPlaybackSpeed completing with speed = $speed")
|
|
263
|
-
(playlistHandler!!.currentMediaPlayer as AudioApi?)!!.setPlaybackSpeed(playbackSpeed)
|
|
264
|
-
}
|
|
265
|
-
}
|
|
266
|
-
|
|
267
|
-
fun beginPlayback(@IntRange(from = 0) seekPosition: Long, startPaused: Boolean) {
|
|
268
|
-
currentItem ?: return
|
|
269
|
-
super.play(seekPosition, startPaused)
|
|
270
|
-
try {
|
|
271
|
-
setVolume(volumeLeft, volumeRight)
|
|
272
|
-
setPlaybackSpeed(playbackSpeed)
|
|
273
|
-
} catch (e: Exception) {
|
|
274
|
-
Log.w(TAG, "beginPlayback: Error setting volume or playback speed: " + e.message)
|
|
275
|
-
}
|
|
276
|
-
}
|
|
277
|
-
|
|
278
|
-
companion object {
|
|
279
|
-
private const val TAG = "PlaylistManager"
|
|
280
|
-
}
|
|
281
|
-
|
|
282
|
-
init {
|
|
283
|
-
setParameters(audioTracks, 0)
|
|
284
|
-
options = Options(application.baseContext)
|
|
285
|
-
}
|
|
286
|
-
}
|
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
package org.dwbn.plugins.playlist.notification
|
|
2
|
-
|
|
3
|
-
import android.annotation.SuppressLint
|
|
4
|
-
import android.app.PendingIntent
|
|
5
|
-
import android.app.PendingIntent.FLAG_UPDATE_CURRENT
|
|
6
|
-
import android.app.PendingIntent.FLAG_IMMUTABLE
|
|
7
|
-
import android.content.Context
|
|
8
|
-
import android.content.Intent
|
|
9
|
-
import com.devbrackets.android.playlistcore.components.notification.DefaultPlaylistNotificationProvider
|
|
10
|
-
|
|
11
|
-
class PlaylistNotificationProvider(context: Context?) : DefaultPlaylistNotificationProvider(context!!) {
|
|
12
|
-
override val clickPendingIntent: PendingIntent?
|
|
13
|
-
@SuppressLint("UnspecifiedImmutableFlag")
|
|
14
|
-
get() {
|
|
15
|
-
val context = context
|
|
16
|
-
val pkgName = context.packageName
|
|
17
|
-
val intent = context
|
|
18
|
-
.packageManager
|
|
19
|
-
.getLaunchIntentForPackage(pkgName)
|
|
20
|
-
intent!!.addFlags(
|
|
21
|
-
Intent.FLAG_ACTIVITY_REORDER_TO_FRONT or Intent.FLAG_ACTIVITY_SINGLE_TOP)
|
|
22
|
-
return PendingIntent.getActivity(this.context,
|
|
23
|
-
0, intent, FLAG_UPDATE_CURRENT or FLAG_IMMUTABLE
|
|
24
|
-
)
|
|
25
|
-
}
|
|
26
|
-
}
|
|
@@ -1,101 +0,0 @@
|
|
|
1
|
-
package org.dwbn.plugins.playlist.playlist
|
|
2
|
-
|
|
3
|
-
import android.content.Context
|
|
4
|
-
import android.media.AudioManager
|
|
5
|
-
import android.net.Uri
|
|
6
|
-
import android.os.PowerManager
|
|
7
|
-
import androidx.annotation.FloatRange
|
|
8
|
-
import androidx.annotation.IntRange
|
|
9
|
-
import com.devbrackets.android.exomedia.AudioPlayer
|
|
10
|
-
import com.devbrackets.android.exomedia.listener.OnErrorListener
|
|
11
|
-
import com.devbrackets.android.playlistcore.manager.BasePlaylistManager
|
|
12
|
-
import com.google.android.exoplayer2.util.EventLogger
|
|
13
|
-
import org.dwbn.plugins.playlist.data.AudioTrack
|
|
14
|
-
import java.lang.ref.WeakReference
|
|
15
|
-
import java.util.concurrent.locks.ReentrantLock
|
|
16
|
-
|
|
17
|
-
class AudioApi(context: Context) : BaseMediaApi() {
|
|
18
|
-
private val audioPlayer: AudioPlayer = AudioPlayer(context.applicationContext)
|
|
19
|
-
|
|
20
|
-
private val errorListenersLock = ReentrantLock(true)
|
|
21
|
-
private val errorListeners = ArrayList<WeakReference<OnErrorListener>>()
|
|
22
|
-
|
|
23
|
-
override val isPlaying: Boolean
|
|
24
|
-
get() = audioPlayer.isPlaying
|
|
25
|
-
|
|
26
|
-
override val handlesOwnAudioFocus: Boolean
|
|
27
|
-
get() = false
|
|
28
|
-
|
|
29
|
-
override val currentPosition: Long
|
|
30
|
-
get() = if (prepared) audioPlayer.currentPosition else 0
|
|
31
|
-
|
|
32
|
-
override val duration: Long
|
|
33
|
-
get() = if (prepared) audioPlayer.duration else 0
|
|
34
|
-
|
|
35
|
-
override val bufferedPercent: Int
|
|
36
|
-
get() = bufferPercent
|
|
37
|
-
|
|
38
|
-
init {
|
|
39
|
-
audioPlayer.setOnErrorListener(this)
|
|
40
|
-
audioPlayer.setOnPreparedListener(this)
|
|
41
|
-
audioPlayer.setOnCompletionListener(this)
|
|
42
|
-
audioPlayer.setOnSeekCompletionListener(this)
|
|
43
|
-
audioPlayer.setOnBufferUpdateListener(this)
|
|
44
|
-
|
|
45
|
-
audioPlayer.setWakeMode(context, PowerManager.PARTIAL_WAKE_LOCK)
|
|
46
|
-
audioPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC)
|
|
47
|
-
audioPlayer.setAnalyticsListener(EventLogger(null))
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
override fun play() {
|
|
51
|
-
audioPlayer.start()
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
override fun pause() {
|
|
55
|
-
audioPlayer.pause()
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
override fun stop() {
|
|
59
|
-
audioPlayer.stopPlayback()
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
override fun reset() {
|
|
63
|
-
audioPlayer.reset()
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
override fun release() {
|
|
67
|
-
audioPlayer.release()
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
override fun setVolume(@FloatRange(from = 0.0, to = 1.0) left: Float, @FloatRange(from = 0.0, to = 1.0) right: Float) {
|
|
71
|
-
audioPlayer.setVolume(left, right)
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
override fun seekTo(@IntRange(from = 0L) milliseconds: Long) {
|
|
75
|
-
audioPlayer.seekTo(milliseconds.toInt().toLong())
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
override fun handlesItem(item: AudioTrack): Boolean {
|
|
79
|
-
return item.mediaType == BasePlaylistManager.AUDIO
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
fun setPlaybackSpeed(@FloatRange(from = 0.0, to = 1.0) speed: Float) {
|
|
83
|
-
audioPlayer.playbackSpeed = speed
|
|
84
|
-
}
|
|
85
|
-
override fun playItem(item: AudioTrack) {
|
|
86
|
-
try {
|
|
87
|
-
prepared = false
|
|
88
|
-
bufferPercent = 0
|
|
89
|
-
audioPlayer.setDataSource(Uri.parse(if (item.downloaded) item.downloadedMediaUri else item.mediaUrl))
|
|
90
|
-
audioPlayer.prepareAsync()
|
|
91
|
-
} catch (e: Exception) {
|
|
92
|
-
//Purposefully left blank
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
fun addErrorListener(listener: OnErrorListener) {
|
|
97
|
-
errorListenersLock.lock()
|
|
98
|
-
errorListeners.add(WeakReference<OnErrorListener>(listener))
|
|
99
|
-
errorListenersLock.unlock()
|
|
100
|
-
}
|
|
101
|
-
}
|
|
Binary file
|
package/android/bin/src/main/java/org/dwbn/plugins/playlist/playlist/AudioPlaylistHandler.class
DELETED
|
Binary file
|
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
package org.dwbn.plugins.playlist.playlist
|
|
2
|
-
|
|
3
|
-
import com.devbrackets.android.exomedia.listener.*
|
|
4
|
-
import com.devbrackets.android.playlistcore.api.MediaPlayerApi
|
|
5
|
-
import com.devbrackets.android.playlistcore.listener.MediaStatusListener
|
|
6
|
-
import org.dwbn.plugins.playlist.data.AudioTrack
|
|
7
|
-
|
|
8
|
-
abstract class BaseMediaApi : MediaPlayerApi<AudioTrack>, OnPreparedListener, OnCompletionListener,
|
|
9
|
-
OnErrorListener, OnSeekCompletionListener, OnBufferUpdateListener {
|
|
10
|
-
protected var prepared: Boolean = false
|
|
11
|
-
protected var bufferPercent: Int = 0
|
|
12
|
-
|
|
13
|
-
protected var statusListener: MediaStatusListener<AudioTrack>? = null
|
|
14
|
-
|
|
15
|
-
override fun setMediaStatusListener(listener: MediaStatusListener<AudioTrack>) {
|
|
16
|
-
statusListener = listener
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
override fun onCompletion() {
|
|
20
|
-
statusListener?.onCompletion(this)
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
override fun onError(e: Exception): Boolean {
|
|
24
|
-
return statusListener?.onError(this) == true
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
override fun onPrepared() {
|
|
28
|
-
prepared = true
|
|
29
|
-
statusListener?.onPrepared(this)
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
override fun onSeekComplete() {
|
|
33
|
-
statusListener?.onSeekComplete(this)
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
override fun onBufferingUpdate(percent: Int) {
|
|
37
|
-
bufferPercent = percent
|
|
38
|
-
statusListener?.onBufferingUpdate(this, percent)
|
|
39
|
-
}
|
|
40
|
-
}
|
|
@@ -1,79 +0,0 @@
|
|
|
1
|
-
package org.dwbn.plugins.playlist.service
|
|
2
|
-
|
|
3
|
-
import android.content.Context
|
|
4
|
-
import android.graphics.Bitmap
|
|
5
|
-
import android.graphics.BitmapFactory
|
|
6
|
-
import com.bumptech.glide.Glide
|
|
7
|
-
import com.bumptech.glide.RequestManager
|
|
8
|
-
import com.bumptech.glide.request.target.SimpleTarget
|
|
9
|
-
import com.bumptech.glide.request.transition.Transition
|
|
10
|
-
import com.devbrackets.android.playlistcore.components.image.ImageProvider
|
|
11
|
-
import org.dwbn.plugins.playlist.FakeR
|
|
12
|
-
import org.dwbn.plugins.playlist.data.AudioTrack
|
|
13
|
-
import org.dwbn.plugins.playlist.manager.Options
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
class MediaImageProvider(
|
|
17
|
-
context: Context,
|
|
18
|
-
val onImageUpdatedListener: OnImageUpdatedListener,
|
|
19
|
-
options: Options
|
|
20
|
-
) : ImageProvider<AudioTrack> {
|
|
21
|
-
|
|
22
|
-
interface OnImageUpdatedListener {
|
|
23
|
-
fun onImageUpdated()
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
private var options: Options? = null
|
|
27
|
-
private val glide: RequestManager = Glide.with(context.applicationContext)
|
|
28
|
-
private val fakeR: FakeR = FakeR(context.applicationContext)
|
|
29
|
-
private val remoteViewImageTarget = RemoteViewImageTarget()
|
|
30
|
-
private var defaultArtworkImage: Bitmap? = null
|
|
31
|
-
private var artworkImage: Bitmap? = null
|
|
32
|
-
private var notificationIconId = 0
|
|
33
|
-
override val notificationIconRes: Int
|
|
34
|
-
get() = mipmapIcon
|
|
35
|
-
|
|
36
|
-
override val remoteViewIconRes: Int
|
|
37
|
-
get() = mipmapIcon
|
|
38
|
-
|
|
39
|
-
override val largeNotificationImage: Bitmap?
|
|
40
|
-
get() = remoteViewArtwork
|
|
41
|
-
|
|
42
|
-
override var remoteViewArtwork: Bitmap? = null
|
|
43
|
-
get() = if (artworkImage != null) artworkImage else defaultArtworkImage
|
|
44
|
-
private set
|
|
45
|
-
|
|
46
|
-
override fun updateImages(playlistItem: AudioTrack) {
|
|
47
|
-
glide.asBitmap().load(playlistItem.artworkUrl).into(remoteViewImageTarget)
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
// return R.mipmap.icon; // this comes from cordova itself.
|
|
51
|
-
private val mipmapIcon: Int
|
|
52
|
-
get() {
|
|
53
|
-
// return R.mipmap.icon; // this comes from cordova itself.
|
|
54
|
-
if (notificationIconId <= 0) {
|
|
55
|
-
notificationIconId = fakeR.getId("drawable", options?.icon)
|
|
56
|
-
}
|
|
57
|
-
return notificationIconId
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
/**
|
|
61
|
-
* A class used to listen to the loading of the large lock screen images and perform
|
|
62
|
-
* the correct functionality to update the artwork once it is loaded.
|
|
63
|
-
*
|
|
64
|
-
* **NOTE:** This is a Glide Image loader class
|
|
65
|
-
*/
|
|
66
|
-
private inner class RemoteViewImageTarget : SimpleTarget<Bitmap>() {
|
|
67
|
-
override fun onResourceReady(resource: Bitmap, transition: Transition<in Bitmap>?) {
|
|
68
|
-
artworkImage = resource
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
init {
|
|
73
|
-
this.options = options
|
|
74
|
-
defaultArtworkImage = BitmapFactory.decodeResource(
|
|
75
|
-
context.resources,
|
|
76
|
-
fakeR.getId("drawable", options.icon)
|
|
77
|
-
)
|
|
78
|
-
}
|
|
79
|
-
}
|
|
@@ -1,53 +0,0 @@
|
|
|
1
|
-
package org.dwbn.plugins.playlist.service
|
|
2
|
-
|
|
3
|
-
import com.devbrackets.android.playlistcore.components.playlisthandler.PlaylistHandler
|
|
4
|
-
import com.devbrackets.android.playlistcore.service.BasePlaylistService
|
|
5
|
-
import org.dwbn.plugins.playlist.App
|
|
6
|
-
import org.dwbn.plugins.playlist.data.AudioTrack
|
|
7
|
-
import org.dwbn.plugins.playlist.manager.PlaylistManager
|
|
8
|
-
import org.dwbn.plugins.playlist.playlist.AudioApi
|
|
9
|
-
import org.dwbn.plugins.playlist.playlist.AudioPlaylistHandler
|
|
10
|
-
import org.dwbn.plugins.playlist.service.MediaImageProvider.OnImageUpdatedListener
|
|
11
|
-
|
|
12
|
-
/**
|
|
13
|
-
* A simple service that extends [BasePlaylistService] in order to provide
|
|
14
|
-
* the application specific information required.
|
|
15
|
-
*/
|
|
16
|
-
class MediaService : BasePlaylistService<AudioTrack, PlaylistManager>() {
|
|
17
|
-
override fun onCreate() {
|
|
18
|
-
super.onCreate()
|
|
19
|
-
// Adds the audio player implementation, otherwise there's nothing to play media with
|
|
20
|
-
val newAudio = AudioApi(applicationContext)
|
|
21
|
-
newAudio.addErrorListener(playlistManager)
|
|
22
|
-
playlistManager.mediaPlayers.add(newAudio)
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
override fun onDestroy() {
|
|
26
|
-
super.onDestroy()
|
|
27
|
-
|
|
28
|
-
// Releases and clears all the MediaPlayersMediaImageProvider
|
|
29
|
-
for (player in playlistManager.mediaPlayers) {
|
|
30
|
-
player.release()
|
|
31
|
-
}
|
|
32
|
-
playlistManager.mediaPlayers.clear()
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
override val playlistManager: PlaylistManager
|
|
36
|
-
get() = (applicationContext as App).playlistManager
|
|
37
|
-
|
|
38
|
-
override fun newPlaylistHandler(): PlaylistHandler<AudioTrack> {
|
|
39
|
-
val imageProvider = MediaImageProvider(applicationContext, object : OnImageUpdatedListener {
|
|
40
|
-
override fun onImageUpdated() {
|
|
41
|
-
playlistHandler.updateMediaControls()
|
|
42
|
-
}
|
|
43
|
-
}, playlistManager.options)
|
|
44
|
-
|
|
45
|
-
return AudioPlaylistHandler.Builder(
|
|
46
|
-
applicationContext,
|
|
47
|
-
javaClass,
|
|
48
|
-
playlistManager,
|
|
49
|
-
imageProvider,
|
|
50
|
-
null
|
|
51
|
-
).build()
|
|
52
|
-
}
|
|
53
|
-
}
|
|
File without changes
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
|
2
|
-
android:width="24dp"
|
|
3
|
-
android:height="24dp"
|
|
4
|
-
android:viewportWidth="24.0"
|
|
5
|
-
android:viewportHeight="24.0">
|
|
6
|
-
<path
|
|
7
|
-
android:fillColor="#FFFFFFFF"
|
|
8
|
-
android:pathData="M19,4L5,4c-1.11,0 -2,0.9 -2,2v12c0,1.1 0.89,2 2,2h14c1.1,0 2,-0.9 2,-2L21,6c0,-1.1 -0.9,-2 -2,-2zM11,11L9.5,11v-0.5h-2v3h2L9.5,13L11,13v1c0,0.55 -0.45,1 -1,1L7,15c-0.55,0 -1,-0.45 -1,-1v-4c0,-0.55 0.45,-1 1,-1h3c0.55,0 1,0.45 1,1v1zM18,11h-1.5v-0.5h-2v3h2L16.5,13L18,13v1c0,0.55 -0.45,1 -1,1h-3c-0.55,0 -1,-0.45 -1,-1v-4c0,-0.55 0.45,-1 1,-1h3c0.55,0 1,0.45 1,1v1z"/>
|
|
9
|
-
</vector>
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
<vector android:height="24dp" android:viewportHeight="50.8"
|
|
2
|
-
android:viewportWidth="50.8" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
|
|
3
|
-
<path android:fillAlpha="1" android:fillColor="#4db6ac"
|
|
4
|
-
android:pathData="m13.76,23.11l0,16.89l3.57,-2.06l0,-14.83z"
|
|
5
|
-
android:strokeAlpha="1" android:strokeColor="#00000000" android:strokeWidth="0.47587052"/>
|
|
6
|
-
<path android:fillAlpha="1" android:fillColor="#aed581"
|
|
7
|
-
android:pathData="m13.76,10.8l0,11.78l15.35,0l0,-3.05L13.98,10.8Z"
|
|
8
|
-
android:strokeAlpha="1" android:strokeColor="#00000000" android:strokeWidth="0.52379054"/>
|
|
9
|
-
<path android:fillAlpha="1" android:fillColor="#f29312"
|
|
10
|
-
android:pathData="m17.85,23.11l0,14.53l12.93,-7.46l-1.66,0l0,-7.07z"
|
|
11
|
-
android:strokeAlpha="1" android:strokeColor="#00000000" android:strokeWidth="0.40285373"/>
|
|
12
|
-
<path android:fillAlpha="1" android:fillColor="#ffee58"
|
|
13
|
-
android:pathData="m29.64,19.84l0,9.81l2.05,0L39.16,25.34Z"
|
|
14
|
-
android:strokeAlpha="1" android:strokeColor="#00000000" android:strokeWidth="0.35085261"/>
|
|
15
|
-
</vector>
|
|
@@ -1,48 +0,0 @@
|
|
|
1
|
-
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
|
2
|
-
android:width="108dp"
|
|
3
|
-
android:height="108dp"
|
|
4
|
-
android:viewportWidth="50.8"
|
|
5
|
-
android:viewportHeight="50.8">
|
|
6
|
-
<path
|
|
7
|
-
android:pathData="M-10.85,-0h72.57v50.8h-72.57z"
|
|
8
|
-
android:fillAlpha="1"
|
|
9
|
-
android:strokeColor="#00000000"
|
|
10
|
-
android:fillColor="#00796b"
|
|
11
|
-
android:strokeWidth="10.03837585"
|
|
12
|
-
android:strokeAlpha="1"/>
|
|
13
|
-
<path
|
|
14
|
-
android:pathData="M0,22.49l19.05,0l0,20.64l-19.05,0z"
|
|
15
|
-
android:fillAlpha="1"
|
|
16
|
-
android:strokeColor="#00000000"
|
|
17
|
-
android:fillColor="#64ffda"
|
|
18
|
-
android:strokeWidth="0.41645226"
|
|
19
|
-
android:strokeAlpha="1"/>
|
|
20
|
-
<path
|
|
21
|
-
android:pathData="M0,7.57l33.34,0l0,14.29l-33.34,0z"
|
|
22
|
-
android:fillAlpha="1"
|
|
23
|
-
android:strokeColor="#00000000"
|
|
24
|
-
android:fillColor="#aed581"
|
|
25
|
-
android:strokeWidth="0.45838892"
|
|
26
|
-
android:strokeAlpha="1"/>
|
|
27
|
-
<path
|
|
28
|
-
android:pathData="M33.97,7.57l16.83,0l0,9.53l-16.83,0z"
|
|
29
|
-
android:fillAlpha="1"
|
|
30
|
-
android:strokeColor="#00000000"
|
|
31
|
-
android:fillColor="#4db6ac"
|
|
32
|
-
android:strokeWidth="0.26590821"
|
|
33
|
-
android:strokeAlpha="1"/>
|
|
34
|
-
<path
|
|
35
|
-
android:pathData="m19.68,22.49l0,20.64l13.65,0 17.46,0L50.8,31.06L33.34,31.06L33.34,22.49Z"
|
|
36
|
-
android:fillAlpha="1"
|
|
37
|
-
android:strokeColor="#00000000"
|
|
38
|
-
android:fillColor="#f29312"
|
|
39
|
-
android:strokeWidth="0.77728117"
|
|
40
|
-
android:strokeAlpha="1"/>
|
|
41
|
-
<path
|
|
42
|
-
android:pathData="M33.97,17.73l16.83,0l0,12.7l-16.83,0z"
|
|
43
|
-
android:fillAlpha="1"
|
|
44
|
-
android:strokeColor="#00000000"
|
|
45
|
-
android:fillColor="#ffee58"
|
|
46
|
-
android:strokeWidth="0.30704439"
|
|
47
|
-
android:strokeAlpha="1"/>
|
|
48
|
-
</vector>
|