WRITE_SETTINGS Неопределенность разрешения
Я создаю свое приложение для Android-маршала 6, ему нужно WRITE_SETTTINGS. После поиска здесь я узнал, что называет это:
requestPermissions(new String[]{Manifest.permission.WRITE_SETTINGS},
101);
не будет отображаться диалоговое разрешение. Итак, на основе решения CommonsWare, мы должны проверить, если Settings.System.canWrite()
возвращает true или false. Итак, я должен вызвать Activity с ACTION_MANAGE_WRITE_SETTINGS
как действие.
Но проблема в том, что когда я вызываю это действие, оно показывает, что моему приложению уже предоставлено разрешение, хотя метод Settings.System.canWrite()
возвращает false.
Мне что-то не хватает, или я должен отключить его, а затем снова включить его.
Ответы
Ответ 1
На моем Nexus 6 с помощью Android 6.0.1 (MMB29S) этот код:
if (!android.provider.Settings.System.canWrite(this)) {
Intent intent = new Intent(Settings.ACTION_MANAGE_WRITE_SETTINGS);
intent.setData(Uri.parse("package:dummy"));
startActivity(intent);
}
открывает настройки только в том случае, если параметр Разрешить изменение настроек системы отключен. Например, при первом запуске после новой установки (т.е. Не переустанавливать)
Изменить (см. комментарии): Некоторое устройство может быть искажено по отношению к этому коду, в тех canWrite()
всегда возвращается false
, независимо от значения параметра.
Ответ 2
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (Settings.System.canWrite(context)) {
//Write code to feature for eg. set brightness or vibrate device
/* ContentResolver cResolver = context.getContentResolver();
Settings.System.putInt(cResolver, Settings.System.SCREEN_BRIGHTNESS,brightness);*/
}
else {
showBrightnessPermissionDialog(context);
}
Диалог: -
private static void showBrightnessPermissionDialog(final Context context) {
final AlertDialog.Builder builder = new AlertDialog.Builder(context);
builder.setCancelable(true);
final AlertDialog alert = builder.create();
builder.setMessage("Please give the permission to change brightness. \n Thanks ")
.setCancelable(false)
.setPositiveButton("OK", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
Intent intent = new Intent(android.provider.Settings.ACTION_MANAGE_WRITE_SETTINGS);
intent.setData(Uri.parse("package:" + context.getPackageName()));
// intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(intent);
alert.dismiss();
}
});
alert.show();
}
например. полный код яркости.
import android.content.ContentResolver;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.net.Uri;
import android.os.Build;
import android.provider.Settings;
import android.support.v7.app.AlertDialog;
public class BrightnessHelper {
public static void setBrightness(Context context, int brightness){
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (Settings.System.canWrite(context)) {
//Write code to feature for eg. set brightness or vibrate device
ContentResolver cResolver = context.getContentResolver(); Settings.System.putInt(cResolver, Settings.System.SCREEN_BRIGHTNESS,brightness);
}
else {
showBrightnessPermissionDialog(context);
}
}
}
public static int getBrightness(Context context) {
ContentResolver cResolver = context.getContentResolver();
try {
return Settings.System.getInt(cResolver, Settings.System.SCREEN_BRIGHTNESS);
} catch (Settings.SettingNotFoundException e) {
return 0;
}
}
private static void showBrightnessPermissionDialog(final Context context) {
final AlertDialog.Builder builder = new AlertDialog.Builder(context);
builder.setCancelable(true);
final AlertDialog alert = builder.create();
builder.setMessage("Please give the permission to change brightness. \n Thanks ")
.setCancelable(false)
.setPositiveButton("OK", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
Intent intent = new Intent(android.provider.Settings.ACTION_MANAGE_WRITE_SETTINGS);
intent.setData(Uri.parse("package:" + context.getPackageName()));
// intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(intent);
alert.dismiss();
}
});
alert.show();
}
/* private boolean checkSystemWritePermission (активность активности) { boolean retVal = true; if (Build.VERSION.SDK_INT >= activity.Build.VERSION_CODES.M) { retVal = Settings.System.canWrite(activity.getApplicationContext()); //Log.d(TAG, "Can Write Settings:" + retVal); если (RetVal) { Toast.makeText(активность, "Запись разрешена:-)", Toast.LENGTH_LONG).show(); } Еще { Toast.makeText(это, "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; } */
}
Ответ 3
Я столкнулся с подобной проблемой при разработке для android 6. Это связано с тем, что теперь разработчики должны запрашивать разрешения во время выполнения. Мое решение здесь -
В окне onCreate отобразите диалоговое окно с правами. Допустим, что имя метода showPermissionsDialog().
//Global variable request code
private static final int WRITE_PERMISSION_REQUEST = 5000;
private void showPermissionsDialog() {
if (Build.VERSION.SDK_INT == 23) {
int hasWriteSettingsPermission = checkSelfPermission(Manifest.permission.WRITE_SETTINGS);
if (hasWriteSettingsPermission != PackageManager.PERMISSION_GRANTED) {
//You can skip the next if block. I use it to explain to user why I wan his permission.
if (!ActivityCompat.shouldShowRequestPermissionRationale(HomeActivity.this, Manifest.permission.ACCESS_FINE_LOCATION)) {
showMessageOKCancel("You need to allow write settings",
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
ActivityCompat.requestPermissions(HomeActivity.this, new String[]{Manifest.permission.WRITE_SETTINGS}, WRITE_PERMISSION_REQUEST);
}
});
return;
}
//The next line causes a dialog to popup, asking the user to allow or deny us write permission
ActivityCompat.requestPermissions(HomeActivity.this, new String[]{Manifest.permission.WRITE_SETTINGS}, WRITE_PERMISSION_REQUEST);
return;
} else {
//Permissions have already been granted. Do whatever you want :)
}
}
}
//Now you only need this if you want to show the rationale behind
//requesting the permission.
private void showMessageOKCancel(String message, DialogInterface.OnClickListener okListener) {
new AlertDialog.Builder(HomeActivity.this).setMessage(message).setPositiveButton("OK", okListener)
.setNegativeButton("Cancel", null).show();
}
//This method is called immediately after the user makes his decision to either allow
// or disallow us permision.
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
switch (requestCode) {
case WRITE_PERMISSION_REQUEST:
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
//User pressed the allowed button
//Do what you want :)
} else {
//User denied the permission
//Come up with how to hand the requested permission
}
default:
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
}
}
Ответ 4
Оказывается, если у вас есть CHANGE_NETWORK_STATE
, объявленный в вашем манифесте, то переключатель, разрешающий WRITE_SETTINGS
, по умолчанию будет включен в позицию, даже если разрешение не предоставлено. Вам даже не нужно объявлять WRITE_SETTINGS
, чтобы встретить эту ошибку.
Ответ 5
напишите этот метод следующим образом:
public void writePermission() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (!Settings.System.canWrite(getApplicationContext())) {
Intent intent = new Intent(Settings.ACTION_MANAGE_WRITE_SETTINGS, Uri.parse("package:" + getPackageName()));
startActivityForResult(intent, 200);
}
}
}
затем вызовите метод (writePermission) непосредственно перед вызовом вашего диалога
Я надеюсь, что это поможет