我正在尝试使用预定义的操作启动服务,但是我收到以下错误:
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)
我用来尝试启动意图的代码如下:
Intent serviceIntent = new Intent(MusicService.ACTION_PLAY);
startService(serviceIntent);
这也不起作用;
startService(new Intent(MusicService.ACTION_PLAY);
我已经在清单中包含了相应的意图过滤器。
答案 0 :(得分:2)
在Android 5.0及更高版本中,您无法再通过隐式bindService()
使用Intent
绑定到服务。隐式Intent
是您使用操作字符串之类的东西,而不是识别您希望绑定到的特定应用程序中的特定Java类。
您有几个选择,包括:
startService()
不受影响,因此您可以将协议更改为与服务交互到命令模式,而不是绑定模式,您可以坚持使用现有的Intent
如果这是您自己的服务,请删除<intent-filter>
,并使用将Intent
构造函数作为第二个参数(例如new Intent(this, MusicThingyService.class)
) 。拥有<intent-filter>
服务的唯一原因是您希望第三方使用该服务。
如果您知道托管所需服务的应用的应用ID,则在您正在使用的setPackage()
上调用Intent
会使其“足够明确”以满足bindService()
。
您可以使用PackageManager
和queryIntentServices()
来查找服务实现。如果没有匹配的服务(例如,未安装您的合作伙伴应用程序),多个匹配服务(例如,其他人试图拦截通信),或者伪装成匹配服务的恶意软件,则允许您优雅地失败(通过检查其他应用程序的签名)。我在this sample app中演示了这种方法。