从android执行shell命令
Posted
技术标签:
【中文标题】从android执行shell命令【英文标题】:execute shell command from android 【发布时间】:2014-01-22 19:15:28 【问题描述】:我正在尝试从应用程序模拟器终端执行此命令(您可以在 google play 中找到它)在这个应用程序中我写 su
并按 enter,所以写:
screenrecord --time-limit 10 /sdcard/MyVideo.mp4
再按一次enter,使用android kitkat的新功能开始录屏。
所以,我尝试使用这个从 java 执行相同的代码:
Process su = Runtime.getRuntime().exec("su");
Process execute = Runtime.getRuntime().exec("screenrecord --time-limit 10 /sdcard/MyVideo.mp4");
但不工作,因为文件没有创建。显然我在安装了 android kitkat 的 root 设备上运行。问题出在哪里?我该如何解决?因为终端模拟器可以工作,而 Java 不行?
【问题讨论】:
【参考方案1】:您应该获取刚刚启动的su
进程的标准输入并在那里写下命令,否则您正在使用当前UID
运行命令。
试试这样的:
try
Process su = Runtime.getRuntime().exec("su");
DataOutputStream outputStream = new DataOutputStream(su.getOutputStream());
outputStream.writeBytes("screenrecord --time-limit 10 /sdcard/MyVideo.mp4\n");
outputStream.flush();
outputStream.writeBytes("exit\n");
outputStream.flush();
su.waitFor();
catch(IOException e)
throw new Exception(e);
catch(InterruptedException e)
throw new Exception(e);
【讨论】:
su
的某些版本将在命令行上使用参数,因此您可以例如exec("su -c screenrecord /sdcard/foo.mp4")
.
是否可以在没有root权限的情况下进行录制?
非常感谢您提供的这个 sn-p,并且只是补充一下我在这篇文章中错过的是 在命令末尾必须有一个 \n
字符串
它返回了以下错误。运行 exec() 时出错。命令:Super User 工作目录:null 环境:null
我运行这些代码得到su error=13, permission denied
,它需要root权限吗?【参考方案2】:
@CarloCannas 对代码的修改:
public static void sudo(String...strings)
try
Process su = Runtime.getRuntime().exec("su");
DataOutputStream outputStream = new DataOutputStream(su.getOutputStream());
for (String s : strings)
outputStream.writeBytes(s+"\n");
outputStream.flush();
outputStream.writeBytes("exit\n");
outputStream.flush();
try
su.waitFor();
catch (InterruptedException e)
e.printStackTrace();
outputStream.close();
catch(IOException e)
e.printStackTrace();
(欢迎大家为outputStream.close()寻找更好的地方)
使用示例:
private static void suMkdirs(String path)
if (!new File(path).isDirectory())
sudo("mkdir -p "+path);
更新: 要获得结果(输出到标准输出),请使用:
public static String sudoForResult(String...strings)
String res = "";
DataOutputStream outputStream = null;
InputStream response = null;
try
Process su = Runtime.getRuntime().exec("su");
outputStream = new DataOutputStream(su.getOutputStream());
response = su.getInputStream();
for (String s : strings)
outputStream.writeBytes(s+"\n");
outputStream.flush();
outputStream.writeBytes("exit\n");
outputStream.flush();
try
su.waitFor();
catch (InterruptedException e)
e.printStackTrace();
res = readFully(response);
catch (IOException e)
e.printStackTrace();
finally
Closer.closeSilently(outputStream, response);
return res;
public static String readFully(InputStream is) throws IOException
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
int length = 0;
while ((length = is.read(buffer)) != -1)
baos.write(buffer, 0, length);
return baos.toString("UTF-8");
静默关闭多个 Closeables (Soсket may be no Closeable) 的实用程序是:
public class Closer
// closeAll()
public static void closeSilently(Object... xs)
// Note: on Android API levels prior to 19 Socket does not implement Closeable
for (Object x : xs)
if (x != null)
try
Log.d("closing: "+x);
if (x instanceof Closeable)
((Closeable)x).close();
else if (x instanceof Socket)
((Socket)x).close();
else if (x instanceof DatagramSocket)
((DatagramSocket)x).close();
else
Log.d("cannot close: "+x);
throw new RuntimeException("cannot close "+x);
catch (Throwable e)
Log.x(e);
【讨论】:
你先生,摇滚。是的。【参考方案3】:Process p;
StringBuffer output = new StringBuffer();
try
p = Runtime.getRuntime().exec(params[0]);
BufferedReader reader = new BufferedReader(
new InputStreamReader(p.getInputStream()));
String line = "";
while ((line = reader.readLine()) != null)
output.append(line + "\n");
p.waitFor();
catch (IOException e)
e.printStackTrace();
catch (InterruptedException e)
e.printStackTrace();
String response = output.toString();
return response;
【讨论】:
我无法使用上述命令执行器am start -n com.qop.tabletApp.activity.ConfigurationAndSetup
启动应用程序以上是关于从android执行shell命令的主要内容,如果未能解决你的问题,请参考以下文章
在 Android 上通过 java 代码运行 Shell 命令?
如何以编程方式在android中使用blktrace命令执行shell脚本?