简体   繁体   English

执行ADB Shell ScreenRecord的Java程序

[英]java program to execute adb shell screenrecord

I want to create an app which executes adb shell screenrecord command on a button click. 我想创建一个在单击按钮时执行adb shell screenrecord命令的应用程序。

i have already tried Runtime.getRuntime().exec() method, but it didn't work. 我已经尝试过Runtime.getRuntime().exec()方法,但是没有用。 I was first trying it on an emulator but i learned that screen record is not supported on emulators. 我最初是在模拟器上尝试的,但是我了解到模拟器不支持屏幕记录。 Please let me know some solution ASAP. 请尽快告诉我一些解决方案。

Thanks in advance.. 提前致谢..

screenrecord need special permission with GID=graphics 屏幕记录需要具有GID = graphics的特殊权限

Runtime.getRuntime().exec() will only set your child process' GID the same as yours. Runtime.getRuntime()。exec()只会将子进程的GID设置为与您的相同。 So you cannot record the screen with this approach. 因此,您无法使用这种方法记录屏幕。

Possible solution: 可能的解决方案:

  1. root your phone, and get a root shell first then tell it to execute screenrecord 为您的手机建立根,并首先获得一个根外壳,然后告诉它执行screenrecord
  2. start a background service process with adb shell, and use your app to control it 使用adb shell启动后台服务进程,并使用您的应用对其进行控制

Here's a proof of concept that can be easily customized (time, location, bit-rate) to your needs: 这是一个概念证明,可以轻松地根据您的需求进行自定义(时间,位置,比特率):

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();

}

Just call record() from onCreate() or invoke it via button click. 只需从onCreate()调用record()或通过单击按钮调用它即可。 Since the AsyncTask is detached from the app UI thread, it will record regardless if app is paused. 由于AsyncTask是与应用程序用户界面线程分离的,因此无论应用程序是否暂停,它都将进行记录。

Nevertheless, the system can kill it at its convenience, so best approach is to control the actual recording from a service. 但是,系统可以在方便时将其杀死,因此最好的方法是控制服务中的实际记录。

您需要成为Java中Process的超级用户,请参见我的示例: https : //github.com/adouggy/MyRecorder

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM