问题
I am trying to launch a service with a predefined action but i get the following error:
java.lang.IllegalArgumentException: Service Intent must be explicit: Intent { act=com.radioafrica.music.action.TOGGLE_PLAYBACK }
at android.app.ContextImpl.validateServiceIntent(ContextImpl.java:1745)
at android.app.ContextImpl.startServiceCommon(ContextImpl.java:1774)
at android.app.ContextImpl.startService(ContextImpl.java:1758)
at android.content.ContextWrapper.startService(ContextWrapper.java:515)
at com.radioafrica.music.activity.MusicPlayer.onClick(MusicPlayer.java:70)
at android.view.View.performClick(View.java:4763)
at android.view.View$PerformClick.run(View.java:19821)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5272)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:909)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:704)
The code i use to try and launch the intent is as follows:
Intent serviceIntent = new Intent(MusicService.ACTION_PLAY);
startService(serviceIntent);
This doesnt work as well;
startService(new Intent(MusicService.ACTION_PLAY);
I have already included the appropriate intent filters in the manifest too.
回答1:
On Android 5.0+, you can no longer bind to a service, using bindService()
, via an implicit Intent
. An implicit Intent
is one where you use things like an action string, rather than identifying the specific Java class in the specific app that you wish to bind to.
You have a few options, including:
startService()
is unaffected, so you could look to change your protocol for interacting with the service to the command pattern, rather that the binding pattern, and you can stick with your existingIntent
.If this is your own service, get rid of the
<intent-filter>
, and use theIntent
constructor that takes the Java class as the second parameter (e.g.,new Intent(this, MusicThingyService.class)
). The only reason for having an<intent-filter>
on a service is if you want third parties to work with that service.If you know the application ID of the app that is hosting the service that you want, calling
setPackage()
on theIntent
that you are using will make it "explicit enough" to satisfybindService()
.You can use
PackageManager
andqueryIntentServices()
to find the service implementation(s). This will allow you to fail gracefully if there are no matching services (e.g., your partner app is not installed), more than one matching service (e.g., somebody else is trying to intercept communications), or malware masquerading as the matching service (via checking the signature of the other app). I demonstrate this approach in this sample app.
来源:https://stackoverflow.com/questions/32331970/service-intent-must-be-explict