READ_LOGS permission on Jelly Bean (api 16)

2019-01-02 23:35发布

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?

4条回答
等我变得足够好
2楼-- · 2019-01-02 23:50

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.

查看更多
聊天终结者
3楼-- · 2019-01-03 00:02

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.

查看更多
ら.Afraid
4楼-- · 2019-01-03 00:04

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

... .getRuntime().exec("su -c logcat -d");
查看更多
迷人小祖宗
5楼-- · 2019-01-03 00:07

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.

查看更多
登录 后发表回答