Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to PROPERLY check android permission dynamically

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.

like image 732
David T. Avatar asked Aug 23 '13 01:08

David T.


People also ask

How do I check if permission is granted Android?

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.

How do I ask for runtime permissions on Android?

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.

How can I tell if an Android user is denied permission?

The method shouldShowRequestPermissionRationale() can be used to check whether the user selected the 'never asked again' option and denied the permission.

How do I set permissions in Android programmatically?

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.


2 Answers

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.

like image 54
dst Avatar answered Sep 30 '22 14:09

dst


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;
}
like image 23
Phil Avatar answered Sep 30 '22 16:09

Phil