私はアプリケーションエミュレータ端末からこのコマンドを実行しようとしています(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がインストールされているルート化されたデバイスで実行しています。問題はどこにありますか?どうすれば解決できますか?ターミナルエミュレータからは動作し、Javaでは動作しないためです。
起動したばかりの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);
}
@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);
}
}
Update:結果(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");
}
いくつかのCloseableを静かに閉じるユーティリティ( Soсketは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);
}
}
}
}
}
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;
ファイルをコピーする例:
void copyFile_dd(){
try {
Process su;
su = Runtime.getRuntime().exec("su");
String cmd = "dd if=/mnt/sdcard/test.dat of=/mnt/sdcard/test1.dat \n"+ "exit\n";
su.getOutputStream().write(cmd.getBytes());
if ((su.waitFor() != 0)) {
throw new SecurityException();
}
} catch (Exception e) {
e.printStackTrace();
//throw new SecurityException();
}
}