本文出自RxRead的博客(http://www.cnblogs.com/waylife/)

由于项目需要root安装软件,并且希望在合适的时候引导用户去开启root安装,故需要检测手机是否root。

最基本的判断如下,直接运行一个底层命令。(参考https://github.com/Trinea/android-common/blob/master/src/cn/trinea/android/common/util/ShellUtils.java)

也可参考csdn http://blog.csdn.net/fm9333/article/details/12752415

/*** check whether has root permission* * @return*/public static boolean checkRootPermission() {return execCommand("echo root", true, false).result == 0;}/*** execute shell commands* * @param commands*            command array* @param isRoot*            whether need to run with root* @param isNeedResultMsg*            whether need result msg* @return <ul>*         <li>if isNeedResultMsg is false, {@link CommandResult#successMsg}*         is null and {@link CommandResult#errorMsg} is null.</li>*         <li>if {@link CommandResult#result} is -1, there maybe some*         excepiton.</li>*         </ul>*/public static CommandResult execCommand(String[] commands, boolean isRoot,boolean isNeedResultMsg) {int result = -1;if (commands == null || commands.length == 0) {return new CommandResult(result, null, null);}Process process = null;BufferedReader successResult = null;BufferedReader errorResult = null;StringBuilder successMsg = null;StringBuilder errorMsg = null;DataOutputStream os = null;try {process = Runtime.getRuntime().exec(isRoot ? COMMAND_SU : COMMAND_SH);os = new DataOutputStream(process.getOutputStream());for (String command : commands) {if (command == null) {continue;}// donnot use os.writeBytes(commmand), avoid chinese charset// erroros.write(command.getBytes());os.writeBytes(COMMAND_LINE_END);os.flush();}os.writeBytes(COMMAND_EXIT);os.flush();result = process.waitFor();// get command resultif (isNeedResultMsg) {successMsg = new StringBuilder();errorMsg = new StringBuilder();successResult = new BufferedReader(new InputStreamReader(process.getInputStream()));errorResult = new BufferedReader(new InputStreamReader(process.getErrorStream()));String s;while ((s = successResult.readLine()) != null) {successMsg.append(s);}while ((s = errorResult.readLine()) != null) {errorMsg.append(s);}}} catch (IOException e) {e.printStackTrace();} catch (Exception e) {e.printStackTrace();} finally {try {if (os != null) {os.close();}if (successResult != null) {successResult.close();}if (errorResult != null) {errorResult.close();}} catch (IOException e) {e.printStackTrace();}if (process != null) {process.destroy();}}return new CommandResult(result, successMsg == null ? null: successMsg.toString(), errorMsg == null ? null: errorMsg.toString());}/*** result of command,* <ul>* <li>{@link CommandResult#result} means result of command, 0 means normal,* else means error, same to excute in linux shell</li>* <li>{@link CommandResult#successMsg} means success message of command* result</li>* <li>{@link CommandResult#errorMsg} means error message of command result</li>* </ul>* * @author Trinea 2013-5-16*/public static class CommandResult {/** result of command **/public int result;/** success message of command result **/public String successMsg;/** error message of command result **/public String errorMsg;public CommandResult(int result) {this.result = result;}public CommandResult(int result, String successMsg, String errorMsg) {this.result = result;this.successMsg = successMsg;this.errorMsg = errorMsg;}}    /*** execute shell command, default return result msg* * @param command*            command* @param isRoot*            whether need to run with root* @return* @see ShellUtils#execCommand(String[], boolean, boolean)*/public static CommandResult execCommand(String command, boolean isRoot) {return execCommand(new String[] { command }, isRoot, true);}

但是这会带来一个问题,每次判断是否root都会弹出一个root请求框。这是十分不友好的一种交互方式,而且,用户如果选择取消,有部分手机是判断为非root的。

这是方法一。交互不友好,而且有误判。

在这个情况下,为了不弹出确认框,考虑到一般root手机都会有一些的特殊文件夹,比如/system/bin/su,/system/xbin/su,里面存放有相关的权限控制文件。

因此只要手机中有一个文件夹存在就判断这个手机root了。

然后经过测试,这种方法在大部分手机都可行。

代码如下:

/** 判断是否具有ROOT权限 ,此方法对有些手机无效,比如小米系列 */public static boolean isRoot() {boolean res = false;try {if ((!new File("/system/bin/su").exists())&& (!new File("/system/xbin/su").exists())) {res = false;} else {res = true;};} catch (Exception e) {res = false;}return res;}

后来测试的过程中发现部分国产,比如小米系列,有这个文件夹,但是系统是未root的,判断成了已root。经过分析,这是由于小米有自身的权限控制系统而导致。

考虑到小米手机有大量的用户群,这个问题必须解决,所以不得不寻找第三种方案。

从原理着手,小米手机无论是否root,应该都是具有相关文件的。但是无效的原因应该是,文件设置了相关的权限。导致用户组无法执行相关文件。

从这个角度看,就可以从判断文件的权限入手。

先看下linux的文件权限吧。

linux文件权限详细可参考《鸟叔的linux私房菜》http://vbird.dic.ksu.edu.tw/linux_basic/0210filepermission.php#filepermission_perm

只需要在第二种方法的基础上,再另外判断文件拥有者对这个文件是否具有可执行权限(第4个字符的状态),就基本可以确定手机是否root了。

在已root手机上(三星i9100 android 4.4),文件权限(x或者s,s权限,可参考http://blog.chinaunix.net/uid-20809581-id-3141879.html)如下

未root手机,大部分手机没有这两个文件夹,小米手机有这个文件夹。未root小米手机权限如下(由于手头暂时没有小米手机,过几天补上,或者有同学帮忙补上,那真是感激不尽)。

【等待补充图片】

代码如下:

/** 判断手机是否root,不弹出root请求框<br/> */public static boolean isRoot() {String binPath = "/system/bin/su";String xBinPath = "/system/xbin/su";if (new File(binPath).exists() && isExecutable(binPath))return true;if (new File(xBinPath).exists() && isExecutable(xBinPath))return true;return false;}private static boolean isExecutable(String filePath) {Process p = null;try {p = Runtime.getRuntime().exec("ls -l " + filePath);// 获取返回内容BufferedReader in = new BufferedReader(new InputStreamReader(p.getInputStream()));String str = in.readLine();Log.i(TAG, str);if (str != null && str.length() >= 4) {char flag = str.charAt(3);if (flag == 's' || flag == 'x')return true;}} catch (IOException e) {e.printStackTrace();}finally{if(p!=null){p.destroy();}}return false;}

这种方法基本可以判断所有的手机,而且不弹出root请求框。这才是我们需要的,perfect。

方法三,交互友好,基本没有误判。

以下是apk以及相关源代码,大家可以下载apk看下运行效果

ROOT检测APK下载地址:http://good.gd/3091610.htm

ROOT检测代码下载:http://good.gd/3091609.htm或者http://download.csdn.net/detail/waylife/7639017

如果有手机使用方法三无法判断,欢迎提出。

也欢迎大家提出其他的更好的办法。

检测手机是否root相关推荐

  1. 安卓检测手机是否root、是否刷了面具。

    command命令是用来直接调用shell命令的,无需查询shell库.其选项-v可显示shell命令的路径.不存在就不会输出.因此也可用于在无权限状态下查询任何命令,且无需调用命令就能知道是否存在该 ...

  2. 检测到你的手机处于root环境_无论你做的多么天衣无缝,你手机root了,就拜拜...

    此篇文章仅探讨Android底层技术.不提供任何软件和安装包-- 我们通过一些底层技术对手机中的各种基础信息进行一个修改. 举例说明:主要修改的参数有: Android_Id.IMEI.手机序列号.手 ...

  3. android手机解除root,手机显示被root什么意思(手机root怎么解除)

    手机root后有什么坏处?如何一键获取手机ROOT权限?在信息时代的大环境下,"黑科技"夺走了大部分的眼球,获取手机root属于所有安卓手机的最大黑科技,也是最基础的搞机技能,本篇 ...

  4. android中如何通过代码检测是否有root权限?

    2019独角兽企业重金招聘Python工程师标准>>> Android android中如何通过代码检测是否有root权限? while 3 票 1892 评论 (0) • 分享 • ...

  5. 华为Android10怎样root,华为手机怎么root?详细的root教程在此

    随着华为手机的热销,相信不少机友都入手了华为手机,华为手机有华为和荣耀两个系列,那华为手机怎么获取root权限呢?很多入手了华为手机的朋友都在纠结于root权限获取的问题之上,因为找不到合适的华为手机 ...

  6. 手机定向root,指定APP获取root权限

    安卓手机定向root,指定APP获取root权限,# su 只让自己的APP有root 防检测 定向root权限,指定root获取root权限.编译supersu或者magsik源码 目的是有效避免系 ...

  7. Android手机一键Root原理分析(作者:非虫,文章来自:《黑客防线》2012年7月)

    之前几天都在做Android漏洞分析的项目,万幸发现了这篇文章.废话不多说,上文章! <Android手机一键Root原理分析> (作者:非虫,文章来自:<黑客防线>2012年 ...

  8. root后的华为手机,华为手机可以root

    我是华为手机不知不觉就root了不知道怎么解除怎么办? 如果您的手机被root了,您可以使用手机助手或者eRecovery两种方法尝试恢复系统: 温馨提醒:以下方法可能会擦除您的个人数据,请您谨慎选择 ...

  9. 手机免root安装kali linux 步骤,离线版(最终可行版)

    手机免root安装kali linux 步骤 下载termux可以通过 F-Droid跳过google play,注意有点老安卓手机不行,比如我的三星i9152,下载f-driod之后显示不兼容,终于 ...

最新文章

  1. idea CRLF LF 编码问题,解决保存时自动更改换行符
  2. 黑客暗网叫卖Zoom账号密码,1分钱能买71个,加密大佬教袁征做人,17年前开源软件现在又火了...
  3. 学计算机须知,学习计算机须知的50个专业术语
  4. Java设计模式(五):单例设计模式
  5. oss图片数据转图片二进制数据_图片数据不够快来试试这些数据增强
  6. 详解python 3下文本文件的编解码
  7. 什么是Shell,Shell教程
  8. .net core 获取binary 文件_7.2 获取文本数据_Csv.Document
  9. docker 运行mysql镜像_docker 生成mysql镜像启动时自动执行sql
  10. Git的使用--如何将本地项目上传到Github(两种简单、方便的方法)
  11. 用DIV+CSS技术设计的网上书城网页与实现制作(大一Web课程设计)
  12. R语言进行的变量相关性显著性检验
  13. 车型代号对照表_2017年最新主机厂OEM车型代号对照表
  14. windows无法上网:代理服务器出现问题或地址有误
  15. sql注入--宽字节注入
  16. Marvin is plain Jane WriteUp_实验吧_Crypto
  17. 论文阅读(7)水母游动的流体动力学 - 海洋科学年刊(2021)
  18. 文字识别(一)--传统方案综述
  19. 自己做一个table插件 (一)Ajax获取数据后动态生成table
  20. 好用的免费 PDF 密码删除工具有哪些?

热门文章

  1. python复习题(附答案)
  2. c语言程序设计之基础题
  3. 样本方差分母为什么是n-1?——无偏估计
  4. 电脑屏幕显示字体边缘颗粒感严重
  5. 科达高密度服务器型号,科达2017存储新品首秀丨“三高一低”24盘位IPSAN磁盘存储阵列...
  6. python google地图_请问该如何在python中使用google maps api?
  7. android 逐字动画,Android实现文本逐字显示View(类似rpg游戏人物对话,文本逐字显示)...
  8. 智慧营销 让营销更精准
  9. 复旦大学计算机音乐实验室,复旦大学 智能视觉科技实验室
  10. 开始LeetCode刷题的第一天