无法获得WRITE_SETTINGS权限

当我在Android M Preview 3上有一个23的目标API时,我似乎无法获得Manifest.permission.WRITE_SETTTINGS权限。

requestPermissions(new String[]{Manifest.permission.WRITE_SETTINGS}, 101); 

请求权限不会调出我期望的对话框,但是如果我没有此权限进行以下调用,

  RingtoneManager.setActualDefaultRingtoneUri(activity, RingtoneManager.TYPE_RINGTONE, ringUri); 

电话会因为我没有权限而被除外。

我不确定该从哪里出发。 有23个新的铃声API? 还是这个权限的改变只是让任何非系统的应用程序无法更改铃声?

要使用WRITE_SETTINGS ,基于文档:

  1. 正常情况下清单中有<uses-permission>元素。

  2. 调用Settings.System.canWrite()来查看是否有资格写出设置。

  3. 如果canWrite()返回false ,则启动ACTION_MANAGE_WRITE_SETTINGS活动,以便用户可以同意允许您的应用程序实际写入设置。

现在,写入设置现在是一个双重select(同意安装,单独同意在设置允许),类似于设备pipe理API,无障碍服务等。

另外请注意,我还没有尝试过使用这些 – 这是基于我昨天在Android 6.0更改上所做的研究 。

除了CommonsWare的回答以及Ogix的评论之外,这里还有一些虚拟代码

 private boolean checkSystemWritePermission() { boolean retVal = true; if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { retVal = Settings.System.canWrite(this); Log.d(TAG, "Can Write Settings: " + retVal); if(retVal){ Toast.makeText(this, "Write allowed :-)", Toast.LENGTH_LONG).show(); }else{ Toast.makeText(this, "Write not allowed :-(", Toast.LENGTH_LONG).show(); FragmentManager fm = getFragmentManager(); PopupWritePermission dialogFragment = new PopupWritePermission(); dialogFragment.show(fm, getString(R.string.popup_writesettings_title)); } } return retVal; } 

片段PopupwritePermission然后给出一个窗口的情况解释。 点击确定button将打开Android系统菜单,授权可以被授予:

 private void openAndroidPermissionsMenu() { Intent intent = new Intent(Settings.ACTION_MANAGE_WRITE_SETTINGS); intent.setData(Uri.parse("package:" + getActivity().getPackageName())); startActivity(intent); } 

以前的答案是很好的,我只是除了获得许可要求的结果。

  public static void youDesirePermissionCode(Activity context){ boolean permission; if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { permission = Settings.System.canWrite(context); } else { permission = ContextCompat.checkSelfPermission(context, Manifest.permission.WRITE_SETTINGS) == PackageManager.PERMISSION_GRANTED; } if (permission) { //do your code } else { if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M) { Intent intent = new Intent(Settings.ACTION_MANAGE_WRITE_SETTINGS); intent.setData(Uri.parse("package:" + context.getPackageName())); context.startActivityForResult(intent, MainActivity.CODE_WRITE_SETTINGS_PERMISSION); } else { ActivityCompat.requestPermissions(context, new String[]{Manifest.permission.WRITE_SETTINGS}, MainActivity.CODE_WRITE_SETTINGS_PERMISSION); } } } 

然后在Activity

 @SuppressLint("NewApi") @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if (requestCode == CODE_WRITE_SETTINGS_PERMISSION && Settings.System.canWrite(this)){ Log.d("TAG", "CODE_WRITE_SETTINGS_PERMISSION success"); //do your code } } @Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { super.onRequestPermissionsResult(requestCode, permissions, grantResults); if (requestCode == CODE_WRITE_SETTINGS_PERMISSION && grantResults[0] == PackageManager.PERMISSION_GRANTED) { //do your code } } 

权限android.permission.WRITE_SETTINGS现在在组signature|appop|pre23|preinstalledandroid.permission.CHANGE_NETWORK_STATEandroid.permission.SYSTEM_ALERT_WINDOW

这意味着你得到它在22和以下。 在较新的版本,你必须是一个应用程序运营商。

这是一个完整的例子:

 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { if (Settings.System.canWrite(context) { // Do stuff here } else { Intent intent = new Intent(android.provider.Settings.ACTION_MANAGE_WRITE_SETTINGS); intent.setData(Uri.parse(“package:” + getActivity().getPackageName())); intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); startActivity(intent); } }