Android Lollipop - 服务意图必须明确
Android Lollipop - Service Intent must be explicit
我有(我确信这是一个简单的)棒棒糖和明确意图的问题。我已经构建了一个通过蓝牙连接与打印机进行通信的应用程序 - 这适用于 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@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.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 个活动中调用了这个函数,所以把它放在它自己的 class 中并通过执行以下操作来调用它:
// 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);
downloadIntent.setData(Uri.parse(fileUrl));
startService(downloadIntent);
除了setData
和putExtras
,我看不出有什么区别。
和上面一样class(广播接收者):
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);
对我来说,这看起来服务已经很明确了,但显然不是!
问题似乎到了 return 的地步,但我迷失了它的不真实!如有任何帮助,我们将不胜感激。
您的 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 :(
}
这使用 BroadcastReceiver
开始的 Intent
调用 stopService()
(广播 Intent
)。如果您查看创建广播 Intent
的代码,它看起来像这样:
Intent broadcastIntent = new Intent();
broadcastIntent.setAction(ExampleClass.PRINT_ACTION);
broadcastIntent.putExtras(ReceivedBundle);
这个Intent
只有一个ACTION和EXTRAS。它是隐式 Intent
,而不是显式 Intent
.
注意:此 "works" 在其他平台上,因为它实际上根本不会停止您的 Service
。调用 stopService()
的代码什么都不做,因为没有 Service
响应 Intent
.
在 Android 5,对 stopService()
的调用抛出异常,因为有关服务的隐式 Intent
的安全收紧。
我有(我确信这是一个简单的)棒棒糖和明确意图的问题。我已经构建了一个通过蓝牙连接与打印机进行通信的应用程序 - 这适用于 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@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.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 个活动中调用了这个函数,所以把它放在它自己的 class 中并通过执行以下操作来调用它:
// 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); downloadIntent.setData(Uri.parse(fileUrl)); startService(downloadIntent);
除了setData
和putExtras
,我看不出有什么区别。
和上面一样class(广播接收者):
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);
对我来说,这看起来服务已经很明确了,但显然不是!
问题似乎到了 return 的地步,但我迷失了它的不真实!如有任何帮助,我们将不胜感激。
您的 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 :(
}
这使用 BroadcastReceiver
开始的 Intent
调用 stopService()
(广播 Intent
)。如果您查看创建广播 Intent
的代码,它看起来像这样:
Intent broadcastIntent = new Intent();
broadcastIntent.setAction(ExampleClass.PRINT_ACTION);
broadcastIntent.putExtras(ReceivedBundle);
这个Intent
只有一个ACTION和EXTRAS。它是隐式 Intent
,而不是显式 Intent
.
注意:此 "works" 在其他平台上,因为它实际上根本不会停止您的 Service
。调用 stopService()
的代码什么都不做,因为没有 Service
响应 Intent
.
在 Android 5,对 stopService()
的调用抛出异常,因为有关服务的隐式 Intent
的安全收紧。