23

Since Android Jelly Bean doesn't support the logs reading permission (according to this google io 2012 video and this one too ) , i would like to know if it's possible for rooted devices (or non-rooted devices) to be able to bypass this restriction and be able to read the logs.

How do i do that? Do i really need to make the app a system app, or is rooting enough?

inazaruk
  • 74,247
  • 24
  • 188
  • 156
android developer
  • 114,585
  • 152
  • 739
  • 1,270

4 Answers4

27

You can obtain the permission on a rooted device by executing the pm grant command from your app. Probably you will have to restart the app after that for the change to take effect, though:

String pname = getPackageName();
String[] CMDLINE_GRANTPERMS = { "su", "-c", null };
if (getPackageManager().checkPermission(android.Manifest.permission.READ_LOGS, pname) != 0) {
    Log.d(TAG, "we do not have the READ_LOGS permission!");
    if (android.os.Build.VERSION.SDK_INT >= 16) {
        Log.d(TAG, "Working around JellyBeans 'feature'...");
        try {
            // format the commandline parameter
            CMDLINE_GRANTPERMS[2] = String.format("pm grant %s android.permission.READ_LOGS", pname);
            java.lang.Process p = Runtime.getRuntime().exec(CMDLINE_GRANTPERMS);
            int res = p.waitFor();
            Log.d(TAG, "exec returned: " + res);
            if (res != 0)
                throw new Exception("failed to become root");
        } catch (Exception e) {
            Log.d(TAG, "exec(): " + e);
            Toast.makeText(context, "Failed to obtain READ_LOGS permission", Toast.LENGTH_LONG).show();
        }
    }
} else
    Log.d(TAG, "we have the READ_LOGS permission already!");

This code should be called from your onCreate(). Once the permission is granted, no more root powers are required.

P.S: The p.waitFor() blocks on the Superuser app, delaying your app start and potentially cause an ANR.

ge0rg
  • 1,816
  • 1
  • 26
  • 38
  • seems to work perfectly (tested on galaxy s3 with android 4.1.1 ) . only had to remember to set the targetSdk to 16 . thank you so much . do you also know how to enable gps using root ? if so , please answer it here: http://stackoverflow.com/questions/11373234/android-toggle-gps-on-root-devices – android developer Sep 28 '12 at 22:28
  • 2
    This approach _requires_ root. If you run `pm grant ...` without `su`, you will get the following output: `Operation not allowed: java.lang.SecurityException: Neither user 100xx nor current process has android.permission.GRANT_REVOKE_PERMISSIONS.` The GRANT_REVOKE_PERMISSIONS is also system-level, so you can not require it in the manifest. – ge0rg Jun 08 '13 at 13:45
  • 1
    this code should be executed outside UI thread... The best approach is to use an AsyncTask and show a dialog onPreExecute it, in order to make user know that the app is performing a task – BamsBamx Jun 03 '14 at 22:11
22

EDIT: It turns out that adb shell pm grant only works on emulators. Production devices do not allow shell to grant and revoke optional permissions.


You don't need to have root. The only thing you need to enable READ_LOGS to non-system applications is to have Android SDK installed.

Basically, you need to call:

adb shell pm grant <pkg.name> android.permission.READ_LOGS

Where <pkg.name> is your application's package name. This is possible because READ_LOGS is not only a "system" permission, but also a "development" permission (this term is introduced in JB). Which actually allows users to grant this permission to any application. No root required.

More information is available in this google groups thread with comments from Dianne Hackborn.

inazaruk
  • 74,247
  • 24
  • 188
  • 156
3

I've got around this on a rooted device by calling logcat with su and reading from stdout

... .getRuntime().exec("su -c logcat -d");
bara
  • 2,964
  • 2
  • 26
  • 24
1

There is another way to access all logs without the need for root permissions. You can use remote debugging. Take a look at the open source rootless Logcat app.

Anton Tananaev
  • 2,458
  • 1
  • 25
  • 48