要让Android应用使用Root权限,首先Android设备必须已经获得Root权限。之后可以通过下面的代码取得process对象。

  Process process = Runtime.getRuntime().exec("su");

Process对象包含可以取得输入输出流及错误流对象,使用OutputStream对象,可以向Linux写入命令,其中getInputStream将取得命令返回的数据,如果出错getErrorStream将返回错误信息。

public abstract OutputStream getOutputStream();
public abstract InputStream getInputStream();
public abstract InputStream getErrorStream();

需要注意的是,使用 cat 查看某些系统文件时,getInputStream 或 getErrorStream 读取数据时不返回,因此代码中最后使用 getOutputStream 在最后再加入一个 exit 命令后,再读取数据。

源码如下

package com.john.wifipwd;

import android.os.Build;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.Looper;
import android.os.Message; import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.Closeable;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.util.ArrayList;
import java.util.List; public class RootCommand { public interface OnCommandCallback {
void onCommandResult(List<String> cmds, String result); void onCommandErrorResult(List<String> cmds, String errorMsg);
} public static final int MESSAGE_COMMAND = 1001; private HandlerThread mHandlerThread; private WorkerHandler mWorkerHandler; private Handler mUIHandler; private OnCommandCallback mOnCommandCallback; public RootCommand() {
this(null, null);
} public RootCommand(OnCommandCallback callback) {
this(null, callback);
} public RootCommand(Handler handler, OnCommandCallback callback) {
mUIHandler = handler;
mOnCommandCallback = callback; mHandlerThread = new HandlerThread("su-Thread");
mHandlerThread.start();
mWorkerHandler = new WorkerHandler(mHandlerThread.getLooper());
} public void addCommand(String cmd) {
if (cmd != null) {
ArrayList<String> obj = new ArrayList<>();
obj.add(cmd);
Message msg = Message.obtain();
msg.what = MESSAGE_COMMAND;
msg.obj = obj;
mWorkerHandler.sendMessage(msg);
}
} public void addCommands(List<String> cmds) {
if (cmds != null) {
ArrayList<String> obj = new ArrayList<>();
obj.addAll(cmds);
Message msg = Message.obtain();
msg.what = MESSAGE_COMMAND;
msg.obj = obj;
mWorkerHandler.sendMessage(msg);
}
} public void quit() {
mWorkerHandler.removeMessages(MESSAGE_COMMAND);
mWorkerHandler.quit();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {
mHandlerThread.quitSafely();
} else {
mHandlerThread.quit();
}
} private class WorkerHandler extends Handler { private boolean mIsQuit; public WorkerHandler(Looper looper) {
super(looper);
} public void quit() {
mIsQuit = true;
} @Override
@SuppressWarnings("unchecked")
public void handleMessage(Message msg) {
super.handleMessage(msg); switch (msg.what) {
case MESSAGE_COMMAND: {
List<String> cmds = (List<String>) msg.obj;
String line;
StringBuilder result = new StringBuilder();
boolean isError = false; Process process = null;
BufferedReader error = null;
BufferedReader reader = null;
BufferedWriter writer = null; try {
process = Runtime.getRuntime().exec("su root");
writer = new BufferedWriter(new OutputStreamWriter(process.getOutputStream()));
error = new BufferedReader(new InputStreamReader(process.getErrorStream()));
reader = new BufferedReader(new InputStreamReader(process.getInputStream())); Dlog.d("--> call write");
for (String command : cmds) {
Dlog.d("handle message:" + command);
writer.write(command + " \n");
}
writer.write("exit \n");
writer.flush();
process.waitFor(); Dlog.d("--> error read");
while (!mIsQuit && (line = error.readLine()) != null) {
result.append(line).append("\n");
isError = true;
}
Dlog.d("--> isError = " + isError);
if (!isError) {
Dlog.d("--> Reader read");
while (!mIsQuit && (line = reader.readLine()) != null) {
result.append(line).append("\n");
}
} if (!mIsQuit) {
if (!isError) {
if (mUIHandler != null) {
mUIHandler.post(new ResultRunnable(cmds, result.toString()));
} else if (mOnCommandCallback != null) {
mOnCommandCallback.onCommandResult(cmds, result.toString());
}
} else {
if (mUIHandler != null) {
mUIHandler.post(new ErrorResultRunnable(cmds, result.toString()));
} else if (mOnCommandCallback != null) {
mOnCommandCallback.onCommandErrorResult(cmds, result.toString());
}
}
}
Dlog.d("handle message end!");
} catch (Exception e) {
Dlog.e("", e);
} finally {
close(writer);
close(error);
close(reader);
if (process != null) {
process.destroy();
}
}
break;
} default:
break;
}
} private void close(Closeable stream) {
try {
if (stream != null) {
stream.close();
}
} catch (IOException e) {
Dlog.e("", e);
}
}
} private class ResultRunnable implements Runnable { private String mResult;
private List<String> mCmds; public ResultRunnable(List<String> cmds, String result) {
mCmds = cmds;
mResult = result;
} @Override
public void run() {
if (mOnCommandCallback != null) {
mOnCommandCallback.onCommandResult(mCmds, mResult);
}
}
} private class ErrorResultRunnable implements Runnable { private String mResult;
private List<String> mCmds; public ErrorResultRunnable(List<String> cmds, String result) {
mCmds = cmds;
mResult = result;
} @Override
public void run() {
if (mOnCommandCallback != null) {
mOnCommandCallback.onCommandErrorResult(mCmds, mResult);
}
}
}
}

