ryanheise / audio_service

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

Google play rejected because of Android Auto.No Auto functionality The app did not appear in the Auto screen or lens picker when we attempted to test functionality. #956

Open terrasuscompany opened 2 years ago

terrasuscompany commented 2 years ago

Feature proposal

No Auto functionality The app did not appear in the Auto screen or lens picker when we attempted to test functionality.

Motivating use case(s)

When i try to publish app with android auto support. Google play reject the app. They say No Auto functionality The app did not appear in the Auto screen or lens picker when we attempted to test functionality.

ryanheise commented 2 years ago

audio_service provides no documentation on how to support Android Auto, so you'll need to read the official Android documentation to understand what you need to do to support this:

https://developer.android.com/training/cars/media

Note that onLoadChildren corresponds to getChildren in audio_service, and onGetRoot corresponds to browsableRootId in audio_service.

terrasuscompany commented 2 years ago

I can test the app with real device too. It seems everything is ok. It is working good. But google always reject. I can not understand which intend should i add in to android manifest.

ryanheise commented 2 years ago

But this is not an appropriate feature proposal. This plugin does everything it can on this end to provide the API, but you have to edit your own manifest file according to Android's official documentation.

terrasuscompany commented 2 years ago

For example api doesn't play song from voice command. For example, if your app is already playing one media item, the user can say “Play [song title]" (for example, "Play Bohemian Rhapsody") to tell your app to play a different song without looking at or touching the car's display. I think that AudioService should handle it. am i wrong?

ryanheise commented 2 years ago

If you can read the Android documentation and find which part of that documentation is not implemented in audio_service, that will help with your feature request.

ryanheise commented 2 years ago

@terrasuscompany have you had a chance to check the documentation and find specifically what API you would like to request be added to audio_service?

Adamteh commented 2 years ago

@terrasuscompany Please have you been able to resolve the google play store rejection issue due to the android auto functionality?

@ryanheise Please how do I prevent my app from being rejected due to the android auto functionality?

ryanheise commented 2 years ago

As mentioned in my previous comment, I need you to read the Android API documentation and if there is anything specifically that is missing in audio_service that you require me to implement, let me know what it is.

keaganhilliard commented 2 years ago

I'll try to make a deeper write up on another issue. The main problems that I'm seeing are that the app doesn't always show up in the list of applications when launching android auto. I think it might have something to do with waking up the flutter engine but I'm not sure. The other issue is that even after implementing the playFromSearch handler playFromSearch does not work in android auto and it is required by google to certify an app that declares the android auto manifest.

ryanheise commented 2 years ago

If it is a case of the FlutterEngine not being started in time, perhaps a similar solution to onGetRoot is in order. This method requires an immediate response, and so audio_service prepares and persists the response value in shared preferences so that the next time the app is woken up, it can immediately fetch the prepared response value and return it even when the engine is not ready yet.

For playFromSearch, there is something interesting in the docs:

If a search cannot be processed quickly, do not block in onPlayFromSearch(). Instead, set the playback state to STATE_CONNECTING and perform the search on an async thread.

In audio_service, this means setting the processing state to loading. Is that what you're already doing?

keaganhilliard commented 2 years ago

I am not setting the processing state to loading. Interestingly the search works now without making any change, but I will implement that.

keaganhilliard commented 1 year ago

Setting the processing state did seem to clear up Google's review issue for me.

Mordtimer commented 1 year ago

Actually, I had a similar problem and found a workaround. Maybe someone will find this useful. The rejection message from play store looked like this:

image

Generally, to test if app is on the list to handle the voice search request, there is a command that takes an effect on device/emulator: adb shell am start -a android.media.action.MEDIA_PLAY_FROM_SEARCH

Despite the fact that my project met all the requirements listed in google AA documentation (intent-filter added to my AudioServiceFragmentActivity) there was still a problem with handling the intent and I got rejected from Play Store as described here. I did some research and there is a similar case here: https://github.com/android/uamp/issues/479. The workaround from this issue worked for me as well. New dummy activity AppCompact with 'android.media.action.MEDIA_PLAY_FROM_SEARCH' makes my app handling voice requests and google play review got accepted as well.

Related issue #984

jeprojects commented 1 year ago

@keaganhilliard I have implemented playFromSearch, but where do I put the intent? I have tried several locations in the AndroidManifest.xml and none of the shows a list after running:

adb shell am start -a android.media.action.MEDIA_PLAY_FROM_SEARCH

@Mordtimer Your suggestion works, but I have a crashlytics exception:

You need to use a Theme.AppCompat theme (or descendant) with this activity.

Maybe my implementation is wrong. Are you able to provide an example? Thanks

jeprojects commented 1 year ago

I found @keaganhilliard audiobookly source and following that (uncommented the intent) and it seems to be working!

jeprojects commented 1 year ago

Just an update, the first time it was approved, the next version without touching any code related to audio got rejected with:

Issue found: Voice commands
Media Apps

Your app does not respond (no music played or error message shown) after issuing a voice command

I have provided the methods for prepareFromSearch, playFromSearch and search, but none of them seems to be getting called.

@keaganhilliard Were you able to get search working?

keaganhilliard commented 1 year ago

Nah eventually I just commented it out and gave up on supporting android auto. It was always a moving target, as the app would get through review one time and not the next. Trying to get more information from Google was impossible so I was never able to understand the issue that they were experiencing if an issue did in fact exist.

jeprojects commented 1 year ago

@keaganhilliard It seems that way. I wonder what voice command they are using to test. Sometimes there is a delay so I am assuming it's hitting my app. Everything I try eventually just wants YouTube music or is unrecognized.

ryanheise commented 1 year ago

Issue found: Voice commands

