ANDROID:如何在Android应用程序中获得root权限?

我正在开发我的第一个Android应用程序,我很好奇是否有任何“标准”方法来执行特权shell命令。 我只能通过执行sufind一种方法,然后将我的命令附加到su进程的stdin中。

 DataOutputStream pOut = new DataOutputStream(p.getOutputStream()); DataInputStream pIn = new DataInputStream(p.getInputStream()); String rv = ""; // su must exit before its output can be read pOut.writeBytes(cmd + "\nexit\n"); pOut.flush(); p.waitFor(); while (pIn.available() > 0) rv += pIn.readLine() + "\n"; 

我已经阅读了有关JNI包装特权( superuser )调用:这可能吗? 如果是这样,一个人怎么办呢? 除此之外,还有没有其他的方式来从Java调用特权指令?

据我所知,你只能使用root权限运行命令行命令。 你可以使用这个通用的类来封装你的代码中的root权限: http : //muzikant-android.blogspot.com/2011/02/how-to-get-root-access-and-execute.html

所有你需要做的就是扩展这个类并覆盖getCommandsToExecute方法来返回你想要以root身份执行的命令。

 public abstract class ExecuteAsRootBase { public static boolean canRunRootCommands() { boolean retval = false; Process suProcess; try { suProcess = Runtime.getRuntime().exec("su"); DataOutputStream os = new DataOutputStream(suProcess.getOutputStream()); DataInputStream osRes = new DataInputStream(suProcess.getInputStream()); if (null != os && null != osRes) { // Getting the id of the current user to check if this is root os.writeBytes("id\n"); os.flush(); String currUid = osRes.readLine(); boolean exitSu = false; if (null == currUid) { retval = false; exitSu = false; Log.d("ROOT", "Can't get root access or denied by user"); } else if (true == currUid.contains("uid=0")) { retval = true; exitSu = true; Log.d("ROOT", "Root access granted"); } else { retval = false; exitSu = true; Log.d("ROOT", "Root access rejected: " + currUid); } if (exitSu) { os.writeBytes("exit\n"); os.flush(); } } } catch (Exception e) { // Can't get root ! // Probably broken pipe exception on trying to write to output stream (os) after su failed, meaning that the device is not rooted retval = false; Log.d("ROOT", "Root access rejected [" + e.getClass().getName() + "] : " + e.getMessage()); } return retval; } public final boolean execute() { boolean retval = false; try { ArrayList<String> commands = getCommandsToExecute(); if (null != commands && commands.size() > 0) { Process suProcess = Runtime.getRuntime().exec("su"); DataOutputStream os = new DataOutputStream(suProcess.getOutputStream()); // Execute commands that require root access for (String currCommand : commands) { os.writeBytes(currCommand + "\n"); os.flush(); } os.writeBytes("exit\n"); os.flush(); try { int suProcessRetval = suProcess.waitFor(); if (255 != suProcessRetval) { // Root access granted retval = true; } else { // Root access denied retval = false; } } catch (Exception ex) { Log.e("ROOT", "Error executing root action", ex); } } } catch (IOException ex) { Log.w("ROOT", "Can't get root access", ex); } catch (SecurityException ex) { Log.w("ROOT", "Can't get root access", ex); } catch (Exception ex) { Log.w("ROOT", "Error executing internal operation", ex); } return retval; } protected abstract ArrayList<String> getCommandsToExecute(); } 

我知道一个可能的解决scheme是签署你的应用程序作为系统,这是不完全一样的根据我所知: 如何签署Android系统签名的应用程序? 。 但我想这不是你想要的。

我做的另一件事是创build一个本地应用程序,它可以完成所需的任务,将其作为外部进程运行。 但是有必要给这个本地应用程序你需要的权限和suid位,只要这个分区不是nosuid。 但是这不是我所想要的。

我猜,通过JNI调用的C代码应该和生活在同一个过程中一样受到限制。

如果你有可用的su二进制文件,那么你可以用java运行命令,如:Runtime.getRuntime().exec(“su -c reboot”)。

我不记得任何其他的方式。