vanilla-music / vanilla

Vanilla Music Player for Android
GNU General Public License v3.0
1.19k stars 296 forks source link

[Bug] Headphone detector for Vanilla Music doesn't detect headphones #955

Open Tianonymus opened 5 years ago

Tianonymus commented 5 years ago

Hello, I tried out Headphone detector for Vanilla Music today after not having used it for some time. Unfortunately it does not work on my device since it updated to Android 8.

Please see below for info. Thanks.

Description

Headphone detector for Vanilla Music (HdfVM) doesn't detect headphones when plugged in.

Installed the latest version, headphones weren't detected. Restarted device, a message is shown that HdfVM is closed (paraphrased, don't use English device: "Unfortunately HdfVM has been closed". Can't say if it's an Android message dialogue or belongs to the app). Headphones aren't detected when Vanilla Music has been started before plugging in either.

Below is a log of the crash.

If I remember correctly this is an issue since the phone updated to Android 8/8.1.

Steps to reproduce the issue

Install HdfVM Restart device Message is shown that HdfVM crashed

Log

[05-09 01:01:03.708 6220:6220 E/AndroidRuntime] FATAL EXCEPTION: main Process: ch.blinkenlights.android.vanillaplug, PID: 6220 java.lang.RuntimeException: Unable to start receiver ch.blinkenlights.android.vanillaplug.BootReceiver: java.lang.IllegalStateException: Not allowed to start service Intent { cmp=ch.blinkenlights.android.vanillaplug/.VPlugService }: app is in background uid UidRecord{c0a85de u0a425 RCVR idle change:uncached procs:1 seq(0,0,0)} at android.app.ActivityThread.handleReceiver(ActivityThread.java:3310) at android.app.ActivityThread.-wrap17(Unknown Source:0) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1710) at android.os.Handler.dispatchMessage(Handler.java:106) at android.os.Looper.loop(Looper.java:175) at android.app.ActivityThread.main(ActivityThread.java:6722) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:810) Caused by: java.lang.IllegalStateException: Not allowed to start service Intent { cmp=ch.blinkenlights.android.vanillaplug/.VPlugService }: app is in background uid UidRecord{c0a85de u0a425 RCVR idle change:uncached procs:1 seq(0,0,0)} at android.app.ContextImpl.startServiceCommon(ContextImpl.java:1522) at android.app.ContextImpl.startService(ContextImpl.java:1478) at android.content.ContextWrapper.startService(ContextWrapper.java:650) at android.content.ContextWrapper.startService(ContextWrapper.java:650) at ch.blinkenlights.android.vanillaplug.BootReceiver.onReceive(BootReceiver.java:29) at android.app.ActivityThread.handleReceiver(ActivityThread.java:3299) ... 8 more

wchen342 commented 5 years ago

I had the same problem so I did some search. The problem is background services are limited from Android O. A quick fix is changing startService to startForegroundService which will eliminate the error, but the service will get killed after 5 seconds unless it displays a notification, which is not a good solution. I think a better way is to move the function to the player and recieve system broadcast there directly.

adrian-bl commented 5 years ago

Not sure if the headphone detector app will ever be useful on more recent android versions.

As wchen342 noted, you are required to show a permanent notification to not get killed.

I think a better way is to move the function to the player and recieve system broadcast there directly.

That wouldn't solve the issue: Vanilla also gets killed after ~5 sec of inactivity (= not playing a song, not showing a notification)

wchen342 commented 5 years ago

I think there are three possible solutions:

  1. Move this functionality to the player and only do headset detection when the player is running. This requires users to run the player once, and the player shall keep its notification alive even not playing unless the users manually quit it.

  2. On device boot up, run the service which displays a notification shortly then deletes the notification.

  3. Use a JobIntentService which pulls the headset status every second on Android 8+. Battery consumption can be a problem in this case.

I prefer solution 1 since starting playing music on boot up even the users never start the player is probably not so desirable, and the player's notification will keep the users aware that the music will possibly play when they plug their headset in.

breversa commented 5 years ago

https://github.com/marverenic/Jockey apparently has such a feature, but I have no idea how it's implemented.

breversa commented 5 years ago

This feature is SO useful when getting ready for a drive : I get in my car, plug the audio plug in the jack, and the music starts, without having to touch the screen. Simply awesome. :)

breversa commented 5 years ago

@adrian-bl : Many background apps have now gone ahead with a permanent notification, and I use the OS's (LineageOs 16 at the moment) notification settings to hide the ones I don't care about. I for one wouldn't blame you about going this way too. :)

breversa commented 4 years ago

Any news on this issue ? It’s one of the features that I’m missing the most, and the most often (several times daily).

wchen342 commented 4 years ago

@breversa I am no longer working on this project. You need to ask @adrian-bl whether he is gonna fix this or not.

breversa commented 4 years ago

Thank you @wchen342 for your reply.

For now, I've found a workaround user Easer (https://f-droid.org/packages/ryey.easer/) :

However, this solution is less than ideal :

However, the logic is there : a background task (with the mandatory notification that can be hidden by the OS (at least with LineageOS) that waits for the headphone to be plugged in, then merges with the "Now playing" notification. @adrian-bl, what do you think about it ?

wchen342 commented 4 years ago

@breversa That's an interesting approach.

One thing I noticed recently is that a lot of applications like firefox are now trying to show a notification at startup and make it hidden very shortly, which keep the application running without disturbing the user. I think that may be a solution.

breversa commented 3 years ago

@adrian-bl : Many background apps have now gone ahead with a permanent notification, and I use the OS's (LineageOs 16 at the moment) notification settings to hide the ones I don't care about. I for one wouldn't blame you about going this way too. :)

Wait wait wait… I see here https://cdn.rawgit.com/vanilla-music/vanilla/HEAD/app/src/main/assets/about.html :

1.0.91

  • NEW Switch to new notification framework

Does that mean that Vanilla Music may have a permanent notification that would bring back the headphones detector back ? :D

adrian-bl commented 3 years ago

No: this just means that we are using the androidx/support APIs to build the notification.

To get the headphone detector app working on newer SDK versions, we would need to change the app (not vanilla) to display a permanent notification.

breversa commented 3 years ago

Alright, I understand.

Once again, I'm all for a permanent notification (I can use the OS to hide it) if that allows to solve this issue. :)

matgoebl commented 3 years ago

Another alternative is using A2DP Volume (https://github.com/jroal/a2dpvolume), that is also available via f-droid. It uses the permanent notification method to survive in background. It can react on headphone jack connection and start an arbitrary app.

VA1DER commented 2 years ago

Is there any movement on this? Every other player I use can pause when I turn off my headset and resume when I turn it on. It's really the only functionality I'm missing in VM.

breversa commented 2 years ago

My workaround was to switch to Auxio: https://github.com/oxygencobalt/Auxio