I did a search on that and found Signal also had their own problems getting accepted through Google Play because of that:

https://github.com/signalapp/Signal-Android/issues/6124

A Signal contributor writes:

I got in contact with a guy at Google, who told me that I should be able to get Voice commands to work if I just switch my device to US English... it shouldn't be tied to some specific region, just the language.

I guess it's as simple as getting in contact with someone at Google :-) Well, actually looking at their eventual fix, it was something different. You may want to take a look here (although that's now 6 years old): https://github.com/signalapp/Signal-Android/pull/6180

But from what I understand there are a LOT of edge cases you can run into with Android Auto, so understandably it would be quite a headache to try to jump through all of those hoops. It's really valuable that you are sharing your experiences so that others can learn from them.

@snipd-mikel I believe you implemented Android Auto recently, did you have any insights on any of the common gotchas?

jeprojects commented 1 year ago

@ryanheise Thanks. I will go through their code.

I found this StackOverflow interesting:

Simply declare an intent-filter for MEDIA_PLAY_FROM_SEARCH in an Activity declaration. It is not mandatory for Android Auto to actually handle the intent, since Android Auto will call the MediaSession.Callback.onPlayFromSearch

I am assuming audio_service is handling MediaSession.Callback.onPlayFromSearch when I declare the playFromSearch method.

followed by

One caveat: you need to publish your app with the intent-filter and wait a few days to get it flagged and indexed for the "Play [x] on [y]" type of query. It is not instantaneous.

Play, stop etc all work via voice commands.

Maybe my issue is I need to publish the app (without Android auto support) and let it get flagged so that when they test the Android auto version, search will work for them. It seems silly but it could be a difference between one Google tester to another.

jeprojects commented 1 year ago

Still waiting for Google Assistant to call the onPlayFromSearch method so maybe it isn't "flagged" yet.

@Ruchit2759 It looks like you had success with getting onPlayFromSearch to work, would you mind sharing some details?

ruchit8960 commented 1 year ago

Hi @jeprojects, Yes my app is approved by google playstore. I have developed a flutter app which supports android auto. For playSearch feature I have added below intent in manifest.

<intent-filter>
                <action android:name="android.media.action.MEDIA_PLAY_FROM_SEARCH" />
                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>

And you can listen assistance's command by overriding playFromSearch method. In this method you can perform your logic. This method contains two parameter including query and extras as map. Query is a string in which you can get your command understood by assistance. And assistance provides many information based on your query in extras parameter.

You can use extras map for getting accurate result. But unfortunately playFromSearch methods return null value in extras. I have resolved this issue in #1015.

I hope this helps @jeprojects. Thank you.

jeprojects commented 1 year ago

@ruchit8960 Definitely helps to confirm that everything is being done correctly.

For me, Google Assistant isn't calling the playFromSearch function at all just yet.

Is the voice command you are using something like "Play X on App Name"?

Did you add the search intent to the main activity?

<activity
            android:name="com.ryanheise.audioservice.AudioServiceActivity"...

Thanks again for your help.

Ruchit2759 commented 1 year ago

Hello @jeprojects No "Play X on App Name", This command is not working for me. I am just using "Play X" and it works.

Sometimes assistance won't be able to understand to command is for which app. B'coz "Play x on AppName" is not working. I believe it is working for known apps like spotify. Maybe there is some another process for this.

So temporary you can follow below steps: Open your app -> start google assistance & use "Play x" command And after that if assistance is replying back that playing x on your app then you will definitely get a callback in playSearchMethod.

Again, make sure that whenever you seek assistance to play something, you will receive a callback if assistance responds with your app name.

jeprojects commented 1 year ago

Thanks @Ruchit2759 for your help.

I am still unable to test the app as onPlayFromSearch/playFromSearch is never triggered using google assistant on both the device and android auto so I went digging a little deeper to try and figure out how and why and came across this great little test app, which might be used by google to test?

Android Media Controller Test App

When using the Android Media Controller app, I can manually trigger onPlayFromSearch (and others) and it is now showing in my app logs.

Now being able to trigger the onPlayFromSearch I was able to find a little bug in my playFromSearch method which I am assuming is why Google had previously rejected the app.

It is now waiting in the play store for review and I will update you if approved/denied.

UPDATE It was approved on the app store!

iosifnicolae2 commented 1 year ago

Does anyone has an example Android Auto app that was approved by Play Store?

Thank you!

jeprojects commented 1 year ago

@iosifnicolae2 I followed audiobookly (Uncomment the android auto parts on lines 30-33 of AndroidManifest.xml)

Also test onPlayFromSearch using: Android Media Controller Test

There are probably more edge cases that will get your app rejected so let me know and I will try and help.

Mordtimer commented 1 year ago

@keaganhilliard I have implemented playFromSearch, but where do I put the intent? I have tried several locations in the AndroidManifest.xml and none of the shows a list after running:

adb shell am start -a android.media.action.MEDIA_PLAY_FROM_SEARCH

@Mordtimer Your suggestion works, but I have a crashlytics exception:

You need to use a Theme.AppCompat theme (or descendant) with this activity.

Maybe my implementation is wrong. Are you able to provide an example? Thanks

Hey, Sorry for long time no-replay. Maybe try to use Activity instead of AppCompatActivity in the dummy class? The alternative solution is to add the theme in app resources, but I don't think this is the correct one for you - I used CompactActivity in my app because there is no other way to make Chromecast work, so you probably don't need it. And it's kinda deprecated as far as I know.

Since my initial experience with AA I implemented AA in 3 different apps, and I never had this issue again during release phase so there has to be a problem that is much harder to track and I cannot provide any consistent solution / minimal reproduction.