Android如何监听是否有应用在使用当前系统权限如定位、语音、摄像头等?

Android如何监听是否有应用在使用当前系统权限如定位、语音、摄像头等?

需求来源:应用正在收集个人敏感信息时,顶部状态栏位置显示图标

使用Android系统服务(Context.APP_OPS_SERVICE)即可监听当前是否有应用使用权限

具体使用代码如下:

	//在AndroidManifest.xml文件中声明使用权限
	<uses-permission android:name="android.permission.WATCH_APPOPS"/>

	private AppOpsManager.OnOpActiveChangedListener changedListener;

	initAppops(getApplicationContext());

	void initAppops(Context context){
        Log.i(TAG, "initAppops()");
        if (context == null) {
            Log.e(TAG, "Context is null!");
            return;
        }

        // 获取 AppOpsManager 实例
        final AppOpsManager appOpsManager = (AppOpsManager) context.getSystemService(Context.APP_OPS_SERVICE);
        if (appOpsManager != null) {
            // 创建监听器并实现回调
            changedListener = new AppOpsManager.OnOpActiveChangedListener() {
                @Override
                public void onOpActiveChanged(String op, int uid, String packageName, boolean active) {
                    Log.i(TAG, "onOpActiveChanged op="  op + ", packageName=" + packageName + ", active=" + active);
                    // 检查是否是相关权限的操作
                    switch (op) {
                        case AppOpsManager.OPSTR_RECORD_AUDIO:
                        case AppOpsManager.OPSTR_MUTE_MICROPHONE:
                        case AppOpsManager.OPSTR_PLAY_AUDIO:
                            Log.d(TAG, String.format("MICROPHONE-麦克风权限被调用, 权限: %s, 状态: %b, 包名: %s", op, active, packageName));
                            break;
                        case AppOpsManager.OPSTR_FINE_LOCATION:
                        case AppOpsManager.OPSTR_COARSE_LOCATION:
                        case AppOpsManager.OPSTR_MONITOR_LOCATION:
                        case AppOpsManager.OPSTR_MONITOR_HIGH_POWER_LOCATION:
                        case AppOpsManager.OPSTR_GPS:
                            Log.d(TAG, String.format("LOCATION-定位权限被调用, 权限: %s, 状态: %b, 包名: %s", op, active, packageName));
                            break;
                        case AppOpsManager.OPSTR_CAMERA:
                            Log.d(TAG, String.format("CAMERA-相机权限被调用, 权限: %s, 状态: %b, 包名: %s", op, active, packageName));
                            break;

                        case AppOpsManager.OPSTR_READ_EXTERNAL_STORAGE:
                        case AppOpsManager.OPSTR_WRITE_EXTERNAL_STORAGE:
                        case AppOpsManager.OPSTR_LEGACY_STORAGE:
                        case AppOpsManager.OPSTR_MANAGE_EXTERNAL_STORAGE:
                            Log.d(TAG, String.format("STORAGE-存储权限被调用, 权限: %s, 状态: %b, 包名: %s", op, active, packageName));
                            break;
                        case AppOpsManager.OPSTR_READ_CONTACTS:
                        case AppOpsManager.OPSTR_WRITE_CONTACTS:
                            Log.d(TAG, String.format("CONTACTS-联系人权限被调用, 权限: %s, 状态: %b, 包名: %s", op, active, packageName));
                            break;
                        case AppOpsManager.OPSTR_READ_CALL_LOG:
                        case AppOpsManager.OPSTR_WRITE_CALL_LOG:
                        case AppOpsManager.OPSTR_READ_PHONE_STATE:
                            Log.d(TAG, String.format("CALL_LOG-通话记录权限被调用, 权限: %s, 状态: %b, 包名: %s", op, active, packageName));
                            break;
                        default:
                            break;
                    }
                }
            };

            // 开始监听相关权限
            appOpsManager.startWatchingActive(
                    new String[]{
                            AppOpsManager.OPSTR_RECORD_AUDIO,  // 麦克风权限
                            AppOpsManager.OPSTR_FINE_LOCATION, // 精确定位权限
                            AppOpsManager.OPSTR_COARSE_LOCATION, // 粗略定位权限
                            AppOpsManager.OPSTR_CAMERA,         // 相机权限
                            AppOpsManager.OPSTR_MONITOR_LOCATION,
                            AppOpsManager.OPSTR_MONITOR_HIGH_POWER_LOCATION,
                            AppOpsManager.OPSTR_GPS,
                            AppOpsManager.OPSTR_MUTE_MICROPHONE,
                            AppOpsManager.OPSTR_PLAY_AUDIO,
                            AppOpsManager.OPSTR_READ_EXTERNAL_STORAGE,
                            AppOpsManager.OPSTR_WRITE_EXTERNAL_STORAGE,
                            AppOpsManager.OPSTR_LEGACY_STORAGE,
                            AppOpsManager.OPSTR_MANAGE_EXTERNAL_STORAGE,
                            AppOpsManager.OPSTR_READ_CONTACTS,
                            AppOpsManager.OPSTR_WRITE_CONTACTS,
                            AppOpsManager.OPSTR_READ_CALL_LOG,
                            AppOpsManager.OPSTR_WRITE_CALL_LOG,
                            AppOpsManager.OPSTR_READ_PHONE_STATE
                    },
                    context.getMainExecutor(),
                    changedListener
            );
        } else {
            Log.e(TAG, "AppOpsManager is not available.");
        }
    }

    // 注销监听器
    public void unregisterAppOpsListener(Context context) {
        if (context == null || changedListener == null) return;

        final AppOpsManager appOpsManager = (AppOpsManager) context.getSystemService(Context.APP_OPS_SERVICE);
        if (appOpsManager != null) {
            appOpsManager.stopWatchingActive(changedListener);
        }
     }
	unregisterAppOpsListener(getApplicationContext());

注意事项:
1、一个应用在持续使用权限,不会持续回调
2、只会发一次true,不使用才会再次回调发false
3、和包名没关系,只和权限相关,单个应用使用权限,只会发一次,如果其他应用在调过来相同权限,是会再次触发回调的
4、要判断包名,有些包使用敏感权限是不需要显示的

如果对你有帮忙的话,用你发财的小手点赞收藏一下吧

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值