以查看连接过的wifi密码为例,下面的代码演示使用方法

package com.john.wifipwd;

import android.os.Bundle;
import android.os.Handler;
import android.support.v7.app.AppCompatActivity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import android.widget.Toast; import java.util.ArrayList;
import java.util.Iterator;
import java.util.List; public class WiFiAcy extends AppCompatActivity implements RootCommand.OnCommandCallback { private RootCommand mRootCommand; private ArrayList<String> mCmds = new ArrayList<>(); private List<WpaInfo> mWpaInfos = new ArrayList<>(); @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.wpa_pwd_acy); mRootCommand = new RootCommand(new Handler(), this);
sendCmd("cat /data/misc/wifi/wpa_supplicant.conf");
} @Override
protected void onDestroy() {
super.onDestroy();
mRootCommand.quit();
} @Override
public void onCommandResult(List<String> cmds, String result) {
Dlog.d("[onCommandResult]");
if (cmds != null && cmds.equals(mCmds)) {
for (String cmd : cmds) {
Dlog.d("--> " + cmd);
}
Dlog.d("" + result); if (result != null) {
mWpaInfos.clear();
parseWpa(mWpaInfos, result);
createNetWorkViews();
}
}
} @Override
public void onCommandErrorResult(List<String> cmds, String errorMsg) {
Dlog.d("[onCommandErrorResult]");
if (cmds != null && cmds.equals(mCmds)) {
for (String cmd : cmds) {
Dlog.d("--> " + cmd);
}
Dlog.d("" + errorMsg);
}
Toast.makeText(this, errorMsg, Toast.LENGTH_LONG).show();
} private void sendCmd(String cmd) {
mCmds.clear();
mCmds.add(cmd);
mRootCommand.addCommands(mCmds);
} private void createNetWorkViews() {
LayoutInflater localLayoutInflater = getLayoutInflater();
ViewGroup localViewGroup = (ViewGroup) findViewById(R.id.ll_wifi_pwds);
if (localViewGroup == null)
return;
localViewGroup.removeAllViews();
Iterator localIterator = mWpaInfos.iterator();
TextView textView;
while (true) {
if (!localIterator.hasNext())
return;
WpaInfo localNetWorkInfo = (WpaInfo) localIterator.next();
Dlog.d(localNetWorkInfo.toString());
View localView = localLayoutInflater.inflate(R.layout.wpa_pwd_item, localViewGroup, false);
textView = (TextView) localView.findViewById(R.id.ssid);
textView.setText(getString(R.string.ssid_tag) + localNetWorkInfo.getSsid());
textView = (TextView) localView.findViewById(R.id.psk);
textView.setText(getString(R.string.psk_tag) + localNetWorkInfo.getPsk());
textView = (TextView) localView.findViewById(R.id.keyMgmt);
textView.setText(getString(R.string.keyMgmt_tag) + localNetWorkInfo.getKeyMgmt());
textView = (TextView) localView.findViewById(R.id.priority);
textView.setText(getString(R.string.priority_tag) + localNetWorkInfo.getPriority());
localViewGroup.addView(localView);
}
} private void parseWpa(List<WpaInfo> outList, String content) {
String[] array = content.split("\n");
WpaInfo wpaInfo = null;
for (String line : array) {
line = line.trim();
if (line.startsWith(WpaInfo.NETWORK_PREFIX)) {
wpaInfo = new WpaInfo();
outList.add(wpaInfo);
} else if (wpaInfo != null) {
if (line.startsWith(WpaInfo.SSID_PREFIX)) {
line = line.substring(WpaInfo.SSID_PREFIX.length());
line = line.replaceAll("\"", "");
wpaInfo.setSsid(line);
} else if (line.startsWith(WpaInfo.PSK_PREFIX)) {
line = line.substring(WpaInfo.PSK_PREFIX.length());
line = line.replaceAll("\"", "");
wpaInfo.setPsk(line);
} else if (line.startsWith(WpaInfo.KEY_MGMT_PREFIX)) {
line = line.substring(WpaInfo.KEY_MGMT_PREFIX.length());
wpaInfo.setKeyMgmt(line);
} else if (line.startsWith(WpaInfo.PRIORITY_PREFIX)) {
line = line.substring(WpaInfo.PRIORITY_PREFIX.length());
wpaInfo.setPriority(line);
Dlog.d("" + wpaInfo);
}
}
}
}
}
package com.john.wifipwd;

