How permission can be checked at runtime without throwing SecurityException?

AndroidSecurityPermissionsRuntime

Android Problem Overview


I design a function that may get/set a resource from SD and if not found from sd then take it from Asset and if possible write the asset back to SD
This function may check by method invocation if SD is mounted and accessible...

boolean bSDisAvalaible = Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED);

My designed function may be used from one app(project) to another (with or without android.permission.WRITE_EXTERNAL_STORAGE)

Then I would like to check if the current application has this particular permission without playing with SecurityException.

Does it exist a "nice" way to consult current defined permissions at runtime ?

Android Solutions


Solution 1 - Android

You can use Context.checkCallingorSelfPermission() function for this. Here is an example:

private boolean checkWriteExternalPermission()
{
    String permission = android.Manifest.permission.WRITE_EXTERNAL_STORAGE;
    int res = getContext().checkCallingOrSelfPermission(permission);
    return (res == PackageManager.PERMISSION_GRANTED);            
}

Solution 2 - Android

This is another solution as well

PackageManager pm = context.getPackageManager();
int hasPerm = pm.checkPermission(
    android.Manifest.permission.WRITE_EXTERNAL_STORAGE, 
	context.getPackageName());
if (hasPerm != PackageManager.PERMISSION_GRANTED) {
   // do stuff
}

Solution 3 - Android

You can also use this:

private boolean doesUserHavePermission()
{
    int result = context.checkCallingOrSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE);
    return result == PackageManager.PERMISSION_GRANTED;
}

Solution 4 - Android

Like Google documentation:

// Assume thisActivity is the current activity
int permissionCheck = ContextCompat.checkSelfPermission(thisActivity, Manifest.permission.WRITE_EXTERNAL_STORAGE);

Solution 5 - Android

Sharing my methods in case someone needs them:

 /** Determines if the context calling has the required permission
 * @param context - the IPC context
 * @param permissions - The permissions to check
 * @return true if the IPC has the granted permission
 */
public static boolean hasPermission(Context context, String permission) {

	int res = context.checkCallingOrSelfPermission(permission);
	
	Log.v(TAG, "permission: " + permission + " = \t\t" + 
	(res == PackageManager.PERMISSION_GRANTED ? "GRANTED" : "DENIED"));
	
	return res == PackageManager.PERMISSION_GRANTED;
	      
}

/** Determines if the context calling has the required permissions
 * @param context - the IPC context
 * @param permissions - The permissions to check
 * @return true if the IPC has the granted permission
 */
public static boolean hasPermissions(Context context, String... permissions) {

	boolean hasAllPermissions = true;
	
	for(String permission : permissions) {
        //you can return false instead of assigning, but by assigning you can log all permission values
		if (! hasPermission(context, permission)) {hasAllPermissions = false; }
	}
	
	return hasAllPermissions;

}

And to call it:

boolean hasAndroidPermissions = SystemUtils.hasPermissions(mContext, new String[] {
				android.Manifest.permission.ACCESS_WIFI_STATE,
				android.Manifest.permission.READ_PHONE_STATE,
				android.Manifest.permission.ACCESS_NETWORK_STATE,
				android.Manifest.permission.INTERNET,
		});

Solution 6 - Android

You should check for permissions in the following way (as described here Android permissions):

int result = ContextCompat.checkSelfPermission(getContext(), Manifest.permission.READ_PHONE_STATE);

then, compare your result to either:

result == PackageManager.PERMISSION_DENIED

or:

result == PackageManager.PERMISSION_GRANTED

Solution 7 - Android

Step 1 - add permission request

    String[] permissionArrays = new String[]{Manifest.permission.CAMERA, 
    Manifest.permission.WRITE_EXTERNAL_STORAGE};
    int REQUEST_CODE = 101;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            requestPermissions(permissionArrays, REQUEST_CODE );
        } else {
             // if already permition granted
            // PUT YOUR ACTION (Like Open cemara etc..)
        }
    }
    
    

Step 2 - Handle Permission result

     @Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
    super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    boolean openActivityOnce = true;
    boolean openDialogOnce = true;
    if (requestCode == REQUEST_CODE ) {
        for (int i = 0; i < grantResults.length; i++) {
            String permission = permissions[i];

            isPermitted = grantResults[i] == PackageManager.PERMISSION_GRANTED;

            if (grantResults[i] == PackageManager.PERMISSION_DENIED) {
                // user rejected the permission
                
            }else {
                //  user grant the permission
                // you can perfome your action 
            }
        }
    }
}
    

Solution 8 - Android

