对 SYSTEM_ALERT_WINDOW 和 WRITE_SETTINGS 的处理

最近开始开始研究 Android 6.0 的适配,关于两个特殊权限,查阅了一下资料,对于处理方法,在这里做个记录。

SYSTEM_ALERT_WINDOW

@TargetApi(Build.VERSION_CODES.M)
    private void requestDrawOverLays() {
        if (!Settings.canDrawOverlays(SettingActivity.this)) {

            AlertDialog dialog = new AlertDialog.Builder(SettingActivity.this)
                    .setTitle("需要您手动授予权限")
                    .setMessage("点击 OK 进入设置页面手动开启权限,允许本应用在其他应用界面之上打开")
                    .setPositiveButton("Ok", new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialog, int which) {
                        //核心代码
                            Intent i = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION,
                                    Uri.parse("package:" + getPackageName()));
                            startActivityForResult(i, OVERLAY_PERMISSION_REQ_CODE);
                        }
                    })
                    .setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialog, int which) {
                            mSwSms.setChecked(false);
                        }
                    })
                    .create();
            dialog.show();
        }
    }

@Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (requestCode == OVERLAY_PERMISSION_REQ_CODE) {
            if (Build.VERSION.SDK_INT >= 23 && !Settings.canDrawOverlays(this)) {
                Toast.makeText(this, "Permission Denied by user.", Toast.LENGTH_SHORT)
                        .show();
                mSwSms.setChecked(false);
            } else {
                Toast.makeText(this, "Permission allowed", Toast.LENGTH_SHORT).show();
            }
        } else if (requestCode == QRCODE_RESULT) {
            if (resultCode == RESULT_OK) {
                Bundle bundle = data.getExtras();
                String scanResult = bundle.getString("result");
                mScanResult.setText(scanResult);
            }
        }
    }

WRITE_SETTINGS

@TargetApi(23)
    private void writeSettingsPermission() {
        if(!Settings.System.canWrite(this)){
            AlertDialog dialog = new AlertDialog.Builder(this)
                    .setTitle("WRITE_SETTINGS权限申请")
                    .setMessage("点击OK进入设置界面授予权限")
                    .setPositiveButton("OK", new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialog, int which) {
                            //核心代码
                            Intent intent = new Intent(Settings.ACTION_MANAGE_WRITE_SETTINGS,
                                    Uri.parse("package:" + getPackageName()));
                            startActivityForResult(intent, REQUEST_CODE_WRITE_SETTINGS);
                        }
                    })
                    .setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialog, int which) {
                        }
                    })
                    .create();
            dialog.show();
        }
    }

    @Override
    @TargetApi(23)
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == REQUEST_CODE_WRITE_SETTINGS) {
            if (Settings.System.canWrite(this)) {
                Toast.makeText(this, "WRITE_SETTINGS permission granted", Toast.LENGTH_SHORT)
                        .show();
            } else {
                Toast.makeText(this, "WRITE_SETINGS permission denied", Toast.LENGTH_SHORT)
                        .show();
            }
        }
    }
作者czy1121,源码settingscompat,特殊权限(Special Permissions)兼容库,悬浮窗权限(SYSTEM_ALERT_WINDOW)与系统设置修改权限(WRITE_SETTINGS) Android 6.0 以前只要在 manifest 中申请了权限就是默认开启的 Android 6.0+需要在 manifest 中申请并且通过发送 Intent 让用户在设置界面进行勾选 适配 检测 API 23+(Android 6.0+/M) 使用 Settings.canDrawOverlays, Settings.System.canWrite API 18+(Android 4.3+/JellyBean MR2) 通过反射使用 AppOpsManager.checkOp API < 18 默认权限开启,时始终返回 true 授权 API 23+(Android 6.0+/M) 去系统设置面板就好 new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION), new Intent(Settings.ACTION_MANAGE_WRITE_SETTINGS) API 18+(Android 4.3+/JellyBean MR2) 默认权限开启 API < 18 默认权限开启,不做任何处理 切换授权状态 AppOpsManager.setMode 可用于Android 4.3/4.4修改授权状态 API 18 添加 AppOpsManager(被隐藏,在 Android 4.4 公开) API 21 后需要签名验证的权限android.Manifest.permission.UPDATE_APP_OPS_STATS,第三方应用用不了了。 ROM 有些 Rom 会默认禁用权限,通常都有自带的权限管理 API 18+ 有些 Rom 会默认禁用权限,通常都有自带的权限管理,这时就需要检测 Rom 类型然后跳转到对应的设置页面 API 23+ 本来去系统设置面板就好了,但有些 Rom 会用自带的权限管理替代系统设置面板,这时仍然需要检测 Rom 类型然后跳转到对应的设置页面 实际上是跳转到手机上的安全中心里对应的权限设置页,当安全中心版本不同时相应的权限设置页也有可能不一样 还有部分 ROM 的应用详细信息页可以设置权限
Android系统中,SystemUI(System User Interface)通常指的是提供系统级界面的小部件或工具栏,如状态栏、导航栏等。如果你想在SystemUI中添加自定义的行为或处理逻辑,你需要对系统服务进行定制,这通常是开发者权限较高的操作。 在Android中,你可以通过以下步骤来尝试添加自定义行为: 1. **权限管理**: - 使用`<uses-permission>`标签在AndroidManifest.xml文件中添加`android.permission.WRITE_SECURE_SETTINGS`或`android.permission.SYSTEM_ALERT_WINDOW`权限,以便访问系统级别的设置和绘制窗口。 2. **创建Service**: - 创建一个`BroadcastReceiver`来监听特定的系统事件,比如屏幕显示/隐藏的变化。然后,可以通过继承`StatusBarManagerService`或相关的SystemUI Service来扩展功能。 ```java public class MyCustomStatusbar extends StatusBarManagerService { // ... } ``` 或者使用`NotificationListenerService`来响应通知栏相关操作。 3. **注册Service**: - 在`onCreate()`方法中,注册你的服务并开启它,确保在`stopSelf()`时正确清理资源。 4. **添加处理逻辑**: - 实现必要的接口方法,例如`drawViewHierarchy()`来更新UI布局,或者`onVisibilityChanged()`来响应状态栏的显示/隐藏。 5. **发送自定义广播**: - 如果你想影响其他部分的SystemUI,可以发送自定义的广播,并在感兴趣的组件上接收并处理这些广播。 6. **测试与调试**: - 使用模拟器或设备进行测试,并可能需要root权限来查看和调试是否成功添加了自定义行为。 注意:这种操作需要对Android底层机制有深入理解,并且可能会导致不稳定或无法通过Google Play Store分发的应用。如果你是在开发自家手机上的预装应用,你可能可以直接修改系统的源码来进行这样的定制。但如果是第三方应用,通常应遵守Google的政策,避免对核心系统进行大幅度修改。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值