public class WpaInfo {

    public static final String NETWORK_PREFIX = "network={";
public static final String SSID_PREFIX = "ssid=";
public static final String PSK_PREFIX = "psk=";
public static final String KEY_MGMT_PREFIX = "key_mgmt=";
public static final String PRIORITY_PREFIX = "priority="; private String ssid;
private String psk;
private String keyMgmt;
private String priority; public WpaInfo() {
} public WpaInfo(String ssid, String psk, String keyMgmt, String priority) {
this.ssid = ssid;
this.psk = psk;
this.keyMgmt = keyMgmt;
this.priority = priority;
} public String getSsid() {
return ssid;
} public void setSsid(String ssid) {
this.ssid = ssid;
} public String getPsk() {
return psk;
} public void setPsk(String psk) {
this.psk = psk;
} public String getKeyMgmt() {
return keyMgmt;
} public void setKeyMgmt(String keyMgmt) {
this.keyMgmt = keyMgmt;
} public String getPriority() {
return priority;
} public void setPriority(String priority) {
this.priority = priority;
} @Override
public boolean equals(Object o) {
if (this == o)
return true;
if (o == null || getClass() != o.getClass())
return false; WpaInfo wpaInfo = (WpaInfo) o; if (ssid != null ? !ssid.equals(wpaInfo.ssid) : wpaInfo.ssid != null)
return false;
if (psk != null ? !psk.equals(wpaInfo.psk) : wpaInfo.psk != null)
return false;
if (keyMgmt != null ? !keyMgmt.equals(wpaInfo.keyMgmt) : wpaInfo.keyMgmt != null)
return false;
return priority != null ? priority.equals(wpaInfo.priority) : wpaInfo.priority == null;
} @Override
public int hashCode() {
int result = ssid != null ? ssid.hashCode() : 0;
result = 31 * result + (psk != null ? psk.hashCode() : 0);
result = 31 * result + (keyMgmt != null ? keyMgmt.hashCode() : 0);
result = 31 * result + (priority != null ? priority.hashCode() : 0);
return result;
} @Override
public String toString() {
return "WpaInfo{" +
"ssid='" + ssid + '\'' +
", psk='" + psk + '\'' +
", keyMgmt='" + keyMgmt + '\'' +
", priority='" + priority + '\'' +
'}';
}
}

