Multiple choice question:
which of the follow will correctly check whether or not an application has a certain permission declared in their AndroidManifest.xml?
getContext().checkCallingOrSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED
or
getContext().getPackageManager().checkPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE, getContext().getPackageName()) == PackageManager.PERMISSION_GRANTED
Basically, i got scared from the android documentation of what checkCallingOrSelfPermission
claims -> it grants an IPC permissions if you just check for it?? what does that even mean?
http://developer.android.com/reference/android/content/Context.html#checkCallingOrSelfPermission(java.lang.String)
So any explanation on the true differences would be awesome :D
*note: I am giving this code in a library, so i am only allowed to check permissions at runtime, unless you know of a better way.
checkSelfPermission(activity, Manifest. permission. X) checks if any permission is already granted, if you check out other answers they do the same, and rest of the code asks for the permissions not granted.
Requesting Android Runtime Permissions For this the following method needs to be called on every permission. checkSelfPermission(String perm); It returns an integer value of PERMISSION_GRANTED or PERMISSION_DENIED.
The method shouldShowRequestPermissionRationale() can be used to check whether the user selected the 'never asked again' option and denied the permission.
You need to declare the permissions in the manifest file first before you request for them programmatically. refer this for more information. declaring the permission in the manifest file is static type declaration by which your os know what kind of permission your app might require.
From my understanding (which might be wrong, as I did not work much with IPC, yet):
Given that your code is executed from another application (e.g. your library was not compiled into the application, but exposed to a third party using Binder
or something like that), you can use checkCallingPermission
to check if the third party application has the given permission, while checkCallingOrSelfPermission
includes permissions from the application your library was compiled into.
You need to handle caller's permissions separately as you could leak permissions to other applications when checking the own permissions, too. From the security tips:
Do not leak permission-protected data. This occurs when your app exposes data over IPC that is only available because it has a specific permission, but does not require that permission of any clients of it’s IPC interface.
[...]
If providing an interface that does require access controls, use
checkCallingPermission()
to verify whether the caller has a required permission. This is especially important before accessing a service on behalf of the caller, as the identify of your application is passed to other interfaces.
The package manager way you describe checks only the permissions of the application your library was compiled into.
So, if your code is not executed from another process you probably don't have to care about the difference. Else, use the package manager way or clear the calling identity stuff if you're interested in whether you can perform an task; additionally check the caller's permissions if you wish to check if the calling process could perform the task, too.
You can use this method:
//for example, permission can be "android.permission.WRITE_EXTERNAL_STORAGE"
public boolean hasPermission(String permission)
{
try {
PackageInfo info = getPackageManager().getPackageInfo(context.getPackageName(), PackageManager.GET_PERMISSIONS);
if (info.requestedPermissions != null) {
for (String p : info.requestedPermissions) {
if (p.equals(permission)) {
return true;
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
return false;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With