首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

java.lang.SecurityException:未被授予此权限:关闭对话框时使用android.permission.WRITE_SETTINGS [Android]

问题分析

java.lang.SecurityException: 未被授予此权限: 关闭对话框时使用 android.permission.WRITE_SETTINGS 这个错误提示表明你的应用在尝试修改系统设置时没有获得相应的权限。

基础概念

在Android系统中,WRITE_SETTINGS 是一个特殊的权限,允许应用修改系统设置。这个权限通常用于更改系统显示设置、网络设置等。由于其敏感性,Android系统默认不允许应用获取这个权限。

相关优势

  • 系统设置修改:允许应用动态修改系统设置,提供更好的用户体验。
  • 灵活性:开发者可以根据应用需求调整系统设置,实现更多功能。

类型

  • 系统权限:这是一个系统级别的权限,不同于普通的运行时权限(Runtime Permissions)。

应用场景

  • 系统级应用:如系统UI、系统工具等。
  • 需要修改系统设置的第三方应用:如某些定制主题应用、网络优化工具等。

问题原因

  1. 权限未声明:在 AndroidManifest.xml 中没有声明 WRITE_SETTINGS 权限。
  2. 用户未授权:即使声明了权限,用户也需要手动授权。

解决方法

1. 声明权限

AndroidManifest.xml 中添加以下权限声明:

代码语言:txt
复制
<uses-permission android:name="android.permission.WRITE_SETTINGS" />

2. 请求权限

从Android 6.0(API 级别 23)开始,需要动态请求 WRITE_SETTINGS 权限。可以通过以下代码请求权限:

代码语言:txt
复制
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
    if (!Settings.System.canWrite(this)) {
        Intent intent = new Intent(Settings.ACTION_MANAGE_WRITE_SETTINGS);
        intent.setData(Uri.parse("package:" + getPackageName()));
        startActivityForResult(intent, REQUEST_CODE_WRITE_SETTINGS);
    }
}

onActivityResult 中处理权限请求结果:

代码语言:txt
复制
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if (requestCode == REQUEST_CODE_WRITE_SETTINGS) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            if (Settings.System.canWrite(this)) {
                // 权限已授予,可以进行系统设置修改
            } else {
                // 权限未授予,提示用户
                Toast.makeText(this, "需要WRITE_SETTINGS权限", Toast.LENGTH_SHORT).show();
            }
        }
    }
}

3. 用户授权

用户需要在系统设置中手动授权 WRITE_SETTINGS 权限。可以通过以下步骤引导用户:

  1. 打开应用设置页面。
  2. 找到应用详情页。
  3. 点击“权限”选项。
  4. 找到并开启 WRITE_SETTINGS 权限。

参考链接

通过以上步骤,你可以解决 java.lang.SecurityException: 未被授予此权限: 关闭对话框时使用 android.permission.WRITE_SETTINGS 的问题。

页面内容是否对你有帮助?
有帮助
没帮助

相关·内容

因为Android M权限问题导致的"Permission Denial: reading com.android.providers.media.MediaProvider"解决办法

最后查明是因为API过高权限访问有修改, 在API级别>=23时, 权限访问被分为三个级别, 分别为”PROTECTION_NORMAL, PROTECTION_DANGEROUS, 和PROTECTION_SIGNATURE(还有两个标志可以和SIGNATURE联合使用才有意义)”. PROTECTION_NORMAL是普通权限, 通过manifest文件在安装时被授予. PROTECTION_SIGNATURE是签名权限, 通过”检查manifest和app签名是否匹配app中声明的权限”在安装时授予. 对于 PROTECTION_DANGEROUS, 不仅需要在manifest中声明, 还需要在运行时通过requestPermissions获得, 也就是弹出来一个个对话框, 让用户确认是否授予app这些权限. 这些是常见PROTECTION_DANGEROUS权限, 如果你在程序中使用了, 那么在API>=23, 很可能会不正常工作. ACCESS_COARSE_LOCATION ACCESS_FINE_LOCATION ADD_VOICEMAIL BODY_SENSORS CALL_PHONE CAMERA GET_ACCOUNTS PROCESS_OUTGOING_CALLS READ_CALENDAR READ_CALL_LOG READ_CELL_BROADCASTS READ_CONTACTS READ_EXTERNAL_STORAGE READ_PHONE_STATE READ_SMS RECEIVE_MMS RECEIVE_SMS RECEIVE_WAP_PUSH RECORD_AUDIO SEND_SMS USE_SIP WRITE_CALENDAR WRITE_CALL_LOG WRITE_CONTACTS WRITE_EXTERNAL_STORAGE

02
  • Android开发笔记(五十五)手机设备基本操作

    手机的基本信息分两类,一类是与电话有关的信息,另一类是设备自身的信息。 与电话有关的信息可由TelephonyManager类获得,常用的参数与对应的方法如下所示: 网络运营商名称 : getNetworkOperatorName 网络运营商编号 : getNetworkOperator,返回五位数字,前三位表示国家代码(中国的为460),后两位表示运营商代码(中国移动为0,中国联通为1,中国电信为2) 手机类型 : getPhoneType 网络类型 : getNetworkType获得细分类型,getNetworkClass获得大类如2G/3G/4G SIM卡状态 : getSimState SIM卡运营商名称 : getSimOperatorName SIM卡运营商编号 : getSimOperator SIM卡序列号 : getSimSerialNumber IMSI : getSubscriberId IMEI : getDeviceId 手机号码 : 实测发现多数情况下getLine1Number和getMsisdn都无法正确取到号码,但是很多APP又需要用户的手机号,那又得想办法获取号码,获取的方法大致有如下几种: 1、用户首次使用,提示用户注册手机号,然后保存起来,下次就能取到手机号了; 2、APP自动用该手机发一条免费短信(比如向10086发),然后到发件箱中寻找该短信的发送号码; 3、如果能连到运营商的支撑系统,那么根据IMSI去后台系统查询手机号,这也是可以的; 设备自身的信息可由Build类获得,常用的参数与对应的方法如下所示: 手机厂商 : Build.MANUFACTURER 手机品牌 : Build.BRAND 手机型号 : Build.MODEL 设备名称 : Build.DEVICE CPU指令 : Build.CPU_ABI 芯片型号 : Build.HARDWARE 手机序列号 : Build.SERIAL SDK版本 : Build.VERSION.SDK_INT 系统版本 : Build.VERSION.RELEASE 版本代号 : Build.VERSION.CODENAME

    02
    领券