android 应用使用Root权限执行linux命令的更多相关文章

  1. 怎么让普通用户使用root权限执行用户命令

    1.添加用户,首先用adduser命令添加一个普通用户,命令如下: #adduser tommy //添加一个名为tommy的用户#passwd tommy //修改密码Changing passwo ...

  2. Delphi编写的Android程序获取Root权限实现(2015.4.15更新,支持Android 4.4)

    借助谷歌,并经过本大侠施展坑.蒙.拐.骗.偷五大绝技,终于成功实现在Delphi下获取Root权限并将其扩展为一个完整功能更加完整的TQAndroidShell记录,在华为荣耀2(Android 4. ...

  3. 使用Android平板编程,执行linux命令

    android有一些应用支持开发, AIDE 介绍http://www.wandoujia.com/apps/com.aide.ui https://play.google.com/store/app ...

  4. 权限执行[Android开发常见问题-4] RunTime.exec()如何以root权限执行多条指令?

    每日一贴,今天的内容关键字为权限执行 RunTime.exec()这个接口可以说是给我们开发者供给了一个很好的直观操纵底层操纵系统的机遇,但是这个接口的使用还有很多需要注意的问题.由于要完全的分析这个 ...

  5. [Android开发常见问题-4] RunTime.exec()如何以root权限执行多条指令?

    转:http://blog.csdn.net/alexander_xfl/article/details/9150971 RunTime.exec()这个接口可以说是给我们开发者提供了一个很好的直观操 ...

  6. android中获取root权限的方法以及原理(转)

    一. 概述 本文介绍了android中获取root权限的方法以及原理,让大家对android 玩家中常说的“越狱”有一个更深层次的认识. 二. Root 的介绍 1. Root 的目的 可以让我们拥有 ...

  7. php利用root权限执行shell脚本 (转)

    转一篇博客,之前搞这个东西搞了好久,结果今天晚上看到了一篇救命博客,瞬间开心了...转载转载 利用sudo来赋予Apache的用户root的执行权限,下面记录一下: 利用PHP利用root权限执行sh ...

  8. PHP 代码内执行Linux命令

    还是那个问题,就是那个php填写pdf表单,因为副武器的原因,改用命令执行了,哎,一个问题好多知识点啊,先来说说PHP执行linux命令,其实挺简单的,但是呢,后面说说我遇到的问题 1.PHP执行命令 ...

  9. 再见Xshell、Xftp!Python执行Linux命令、上传下载远程文件

    相信大家应该都接触过Linux操作系统(Ubuntu.Centos等),那么在使用的Linux操作系统需要使用一些远程ssh工具,尤其是公网服务器. 常用的ssh工具主要有:Xshell.MobaXt ...

随机推荐

  1. Python基础 之 set集合 与 字符串格式化

    数据类型的回顾与总结 可变与不可变1.可变:列表,字典2.不可变:字符串,数字,元组 访问顺序:1.直接访问:数字2.顺序访问:字符串,列表,元祖3.映射:字典 存放元素个数:容器类型:列表,元祖,字 ...

  2. Matlab 图象操作函数讲解

    h = imrect;pos = getPosition(h); 这个函数用来获取图象上特定区域的坐标,其中pos的返回值中有四个参数[xmin,ymin,width,height],特定区域的左上角 ...

  3. Struts2文件上传带进度条,虽然不是很完美

    好久没有写东西,最近在做个项目,要用到文件h 传的,以前虽然也做上传,但是总觉得不好用 ,现在和队友合作做了一个带进度条的上传,觉得还行~~和大家分享一下. 首先说一下大概是这样实现的,在我们平时的上 ...

  4. HDU 3007 Buried memory(计算几何の最小圆覆盖,模版题)

    Problem Description Each person had do something foolish along with his or her growth.But,when he or ...

  5. js随机数算法

    function rnd( seed ){ seed = ( seed * 9301 + 49297 ) % 233280; //为何使用这三个数? return seed / ( 233280.0 ...

  6. location 匹配规则 (NGINX)

    转:https://moonbingbing.gitbooks.io/openresty-best-practices/ngx/nginx_local_pcre.html location 匹配规则 ...

  7. Java版office文档在线预览

    java将office文档pdf文档转换成swf文件在线预览 第一步,安装openoffice.org openoffice.org是一套sun的开源office办公套件,能在widows,linux ...

  8. <Android>spinner/AutoCompleteTextView绑定适配器

    position = (Spinner)findViewById(R.id.position); String[] str = {"CEO","CFO",&qu ...

  9. 【Docker 命令】 - search 命令

    docker search : 从Docker Hub查找镜像 语法 docker search [OPTIONS] TERM OPTIONS说明: --automated :只列出 automate ...

  10. C# Designer.cs

    designer.cs 是窗体设计器生成的代码文件,作用是对窗体上的控件做初始化工作(在函数InitializeComponent()中) VS2003以前都把这部分代码放到窗体的cs文件中,由于这部 ...