安卓权限BIND_NOTIFICATION_LISTENER_SERVICE无法正常工作

6

我正在开发React Native应用。我在Android上努力使用Notification ServicesBIND_NOTIFICATION_LISTENER_SERVICE。我正在尝试使用NotificationListenerService读取来电通知。

我使用One Plus 5T (Android Oreo)进行调试。

我已经尝试了很多重复的问题解决方案,包括:

1.重新启动手机(听起来有点傻,但并没有起作用)

2.重新安装/重建应用程序

  1. 重命名NotificationListenerService类文件并运行等。

我一直面临的问题:

1.在“通知访问”设置中看不到我的应用程序。

2.当我收到任何通知时,onCreate/onNotificationPosted都没有被调用。

3.使用下面的代码检查我的应用程序是否具有通知许可,并返回“false”(显然,这是我的问题)

ComponentName cn = new ComponentName(getReactApplicationContext(), NotificationListener.class);
String flat = Settings.Secure.getString(getReactApplicationContext()
                   .getContentResolver(), "enabled_notification_listeners");
final boolean hasPermission = flat != null && flat.contains(cn.flattenToString());
// hasPermission - false

由于BIND_NOTIFICATION_LISTENER_SERVICE未列在Dangerous permissions清单中,我认为在Manifest中定义它(下面为您提供了源代码)就足够了,而不需要请求运行时权限。

我按照教程以及其他教程进行操作,但是找不出我的错误所在。一切看起来完美无缺。在整整一天的思考后,我认为我需要寻求您的帮助。

请在下面查看我的源代码。

非常感谢您的时间和耐心。(:

我的源代码

AndroidManifest.xml

      <service
            android:name=".NotificationListener"
            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>

NotificationListener.java(没有任何日志输出)

public class NotificationListener extends NotificationListenerService {

    Context context;

    private String TAG = this.getClass().getSimpleName();

    @Override
    public void onCreate() {
        super.onCreate();
        Log.d("KBT", "FROM LISTENER onCreate");
        context = getApplicationContext();
    }

    @Override
    public void onNotificationPosted(StatusBarNotification sbn) {

        Log.d("KBT", "FROM LISTENER onNotificationPosted");

        String pack = sbn.getPackageName();
        String ticker ="";
        if(sbn.getNotification().tickerText !=null) {
            ticker = sbn.getNotification().tickerText.toString();
        }
        Bundle extras = sbn.getNotification().extras;
        String title = extras.getString("android.title");
        String text = extras.getCharSequence("android.text").toString();

        Intent msgrcv = new Intent("NOTIFICATION_POSTED_KBT");
        msgrcv.putExtras(extras);

        LocalBroadcastManager.getInstance(context).sendBroadcast(msgrcv);
    }

    @Override
    public void onNotificationRemoved(StatusBarNotification sbn) {
        Log.i(TAG, "********** onNOtificationRemoved");
    }

}

NotificationListenerModule.java

public class NotificationListenerModule extends ReactContextBaseJavaModule {
    Context mainContext;
    public NotificationListenerModule(ReactApplicationContext reactContext) {
        super(reactContext);
        mainContext = getReactApplicationContext();
    }

    @Override
    public String getName() {
        return "BatteryStatus";
    }

    @ReactMethod
    public void registerNotificationEvent(Callback successCallback) {

        // This log is printed successfully hence this function is getting called.
        Log.d("KBT","registerNotificationEvent called");

        // Registering Receiver
        LocalBroadcastManager.getInstance(mainContext).registerReceiver(myReceiver, new IntentFilter("NOTIFICATION_POSTED_KBT"));

        // Check Notification Permission in our app
        ComponentName cn = new ComponentName(getReactApplicationContext(), NotificationListener.class);
        String flat = Settings.Secure.getString(getReactApplicationContext().getContentResolver(), "enabled_notification_listeners");
        final boolean enabled = flat != null && flat.contains(cn.flattenToString());
]    }


    private class NLServiceReceiver extends BroadcastReceiver {

        @Override public void onReceive(Context context, Intent intent) {
            Bundle bundle = intent.getExtras();
            JSONObject json = new JSONObject();
            Set<String> keys = bundle.keySet();
            for (String key : keys) {
                try {
                    // json.put(key, bundle.get(key)); see edit below
                    json.put(key, JSONObject.wrap(bundle.get(key)));
                } catch(JSONException e) {
                    //Handle exception here
                }
            }

            // Emitting the event to React Native
            getReactApplicationContext()
                        .getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)
                        .emit("onNotificationPosted", json);
        }
    }
}

日志(com.logcharge 是我的包名)

    09-23 10:19:23.968 1035-1653/? E/InputDispatcher: channel '2888e2a com.logcharge/com.logcharge.MainActivity (server)' ~ Channel is unrecoverably broken and will be disposed!
