【问题标题】:NotificationListenerService with RemoteController.OnClientUpdateListener crashes on API18 (4.3)带有 RemoteController.OnClientUpdateListener 的 NotificationListenerService 在 API18 (4.3) 上崩溃
【发布时间】:2014-05-24 14:01:15
【问题描述】:

问题

我想实现新的RemoteController API,它一直是introduced with API19 (Kitkat,4.4)。 API 要求我实现一个扩展自 NotificationListenerService 的类(由 API18 引入)并实现 RemoteController.OnClientUpdateListener 接口。 (有关如何实现所有这些的更多信息可以在here 找到,一个非常有用的示例项目可以在here 找到)

在我的 API19 (Kitkat,4.4) 设备和所有其他 API

05-24 09:32:48.945      893-893/com.example E/AndroidRuntime﹕ FATAL EXCEPTION: main
java.lang.RuntimeException: Unable to instantiate service com.example.RemoteService: java.lang.ClassNotFoundException: Didn't find class "com.example.RemoteService" on path: DexPathList[[zip file "/data/app/com.example-1.apk"],nativeLibraryDirectories=[/data/app-lib/com.example-1, /system/lib]]
        at android.app.ActivityThread.handleCreateService(ActivityThread.java:2561)
        at android.app.ActivityThread.access$1600(ActivityThread.java:141)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1338)
        at android.os.Handler.dispatchMessage(Handler.java:99)
        at android.os.Looper.loop(Looper.java:137)
        at android.app.ActivityThread.main(ActivityThread.java:5103)
        at java.lang.reflect.Method.invokeNative(Native Method)
        at java.lang.reflect.Method.invoke(Method.java:525)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:737)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
        at dalvik.system.NativeStart.main(Native Method)
 Caused by: java.lang.ClassNotFoundException: Didn't find class "com.example.RemoteService" on path: DexPathList[[zip file "/data/app/com.example-1.apk"],nativeLibraryDirectories=[/data/app-lib/com.example-1, /system/lib]]
        at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:53)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:501)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:461)
        at android.app.ActivityThread.handleCreateService(ActivityThread.java:2558)
        at android.app.ActivityThread.access$1600(ActivityThread.java:141
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1338)
...

这是由一个简单的事实引起的,RemoteController 以及因此实现的接口 RemoteController.OnClientUpdateListener 在 API18 上不可用,但 NotificationListenerService 可用。并非在每台设备上都发送意图

到目前为止我已经尝试过什么

  • 在其上添加另一层抽象并构建一个简单的“if (API>=19)”检查。 我试图通过使用第二个空的NotificationListenerService 来做到这一点,它可以作为一种调用服务。我会将第二个服务放在我的 AndroidManifest 中,以便它接收意图,然后我只需将“if (API>=19)”检查放入其 onCreate 并从那里启动我的实际 RemoteService。结果是,我的应用程序不再崩溃(耶)。不幸的是,它也不再适用于 API19 Kitkat :(。我认为这是因为我必须直接在我的 AndroidManifest 中将我的 RemoteService 注册为侦听器,否则它不会收到任何东西。

代码 sn-ps

RemoteService.java:

public class RemoteService extends NotificationListenerService
    implements RemoteController.OnClientUpdateListener {
...
}

AndroidManifest.xml:

<manifest ...>
    <application ...>
        <service android:name="com.example.RemoteService"
             android:label="@string/app_name"
             android:permission="android.permission.BIND_NOTIFICATION_LISTENER_SERVICE">
            <intent-filter>
                <action android:name="android.service.notification.NotificationListenerService" />
            </intent-filter>
        </service>
    </application>
</manifest>

【问题讨论】:

    标签: android service android-notifications android-4.4-kitkat


    【解决方案1】:

    解决方案

    在 values 和 values-v19 中的 xml 文件中放置一个布尔值。在 values-v19 中将其设置为 false 并在 values-v19 中设置为 true。现在将 NotificationListenerService 的“android:enabled”标签设置为这个布尔值。

    ./values/bool_switches.xml:

    <resources>
        <bool name="remotecontrollerservice_enabled">false</bool>
    </resources>
    

    ./values-v19/bool_switches.xml:

    <resources>
        <bool name="remotecontrollerservice_enabled">true</bool>
    </resources>
    

    ./AndroidManifest.xml:

    ...
    <service android:name=".services.RemoteControllerService"
             android:label="@string/scrobblingservice_string"
             android:permission="android.permission.BIND_NOTIFICATION_LISTENER_SERVICE"
             android:enabled="@bool/remotecontrollerservice_enabled">
        <intent-filter>
            <action android:name="android.service.notification.NotificationListenerService"/>
        </intent-filter>
    </service>
    ...
    

    【讨论】:

      【解决方案2】:

      只需使用 android:enabled="false" 禁用该服务,然后在 Application.onCreate 中启用它(如果设备正在运行 KitKat 或更新版本)。

      【讨论】:

      • 但这不是说系统不能自己实例化服务吗?如果我重新启动设备而不再次打开我的应用程序,系统应该仍然能够启动我的服务,从而使我能够处理传入的数据。
      • 我已经根据您的建议更新了解决方案。
      猜你喜欢
      • 1970-01-01
      • 2011-07-24
      • 2013-08-10
      • 2011-07-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-10-26
      • 2012-03-08
      相关资源
      最近更新 更多