如何在运行时检查权限而不引发 SecurityException?

我设计了一个函数,它可以从 SD 获取/设置一个资源,如果在 SD 中没有找到,那么从 Asset 中获取,如果可能的话,将资源写回 SD
这个函数可以通过方法调用检查 SD 是否安装并可访问..。

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

我设计的函数可以从一个应用程序(项目)用到另一个应用程序(有或没有 android.permission. WRITE _ EXTERNAL _ STORAGE)

然后,我想检查当前应用程序是否具有这个特定的权限,而不使用 SecurityException。

它是否存在一种在运行时查询当前定义的权限的“好”方法?

137581 次浏览

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

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
}

You can also use this:

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

Like Google documentation:

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

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

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

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

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

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


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




}
}

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