我的应用程序有一个特定的功能,只能在根可用的设备上工作。与其让这个特性在使用时失败(然后向用户显示适当的错误消息),我更希望能够先静默地检查根目录是否可用,如果不可用,则首先隐藏相应的选项。
有办法做到这一点吗?
我的应用程序有一个特定的功能,只能在根可用的设备上工作。与其让这个特性在使用时失败(然后向用户显示适当的错误消息),我更希望能够先静默地检查根目录是否可用,如果不可用,则首先隐藏相应的选项。
有办法做到这一点吗?
当前回答
一些用于设置系统属性ro的修改版本。Modversion用于此目的。事情似乎已经发生了变化;我几个月前在TheDude上的构建是这样的:
cmb@apollo:~$ adb -d shell getprop |grep build
[ro.build.id]: [CUPCAKE]
[ro.build.display.id]: [htc_dream-eng 1.5 CUPCAKE eng.TheDudeAbides.20090427.235325 test-keys]
[ro.build.version.incremental]: [eng.TheDude.2009027.235325]
[ro.build.version.sdk]: [3]
[ro.build.version.release]: [1.5]
[ro.build.date]: [Mon Apr 20 01:42:32 CDT 2009]
[ro.build.date.utc]: [1240209752]
[ro.build.type]: [eng]
[ro.build.user]: [TheDude]
[ro.build.host]: [ender]
[ro.build.tags]: [test-keys]
[ro.build.product]: [dream]
[ro.build.description]: [kila-user 1.1 PLAT-RC33 126986 ota-rel-keys,release-keys]
[ro.build.fingerprint]: [tmobile/kila/dream/trout:1.1/PLAT-RC33/126986:user/ota-rel-keys,release-keys]
[ro.build.changelist]: [17615# end build properties]
另一方面,来自1.5 SDK的模拟器,运行1.5镜像,也有根,可能类似于Android Dev Phone 1(你可能想要允许),并有这个:
cmb@apollo:~$ adb -e shell getprop |grep build
[ro.build.id]: [CUPCAKE]
[ro.build.display.id]: [sdk-eng 1.5 CUPCAKE 148875 test-keys]
[ro.build.version.incremental]: [148875]
[ro.build.version.sdk]: [3]
[ro.build.version.release]: [1.5]
[ro.build.date]: [Thu May 14 18:09:10 PDT 2009]
[ro.build.date.utc]: [1242349750]
[ro.build.type]: [eng]
[ro.build.user]: [android-build]
[ro.build.host]: [undroid16.mtv.corp.google.com]
[ro.build.tags]: [test-keys]
[ro.build.product]: [generic]
[ro.build.description]: [sdk-eng 1.5 CUPCAKE 148875 test-keys]
[ro.build.fingerprint]: [generic/sdk/generic/:1.5/CUPCAKE/148875:eng/test-keys]
至于零售构建,我手头没有,但在site:xda developers.com下的各种搜索提供了大量信息。这是荷兰的G1, ro。build。tags没有test-key,我认为这可能是最可靠的属性。
其他回答
这确实是一个有趣的问题,到目前为止还没有人获奖。我使用以下代码:
boolean isRooted() {
try {
ServerSocket ss = new ServerSocket(81);
ss.close();
return true;
} catch (Exception e) {
// not sure
}
return false;
}
代码当然不是无懈可击的,因为网络可能不可用,所以会出现异常。如果该方法返回true,则99%可以确定,否则只有50%不确定。网络权限也可能破坏解决方案。
下面是一个类,它将以三种方式之一检查Root。
/** @author Kevin Kowalewski */
public class RootUtil {
public static boolean isDeviceRooted() {
return checkRootMethod1() || checkRootMethod2() || checkRootMethod3();
}
private static boolean checkRootMethod1() {
String buildTags = android.os.Build.TAGS;
return buildTags != null && buildTags.contains("test-keys");
}
private static boolean checkRootMethod2() {
String[] paths = { "/system/app/Superuser.apk", "/sbin/su", "/system/bin/su", "/system/xbin/su", "/data/local/xbin/su", "/data/local/bin/su", "/system/sd/xbin/su",
"/system/bin/failsafe/su", "/data/local/su", "/su/bin/su"};
for (String path : paths) {
if (new File(path).exists()) return true;
}
return false;
}
private static boolean checkRootMethod3() {
Process process = null;
try {
process = Runtime.getRuntime().exec(new String[] { "/system/xbin/which", "su" });
BufferedReader in = new BufferedReader(new InputStreamReader(process.getInputStream()));
if (in.readLine() != null) return true;
return false;
} catch (Throwable t) {
return false;
} finally {
if (process != null) process.destroy();
}
}
}
另外两个方法,如果你想检查一个设备在你的应用程序中是否具有根功能:
检查是否存在“su”二进制文件:从Runtime.getRuntime().exec()运行"which su" 在/system/app/ SuperUser.apk目录下查找SuperUser.apk
http://code.google.com/p/roottools/
如果你不想使用jar文件,请使用下面的代码:
public static boolean findBinary(String binaryName) {
boolean found = false;
if (!found) {
String[] places = { "/sbin/", "/system/bin/", "/system/xbin/",
"/data/local/xbin/", "/data/local/bin/",
"/system/sd/xbin/", "/system/bin/failsafe/", "/data/local/" };
for (String where : places) {
if (new File(where + binaryName).exists()) {
found = true;
break;
}
}
}
return found;
}
程序将尝试查找su文件夹:
private static boolean isRooted() {
return findBinary("su");
}
例子:
if (isRooted()) {
textView.setText("Device Rooted");
} else {
textView.setText("Device Unrooted");
}
在rootbox中使用我的库非常简单。检查所需的代码如下:
//Pass true to <Shell>.start(...) call to run as superuser
Shell shell = null;
try {
shell = Shell.start(true);
} catch (IOException exception) {
exception.printStackTrace();
}
if (shell == null)
// We failed to execute su binary
return;
if (shell.isRoot()) {
// Verified running as uid 0 (root), can continue with commands
...
} else
throw Exception("Unable to gain root access. Make sure you pressed Allow/Grant in superuser prompt.");