我正在尝试从应用程序模拟器终端执行此命令(您可以在谷歌播放中找到它)在此应用程序中我写su
并按输入,所以写:< / p>
screenrecord --time-limit 10 /sdcard/MyVideo.mp4
然后再次按输入并使用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中没有?
答案 0 :(得分:63)
您应该抓住刚刚启动的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);
}
答案 1 :(得分:28)
@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);
}
}
<强>更新强> 要获得结果(输出到stdout),请使用:
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);
}
}
}
}
}
答案 2 :(得分:5)
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;
答案 3 :(得分:1)
复制文件的示例:
ModelAndView