Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

WRITE_SETTINGS Permission ambiguity

I'm building my app for android 6.0 Marshmallow, it needs WRITE_SETTTINGS permission. After searching from here I came to know that calling this:

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

won't show dialog permission. So, based on CommonsWare solution, we should check if Settings.System.canWrite() returns true or false. So, I should call Activity with ACTION_MANAGE_WRITE_SETTINGS as action.

But the issue is when I call this activity, it shows my app has already been granted permission though the method Settings.System.canWrite() returns false.

Am I missing something here or I have to disable it then enable it again.

like image 698
Pankaj Avatar asked Jan 28 '16 06:01

Pankaj


4 Answers

On my Nexus 6 using Android 6.0.1 (MMB29S) this code:

if (!Settings.System.canWrite(this)) {
    Intent intent = new Intent(Settings.ACTION_MANAGE_WRITE_SETTINGS);
    intent.setData(Uri.parse("package:dummy"));
    startActivity(intent);
}

opens the Settings only if Allow modify system settings is set to disabled. For instance, at first launch after fresh install (i.e. not reinstall)

Edit (see comments): Some device may be bugged with respect to this code, in those canWrite() always returns false, whatever the value of the setting.

like image 185
cuihtlauac Avatar answered Oct 26 '22 11:10

cuihtlauac


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);
        }

Dialog :-

 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();
}

for eg. complete code for Brightness .

 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(Activity activity) {
        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);
            if(retVal){
                Toast.makeText(activity, "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;
    }*/
}
like image 32
Ashish Saini Avatar answered Oct 26 '22 12:10

Ashish Saini


write this method as follows:

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);

        }
    }
}

then call the method (writePermission) just before you call your dialog

I hope this helps

like image 23
olammy Avatar answered Oct 26 '22 13:10

olammy


It turns out that if you have CHANGE_NETWORK_STATE declared in your manifest, the toggle to allow WRITE_SETTINGS will default to the on position even though the permission is not granted. You don't even need to declare WRITE_SETTINGS to encounter this bug.

like image 29
Anish Bhandari Avatar answered Oct 26 '22 11:10

Anish Bhandari