android 应用使用Root权限执行linux命令
要让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命令的更多相关文章
- 怎么让普通用户使用root权限执行用户命令
1.添加用户,首先用adduser命令添加一个普通用户,命令如下: #adduser tommy //添加一个名为tommy的用户#passwd tommy //修改密码Changing passwo ...
- Delphi编写的Android程序获取Root权限实现(2015.4.15更新,支持Android 4.4)
借助谷歌,并经过本大侠施展坑.蒙.拐.骗.偷五大绝技,终于成功实现在Delphi下获取Root权限并将其扩展为一个完整功能更加完整的TQAndroidShell记录,在华为荣耀2(Android 4. ...
- 使用Android平板编程,执行linux命令
android有一些应用支持开发, AIDE 介绍http://www.wandoujia.com/apps/com.aide.ui https://play.google.com/store/app ...
- 权限执行[Android开发常见问题-4] RunTime.exec()如何以root权限执行多条指令?
每日一贴,今天的内容关键字为权限执行 RunTime.exec()这个接口可以说是给我们开发者供给了一个很好的直观操纵底层操纵系统的机遇,但是这个接口的使用还有很多需要注意的问题.由于要完全的分析这个 ...
- [Android开发常见问题-4] RunTime.exec()如何以root权限执行多条指令?
转:http://blog.csdn.net/alexander_xfl/article/details/9150971 RunTime.exec()这个接口可以说是给我们开发者提供了一个很好的直观操 ...
- android中获取root权限的方法以及原理(转)
一. 概述 本文介绍了android中获取root权限的方法以及原理,让大家对android 玩家中常说的“越狱”有一个更深层次的认识. 二. Root 的介绍 1. Root 的目的 可以让我们拥有 ...
- php利用root权限执行shell脚本 (转)
转一篇博客,之前搞这个东西搞了好久,结果今天晚上看到了一篇救命博客,瞬间开心了...转载转载 利用sudo来赋予Apache的用户root的执行权限,下面记录一下: 利用PHP利用root权限执行sh ...
- PHP 代码内执行Linux命令
还是那个问题,就是那个php填写pdf表单,因为副武器的原因,改用命令执行了,哎,一个问题好多知识点啊,先来说说PHP执行linux命令,其实挺简单的,但是呢,后面说说我遇到的问题 1.PHP执行命令 ...
- 再见Xshell、Xftp!Python执行Linux命令、上传下载远程文件
相信大家应该都接触过Linux操作系统(Ubuntu.Centos等),那么在使用的Linux操作系统需要使用一些远程ssh工具,尤其是公网服务器. 常用的ssh工具主要有:Xshell.MobaXt ...
随机推荐
- 【转】: 探索Lua5.2内部实现:虚拟机指令(2) MOVE & LOAD
name args desc OP_MOVE A B R(A) := R(B) OP_MOVE用来将寄存器B中的值拷贝到寄存器A中.由于Lua是register based vm,大部分的指令都是直接 ...
- DP动态规划练习
先来看一下经典的背包问题吧 http://www.cnblogs.com/Kalix/p/7617856.html 01背包问题 https://www.cnblogs.com/Kalix/p/76 ...
- Ext JS 6学习文档-第8章-主题和响应式设计
Ext JS 6学习文档-第8章-主题和响应式设计 主题和响应式设计 本章重点在 ExtJS 应用的主题和响应式设计.主要有以下几点内容: SASS 介绍和入门 主题 响应式设计 SASS 介绍和入门 ...
- 本周PSP图
本周共写博文5篇,共计4800字,知识点:知道了博客应当如何写,接触了博客园,阅读了构建之法 内容 开始时间 结束时间 中断时间 共计时间 9月8日博文 22:00 22:55 10min聊天 45m ...
- 软工实践Alpha冲刺(3/10)
队名:我头发呢队 组长博客 作业博客 杰(组长) 过去两天完成了哪些任务 继续翻阅Google Material Design 2的官方文档 接下来的计划 音源爬取 还剩下哪些任务 app开发 燃尽图 ...
- lintcode-158-两个字符串是变位词
158-两个字符串是变位词 写出一个函数 anagram(s, t) 判断两个字符串是否可以通过改变字母的顺序变成一样的字符串. 说明 What is Anagram? Two strings are ...
- 【转】bind简单示例
bind简单示例代码 namespace { class placeholder_ {}; placeholder_ __1; } template <typename R, typename ...
- Zigbee安全基础篇Part.3
原文地址: https://www.4hou.com/wireless/14294.html 导语:在之前的文章中提供了ZigBee协议及其安全功能的简要概述.在本文中,我们将探讨可在ZigBee网络 ...
- 微信小程序wx.pageScrollTo的替代方案
wx.pageScrollTo这个微信小程序的api功能如下: 简而言之就是实现页面滚动的.但是在实际应用当中显得有些鸡肋,为啥呢?使用中有明显页面有明显的抖动,这无疑是极不好的用户体验.我用的华为6 ...
- [CLR via C#]值类型的装箱和拆箱
我们先来看一个示例代码: namespace ConsoleApplication1 { class Program { static void Main(string[] args) { Array ...