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 ...
随机推荐
- GIT: 分布式开发 代码管理工具使用命令大全
代码管理工具: GIT 什么是GIT? Git是一款免费.开源的分布式版本控制系统,用于敏捷高效地处理任何或小或大的项目 Git是一个开源的分布式版本控制系统,用以有效.高速的处理从很小到非常 ...
- servlet和Jsp的复习整理
servlet 1.生命周期 a.构造方法.生成一个servlet b.init()方法.当开启服务器时,servlet第一次被装载,servlet引擎调用这个servlet的init()的方法,只调 ...
- python 终极篇 --- django 视图系统
Django的View(视图) 一个视图函数(类),简称视图,是一个简单的Python 函数(类),它接受Web请求并且返回Web响应. 响应可以是一张网页的HTML内容,一个重定向,一个404错误, ...
- leetcode-颜色分类
颜色分类 给定一个包含红色.白色和蓝色,一共 n 个元素的数组,原地对它们进行排序,使得相同颜色的元素相邻,并按照红色.白色.蓝色顺序排列. 此题中,我们使用整数 0. 1 和 2 分别表示 ...
- spark集群安装部署
通过Ambari(HDP)或者Cloudera Management (CDH)等集群管理服务安装和部署在此不多介绍,只需要在界面直接操作和配置即可,本文主要通过原生安装,熟悉安装配置流程. 1.选取 ...
- 《javascript模式--by Stoyan Stefanov》书摘--字面量和构造函数
二.字面量和构造函数 1,能够使用对象字面量时,就没理由使用new Object构造函数 // 一个空对象var 0 = new Object();console.log( o.constructor ...
- c# 生成的没用文件
1.pdb 2.vhost 3.application 4.含有更新功能(更新文件夹)
- Web后台任务处理
文章:.NET Core开源组件:后台任务利器之Hangfire Hangfire官网介绍:在.NET和.NET Core应用程序中执行后台处理的简便方法.无需Windows服务或单独的过程. 以持久 ...
- iOS- 用MapKit和CoreLocation 来实现移动设备(地图与定位)
1.前言 发现在很多的社交软件都引入了地图和定位功能,如果我们要想实现这两大功能,需要利用到两个框架:MapKit和CoreLocation 我们先来看看CoreLocation框架: 它可以 ...
- IOS开发NSBundle使用
bundle是一个目录,其中包含了程序会使用到的资源. 这些资源包含了如图像,声音,编译好的代码,nib文件(用户也会把bundle称为plug-in). 对应bundle,cocoa提供了类NSBu ...