ryanheise / audio_service

Flutter plugin to play audio in the background while the screen is off.
803 stars 480 forks source link

Cover art saved as a file does not get displayed on Android Auto #1049

Closed daniel-naegele closed 1 year ago

daniel-naegele commented 1 year ago

Documented behaviour

Supported types of URIs are:

File - file://
Network - http:// https:// etc.
Android content URIs - content://

Actual behaviour

When adding a media item, which uses a file:// artUri, the cover art gets displayed in the normal android media notification, but not in Android Auto (blank space). Regardless if the MediaItem is currently playing or if it is just one of the browsable MediaItems. image

Minimal reproduction project

https://github.com/daniel-naegele/audio_service Just run the normal example.

Reproduction steps

  1. (Start playback)
  2. Open Android Auto
  3. Click on the app or the currently running media

    Output of flutter doctor

    
    [✓] Flutter (Channel stable, 3.13.9, on Fedora Linux 38 (Workstation Edition) 6.5.10-200.fc38.x86_64, locale de_DE.UTF-8)
    [✓] Android toolchain - develop for Android devices (Android SDK version 33.0.2)
    [✓] Chrome - develop for the web
    [✓] Linux toolchain - develop for Linux desktop
    [✓] Android Studio (version 2022.3)
    [✓] IntelliJ IDEA Ultimate Edition (version 2023.2)
    [✓] Connected device (3 available)
    [✓] Network resources

• No issues found!```

Devices exhibiting the bug

OnePlus 8 Pro (Android 13) with Desktop Head Unit for Android Auto. We also tested it with another device and a real car, same result.

ryanheise commented 1 year ago

Hi, you should use a content:// URI as demonstrated in example_android_songs.dart.

daniel-naegele commented 12 months ago

Just ouf of curiosity, why does Android Auto not support file Uris but https Uris? Also is this mentioned somewhere in the README/docs? Because I couldn't find it. If it is not already there, it should be added imo.

ryanheise commented 12 months ago

There is an absence of documentation on my end regarding Android Auto mainly because I am not an expert in it, but also because many app developers (not specifically Flutter but even native Android developers) report AA as being very difficult to get right, with various edge cases, and a lot of configuration that if not done correctly will prevent the app from being approved for the Play Store. It's quite overwhelming, and would therefore be overwhelming to document. Instead, anyone who wants to implement AA should consult the original Android documentation and once they understand everything that's involved, they can look at how those APIs are wrapped in audio_service. Understanding file vs content vs http URIs would be an example of that. What I can say is that on my end I have tried to replicate all of the relevant native APIs that pertain to AA, but you would still need to learn how AA works on Android from the original documentation on Android.

That said, if someone were to come along and submit a pull request to write the AA documentation for audio_service, or write a tutorial on (say) Medium that I could link to, I would be happy to accept the contribution.

ryanheise commented 12 months ago

Just ouf of curiosity, why does Android Auto not support file Uris but https Uris?

On this, I think it's probably because only apps running directly on your Phone can directly access the phone's filesystem. Android Auto, however, actually runs on a separate device and connects to your phone through networking. Any reference to a file from the Android Auto device would only be able to refer to files on the Auto device itself, and I don't think it's designed to have its own filesystem. So it needs to connect to your phone through the connection between the two - that requires a different kind of Uri.

daniel-naegele commented 12 months ago

So if I understand you and the AA/Media documentation correctly, file cover arts can be displayed via the following: Set artUri to content://... -> Have the ContentProvider return a file descriptor for the specified content uri

I tried to achieve all this in our production as well as in a small reproducible example with a similar implementation like here, but couldn't get it to work. The notification as well as android auto do not work at all. It seems that the openFile method in the dart content_provider does not get called properly. As far as I have unterstood the code from the AudioService#loadArtBitmap method correctly, openFile should get called, as the loadThumbnailUri parameter should be null.

Idk if this is an issue in my implementation, this package or the android_content_provider package. Am I missing something?

Once I get this reliably working, I am willing to provide examples/docs maybe even a medium blog article.

ryanheise commented 12 months ago

Did you try the example in this repository? If that doesn't work, you could report a bug.

daniel-naegele commented 11 months ago

As far as I understand, the example_android_songs.dart is not my use case. That example is for querying/using the android media store and the AndroidContentResolver. Also

Our original problem was to display an asset if no cover art for a certain song could be found. The first solution was just to copy the asset to the apps cache/support directory and set the artUri to sth. like file://.../asset.png. But as reported, this does not work on AA, so I wrote a AndroidContentProvider to return the file descriptor to the copied asset file.

I think that there would be two other possible workarounds:

  1. Host the placeholder image on a CDN and just provide the https uri
  2. Insert a fake title into the MediaStore with our placeholder and use that. But we want to avoid these kind of workarounds as much as possible.

Our problem is basically to display an asset cover art on android auto.

github-actions[bot] commented 11 months ago

This issue has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs, or use StackOverflow if you need help with audio_service.