09-23 10:19:24.175 2465-3354/? E/RecentsTaskLoader: Unexpected null component name or activity info: ComponentInfo{com.logcharge/com.logcharge.MainActivity}, null
09-23 10:19:24.177 2465-3354/? E/RecentsTaskLoader: Unexpected null component name or activity info: ComponentInfo{com.logcharge/com.logcharge.MainActivity}, null
09-23 10:19:24.662 2668-2668/? E/OPUtils: removeMultiApp ,com.logcharge
09-23 10:19:26.981 1035-1324/? E/ActivityManager: Failure starting process com.logcharge
    java.lang.SecurityException: Package com.logcharge was not found!
        at com.android.server.pm.PackageManagerService.checkPackageStartable(PackageManagerService.java:4350)
        at com.android.server.am.ActivityManagerService.startProcessLocked(ActivityManagerService.java:4446)
        at com.android.server.am.ActivityManagerService.startProcessLocked(ActivityManagerService.java:4407)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.server.am.EmbryoHelper.startProcessLocked(EmbryoHelper.java:93)
        at com.android.server.am.Uterus$BirthRunnable.run(Uterus.java:720)
        at android.os.Handler.handleCallback(Handler.java:790)
        at android.os.Handler.dispatchMessage(Handler.java:99)
        at android.os.Looper.loop(Looper.java:164)
        at android.os.HandlerThread.run(HandlerThread.java:65)
09-23 10:20:19.029 1035-1370/? E/PackageManager.DexOptimizer: Well this is awkward; package com.logcharge.MainApplication had UID -1
    java.lang.Throwable
        at com.android.server.pm.PackageDexOptimizer.performDexOptLI(PackageDexOptimizer.java:150)
        at com.android.server.pm.PackageDexOptimizer.performDexOpt(PackageDexOptimizer.java:126)
        at com.android.server.pm.PackageManagerService.installPackageLI(PackageManagerService.java:19987)
        at com.android.server.pm.PackageManagerService.installPackageTracedLI(PackageManagerService.java:19547)
        at com.android.server.pm.PackageManagerService.-wrap35(Unknown Source:0)
        at com.android.server.pm.PackageManagerService$9.run(PackageManagerService.java:16810)
        at android.os.Handler.handleCallback(Handler.java:790)
        at android.os.Handler.dispatchMessage(Handler.java:99)
        at android.os.Looper.loop(Looper.java:164)
        at android.os.HandlerThread.run(HandlerThread.java:65)
        at com.android.server.ServiceThread.run(ServiceThread.java:46)
09-23 10:20:21.277 25936-25936/? E/SensorManager: sensorName:BMI160 Accelerometer,isWakeUpSensor:false,callingApp: com.logcharge,callingPid:25936,callingUid:10632
09-23 10:20:22.014 646-659/? E/cutils: Nothing there yet; let's create it: /storage/emulated/0/Android/data/com.logcharge
09-23 10:20:22.015 646-659/? E/cutils: Nothing there yet; let's create it: /storage/emulated/0/Android/data/com.logcharge/cache

1
日志中可能有一些有用的信息。在详细模式下搜索(不要使用“无过滤器”),查找“通知”,看看在安装应用程序后是否显示了任何相关内容。 - TheWanderer
@TheWanderer 值得查看日志。但是我在我的Android日志以及React-Native日志中没有发现任何可疑的东西。我也已经在我的问题中更新了日志。 - Ganesh
1
看起来您仅筛选了来自您的应用程序的日志。将其更改为“无过滤器”,然后重新搜索。 - TheWanderer
1
@TheWanderer,你是对的。我已经改成了无过滤器,但是其他应用程序中出现了一堆错误。其中一个错误我认为与我的应用有关。它说 E/PackageManager.DexOptimizer: 这很尴尬; 包com.logcharge.MainApplication 的UID为-1 java.lang.Throwable - Ganesh
@TheWanderer 我遇到了一个可能很有用的错误:com.logcharge进程启动失败,且出现了java.lang.SecurityException:未找到com.logcharge包! - Ganesh
在重新安装时会发生这种情况。没有什么大问题。 - TheWanderer
1个回答

0

这很奇怪,但是我在非常仔细地按照以下步骤操作后,第二天成功地运行了它(没有跳过任何步骤)

  1. 卸载应用程序

  2. 停止/关闭React Native服务器

  3. 重命名NotificationListenerService类文件

  4. 重新连接USB电缆(如果不是模拟器),并将连接类型从仅充电更改为媒体传输

  5. 构建您的Android代码

  6. 执行react-native run-android

  7. 祈求上帝 _/\_(开玩笑的,但确实有帮助)

祝你好运。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接