1
+ package com.musiclibrary.tracks
2
+
3
+ import android.content.ContentResolver
4
+ import android.provider.MediaStore
5
+ import com.musiclibrary.models.*
6
+
7
+ object GetTracksByArtistQuery {
8
+ fun getTracksByArtist (
9
+ contentResolver : ContentResolver ,
10
+ artistId : String ,
11
+ options : AssetsOptions ,
12
+ ): PaginatedResult <Track > {
13
+ val projection = arrayOf(
14
+ MediaStore .Audio .Media ._ID ,
15
+ MediaStore .Audio .Media .TITLE ,
16
+ MediaStore .Audio .Media .ARTIST ,
17
+ MediaStore .Audio .Media .ALBUM ,
18
+ MediaStore .Audio .Media .DURATION ,
19
+ MediaStore .Audio .Media .DATA ,
20
+ MediaStore .Audio .Media .DATE_ADDED ,
21
+ MediaStore .Audio .Media .SIZE ,
22
+ MediaStore .Audio .Media .TRACK ,
23
+ )
24
+
25
+ val selection = " ${MediaStore .Audio .Media .ARTIST_ID } = ? AND ${MediaStore .Audio .Media .IS_MUSIC } = 1 AND ${MediaStore .Audio .Media .DURATION } > 0"
26
+ val selectionArgs = arrayOf(artistId)
27
+ val sortOrder = " ${MediaStore .Audio .Media .ALBUM } ASC, ${MediaStore .Audio .Media .TRACK } ASC, ${MediaStore .Audio .Media .TITLE } ASC"
28
+
29
+ val cursor = contentResolver.query(
30
+ MediaStore .Audio .Media .EXTERNAL_CONTENT_URI ,
31
+ projection,
32
+ selection,
33
+ selectionArgs,
34
+ sortOrder
35
+ ) ? : throw RuntimeException (" Failed to query MediaStore: cursor is null" )
36
+
37
+ val tracks = mutableListOf<Track >()
38
+ var hasNextPage: Boolean
39
+ var endCursor: String? = null
40
+ val totalCount = cursor.count
41
+
42
+ cursor.use { c ->
43
+ val idColumn = c.getColumnIndexOrThrow(MediaStore .Audio .Media ._ID )
44
+ val titleColumn = c.getColumnIndexOrThrow(MediaStore .Audio .Media .TITLE )
45
+ val artistColumn = c.getColumnIndexOrThrow(MediaStore .Audio .Media .ARTIST )
46
+ val albumColumn = c.getColumnIndexOrThrow(MediaStore .Audio .Media .ALBUM )
47
+ val durationColumn = c.getColumnIndexOrThrow(MediaStore .Audio .Media .DURATION )
48
+ val dataColumn = c.getColumnIndexOrThrow(MediaStore .Audio .Media .DATA )
49
+ val dateAddedColumn = c.getColumnIndexOrThrow(MediaStore .Audio .Media .DATE_ADDED )
50
+ val sizeColumn = c.getColumnIndexOrThrow(MediaStore .Audio .Media .SIZE )
51
+
52
+ // Jump to the specified start position
53
+ val foundAfter = if (options.after == null ) {
54
+ cursor.moveToFirst() // Move to the first record
55
+ true
56
+ } else {
57
+ var found = false
58
+ if (cursor.moveToFirst()) {
59
+ do {
60
+ val id = cursor.getLong(idColumn).toString()
61
+ if (id == options.after) {
62
+ found = true
63
+ break
64
+ }
65
+ } while (cursor.moveToNext())
66
+ }
67
+ // Move to the next record after the specified after if found
68
+ found && cursor.moveToNext()
69
+ }
70
+
71
+ var count = 0
72
+ val maxItems = options.first.coerceAtMost(1000 ) // Limit the maximum number of queries
73
+
74
+ while (foundAfter && count < maxItems) {
75
+ try {
76
+ val id = c.getLong(idColumn)
77
+ val data = c.getString(dataColumn) ? : " "
78
+
79
+ // Skip invalid data
80
+ if (data.isEmpty()) {
81
+ continue
82
+ }
83
+
84
+ val title = c.getString(titleColumn) ? : " "
85
+ val artist = c.getString(artistColumn)
86
+ val album = c.getString(albumColumn)
87
+ val duration = c.getLong(durationColumn) / 1000.0 // Convert to seconds
88
+ val dateAdded = c.getLong(dateAddedColumn)
89
+ val fileSize = c.getLong(sizeColumn)
90
+ val artworkUri = " content://media/external/audio/media/${id} /albumart"
91
+
92
+ // Create a Track
93
+ val track = Track (
94
+ id = id.toString(),
95
+ title = title,
96
+ artist = artist,
97
+ artwork = artworkUri,
98
+ album = album,
99
+ duration = duration,
100
+ url = " file://$data " ,
101
+ createdAt = dateAdded * 1000 , // Convert to milliseconds
102
+ modifiedAt = dateAdded * 1000 , // Convert to milliseconds
103
+ fileSize = fileSize
104
+ )
105
+
106
+ tracks.add(track)
107
+ endCursor = id.toString()
108
+ count++
109
+ } catch (e: Exception ) {
110
+ continue
111
+ }
112
+
113
+ if (! cursor.moveToNext()) break
114
+ }
115
+
116
+ // Check if there are more data
117
+ hasNextPage = ! c.isAfterLast
118
+ }
119
+
120
+ return PaginatedResult (
121
+ items = tracks,
122
+ hasNextPage = hasNextPage,
123
+ endCursor = endCursor,
124
+ totalCount = totalCount
125
+ )
126
+ }
127
+ }
0 commit comments