The code which works fine for me is :-

  final int MY_PERMISSIONS_REQUEST_WRITE_EXTERNAL_STORAGE = 102;
  if ((ContextCompat.checkSelfPermission(getActivity(),Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED)) {

                requestPermissions(new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},
                        MY_PERMISSIONS_REQUEST_WRITE_EXTERNAL_STORAGE);
            } else {
	    // user already provided permission
                // perform function for what you want to achieve
     }

@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {

    boolean canUseExternalStorage = false;

    switch (requestCode) {
        case MY_PERMISSIONS_REQUEST_WRITE_EXTERNAL_STORAGE: {
            if (grantResults.length > 0
                    && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                canUseExternalStorage = true;
            }

            if (!canUseExternalStorage) {
                Toast.makeText(getActivity(), "Cannot use this feature without requested permission", Toast.LENGTH_SHORT).show();
            } else {
                // user now provided permission
                // perform function for what you want to achieve
            }
        }
      }
 }

Solution 9 - Android

if ((ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) && (ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) && (ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED)) {

	if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {

		requestPermissions(new String[]{Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.CAMERA},
				MY_PERMISSIONS_REQUEST_WRITE_EXTERNAL_STORAGE);
	}
} 

Solution 10 - Android

Check Permissions In KOTLIN (RunTime)

In Manifest: (android.permission.WRITE_EXTERNAL_STORAGE)

    fun checkPermissions(){

      var permission_array=arrayOf(android.Manifest.permission.WRITE_EXTERNAL_STORAGE)
      if((ContextCompat.checkSelfPermission(this,permission_array[0]))==PackageManager.PERMI   SSION_DENIED){
        requestPermissions(permission_array,0)
      }
    }

    override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<out String>, grantResults: IntArray) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults)

          if(requestCode==0 && grantResults[0]==PackageManager.PERMISSION_GRANTED){

       //Do Your Operations Here

        ---------->
         //


          }
    }

Solution 11 - Android

Enable GPS location Android Studio

  1. Add permission entry in AndroidManifest.Xml

  1. MapsActivity.java

     public class MapsActivity extends FragmentActivity implements OnMapReadyCallback {
    
     private GoogleMap mMap;
     private Context context;
     private static final int PERMISSION_REQUEST_CODE = 1;
     Activity activity;
     /**
      * ATTENTION: This was auto-generated to implement the App Indexing API.
      * See https://g.co/AppIndexing/AndroidStudio for more information.
      */
     private GoogleApiClient client;
    
     @Override
     protected void onCreate(Bundle savedInstanceState) {
         context = getApplicationContext();
         activity = this;
         super.onCreate(savedInstanceState);
         requestPermission();
         checkPermission();
         setContentView(R.layout.activity_maps);
         // Obtain the SupportMapFragment and get notified when the map is ready to be used.
         SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
                 .findFragmentById(R.id.map);
         mapFragment.getMapAsync(this);
    
     }
    
     @Override
     public void onMapReady(GoogleMap googleMap) {
         mMap = googleMap;
         LatLng location = new LatLng(0, 0);
         mMap.addMarker(new MarkerOptions().position(location).title("Marker in Bangalore"));
         mMap.moveCamera(CameraUpdateFactory.newLatLng(location));
         mMap.setMyLocationEnabled(true);
     }
    
     private void requestPermission() {
         if (ActivityCompat.shouldShowRequestPermissionRationale(activity, Manifest.permission.ACCESS_FINE_LOCATION)) {
             Toast.makeText(context, "GPS permission allows us to access location data. Please allow in App Settings for additional functionality.", Toast.LENGTH_LONG).show();
         } else {
             ActivityCompat.requestPermissions(activity, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, PERMISSION_REQUEST_CODE);
         }
     }
    
     private boolean checkPermission() {
         int result = ContextCompat.checkSelfPermission(context, Manifest.permission.ACCESS_FINE_LOCATION);
         if (result == PackageManager.PERMISSION_GRANTED) {
             return true;
         } else {
             return false;
         }
     }
    

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionEmmanuel DevauxView Question on Stackoverflow
Solution 1 - AndroidinazarukView Answer on Stackoverflow
Solution 2 - Androiduser123321View Answer on Stackoverflow
Solution 3 - AndroidMrAppaView Answer on Stackoverflow
Solution 4 - AndroidbeniView Answer on Stackoverflow
Solution 5 - AndroidhtafoyaView Answer on Stackoverflow
Solution 6 - AndroidboxView Answer on Stackoverflow
Solution 7 - AndroidJaydeep DobariyaView Answer on Stackoverflow
Solution 8 - AndroidSanoop SurendranView Answer on Stackoverflow
Solution 9 - Androiddhaval malaviaView Answer on Stackoverflow
Solution 10 - AndroidAnkush ShrivastavaView Answer on Stackoverflow
Solution 11 - AndroidNaveen SharmaView Answer on Stackoverflow