Android Jelly Bean はログの読み取り許可をサポートしていないため(この google io 2012 ビデオとこれも)、ルート化されたデバイス (またはルート化されていないデバイス) がこれをバイパスできるかどうかを知りたい制限し、ログを読み取ることができます。
それ、どうやったら出来るの?本当にアプリをシステムアプリにする必要がありますか、それともルート化で十分ですか?
Android Jelly Bean はログの読み取り許可をサポートしていないため(この google io 2012 ビデオとこれも)、ルート化されたデバイス (またはルート化されていないデバイス) がこれをバイパスできるかどうかを知りたい制限し、ログを読み取ることができます。
それ、どうやったら出来るの?本当にアプリをシステムアプリにする必要がありますか、それともルート化で十分ですか?
アプリから pm grant コマンドを実行することで、root 化されたデバイスで権限を取得できます。ただし、変更を有効にするには、その後アプリを再起動する必要があります。
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!");
このコードは onCreate() から呼び出す必要があります。許可が付与されると、それ以上の root 権限は必要ありません。
PS: Superuser アプリで p.waitFor() がブロックされ、アプリの起動が遅れ、ANR が発生する可能性があります。
編集:adb shell pm grant
エミュレータでのみ機能することがわかりました。shell
実稼働デバイスでは、オプションのアクセス許可を付与および取り消すことはできません。
ルートを持つ必要はありません。非システム アプリケーションに対して READ_LOGS を有効にするために必要なのは、Android SDK をインストールすることだけです。
基本的に、次のように呼び出す必要があります。
adb shell pm grant <pkg.name> android.permission.READ_LOGS
<pkg.name>
アプリケーションのパッケージ名はどこにありますか。これが可能なのは、READ_LOGS が「システム」パーミッションであるだけでなく、「開発」パーミッションでもあるためです (この用語は JB で導入されました)。これにより、ユーザーは実際にこの許可を任意のアプリケーションに付与できます。ルートは必要ありません。
詳細については、Dianne Hackborn からのコメントを含むこのGoogle グループ スレッドを参照してください。
ルート化されたデバイスでlogcatを呼び出しsu
てstdoutから読み取ることで、これを回避しました
... .getRuntime().exec("su -c logcat -d");