【问题标题】:Android Lollipop - Service Intent must be explicitAndroid Lollipop - 服务意图必须是明确的
【发布时间】:2015-03-02 15:12:24
【问题描述】:

我在 Lollipop 和明确的意图方面遇到了(我确信这是一个简单的)问题。我已经构建了一个通过蓝牙连接与打印机通信的应用程序 - 这在 Lollipop 下的任何东西上都可以正常工作。

我检查了其他各种答案和 Android 文档,但看不出他们创建明确意图的方式与我这样做的方式之间有什么区别。

来自 logcat 的错误如下:

03-02 14:35:43.471: E/AndroidRuntime(28094): FATAL EXCEPTION: main
03-02 14:35:43.471: E/AndroidRuntime(28094): Process: com.example.app, PID: 28094
03-02 14:35:43.471: E/AndroidRuntime(28094): java.lang.RuntimeException: Error receiving broadcast Intent { act=printing flg=0x10 (has extras) } in com.example.app.AppName$1@351d4863
03-02 14:35:43.471: E/AndroidRuntime(28094):    at android.app.LoadedApk$ReceiverDispatcher$Args.run(LoadedApk.java:969)
03-02 14:35:43.471: E/AndroidRuntime(28094):    at android.os.Handler.handleCallback(Handler.java:739)
03-02 14:35:43.471: E/AndroidRuntime(28094):    at android.os.Handler.dispatchMessage(Handler.java:95)
03-02 14:35:43.471: E/AndroidRuntime(28094):    at android.os.Looper.loop(Looper.java:155)
03-02 14:35:43.471: E/AndroidRuntime(28094):    at android.app.ActivityThread.main(ActivityThread.java:5696)
03-02 14:35:43.471: E/AndroidRuntime(28094):    at java.lang.reflect.Method.invoke(Native Method)
03-02 14:35:43.471: E/AndroidRuntime(28094):    at java.lang.reflect.Method.invoke(Method.java:372)
03-02 14:35:43.471: E/AndroidRuntime(28094):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1028)
03-02 14:35:43.471: E/AndroidRuntime(28094):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:823)
03-02 14:35:43.471: E/AndroidRuntime(28094): Caused by: java.lang.IllegalArgumentException: Service Intent must be explicit: Intent { act=printing flg=0x10 (has extras) }
03-02 14:35:43.471: E/AndroidRuntime(28094):    at android.app.ContextImpl.validateServiceIntent(ContextImpl.java:1786)
03-02 14:35:43.471: E/AndroidRuntime(28094):    at android.app.ContextImpl.stopServiceCommon(ContextImpl.java:1844)
03-02 14:35:43.471: E/AndroidRuntime(28094):    at android.app.ContextImpl.stopService(ContextImpl.java:1805)
03-02 14:35:43.471: E/AndroidRuntime(28094):    at android.content.ContextWrapper.stopService(ContextWrapper.java:520)
03-02 14:35:43.471: E/AndroidRuntime(28094):    at com.example.app.AppName$1.onReceive(ExampleClass.java:530)
03-02 14:35:43.471: E/AndroidRuntime(28094):    at android.app.LoadedApk$ReceiverDispatcher$Args.run(LoadedApk.java:950)
03-02 14:35:43.471: E/AndroidRuntime(28094):    
... 8 more

我从其他 3 个活动中调用此函数,因此将其放入它自己的类中并通过执行以下操作来调用它:

// In the activity I call it from
ExampleClass example = new Example(this);
example.print(); // Function in the example class

然后在这个打印函数中:

IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(PRINT_ACTION);
ctx.registerReceiver(intentReciever, intentFilter); // Where ctx is the context                 
Intent i = new Intent(ctx, printerService.class);
i.putExtras(bundle);
ctx.startService(i); // Start the relevant service

android 文档:

Intent downloadIntent = new Intent(this, DownloadService.class); 下载Intent.setData(Uri.parse(fileUrl)); startService(downloadIntent);

除了setDataputExtras,我看不出有什么区别。

并且在与上述相同的类中(广播接收器):

private BroadcastReceiver intentReciever = new BroadcastReceiver() {
    @Override
    public void onReceive(Context context, Intent intent) {
        context.unregisterReceiver(intentReciever);
        context.stopService(intent); // If I remove this, I get multiple returns, but if I leave it - it crashes :(
    }
};

在我拥有的 printerClass.class (intentService) 文件中:

Intent broadcastIntent = new Intent();
broadcastIntent.setAction(ExampleClass.PRINT_ACTION);
broadcastIntent.putExtras(ReceivedBundle); // Put all the received data back in and send back!
getBaseContext().sendBroadcast(broadcastIntent);

对我来说,这看起来服务已经是明确的但显然不是!

问题看起来已经到了回归点,但我迷失了它的不真实!对此的任何帮助将不胜感激。

【问题讨论】:

标签: android android-intent service bluetooth android-5.0-lollipop


【解决方案1】:

您的 onReceive() 方法执行此操作:

public void onReceive(Context context, Intent intent) {
    context.unregisterReceiver(intentReciever);
    context.stopService(intent); // If I remove this, I get multiple returns, but if I leave it - it crashes :(
}

这会使用Intent 调用stopService()BroadcastReceiver 是从它开始的(广播Intent)。如果您查看创建广播 Intent 的代码,它看起来像这样:

Intent broadcastIntent = new Intent();
broadcastIntent.setAction(ExampleClass.PRINT_ACTION);
broadcastIntent.putExtras(ReceivedBundle);

这个Intent 只有一个 ACTION 和 EXTRAS。它是隐式的Intent,而不是显式的Intent

注意:这在其他平台上“有效”,因为它实际上根本不会阻止您的 Service。调用stopService() 的代码什么也不做,因为没有响应IntentService

在 Android 5 上,由于对服务的隐式 Intent 的安全性收紧,对 stopService() 的调用会引发异常。

【讨论】:

  • 我删除了context.stopService(intent),这似乎确实阻止了崩溃。谢谢你的帮助。
  • 你确定你的笔记吗?我已经在 Android 4.4 上对其进行了测试,并且该服务非常高兴地停止并销毁了。就我而言,它是前台服务。
猜你喜欢
  • 1970-01-01
  • 2015-03-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-02-12
相关资源
最近更新 更多