import java.io.DataOutputStream; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; import java.nio.charset.Charset; import java.util.Scanner; import android.content.res.AssetManager; import android.os.Build; import android.util.Log; public class ShellUtils { private static String busyboxPath="/system/xbin/busybox"; /** * Set custom busybox path * @param path Path */ public static void setCustomBusybox(String path){ busyboxPath = path; } public static boolean checkBusyboxPath(){ try{ if (!new File("/system/xbin/busybox").exists()){ if(!new File("/system/bin/busybox").exists()) return false; else busyboxPath="/system/bin/busybox"; } else busyboxPath="/system/xbin/busybox"; }catch (SecurityException e){ return false; } return true; } /** * Try to get root permission * @return true means success; false means fail */ public static boolean rootCheck(){ //List all the files under "/data/data", doing this operation needs root permission //CommandResult commandResult = execCommand(false,true, "ls /data/data/"); //Empty result means there's no root permission //return !commandResult.successMsg.isEmpty(); return execCommand(false,true,"").result==0; } @SuppressWarnings("deprecation") public static boolean initiateBusybox(){ //Clear old files File busybox = new File(GlobalVariable.getContext().getFilesDir()+"/busybox"); if (busybox.exists()) busybox.delete(); //Copy corresponding busybox to internal folder String cpuVersion; if (android.os.Build.VERSION.SDK_INT <21) cpuVersion= Build.CPU_ABI; else cpuVersion=Build.SUPPORTED_ABIS[0]; //Determine busybox version String filename; cpuVersion=cpuVersion.toLowerCase(); if (cpuVersion.contains("arm")) filename="busybox-armv5l"; else if (cpuVersion.contains("x86")) filename="busybox-i686"; else return false; AssetManager assetManager = GlobalVariable.getContext().getAssets(); InputStream in = null; OutputStream out = null; try { in = assetManager.open(filename); out = new FileOutputStream(busybox); byte[] buffer = new byte[1024]; int read; while ((read = in.read(buffer)) != -1) { out.write(buffer, 0, read); } } catch (IOException e) { e.printStackTrace(); return false; } finally { if (in != null) { try { in.close(); } catch (IOException e) { e.printStackTrace(); } } if (out != null) { try { out.close(); } catch (IOException e) { e.printStackTrace(); } } } //Make busybox executables ShellUtils.execCommand(false, true, "chmod 0755 " + GlobalVariable.getContext().getFilesDir() + "/busybox"); return true; } /** * Execute commands and get the results * @param isBusybox Run cmds via busybox or not * @param isRoot Run cmds as root? * @param cmds Command(s) * @return Results of commands */ public static CommandResult execCommand(boolean isBusybox, boolean isRoot, String...cmds){ int result=-1; StringBuilder successMsg = null; StringBuilder errorMsg = null; if (cmds==null || cmds.length==0) return new CommandResult(result,null,null); try{ Process proc=Runtime.getRuntime().exec(isRoot?"su":"sh"); DataOutputStream opt = new DataOutputStream(proc.getOutputStream()); boolean exitCmdFound=false; //Write cmds for(String cmd:cmds){ //Using busybox and check its path if (isBusybox) opt.writeBytes(busyboxPath + " "); //Unless make sure cmd is in English, using UTF-8 coding, avoid wrong coding. opt.write(cmd.getBytes(Charset.forName("utf-8"))); if(!exitCmdFound && cmd.equals("exit")) exitCmdFound=true; opt.writeBytes("\n"); } if(!exitCmdFound) opt.writeBytes("exit\n"); opt.flush(); //Get results result=proc.waitFor(); successMsg = new StringBuilder(); errorMsg = new StringBuilder(); Scanner scanner; scanner=new Scanner(new InputStreamReader(proc.getInputStream())); while (scanner.hasNextLine()) successMsg.append(scanner.nextLine()); scanner=new Scanner(new InputStreamReader(proc.getErrorStream())); while (scanner.hasNextLine()) errorMsg.append(scanner.nextLine()); } catch (Exception e){ e.printStackTrace(); } return new CommandResult(result,successMsg==null?null:successMsg.toString(), errorMsg==null?null:errorMsg.toString()); } public static class CommandResult { /** * Result of command * 0: normal * else: error */ public int result; public String successMsg; public String errorMsg; public CommandResult(int result, String successMsg, String errorMsg) { this.result = result; this.successMsg = successMsg; this.errorMsg = errorMsg; } } }
上色
Code Block
2015年12月11日 星期五
[Android] Shell Tool for root commands
訂閱:
張貼留言 (Atom)
沒有留言:
張貼留言