Skip to content

Commit

Permalink
WIP to use content:// Uris for album art.
Browse files Browse the repository at this point in the history
This addresses #235

At the moment, the first time art is retrieved it doesn't appear.
Subsequent loads will show the images.

This is likely related to Glide not observing the Uri for changes. This
might work on other form factors (for example, Automotive OS) but it
also might be necessary to update the MediaItems themselves.

The change is probably going to wait until January 2021 to be resolved.
  • Loading branch information
nic0lette authored and dturner committed Feb 9, 2021
1 parent 8dda0e8 commit 1982032
Show file tree
Hide file tree
Showing 6 changed files with 58 additions and 13 deletions.
9 changes: 9 additions & 0 deletions .idea/codeStyles/Project.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion common/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@

<provider
android:name=".library.AlbumArtContentProvider"
android:authorities="com.example.android.uamp.media.library.provider"
android:authorities="com.example.android.uamp"
android:exported="true" />

</application>
Expand Down
Binary file added common/src/main/assets/default_art.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
Expand Up @@ -35,4 +35,4 @@ fun File.asAlbumArtContentUri(): Uri {
.build()
}

private const val AUTHORITY = "com.example.android.uamp.media.library.provider"
private const val AUTHORITY = "com.example.android.uamp"
Original file line number Diff line number Diff line change
Expand Up @@ -17,29 +17,64 @@
package com.example.android.uamp.media.library

import android.content.ContentProvider
import android.content.ContentResolver
import android.content.ContentValues
import android.database.Cursor
import android.net.Uri
import android.os.ParcelFileDescriptor
import android.util.Log
import com.bumptech.glide.Glide
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
import java.io.File
import java.io.FileNotFoundException

class AlbumArtContentProvider : ContentProvider() {

companion object {
private val uriMap = mutableMapOf<Uri, Uri>()

fun mapUri(uri: Uri): Uri {
val path = uri.encodedPath?.substring(1)?.replace('/', ':') ?: return Uri.EMPTY
val contentUri = Uri.Builder()
.scheme(ContentResolver.SCHEME_CONTENT)
.authority("com.example.android.uamp")
.path(path)
.build()
uriMap[contentUri] = uri
return contentUri
}
}

override fun onCreate() = true

override fun openFile(uri: Uri, mode: String): ParcelFileDescriptor? {
val context = this.context ?: return null
val file = File(uri.path)
if (!file.exists()) {
throw FileNotFoundException(uri.path)
}
// Only allow access to files under cache path
val cachePath = context.cacheDir.path
if (!file.path.startsWith(cachePath)) {
throw FileNotFoundException()
val remoteUri = uriMap[uri] ?: throw FileNotFoundException(uri.path)

val file = File(context.cacheDir, uri.path)
return if (!file.exists()) {
GlobalScope.launch(Dispatchers.IO) {
// Use Glide to download the album art
val cacheFile = Glide.with(context)
.asFile()
.load(remoteUri)
.submit()
.get()

// Rename the file Glide created to match our own scheme.
cacheFile.renameTo(file)

// Notify the caller that the artwork has been updated.
context.contentResolver.notifyChange(uri, null)
}

// Provide placeholder art until the correct art can be downloaded.
context.assets.openFd("default_art.png").parcelFileDescriptor
} else {
ParcelFileDescriptor.open(file, ParcelFileDescriptor.MODE_READ_ONLY)
}
return ParcelFileDescriptor.open(file, ParcelFileDescriptor.MODE_READ_ONLY)
}

override fun insert(uri: Uri, values: ContentValues?): Uri? = null
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -98,12 +98,13 @@ class JsonSource(private val source: Uri) : AbstractMusicSource() {
song.image = baseUri + song.image
}
}
val imageUri = AlbumArtContentProvider.mapUri(Uri.parse(song.image))

MediaMetadataCompat.Builder()
.from(song)
.apply {
displayIconUri = song.image // Used by ExoPlayer and Notification
albumArtUri = song.image
displayIconUri = imageUri.toString() // Used by ExoPlayer and Notification
albumArtUri = imageUri.toString()
}
.build()
}.toList()
Expand Down

0 comments on commit 1982032

Please sign in to comment.