服务意图必须明确 [英] Service Intent Must Be Explict

查看:100
本文介绍了服务意图必须明确的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试通过预定义的操作启动服务,但是出现以下错误:

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);

这也不起作用;

startService(new Intent(MusicService.ACTION_PLAY);

我也已经在清单中包括了适当的意图过滤器.

I have already included the appropriate intent filters in the manifest too.

推荐答案

在Android 5.0+上,您不再可以使用bindService()通过隐式Intent绑定到服务.隐式Intent是您在其中使用诸如操作字符串之类的东西的方法,而不是在您希望绑定到的特定应用程序中标识特定的Java类.

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.

您有几种选择,包括:

  1. startService()不受影响,因此您可以将与服务交互的协议更改为命令模式,而不是绑定模式,并且可以坚持使用现有的Intent.

  1. 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 existing Intent.

如果这是您自己的服务,请除去<intent-filter>,然后使用将Java类作为第二个参数的Intent构造函数(例如,new Intent(this, MusicThingyService.class)).在服务上使用<intent-filter>的唯一原因是您是否希望第三方使用该服务.

If this is your own service, get rid of the <intent-filter>, and use the Intent 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.

如果您知道托管所需服务的应用程序的应用程序ID,则在所使用的Intent上调用setPackage()将使其显式"满足bindService().

If you know the application ID of the app that is hosting the service that you want, calling setPackage() on the Intent that you are using will make it "explicit enough" to satisfy bindService().

您可以使用PackageManagerqueryIntentServices()查找服务实现.如果没有匹配服务(例如,未安装您的合作伙伴应用程序),多个匹配服务(例如,其他人试图拦截通信)或伪装成匹配服务的恶意软件(通过检查其他应用程序的签名).我在此示例应用中演示了这种方法.

You can use PackageManager and queryIntentServices() 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.

这篇关于服务意图必须明确的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