Skip to content

Commit

Permalink
Fix:Android internal file paths using file provider
Browse files Browse the repository at this point in the history
  • Loading branch information
advplyr committed Jun 19, 2023
1 parent 0d1312e commit 13d32dc
Show file tree
Hide file tree
Showing 9 changed files with 58 additions and 36 deletions.
10 changes: 10 additions & 0 deletions android/app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,16 @@
<action android:name="android.media.browse.MediaBrowserService" />
</intent-filter>
</service>

<provider
android:name="androidx.core.content.FileProvider"
android:authorities="com.audiobookshelf.app.fileprovider"
android:grantUriPermissions="true"
android:exported="false">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/file_paths" />
</provider>
</application>

</manifest>
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ internal fun updateAppWidget(context: Context, appWidgetManager: AppWidgetManage

views.setOnClickPendingIntent(R.id.widgetBackground, wholeWidgetClickPI)

val imageUri = playbackSession?.getCoverUri() ?: Uri.parse("android.resource://${BuildConfig.APPLICATION_ID}/" + R.drawable.icon)
val imageUri = playbackSession?.getCoverUri(context) ?: Uri.parse("android.resource://${BuildConfig.APPLICATION_ID}/" + R.drawable.icon)
val awt: AppWidgetTarget = object : AppWidgetTarget(context.applicationContext, R.id.widgetAlbumArt, views, appWidgetId) {
override fun onResourceReady(resource: Bitmap, transition: Transition<in Bitmap>?) {
super.onResourceReady(resource, transition)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -258,9 +258,9 @@ data class PodcastEpisode(
var localEpisodeId:String? // For Android Auto server episodes with local copy
) {
@JsonIgnore
fun getMediaDescription(libraryItem:LibraryItemWrapper, progress:MediaProgressWrapper?, ctx: Context?): MediaDescriptionCompat {
fun getMediaDescription(libraryItem:LibraryItemWrapper, progress:MediaProgressWrapper?, ctx: Context): MediaDescriptionCompat {
val coverUri = if (libraryItem is LocalLibraryItem) {
libraryItem.getCoverUri()
libraryItem.getCoverUri(ctx)
} else {
(libraryItem as LibraryItem).getCoverUri()
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ data class LocalFolder(
)
open class LibraryItemWrapper(var id:String) {
@JsonIgnore
open fun getMediaDescription(progress:MediaProgressWrapper?, ctx: Context?): MediaDescriptionCompat { return MediaDescriptionCompat.Builder().build() }
open fun getMediaDescription(progress:MediaProgressWrapper?, ctx: Context): MediaDescriptionCompat { return MediaDescriptionCompat.Builder().build() }
}

@JsonIgnoreProperties(ignoreUnknown = true)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ class LibraryItem(
}

@JsonIgnore
override fun getMediaDescription(progress:MediaProgressWrapper?, ctx: Context?): MediaDescriptionCompat {
override fun getMediaDescription(progress:MediaProgressWrapper?, ctx: Context): MediaDescriptionCompat {
val extras = Bundle()

if (localLibraryItemId != null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ import android.os.Bundle
import android.provider.MediaStore
import android.support.v4.media.MediaDescriptionCompat
import android.util.Log
import androidx.core.content.FileProvider
import androidx.core.net.toFile
import androidx.media.utils.MediaConstants
import com.audiobookshelf.app.BuildConfig
import com.audiobookshelf.app.R
Expand Down Expand Up @@ -46,7 +48,10 @@ class LocalLibraryItem(
val isPodcast get() = mediaType == "podcast"

@JsonIgnore
fun getCoverUri(): Uri {
fun getCoverUri(ctx:Context): Uri {
if (coverContentUrl?.startsWith("file:") == true) {
return FileProvider.getUriForFile(ctx, "com.audiobookshelf.app.fileprovider", Uri.parse(coverContentUrl).toFile())
}
return if (coverContentUrl != null) Uri.parse(coverContentUrl) else Uri.parse("android.resource://${BuildConfig.APPLICATION_ID}/" + R.drawable.icon)
}

Expand Down Expand Up @@ -107,18 +112,16 @@ class LocalLibraryItem(
}

@JsonIgnore
override fun getMediaDescription(progress:MediaProgressWrapper?, ctx:Context?): MediaDescriptionCompat {
val coverUri = getCoverUri()
override fun getMediaDescription(progress:MediaProgressWrapper?, ctx:Context): MediaDescriptionCompat {
val coverUri = getCoverUri(ctx)

var bitmap:Bitmap? = null
if (coverContentUrl != null) {
ctx?.let {
bitmap = if (Build.VERSION.SDK_INT < 28) {
MediaStore.Images.Media.getBitmap(it.contentResolver, coverUri)
} else {
val source: ImageDecoder.Source = ImageDecoder.createSource(it.contentResolver, coverUri)
ImageDecoder.decodeBitmap(source)
}
bitmap = if (Build.VERSION.SDK_INT < 28) {
MediaStore.Images.Media.getBitmap(ctx.contentResolver, coverUri)
} else {
val source: ImageDecoder.Source = ImageDecoder.createSource(ctx.contentResolver, coverUri)
ImageDecoder.decodeBitmap(source)
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ import android.net.Uri
import android.os.Build
import android.provider.MediaStore
import android.support.v4.media.MediaMetadataCompat
import androidx.core.content.FileProvider
import androidx.core.net.toFile
import com.audiobookshelf.app.BuildConfig
import com.audiobookshelf.app.R
import com.audiobookshelf.app.device.DeviceManager
Expand Down Expand Up @@ -138,8 +140,15 @@ class PlaybackSession(
}

@JsonIgnore
fun getCoverUri(): Uri {
if (localLibraryItem?.coverContentUrl != null) return Uri.parse(localLibraryItem?.coverContentUrl) ?: Uri.parse("android.resource://${BuildConfig.APPLICATION_ID}/" + R.drawable.icon)
fun getCoverUri(ctx:Context): Uri {
if (localLibraryItem?.coverContentUrl != null) {
var coverUri = Uri.parse(localLibraryItem?.coverContentUrl.toString())
if (coverUri.toString().startsWith("file:")) {
coverUri = FileProvider.getUriForFile(ctx, "com.audiobookshelf.app.fileprovider", coverUri.toFile())
}

return coverUri ?: Uri.parse("android.resource://${BuildConfig.APPLICATION_ID}/" + R.drawable.icon)
}

if (coverPath == null) return Uri.parse("android.resource://${BuildConfig.APPLICATION_ID}/" + R.drawable.icon)
return Uri.parse("$serverAddress/api/items/$libraryItemId/cover?token=${DeviceManager.token}")
Expand All @@ -153,6 +162,8 @@ class PlaybackSession(

@JsonIgnore
fun getMediaMetadataCompat(ctx: Context): MediaMetadataCompat {
val coverUri = getCoverUri(ctx)

val metadataBuilder = MediaMetadataCompat.Builder()
.putString(MediaMetadataCompat.METADATA_KEY_TITLE, displayTitle)
.putString(MediaMetadataCompat.METADATA_KEY_DISPLAY_TITLE, displayTitle)
Expand All @@ -163,16 +174,16 @@ class PlaybackSession(
.putString(MediaMetadataCompat.METADATA_KEY_ALBUM_ARTIST, displayAuthor)
.putString(MediaMetadataCompat.METADATA_KEY_DISPLAY_DESCRIPTION, displayAuthor)
.putString(MediaMetadataCompat.METADATA_KEY_MEDIA_ID, id)
.putString(MediaMetadataCompat.METADATA_KEY_ALBUM_ART_URI, getCoverUri().toString())
.putString(MediaMetadataCompat.METADATA_KEY_ART_URI, getCoverUri().toString())
.putString(MediaMetadataCompat.METADATA_KEY_DISPLAY_ICON_URI, getCoverUri().toString())
.putString(MediaMetadataCompat.METADATA_KEY_ALBUM_ART_URI, coverUri.toString())
.putString(MediaMetadataCompat.METADATA_KEY_ART_URI, coverUri.toString())
.putString(MediaMetadataCompat.METADATA_KEY_DISPLAY_ICON_URI, coverUri.toString())

// Local covers get bitmap
if (localLibraryItem?.coverContentUrl != null) {
val bitmap = if (Build.VERSION.SDK_INT < 28) {
MediaStore.Images.Media.getBitmap(ctx.contentResolver, getCoverUri())
MediaStore.Images.Media.getBitmap(ctx.contentResolver, coverUri)
} else {
val source: ImageDecoder.Source = ImageDecoder.createSource(ctx.contentResolver, getCoverUri())
val source: ImageDecoder.Source = ImageDecoder.createSource(ctx.contentResolver, coverUri)
ImageDecoder.decodeBitmap(source)
}
metadataBuilder.putBitmap(MediaMetadataCompat.METADATA_KEY_ALBUM_ART, bitmap)
Expand All @@ -183,7 +194,9 @@ class PlaybackSession(
}

@JsonIgnore
fun getExoMediaMetadata(): MediaMetadata {
fun getExoMediaMetadata(ctx:Context): MediaMetadata {
val coverUri = getCoverUri(ctx)

val metadataBuilder = MediaMetadata.Builder()
.setTitle(displayTitle)
.setDisplayTitle(displayTitle)
Expand All @@ -192,18 +205,18 @@ class PlaybackSession(
.setSubtitle(displayAuthor)
.setAlbumTitle(displayAuthor)
.setDescription(displayAuthor)
.setArtworkUri(getCoverUri())
.setArtworkUri(coverUri)
.setMediaType(MediaMetadata.MEDIA_TYPE_AUDIO_BOOK)

return metadataBuilder.build()
}

@JsonIgnore
fun getMediaItems():List<MediaItem> {
fun getMediaItems(ctx:Context):List<MediaItem> {
val mediaItems:MutableList<MediaItem> = mutableListOf()

for (audioTrack in audioTracks) {
val mediaMetadata = this.getExoMediaMetadata()
val mediaMetadata = this.getExoMediaMetadata(ctx)
val mediaUri = this.getContentUri(audioTrack)
val mimeType = audioTrack.mimeType

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,7 @@ import android.graphics.Color
import android.graphics.ImageDecoder
import android.hardware.Sensor
import android.hardware.SensorManager
import android.net.ConnectivityManager
import android.net.Network
import android.net.NetworkCapabilities
import android.net.NetworkRequest
import android.net.*
import android.os.*
import android.provider.MediaStore
import android.provider.Settings
Expand Down Expand Up @@ -292,7 +289,7 @@ class PlayerNotificationService : MediaBrowserServiceCompat() {
return MediaDescriptionCompat.Builder().build()
}

val coverUri = currentPlaybackSession!!.getCoverUri()
val coverUri = currentPlaybackSession!!.getCoverUri(ctx)

var bitmap: Bitmap? = null
// Local covers get bitmap
Expand Down Expand Up @@ -398,7 +395,7 @@ class PlayerNotificationService : MediaBrowserServiceCompat() {

val metadata = playbackSession.getMediaMetadataCompat(ctx)
mediaSession.setMetadata(metadata)
val mediaItems = playbackSession.getMediaItems()
val mediaItems = playbackSession.getMediaItems(ctx)
val playbackRateToUse = playbackRate ?: initialPlaybackRate ?: 1f
initialPlaybackRate = playbackRate

Expand Down Expand Up @@ -501,7 +498,7 @@ class PlayerNotificationService : MediaBrowserServiceCompat() {
}

private fun setMediaSessionConnectorCustomActions(playbackSession:PlaybackSession) {
val mediaItems = playbackSession.getMediaItems()
val mediaItems = playbackSession.getMediaItems(ctx)
val customActionProviders = mutableListOf(
JumpBackwardCustomActionProvider(),
JumpForwardCustomActionProvider(),
Expand Down
5 changes: 2 additions & 3 deletions android/app/src/main/res/xml/file_paths.xml
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<external-path name="my_images" path="." />
<cache-path name="my_cache_images" path="." />
<paths>
<files-path name="downloads" path="downloads/" />
</paths>

0 comments on commit 13d32dc

Please sign in to comment.