Skip to content

Commit 841de57

Browse files
author
Lucas Pinheiro
committed
Fixed queryArtwork and removed unnecessary code in queryWithFilters
1 parent adece09 commit 841de57

File tree

3 files changed

+88
-164
lines changed

3 files changed

+88
-164
lines changed

android/src/main/kotlin/com/lucasjosino/on_audio_query/query/OnArtworksQuery.kt

+3-3
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ import kotlin.properties.Delegates
2323
class OnArtworksQuery : ViewModel() {
2424

2525
//Main parameters
26-
private var id: Int = 0
26+
private var id: Long = 0
2727
private var size by Delegates.notNull<Int>()
2828
private lateinit var uri: Uri
2929
private lateinit var resolver: ContentResolver
@@ -34,7 +34,7 @@ class OnArtworksQuery : ViewModel() {
3434
resolver = context.contentResolver
3535

3636
//Id, size, and uri
37-
id = call.argument<Int>("id")!! ; size = call.argument<Int>("size")!!
37+
id = call.argument<Long>("id")!! ; size = call.argument<Int>("size")!!
3838
format = checkArtworkFormat(call.argument<Int>("format")!!)
3939
uri = checkArtworkType(call.argument<Int>("type")!!)
4040

@@ -53,7 +53,7 @@ class OnArtworksQuery : ViewModel() {
5353
private suspend fun loadArt() : ByteArray = withContext(Dispatchers.IO) {
5454
var artData = ByteArray(0)
5555
if (Build.VERSION.SDK_INT >= 29) {
56-
val query = ContentUris.withAppendedId(uri, id.toLong())
56+
val query = ContentUris.withAppendedId(uri, id)
5757
try {
5858
val bitmap = resolver.loadThumbnail(query, Size(size, size), null)
5959
artData = convertToByteArray(bitmap)!!

android/src/main/kotlin/com/lucasjosino/on_audio_query/query/OnWithFiltersQuery.kt

+25-161
Original file line numberDiff line numberDiff line change
@@ -18,72 +18,14 @@ import kotlinx.coroutines.withContext
1818
class OnWithFiltersQuery : ViewModel() {
1919

2020
//Main parameters
21-
private val channelError = "on_audio_error"
21+
private var projection: Array<String>? = arrayOf()
2222
private lateinit var resolver: ContentResolver
2323
@SuppressLint("StaticFieldLeak")
2424
private lateinit var context: Context
2525
private lateinit var resultWithFiltersList: ArrayList<MutableMap<String, Any>>
2626
private lateinit var withType: Uri
2727
private lateinit var args: String
28-
private lateinit var argsKey:String
29-
30-
//Uri projection
31-
private val withTypeProjection = arrayOf(
32-
MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,
33-
MediaStore.Audio.Albums.EXTERNAL_CONTENT_URI,
34-
MediaStore.Audio.Playlists.EXTERNAL_CONTENT_URI,
35-
MediaStore.Audio.Artists.EXTERNAL_CONTENT_URI,
36-
MediaStore.Audio.Genres.EXTERNAL_CONTENT_URI
37-
)
38-
39-
//Query songs projection
40-
@SuppressLint("InlinedApi")
41-
private val songProjection = arrayOf(
42-
MediaStore.Audio.Media.DATA, //
43-
MediaStore.Audio.Media.DISPLAY_NAME,
44-
MediaStore.Audio.Media._ID,
45-
MediaStore.Audio.Media.SIZE,
46-
MediaStore.Audio.Media.ALBUM,
47-
MediaStore.Audio.Media.ALBUM_ARTIST,
48-
MediaStore.Audio.Media.ALBUM_ID,
49-
MediaStore.Audio.Media.ARTIST,
50-
MediaStore.Audio.Media.ARTIST_ID,
51-
MediaStore.Audio.Media.BOOKMARK,
52-
MediaStore.Audio.Media.COMPOSER,
53-
MediaStore.Audio.Media.DATE_ADDED,
54-
MediaStore.Audio.Media.DURATION,
55-
MediaStore.Audio.Media.TITLE,
56-
MediaStore.Audio.Media.TRACK,
57-
MediaStore.Audio.Media.YEAR,
58-
MediaStore.Audio.Media.IS_ALARM,
59-
MediaStore.Audio.Media.IS_MUSIC, // 17
60-
MediaStore.Audio.Media.IS_NOTIFICATION,
61-
MediaStore.Audio.Media.IS_PODCAST,
62-
MediaStore.Audio.Media.IS_RINGTONE
63-
)
64-
65-
//Query playlists projection
66-
private val playlistProjection = arrayOf(
67-
MediaStore.Audio.Playlists.DATA,
68-
MediaStore.Audio.Playlists._ID,
69-
MediaStore.Audio.Playlists.DATE_ADDED,
70-
MediaStore.Audio.Playlists.DATE_MODIFIED,
71-
MediaStore.Audio.Playlists.NAME
72-
)
73-
74-
//Query artists projection
75-
private val artistProjection = arrayOf(
76-
MediaStore.Audio.Artists._ID,
77-
MediaStore.Audio.Artists.ARTIST,
78-
MediaStore.Audio.Artists.NUMBER_OF_ALBUMS,
79-
MediaStore.Audio.Artists.NUMBER_OF_TRACKS
80-
)
81-
82-
//Query genres projection
83-
private val genreProjection = arrayOf(
84-
MediaStore.Audio.Genres._ID,
85-
MediaStore.Audio.Genres.NAME
86-
)
28+
private lateinit var argsKey: String
8729

8830
//
8931
fun queryWithFilters(context: Context, result: MethodChannel.Result, call: MethodCall) {
@@ -92,97 +34,30 @@ class OnWithFiltersQuery : ViewModel() {
9234
//Setup Type and Args
9335
withType = checkWithFiltersType(call.argument<Int>("withType")!!)
9436
args = call.argument<String>("argsVal")!! + "%"
37+
projection = checkProjection(withType)
38+
39+
//Setup Args
40+
argsKey = when (withType) {
41+
MediaStore.Audio.Media.EXTERNAL_CONTENT_URI -> checkSongsArgs(call.argument<Int>("args")!!)
42+
MediaStore.Audio.Albums.EXTERNAL_CONTENT_URI -> checkAlbumsArgs(call.argument<Int>("args")!!)
43+
MediaStore.Audio.Playlists.EXTERNAL_CONTENT_URI -> checkPlaylistsArgs(call.argument<Int>("args")!!)
44+
MediaStore.Audio.Artists.EXTERNAL_CONTENT_URI -> checkArtistsArgs(call.argument<Int>("args")!!)
45+
MediaStore.Audio.Genres.EXTERNAL_CONTENT_URI -> checkGenresArgs(call.argument<Int>("args")!!)
46+
else -> throw Exception("[argsKey] returned null. Report this issue on [on_audio_query] GitHub.")
47+
}
9548

96-
//
97-
when (withType) {
98-
//
99-
withTypeProjection[0] ->
100-
viewModelScope.launch { argsKey = checkSongsArgs(call.argument<Int>("args")!!)
101-
resultWithFiltersList = loadSongsWithFilters() ; result.success(resultWithFiltersList) }
102-
103-
//
104-
withTypeProjection[1] ->
105-
viewModelScope.launch { argsKey = checkAlbumsArgs(call.argument<Int>("args")!!)
106-
resultWithFiltersList = loadAlbumsWithFilters() ; result.success(resultWithFiltersList) }
107-
108-
//
109-
withTypeProjection[2] ->
110-
viewModelScope.launch { argsKey = checkPlaylistsArgs(call.argument<Int>("args")!!)
111-
resultWithFiltersList = loadPlaylistsWithFilters() ; result.success(resultWithFiltersList) }
49+
//Query everything in the Background it's necessary for better performance
50+
viewModelScope.launch {
51+
//Start querying
52+
resultWithFiltersList = loadSongsWithFilters()
11253

11354
//
114-
withTypeProjection[3] ->
115-
viewModelScope.launch { argsKey = checkArtistsArgs(call.argument<Int>("args")!!)
116-
resultWithFiltersList = loadArtistsWithFilters() ; result.success(resultWithFiltersList) }
117-
118-
//
119-
withTypeProjection[4] ->
120-
viewModelScope.launch { argsKey = checkGenresArgs(call.argument<Int>("args")!!)
121-
resultWithFiltersList = loadGenresWithFilters() ; result.success(resultWithFiltersList) }
122-
123-
//
124-
else -> result.error(channelError, "Filter type in [queryWithFilters] not found", null)
125-
}
55+
result.success(resultWithFiltersList) }
12656
}
12757

12858
//Loading in Background
12959
private suspend fun loadSongsWithFilters() : ArrayList<MutableMap<String, Any>> = withContext(Dispatchers.IO) {
130-
val cursor = resolver.query(withType, songProjection, argsKey, arrayOf(args), null)
131-
val withFiltersList: ArrayList<MutableMap<String, Any>> = ArrayList()
132-
while (cursor != null && cursor.moveToNext()) {
133-
val withFiltersData: MutableMap<String, Any> = HashMap()
134-
for (audioMedia in cursor.columnNames) {
135-
if (cursor.getString(cursor.getColumnIndex(audioMedia)) != null) {
136-
withFiltersData[audioMedia] = cursor.getString(cursor.getColumnIndex(audioMedia))
137-
} else withFiltersData[audioMedia] = ""
138-
}
139-
140-
//Artwork
141-
val art = loadArtwork(context, withFiltersData["album"].toString())
142-
if (art.isNotEmpty()) withFiltersData["artwork"] = art
143-
withFiltersList.add(withFiltersData)
144-
}
145-
cursor?.close()
146-
return@withContext withFiltersList
147-
}
148-
149-
//Loading in Background
150-
private suspend fun loadAlbumsWithFilters() : ArrayList<MutableMap<String, Any>> = withContext(Dispatchers.IO) {
151-
val cursor = resolver.query(withType, null, argsKey, arrayOf(args), null)
152-
val withFiltersList: ArrayList<MutableMap<String, Any>> = ArrayList()
153-
while (cursor != null && cursor.moveToNext()) {
154-
val withFiltersData: MutableMap<String, Any> = HashMap()
155-
for (audioMedia in cursor.columnNames) {
156-
if (cursor.getString(cursor.getColumnIndex(audioMedia)) != null) {
157-
withFiltersData[audioMedia] = cursor.getString(cursor.getColumnIndex(audioMedia))
158-
} else withFiltersData[audioMedia] = ""
159-
}
160-
withFiltersList.add(withFiltersData)
161-
}
162-
cursor?.close()
163-
return@withContext withFiltersList
164-
}
165-
166-
//Loading in Background
167-
private suspend fun loadArtistsWithFilters() : ArrayList<MutableMap<String, Any>> = withContext(Dispatchers.IO) {
168-
val cursor = resolver.query(withType, artistProjection, argsKey, arrayOf(args), null)
169-
val withFiltersList: ArrayList<MutableMap<String, Any>> = ArrayList()
170-
while (cursor != null && cursor.moveToNext()) {
171-
val withFiltersData: MutableMap<String, Any> = HashMap()
172-
for (audioMedia in cursor.columnNames) {
173-
if (cursor.getString(cursor.getColumnIndex(audioMedia)) != null) {
174-
withFiltersData[audioMedia] = cursor.getString(cursor.getColumnIndex(audioMedia))
175-
} else withFiltersData[audioMedia] = ""
176-
}
177-
withFiltersList.add(withFiltersData)
178-
}
179-
cursor?.close()
180-
return@withContext withFiltersList
181-
}
182-
183-
//Loading in Background
184-
private suspend fun loadPlaylistsWithFilters() : ArrayList<MutableMap<String, Any>> = withContext(Dispatchers.IO) {
185-
val cursor = resolver.query(withType, playlistProjection, argsKey, arrayOf(args), null)
60+
val cursor = resolver.query(withType, projection, argsKey, arrayOf(args), null)
18661
val withFiltersList: ArrayList<MutableMap<String, Any>> = ArrayList()
18762
while (cursor != null && cursor.moveToNext()) {
18863
val withFiltersData: MutableMap<String, Any> = HashMap()
@@ -191,24 +66,13 @@ class OnWithFiltersQuery : ViewModel() {
19166
withFiltersData[audioMedia] = cursor.getString(cursor.getColumnIndex(audioMedia))
19267
} else withFiltersData[audioMedia] = ""
19368
}
194-
withFiltersList.add(withFiltersData)
195-
}
196-
cursor?.close()
197-
return@withContext withFiltersList
198-
}
19969

200-
//Loading in Background
201-
private suspend fun loadGenresWithFilters() : ArrayList<MutableMap<String, Any>> = withContext(Dispatchers.IO) {
202-
val cursor = resolver.query(withType, genreProjection, argsKey, arrayOf(args), null)
203-
val withFiltersList: ArrayList<MutableMap<String, Any>> = ArrayList()
204-
while (cursor != null && cursor.moveToNext()) {
205-
val withFiltersData: MutableMap<String, Any> = HashMap()
206-
for (audioMedia in cursor.columnNames) {
207-
if (cursor.getString(cursor.getColumnIndex(audioMedia)) != null) {
208-
withFiltersData[audioMedia] = cursor.getString(cursor.getColumnIndex(audioMedia))
209-
} else withFiltersData[audioMedia] = ""
210-
}
211-
withFiltersList.add(withFiltersData)
70+
if (withType == MediaStore.Audio.Media.EXTERNAL_CONTENT_URI) {
71+
//Artwork
72+
val art = loadArtwork(context, withFiltersData["album"].toString())
73+
if (art.isNotEmpty()) withFiltersData["artwork"] = art
74+
withFiltersList.add(withFiltersData)
75+
} else withFiltersList.add(withFiltersData)
21276
}
21377
cursor?.close()
21478
return@withContext withFiltersList

android/src/main/kotlin/com/lucasjosino/on_audio_query/types/WithFiltersType.kt

+60
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,17 @@ fun checkWithFiltersType(sortType: Int): Uri {
1515
}
1616
}
1717

18+
fun checkProjection(withType: Uri) : Array<String>? {
19+
return when (withType) {
20+
MediaStore.Audio.Media.EXTERNAL_CONTENT_URI -> songProjection
21+
MediaStore.Audio.Albums.EXTERNAL_CONTENT_URI -> null
22+
MediaStore.Audio.Playlists.EXTERNAL_CONTENT_URI -> playlistProjection
23+
MediaStore.Audio.Artists.EXTERNAL_CONTENT_URI -> artistProjection
24+
MediaStore.Audio.Genres.EXTERNAL_CONTENT_URI -> genreProjection
25+
else -> songProjection
26+
}
27+
}
28+
1829
@SuppressLint("InlinedApi")
1930
fun checkSongsArgs(args: Int): String {
2031
return when (args) {
@@ -54,3 +65,52 @@ fun checkGenresArgs(args: Int): String {
5465
else -> MediaStore.Audio.Genres.NAME + " like ?"
5566
}
5667
}
68+
69+
//Query songs projection
70+
@SuppressLint("InlinedApi")
71+
private val songProjection = arrayOf(
72+
MediaStore.Audio.Media.DATA, //
73+
MediaStore.Audio.Media.DISPLAY_NAME,
74+
MediaStore.Audio.Media._ID,
75+
MediaStore.Audio.Media.SIZE,
76+
MediaStore.Audio.Media.ALBUM,
77+
MediaStore.Audio.Media.ALBUM_ARTIST,
78+
MediaStore.Audio.Media.ALBUM_ID,
79+
MediaStore.Audio.Media.ARTIST,
80+
MediaStore.Audio.Media.ARTIST_ID,
81+
MediaStore.Audio.Media.BOOKMARK,
82+
MediaStore.Audio.Media.COMPOSER,
83+
MediaStore.Audio.Media.DATE_ADDED,
84+
MediaStore.Audio.Media.DURATION,
85+
MediaStore.Audio.Media.TITLE,
86+
MediaStore.Audio.Media.TRACK,
87+
MediaStore.Audio.Media.YEAR,
88+
MediaStore.Audio.Media.IS_ALARM,
89+
MediaStore.Audio.Media.IS_MUSIC, // 17
90+
MediaStore.Audio.Media.IS_NOTIFICATION,
91+
MediaStore.Audio.Media.IS_PODCAST,
92+
MediaStore.Audio.Media.IS_RINGTONE
93+
)
94+
95+
//Query playlists projection
96+
private val playlistProjection = arrayOf(
97+
MediaStore.Audio.Playlists.DATA,
98+
MediaStore.Audio.Playlists._ID,
99+
MediaStore.Audio.Playlists.DATE_ADDED,
100+
MediaStore.Audio.Playlists.DATE_MODIFIED,
101+
MediaStore.Audio.Playlists.NAME
102+
)
103+
104+
//Query artists projection
105+
private val artistProjection = arrayOf(
106+
MediaStore.Audio.Artists._ID,
107+
MediaStore.Audio.Artists.ARTIST,
108+
MediaStore.Audio.Artists.NUMBER_OF_ALBUMS,
109+
MediaStore.Audio.Artists.NUMBER_OF_TRACKS
110+
)
111+
112+
//Query genres projection
113+
private val genreProjection = arrayOf(
114+
MediaStore.Audio.Genres._ID,
115+
MediaStore.Audio.Genres.NAME
116+
)

0 commit comments

Comments
 (0)