21

I have to programmatically retrieve permissions from the manifest.xml of an android application and I don't know how to do it.

I read the post here but I am not entirely satisfied by the answers. I guess there should be a class in the android API which would allow to retrieve information from the manifest.

Thank you.

Community
  • 1
  • 1
Alexis Le Compte
  • 277
  • 1
  • 2
  • 12

6 Answers6

28

You can get an application's requested permissions (they may not be granted) using PackageManager:

PackageInfo info = getPackageManager().getPackageInfo(context.getPackageName(), PackageManager.GET_PERMISSIONS);
String[] permissions = info.requestedPermissions;//This array contains the requested permissions.

I have used this in a utility method to check if the expected permission is declared:

//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;
}
Phil
  • 35,089
  • 23
  • 123
  • 159
  • That is not exactly what I had asked for, but it led me to find a way of doing what I wanted using most of the code suggested, and without having to parse the manifest. In the OP, I had also said that I wanted to avoid the solutions presented elsewhere which mainly consisted in parsing the manifest. – Alexis Le Compte Sep 09 '16 at 14:20
  • When I used .equals on line 8 in your code it always returned false, so I had to change it from p.equals to p.contains and then it worked perfect. – Wraithious Jun 29 '18 at 05:28
  • 1
    Can the OP post what code he ended up actually using since this answer isn't really what was asked? – robross0606 Jul 03 '18 at 19:43
17

Here's a useful utility method that does just that.

public static String[] retrievePermissions(Context context) {
    try {
        return context
                .getPackageManager()
                .getPackageInfo(context.getPackageName(), PackageManager.GET_PERMISSIONS)
                .requestedPermissions;
    } catch (PackageManager.NameNotFoundException e) {
         return new String[0];
         // Better to throw a custom exception since this should never happen unless the API has changed somehow.
    }
}

You can get a working class from this gist.

Anis LOUNIS
  • 4,472
  • 5
  • 30
  • 58
  • Sorry if this question is too stupid, but I was wondering where do I input the manifest.xml file in this code? (I am trying to extract permissions from a third party app) – misteeque Mar 29 '22 at 21:30
  • 1
    @misteeque this code doesn't rely on manifest.xml – Anis LOUNIS Mar 30 '22 at 13:49
  • Thanks! Can this be used for an external APK file? – misteeque Mar 30 '22 at 13:53
  • @misteeque I wouldn't think so, and honestly don't think I understand your use-case. Are you trying to list the permissions of some other app running on the same device? – Anis LOUNIS Mar 30 '22 at 16:11
  • Well, in short I am doing a research on finding information control flow vulnerabilities when two apps communicate via intents. So for my use case, I'd just like to input an apk file in a traditional java program and list down all the permissions it has, do the same for another apk, and so forth. This is followed by comparing their permissions, etc. – misteeque Mar 30 '22 at 18:15
  • @misteeque just look up some android manifest parsers, or write your own , shouldn't be that hard. – Anis LOUNIS Mar 30 '22 at 22:51
  • Thanks! Yeah, will do that. Just wanted to ensure I'm not re-inventing the wheel before I start :) – misteeque Mar 31 '22 at 08:03
3

Use this:

public static String getListOfPermissions(final Context context)
{
    String _permissions = "";

    try
    {
        final AssetManager _am = context.createPackageContext(context.getPackageName(), 0).getAssets();
        final XmlResourceParser _xmlParser = _am.openXmlResourceParser(0, "AndroidManifest.xml");
        int _eventType = _xmlParser.getEventType();
        while (_eventType != XmlPullParser.END_DOCUMENT)
        {
            if ((_eventType == XmlPullParser.START_TAG) && "uses-permission".equals(_xmlParser.getName()))
            {
                for (byte i = 0; i < _xmlParser.getAttributeCount(); i ++)
                {
                    if (_xmlParser.getAttributeName(i).equals("name"))
                    {
                        _permissions += _xmlParser.getAttributeValue(i) + "\n";
                    }
                }
            }
            _eventType = _xmlParser.nextToken();
        }
        _xmlParser.close(); // Pervents memory leak.
    }
    catch (final XmlPullParserException exception)
    {
        exception.printStackTrace();
    }
    catch (final PackageManager.NameNotFoundException exception)
    {
        exception.printStackTrace();
    }
    catch (final IOException exception)
    {
        exception.printStackTrace();
    }

    return _permissions;
}
// Test: Log.wtf("test", getListOfPermissions(getApplicationContext()));
Yousha Aleayoub
  • 3,939
  • 4
  • 49
  • 62
  • 2
    Hi. Thanks for the answer, although it is a 2 years old question which already had an answer. Regarding your answer, I would still use the accepted answer as a basis for a solution as it uses the class designed to retrieve info about the application. I believe this is more reliable than parsing the manifest, which has a structure that could potentially change depending on the targeted version of android. It is also shorter. By the way, did you downvote the OP? – Alexis Le Compte Sep 09 '16 at 14:27
  • 1
    @AlexisLeCompte No. – Yousha Aleayoub Sep 09 '16 at 18:47
  • Rather than checking different permissions for each different app you must define in code, this one is really convenient, especially with Android 6 and above. Saved my day and got an upvote! :-) – Anticro Nov 15 '16 at 12:51
  • Idea is great, but it is **not working!** No `` found, even the manifest contains many of them. Have you actually tested your code? I would love to make it work, since other solutions do not offer to retrieve all information from manifest file. Please test your code and make necessary adjustments to make it work. Thank you! – Ωmega Mar 14 '18 at 13:47
  • What if we're using other modules that have their own manifest file? I think it's better to go the by design way and use the api. – Anis LOUNIS Jul 24 '18 at 21:39
0

If anyone is looking for a short Kotlin Version

fun Manifest.getDeclaredPermissions(context: Context): Array<String> {
    return context.packageManager.getPackageInfo(context.packageName, PackageManager.GET_PERMISSIONS).requestedPermissions
}
OhhhThatVarun
  • 3,431
  • 2
  • 21
  • 43
-4

I have a simple C# code, "using System.Xml"

private void ShowPermissions()
   {
    XmlDocument doc = new XmlDocument();
    doc.Load("c:\\manifest.xml");

    XmlNodeList nodeList = doc.GetElementsByTagName("uses-permission");


    foreach(XmlNode node in nodeList)
    {
        XmlAttributeCollection Attr = node.Attributes;
        string Permission=Attr["android:permission"].Value;

        MessageBox.Show(Permission);
    }
}
-5

You can used this function:

public boolean hasPermission(Context ctx,String permission){
        return ctx.getPackageManager().checkPermission(permission, ctx.getPackageName())
               == PackageManager.PERMISSION_GRANTED); 
}

Usage:

hasPermission(this,Manifest.permission.GET_ACCOUNTS);
crm27
  • 63
  • 8
  • 3
    This is a very bad answer. Because the question wasn't about to check the system permission (if it was granted). The question is about the permissions list which are declared in `AndroidManifest.xml` – StefMa Jan 15 '16 at 14:05
  • This is to check if the runtime permission is available or not. The question is to check if the permission is added to the manifest or not. – Keval Patel Jan 23 '17 at 13:16