【发布时间】:2014-03-16 06:22:27
【问题描述】:
我想创建一个在单击按钮时执行adb shell screenrecord 命令的应用程序。
我已经尝试过Runtime.getRuntime().exec() 方法,但是没有用。我第一次在模拟器上尝试它,但我了解到模拟器不支持屏幕记录。请尽快告诉我一些解决方案。
提前谢谢..
【问题讨论】:
我想创建一个在单击按钮时执行adb shell screenrecord 命令的应用程序。
我已经尝试过Runtime.getRuntime().exec() 方法,但是没有用。我第一次在模拟器上尝试它,但我了解到模拟器不支持屏幕记录。请尽快告诉我一些解决方案。
提前谢谢..
【问题讨论】:
screenrecord 需要 GID=graphics 的特殊权限
Runtime.getRuntime().exec() 只会将您的子进程的 GID 设置为与您的相同。所以你不能用这种方法录屏。
可能的解决方案:
【讨论】:
这是一个可以根据您的需求轻松定制(时间、位置、比特率)的概念证明:
private void record() {
Log.d(getClass().getSimpleName(), "record()");
final StringBuilder sbConsole = new StringBuilder();
final StringBuilder sbErrors = new StringBuilder();
AsyncTask<Void, Void, Void> recordTask = new AsyncTask<Void, Void, Void>() {
@Override
protected Void doInBackground(Void... objects) {
Log.d(getClass().getSimpleName(), "recordTask.doInBackground()");
DataOutputStream os = null;
BufferedReader isReader = null;
BufferedReader esReader = null;
try {
long start = System.currentTimeMillis();
Process process = Runtime.getRuntime().exec("su");
isReader = new BufferedReader(new InputStreamReader(process.getInputStream()));
esReader = new BufferedReader(new InputStreamReader(process.getErrorStream()));
os = new DataOutputStream(process.getOutputStream());
os.writeBytes("screenrecord --verbose --time-limit 10 --bit-rate 6000000 /sdcard/demo_6m.mp4\n");
// os.writeBytes("exit\n");
os.flush();
String line;
while ((line = esReader.readLine()) != null) {
sbErrors.append(line);
}
while ((line = isReader.readLine()) != null) {
sbConsole.append(line);
}
process.waitFor();
long end = System.currentTimeMillis();
Log.d(getClass().getSimpleName(), "recordTask.doInBackground(); elapsed: "
+ (end - start) + " ms");
} catch (IOException e) {
Log.e(getClass().getSimpleName(), "Exception: ", e);
} catch (InterruptedException e) {
Log.e(getClass().getSimpleName(), "Exception: ", e);
}
return null;
}
@Override
protected void onPostExecute(Void result) {
Log.i(getClass().getSimpleName(), "Output: " + sbConsole.toString());
Log.e(getClass().getSimpleName(), "Errors: " + sbErrors.toString());
}
};
recordTask.execute();
}
只需从 onCreate() 调用 record() 或通过单击按钮调用它。由于 AsyncTask 与应用 UI 线程分离,因此无论应用是否暂停,它都会记录。
尽管如此,系统可以在方便时将其杀死,因此最好的方法是从服务控制实际记录。
【讨论】:
您需要是 Java 进程的超级用户,请参阅我的示例: https://github.com/adouggy/MyRecorder
【讨论】: