Android marshmallow request permission?

I am currently working on an application that requires several “dangerous” permissions. So I tried adding “ask for permission” as required in Android Marshmallow(API Level 23), but couldn’t find how to do it.

How can I ask for permission using new permission model in my app?

  • Set Alpha/Opacity of Layout
  • How to update/refresh specific item in RecyclerView
  • How do I include http headers with MediaPlayer setDataSource?
  • how can I detect whether the android phone in Silent mode programmatically
  • Which order of nested layouts is most efficient in Android
  • SparseArray, check if key exists
  • Set RelativeLayout child to fill unused space
  • SyncAdapter always in pending state
  • How do I return a boolean from AsyncTask?
  • Easy way to hide system bar on Android ICS
  • Android append text file
  • Source code for android apps?
  • 12 Solutions collect form web for “Android marshmallow request permission?”

    Open a Dialog using the code below:

     ActivityCompat.requestPermissions(MainActivity.this,
                        new String[]{Manifest.permission.READ_EXTERNAL_STORAGE},
                        1);
    

    Get the Activity result as below:

    @Override
    public void onRequestPermissionsResult(int requestCode,
                                           String permissions[], int[] grantResults) {
        switch (requestCode) {
            case 1: {
    
              // If request is cancelled, the result arrays are empty.
              if (grantResults.length > 0
                        && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
    
                    // permission was granted, yay! Do the
                    // contacts-related task you need to do.          
                } else {
    
                    // permission denied, boo! Disable the
                    // functionality that depends on this permission.
                    Toast.makeText(MainActivity.this, "Permission denied to read your External storage", Toast.LENGTH_SHORT).show();
                }
                return;
            }
    
            // other 'case' lines to check for other
            // permissions this app might request
        }
    }
    

    More info: https://developer.android.com/training/permissions/requesting.html

    This structure I am using to check if my app has permission and than request if it does not have permission. So in my main code from where i want to check write following :

    int MyVersion = Build.VERSION.SDK_INT;
    if (MyVersion > Build.VERSION_CODES.LOLLIPOP_MR1) {
                    if (!checkIfAlreadyhavePermission()) {
                        requestForSpecificPermission();
                    }
    }
    

    Module checkIfAlreadyhavePermission() is implemented as :

    private boolean checkIfAlreadyhavePermission() {
        int result = ContextCompat.checkSelfPermission(this, Manifest.permission.GET_ACCOUNTS);
        if (result == PackageManager.PERMISSION_GRANTED) {
            return true;
        } else {
            return false;
        }
    }
    

    Module requestForSpecificPermission() is implemented as :

    private void requestForSpecificPermission() {
            ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.GET_ACCOUNTS, Manifest.permission.RECEIVE_SMS, Manifest.permission.READ_SMS, Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE}, 101);
    }
    

    and Override in Activity :

    @Override
    public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
        switch (requestCode) {
            case 101:
                if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                    //granted
                } else {
                    //not granted
                }
                break;
            default:
                super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        }
    }
    

    Refer this link for more details : http://revisitingandroid.blogspot.in/2017/01/how-to-check-and-request-for-run-time.html

    Starting from android marshmallow we need to request the user for specific permissions, we can also check through code if the permission already is given. Take a look at the list of permissions needed in most commonly

    android.permission-group.CALENDAR
    android.permission.READ_CALENDAR
    android.permission.WRITE_CALENDAR

    android.permission-group.CAMERA android.permission.CAMERA

    android.permission-group.CONTACTS android.permission.READ_CONTACTS
    android.permission.WRITE_CONTACTS android.permission.GET_ACCOUNTS

    android.permission-group.LOCATION
    android.permission.ACCESS_FINE_LOCATION
    android.permission.ACCESS_COARSE_LOCATION

    android.permission-group.MICROPHONE android.permission.RECORD_AUDIO

    android.permission-group.PHONE android.permission.READ_PHONE_STATE
    android.permission.CALL_PHONE android.permission.READ_CALL_LOG
    android.permission.WRITE_CALL_LOG android.permission.ADD_VOICEMAIL
    android.permission.USE_SIP android.permission.PROCESS_OUTGOING_CALLS

    android.permission-group.SENSORS android.permission.BODY_SENSORS

    android.permission-group.SMS android.permission.SEND_SMS
    android.permission.RECEIVE_SMS android.permission.READ_SMS
    android.permission.RECEIVE_WAP_PUSH android.permission.RECEIVE_MMS
    android.permission.READ_CELL_BROADCASTS

    android.permission-group.STORAGE
    android.permission.READ_EXTERNAL_STORAGE
    android.permission.WRITE_EXTERNAL_STORAGE

    Here is sample if we need to check for any permission

    if (ContextCompat.checkSelfPermission(context, Manifest.permission.WRITE_CALENDAR) != PackageManager.PERMISSION_GRANTED) {
                if (ActivityCompat.shouldShowRequestPermissionRationale((Activity) context, Manifest.permission.WRITE_CALENDAR)) {
                    AlertDialog.Builder alertBuilder = new AlertDialog.Builder(context);
                    alertBuilder.setCancelable(true);
                    alertBuilder.setMessage("Write calendar permission is necessary to write event!!!");
                    alertBuilder.setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() {
                        @TargetApi(Build.VERSION_CODES.JELLY_BEAN)
                        public void onClick(DialogInterface dialog, int which) {
                            ActivityCompat.requestPermissions((Activity)context, new String[]{Manifest.permission.WRITE_CALENDAR}, MY_PERMISSIONS_REQUEST_WRITE_CALENDAR);
                        }
                    });               
                } else {
                ActivityCompat.requestPermissions((Activity)context, new String[]{Manifest.permission.WRITE_CALENDAR}, MY_PERMISSIONS_REQUEST_WRITE_CALENDAR);
                }           
            }
    

    Android-M ie, API 23 introduced Runtime Permissions for reducing security flaws in android device, where users can now directly manage app permissions at runtime.so if the user denies a particular permission of your application you have to obtain it by asking the permission dialog that you mentioned in your query.

    So check before action ie, check you have permission to access the resource link and if your application doesn’t have that particular permission you can request the permission link and handle the the permissions request response like below.

    @Override
    public void onRequestPermissionsResult(int requestCode,
            String permissions[], int[] grantResults) {
        switch (requestCode) {
            case MY_PERMISSIONS_REQUEST_READ_CONTACTS: {
                // If request is cancelled, the result arrays are empty.
                if (grantResults.length > 0
                    && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
    
                    // permission was granted, yay! Do the
                    // contacts-related task you need to do.
    
                   } else {
    
                    // permission denied, boo! Disable the
                    // functionality that depends on this permission.
                }
                return;
            }
    
            // other 'case' lines to check for other
            // permissions this app might request
        }
    }
    

    So finally, It’s a good practice to go through behavior changes if you are planning to work with new versions to avoid force closes 🙂

    Permissions Best Practices.

    You can download official sample app here.

    I have used this wrapper (Recommended) written by google developers. Its super easy to use.

    https://github.com/googlesamples/easypermissions

    Function dealing with checking and ask for permission if required

    public void locationAndContactsTask() {
        String[] perms = { Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.READ_CONTACTS };
        if (EasyPermissions.hasPermissions(this, perms)) {
            // Have permissions, do the thing!
            Toast.makeText(this, "TODO: Location and Contacts things", Toast.LENGTH_LONG).show();
        } else {
            // Ask for both permissions
            EasyPermissions.requestPermissions(this, getString(R.string.rationale_location_contacts),
                    RC_LOCATION_CONTACTS_PERM, perms);
        }
    }
    

    Happy coding 🙂

    From Android Marshmallow(API 23) and above by default all dangerous permission ( as per official doc official doc) disabled. After installation when app open first time then you have to grant permission at Run Time.

    I achieved this following way:

    public class MarshMallowPermission {
    
        public static final int EXTERNAL_STORAGE_PERMISSION_REQUEST_CODE_BY_GALLERY = 0;
        public static final int EXTERNAL_STORAGE_PERMISSION_REQUEST_CODE_BY_CAMERA = 1;
        public static final int EXTERNAL_STORAGE_PERMISSION_REQUEST_CODE_BY_LOAD_PROFILE = 2;
        public static final int CAMERA_PERMISSION_REQUEST_CODE = 3;
        public static final int LOCATION_PERMISSION_REQUEST_CODE = 4;
        Activity activity;
        Context mContext;
    
        public MarshMallowPermission(Activity activity) {
            this.activity = activity;
            this.mContext = activity;
        }
    
        public boolean checkPermissionForExternalStorage(){
            int result = ContextCompat.checkSelfPermission(activity, Manifest.permission.WRITE_EXTERNAL_STORAGE);
            if (result == PackageManager.PERMISSION_GRANTED){
                return true;
            } else {
                return false;
            }
        }
    
        public boolean checkPermissionForCamera(){
            int result = ContextCompat.checkSelfPermission(activity, Manifest.permission.CAMERA);
            if (result == PackageManager.PERMISSION_GRANTED){
                return true;
            } else {
                return false;
            }
        }
    
        public boolean checkLocationPermission(){
    
            int result = ActivityCompat.checkSelfPermission(activity, Manifest.permission.ACCESS_FINE_LOCATION);
            if (result == PackageManager.PERMISSION_GRANTED){
                return true;
            } else {
                return false;
            }
        }
    
        public void requestPermissionForExternalStorage(int requestCode){
            if (ActivityCompat.shouldShowRequestPermissionRationale(activity, Manifest.permission.WRITE_EXTERNAL_STORAGE)){
                Toast.makeText(mContext.getApplicationContext(), "External Storage permission needed. Please allow in App Settings for additional functionality.", Toast.LENGTH_LONG).show();
            } else {
                ActivityCompat.requestPermissions(activity,new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},requestCode);
            }
        }
    
        public void requestPermissionForCamera(){
            if (ActivityCompat.shouldShowRequestPermissionRationale(activity, Manifest.permission.CAMERA)){
                Toast.makeText(mContext.getApplicationContext(), "Camera permission needed. Please allow in App Settings for additional functionality.", Toast.LENGTH_LONG).show();
            } else {
                ActivityCompat.requestPermissions(activity,new String[]{Manifest.permission.CAMERA},CAMERA_PERMISSION_REQUEST_CODE);
            }
        }
        public void requestPermissionForLocation(){
            if (ActivityCompat.shouldShowRequestPermissionRationale(activity, Manifest.permission.ACCESS_FINE_LOCATION) && ActivityCompat.shouldShowRequestPermissionRationale(activity, Manifest.permission.ACCESS_COARSE_LOCATION)){
                Toast.makeText(mContext.getApplicationContext(), "Location permission needed. Please allow in App Settings for additional functionality.", Toast.LENGTH_LONG).show();
            } else {
                ActivityCompat.requestPermissions(activity, new String[]{Manifest.permission.ACCESS_FINE_LOCATION,Manifest.permission.ACCESS_COARSE_LOCATION}, LOCATION_PERMISSION_REQUEST_CODE);
            }
        }
    }
    

    IN Your activity class:

     public class MainActivity extends AppCompatActivity{
    
       private MarshMallowPermission marshMallowPermission;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            Log.d("NavHome", "Oncreate_nav");
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            marshMallowPermission = new MarshMallowPermission(MainActivity.this);
    
    
    
            if (!marshMallowPermission.checkPermissionForExternalStorage()) {
                marshMallowPermission.requestPermissionForExternalStorage(MarshMallowPermission.EXTERNAL_STORAGE_PERMISSION_REQUEST_CODE_BY_LOAD_PROFILE);
            }
        }
    
        @Override
        public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
            super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    
            switch (requestCode) {
                case MarshMallowPermission.EXTERNAL_STORAGE_PERMISSION_REQUEST_CODE_BY_LOAD_PROFILE:
                    if (grantResults.length > 0
                            && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
    
                        //permission granted successfully
    
                    } else {
    
                     //permission denied
    
                    }
                    break;
        }
        }
    
    }
    

    I’m using this as a base Fragment class. I only ask for permissions from a fragment, but you could refactor it and make a similar Activity version.

    public class BaseFragment extends Fragment {
    
        private static final int PERMISSION_REQUEST_BLOCK_INTERNAL = 555;
        private static final String PERMISSION_SHARED_PREFERENCES = "permissions";
    
        @Override
        public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
            if (requestCode == PERMISSION_REQUEST_BLOCK_INTERNAL) {
                boolean allPermissionsGranted = true;
    
                for (int iGranting : grantResults) {
                    if (iGranting != PermissionChecker.PERMISSION_GRANTED) {
                        allPermissionsGranted = false;
                        break;
                    }
                }
    
                if (allPermissionsGranted && permissionBlock != null) {
                    permissionBlock.run();
                }
    
                permissionBlock = null;
            }
        }
    
        public void runNowOrAskForPermissionsFirst(String permission, Runnable block) {
            if (hasPermission(permission)) {
                block.run();
            } else if (!hasPermissionOrWillAsk(permission)) {
                permissionBlock = block;
                askForPermission(permission, PERMISSION_REQUEST_BLOCK_INTERNAL);
            }
        }
    
        public boolean hasPermissionOrWillAsk(String permission) {
            boolean hasPermission = hasPermission(permission);
            boolean hasAsked = hasPreviouslyAskedForPermission(permission);
            boolean shouldExplain = shouldShowRequestPermissionRationale(permission);
    
            return hasPermission || (hasAsked && !shouldExplain);
        }
    
        private boolean hasPermission(String permission) {
            return (ContextCompat.checkSelfPermission(getContext(), permission) == PackageManager.PERMISSION_GRANTED);
        }
    
        private boolean hasPreviouslyAskedForPermission(String permission) {
            SharedPreferences prefs = getContext().getSharedPreferences(PERMISSION_SHARED_PREFERENCES, Context.MODE_PRIVATE);
            return prefs.getBoolean(permission, false);
        }
    
        private void askForPermission(String permission, int requestCode) {
            SharedPreferences.Editor editor = getContext().getSharedPreferences(PERMISSION_SHARED_PREFERENCES, Context.MODE_PRIVATE).edit();
    
            editor.putBoolean(permission, true);
            editor.apply();
    
            requestPermissions(new String[] { permission }, requestCode);
        }
    }
    

    There are two key methods you should use:

    • hasPermissionOrWillAsk – Use this to see if a permission has been asked for and denies by a user who doesn’t want to be asked again. This is useful for disabling UI when the user has given their final answer about NOT wanting a feature.

    • runNowOrAskForPermissionsFirst – Use this to run some code that requires permissions. If the user has already granted permission, the code will run immediately. Otherwise, the code will run later if the user grants permission. Or not at all. It’s nice because you specify the code in one place.

    Here’s an example:

    mFragment.runNowOrAskForPermissionsFirst(Manifest.permission.ACCESS_FINE_LOCATION, new Runnable() {
        @Override
        public void run() {
            ...do something if we have permission...
        }
    });
    

    Happy to get feedback on this. Not that this specific example is a little simplified in that you also need to check to see if Location Services are enabled on the device. (That’s different than permissions.) Also, it only supports one permission at a time, but would be simple to modify if you need it to support more than one at a time.

    It may be a cleaner way. Add all your permissions in an array like

    private static final String[] INITIAL_PERMS={
                android.Manifest.permission.ACCESS_FINE_LOCATION,
                android.Manifest.permission.ACCESS_COARSE_LOCATION
        };
        private static final int INITIAL_REQUEST=1337;
    

    Whatever your permision is create method for each permision

    @RequiresApi(api = Build.VERSION_CODES.M)
    private boolean canAccessFineLocation() {
        return(hasPermission(Manifest.permission.ACCESS_FINE_LOCATION));
    }
    
    @RequiresApi(api = Build.VERSION_CODES.M)
    private boolean canAccessCoarseLocation() {
        return(hasPermission(Manifest.permission.ACCESS_COARSE_LOCATION));
    }
    
    @RequiresApi(api = Build.VERSION_CODES.M)
    private boolean hasPermission(String perm) {
        return(PackageManager.PERMISSION_GRANTED == checkSelfPermission(perm));
    }
    

    Call this method in onCreate

     if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M){
          if(!canAccessCoarseLocation() || !canAccessFineLocation()){
                requestPermissions(INITIAL_PERMS, INITIAL_REQUEST);
            }
     }
    

    Now override onRequestPermissionsResult

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
    
        if(requestCode == INITIAL_REQUEST){
            if (canAccessFineLocation() && canAccessCoarseLocation())  {
                //call your method
            }
            else {
                //show Toast or alert that this permissions is neccessary
            }
        }
    }
    

    For multiple permission at a time you can use this. This work for me.. I got another solution. if you give your targetSdkVersion bellow 22 it works for me. and it behavior as like getting permission from manifest.xml. Tested and works for me.

    final private int REQUEST_CODE_ASK_MULTIPLE_PERMISSIONS = 124;
    
        private void insertDummyContactWrapper() {
            List<String> permissionsNeeded = new ArrayList<String>();
    
            final List<String> permissionsList = new ArrayList<String>();
            if (!addPermission(permissionsList, Manifest.permission.ACCESS_FINE_LOCATION))
                permissionsNeeded.add("GPS");
            if (!addPermission(permissionsList, Manifest.permission.READ_CONTACTS))
                permissionsNeeded.add("Read Contacts");
            if (!addPermission(permissionsList, Manifest.permission.WRITE_CONTACTS))
                permissionsNeeded.add("Write Contacts");
    
            if (permissionsList.size() > 0) {
                if (permissionsNeeded.size() > 0) {
                    // Need Rationale
                    String message = "You need to grant access to " + permissionsNeeded.get(0);
                    for (int i = 1; i < permissionsNeeded.size(); i++)
                        message = message + ", " + permissionsNeeded.get(i);
                    showMessageOKCancel(message,
                            new DialogInterface.OnClickListener() {
                                @Override
                                public void onClick(DialogInterface dialog, int which) {
                                    requestPermissions(permissionsList.toArray(new String[permissionsList.size()]),
                                            REQUEST_CODE_ASK_MULTIPLE_PERMISSIONS);
                                }
                            });
                    return;
                }
                requestPermissions(permissionsList.toArray(new String[permissionsList.size()]),
                        REQUEST_CODE_ASK_MULTIPLE_PERMISSIONS);
                return;
            }
    
            insertDummyContact();
        }
    
        private boolean addPermission(List<String> permissionsList, String permission) {
            if (checkSelfPermission(permission) != PackageManager.PERMISSION_GRANTED) {
                permissionsList.add(permission);
                // Check for Rationale Option
                if (!shouldShowRequestPermissionRationale(permission))
                    return false;
            }
            return true;
        }
    
    
    
    
    
    
    @Override
        public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
            switch (requestCode) {
                case REQUEST_CODE_ASK_MULTIPLE_PERMISSIONS:
                    {
                    Map<String, Integer> perms = new HashMap<String, Integer>();
                    // Initial
                    perms.put(Manifest.permission.ACCESS_FINE_LOCATION, PackageManager.PERMISSION_GRANTED);
                    perms.put(Manifest.permission.READ_CONTACTS, PackageManager.PERMISSION_GRANTED);
                    perms.put(Manifest.permission.WRITE_CONTACTS, PackageManager.PERMISSION_GRANTED);
                    // Fill with results
                    for (int i = 0; i < permissions.length; i++)
                        perms.put(permissions[i], grantResults[i]);
                    // Check for ACCESS_FINE_LOCATION
                    if (perms.get(Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED
                            && perms.get(Manifest.permission.READ_CONTACTS) == PackageManager.PERMISSION_GRANTED
                            && perms.get(Manifest.permission.WRITE_CONTACTS) == PackageManager.PERMISSION_GRANTED) {
                        // All Permissions Granted
                        insertDummyContact();
                    } else {
                        // Permission Denied
                        Toast.makeText(MainActivity.this, "Some Permission is Denied", Toast.LENGTH_SHORT)
                                .show();
                    }
                    }
                    break;
                default:
                    super.onRequestPermissionsResult(requestCode, permissions, grantResults);
            }
        }
    

    For more details. Check bellow link

    https://inthecheesefactory.com/blog/things-you-need-to-know-about-android-m-permission-developer-edition/en

    There is a good library that can be used in case permissions need to be asked when permission is needed by a background service. Although a limitation of library is that it can not be used to just determine whether permissions are currently given to the app or not. It always asks the user if app doesn’t already have them.

    Do give it a try as it makes life simpler: Android Permissions

    To handle runtime permission google has provided a library project. You can check this from here https://github.com/googlesamples/easypermissions

    EasyPermissions is installed by adding the following dependency to your build.gradle file:

    dependencies {
    compile 'pub.devrel:easypermissions:0.3.0'
    }
    

    To begin using EasyPermissions, have your Activity (or Fragment) override the onRequestPermissionsResult method:

    public class MainActivity extends AppCompatActivity implements EasyPermissions.PermissionCallbacks {
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }
    
    @Override
    public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    
        // Forward results to EasyPermissions
        EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this);
    }
    
    @Override
    public void onPermissionsGranted(int requestCode, List<String> list) {
        // Some permissions have been granted
        // ...
    }
    
    @Override
    public void onPermissionsDenied(int requestCode, List<String> list) {
        // Some permissions have been denied
        // ...
    }
    }
    

    Here you will get a working example how this library works
    https://github.com/milon87/EasyPermission

      if (CommonMethod.isNetworkAvailable(MainActivity.this)) {
                        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                            int permissionCheck = ContextCompat.checkSelfPermission(MainActivity.this,
                                    android.Manifest.permission.CAMERA);
                            if (permissionCheck == PackageManager.PERMISSION_GRANTED) {
                                //showing dialog to select image
                                callFacebook();
                                Log.e("permission", "granted MarshMallow");
                            } else {
                                ActivityCompat.requestPermissions(MainActivity.this,
                                        new String[]{android.Manifest.permission.READ_EXTERNAL_STORAGE,
                                                android.Manifest.permission.WRITE_EXTERNAL_STORAGE, android.Manifest.permission.CAMERA}, 1);
                            }
                        } else {
                            Log.e("permission", "Not Required Less than MarshMallow Version");
                            callFacebook();
                        }
                    } else {
                        CommonMethod.showAlert("Internet Connectivity Failure", MainActivity.this);
                    }
    
    Android Babe is a Google Android Fan, All about Android Phones, Android Wear, Android Dev and Android Games Apps and so on.