Android снимок экрана на рутированном устройстве

UPDATE Есть ряд других постов, спрашивающих, как сделать скриншот в Android, но ни один, похоже, не дал полного ответа о том, как это сделать. Первоначально я опубликовал это как вопрос из-за конкретной проблемы, с которой я столкнулся при попытке открыть поток в буфер кадров. Теперь я переключился на сброс буфера кадров в файл, поэтому я обновил свой пост, чтобы показать, как я туда попал. Для справки (и подтверждения) я нашел команду для отправки FrameBuffer в файл изэта почта (к сожалению, он не сообщил, как он дошел до этого момента). Мне просто не хватает, как превратить необработанные данные, которые я извлек из буфера кадров, в настоящий файл изображения.

Мое намерение состояло в том, чтобы взять полный дамп реального экрана на устройстве Android.only Я смог найти способ сделать это без использования моста adb - прямой доступ к кадровому буферу системы. Очевидно, что этот подход потребует привилегий суперпользователя на устройстве и для приложения, на котором он запущен! К счастью, для моих целей у меня есть контроль над тем, как настроено устройство и как рутирование устройства с привилегиями root, предоставленными моему приложению, возможно. Мое тестирование в настоящее время проводится на старом Droid 2.2.3.

Я нашел свои первые намеки на то, как подойти к нему сhttps://stackoverflow.com/a/6970338/1446554, После нескольких дополнительных исследований я нашел другую статью, в которой описано, как правильнозапускать команды оболочки от имени пользователя root, Они использовали его для перезагрузки, я использую его для отправки текущего кадра буфера в реальный файл. Мое текущее тестирование дало мне возможность проделать это только через ADB и в базовом действии (каждому из них был предоставлен root). Я буду проводить дальнейшее тестирование из Службы, работающей в фоновом режиме, обновления будут доступны! Вот все мои тестовые действия, которые могут экспортировать текущий экран в файл:

public class ScreenshotterActivity extends Activity {
    public static final String TAG = "ScreenShotter";

    private Button _SSButton;
    private PullScreenAsyncTask _Puller;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);


        _SSButton = (Button)findViewById(R.id.main_screenshotButton);
        _SSButton.setOnClickListener(new OnClickListener() {

            public void onClick(View v) {
                if (_Puller != null)
                    return;
                //TODO: Verify that external storage is available! Could always use internal instead...

                _Puller = new PullScreenAsyncTask();
                _Puller.execute((Void[])null);
            }
        });
    }

    private void runSuShellCommand(String cmd) {
        Runtime runtime = Runtime.getRuntime();
        Process proc = null;
        OutputStreamWriter osw = null;
        StringBuilder sbstdOut = new StringBuilder();
        StringBuilder sbstdErr = new StringBuilder();

        try { // Run Script
            proc = runtime.exec("su");
            osw = new OutputStreamWriter(proc.getOutputStream());
            osw.write(cmd);
            osw.flush();
            osw.close();
        } catch (IOException ex) {
            ex.printStackTrace();
        } finally {
            if (osw != null) {
                try {
                    osw.close();
                } catch (IOException e) {
                    e.printStackTrace();                    
                }
            }
        }

        try {
            if (proc != null)
                proc.waitFor();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        sbstdOut.append(readBufferedReader(new InputStreamReader(proc.getInputStream())));
        sbstdErr.append(readBufferedReader(new InputStreamReader(proc.getErrorStream())));
    }

    private String readBufferedReader(InputStreamReader input) {

        BufferedReader reader = new BufferedReader(input);
        StringBuilder found = new StringBuilder();
        String currLine = null;
        String sep = System.getProperty("line.separator");
        try {
            // Read it all in, line by line.
            while ((currLine = reader.readLine()) != null) {
                found.append(currLine);
                found.append(sep);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                reader.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        return null;
    }

    class PullScreenAsyncTask extends AsyncTask<Void, Void, Void> {

        @Override
        protected Void doInBackground(Void... params) {

            File ssDir = new File(Environment.getExternalStorageDirectory(), "/screenshots");
            if (ssDir.exists() == false) {
                Log.i(TAG, "Screenshot directory doesn't already exist, creating...");
                if (ssDir.mkdirs() == false) {
                    //TODO: We're kinda screwed... what can be done?
                    Log.w(TAG, "Failed to create directory structure necessary to work with screenshots!");
                    return null;
                }
            }
            File ss = new File(ssDir, "ss.raw");            
            if (ss.exists() == true) {
                ss.delete();
                Log.i(TAG, "Deleted old Screenshot file.");
            }
            String cmd = "/system/bin/cat /dev/graphics/fb0 > "+ ss.getAbsolutePath();
            runSuShellCommand(cmd);
            return null;
        }

        @Override
        protected void onPostExecute(Void result) {
            super.onPostExecute(result);
            _Puller = null;
        }
    }
}

Это также требует добавленияandroid.permission.WRITE_EXTERNAL_STORAGE разрешение на Манифест. Как предложено вэта почта, В противном случае он запускается, не жалуется, не создает каталоги или файл.

Первоначально я не мог получить пригодные для использования данные из буфера кадров из-за непонимания того, как правильно запускать команды оболочки. Теперь, когда я перешел к использованию потоков для выполнения команд, я могу использовать & gt; отправлять текущие данные буфера кадров в фактический файл ...

Ответы на вопрос(3)

Ваш ответ на вопрос