READ_LOGS permission on Jelly Bean (api 16)
Asked Answered
V

4

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?

Veljkov answered 12/7, 2012 at 22:26 Comment(5)
It is not possible to be a system app unless you have the manufacturers key or root the device.Heuer
everything still seems to work on the emulator. anyone tested read_logs on a real device with JB?Guggle
that's because i couldn't understand what you meant . sorry . i really didn't mean to frustrate you.Veljkov
Do you want to read your app's logs, or the whole system's logs?Achlorhydria
the whole system logs . that's why i say that if a root (or being a system app) is needed, so be it.Veljkov
D
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.

Delacourt answered 28/9, 2012 at 15:26 Comment(3)
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: #11373734Veljkov
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.Delacourt
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 taskInexorable
L
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.

Libidinous answered 17/7, 2012 at 6:57 Comment(5)
interesting . when you call this command , will it show anything to the end user? have you tested it out on a JB version ?Veljkov
Yes, I did test it. It doesn't show anything to end-user. This is moslty a developer thing, not for regular users.Libidinous
so there is no way to read logs , even on root devices? surely there is a way , no?Veljkov
Emulators only! I just set that on my Nexus 6 and I don't have root!Kelwunn
Would an app using this code pass Google Play malicious spam filter?Unsubstantial
L
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");
Lincolnlincolnshire answered 14/5, 2013 at 15:0 Comment(1)
this is a shorter version of the first answer: https://mcmap.net/q/557703/-read_logs-permission-on-jelly-bean-api-16 , but it should work too.Veljkov
S
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.

Spirituality answered 5/7, 2016 at 2:46 Comment(8)
Interesting. It uses the adb tool while connected to the PC to enable remote access. But then what does it do? Does the app itself connect to this port, and then just read from it somehow? how?Veljkov
Yes, the app connects to local adb daemon on the phone and reads logs from there directly.Spirituality
How does it do it?Veljkov
Via network connection to "localhost" on the phone. When you enable remote debugging, phone starts to listen for TCP connections. Now you can connect to the port it listens on, and use ADB protocol to send commands, including the command to read logs.Spirituality
Interesting. Can you please show a link about how to do it?Veljkov
Well, you can take a look at the source code of the app. It's pretty simple.Spirituality
Do you know in which file there?Veljkov
It's in the MainActivity. Actual protocol implementation is is adblib library.Spirituality

© 2022 - 2024 — McMap. All rights reserved.