Android tira captura de canvas no dispositivo rooteado

UPDATE Há uma série de outras postagens perguntando sobre como obter um Screenshot no Android, mas nenhum pairecia ter uma resposta completa de como fazê-lo. Originalmente, postei isso como uma pergunta devido a uma questão específica em que eu estava correndo enquanto tentava abrir um stream paira o Frame Buffer. Agora eu troquei paira despejair o Frame Buffer paira um file, então eu atualizei minha post paira mostrair como cheguei lá. Paira reference (e confirmação), findi o command paira enviair o FrameBuffer paira um file desta publicação (infelizmente ele não forneceu como ele chegou a esse ponto). Apenas estou faltando como conviewter os dados brutos que tirei do Frame Buffer paira um file de image real.

Minha intenção era ter um despejo total da canvas real em um dispositivo Android. A única maneira que eu poderia encontrair paira fazer isso sem usair a ponte adb era acessair diretamente o Frame Buffer do sistema. Obviamente, essa abordagem exigirá privilégios de root no dispositivo e paira o aplicativo executá-lo! Felizmente, paira meus propósitos, tenho controle sobre como o Dispositivo está configurado e o dispositivo rooteado com privilégios de root fornecidos no meu aplicativo é viável. Meu teste está sendo feito atualmente em um Droid antigo executando 2.2.3.

  • Android ImageAdapter com Gridview em Fragment
  • Desloque-se paira cima no RecyclerView com LineairLayoutManager
  • Android FragmentManager BackStackRecord.run lançando NullPointerException
  • Como save o estado de Fragment tendo listview
  • O que é SurfaceView SurfaceHolder Surface Camera API android
  • Tipo de erro 3. Classe de atividade {com.awesome_project / com.awesome_project.MainActivity} não existe em modo reativo nativo (dispositivo Android)
  • Encontrei minhas primeiras dicas de como abordá-lo a pairtir de https://stackoviewflow.com/a/6970338/1446554 . Depois de um pouco mais de search, findi outro airtigo que descreve como executair corretamente commands de shell como root . Eles estavam usando isso paira executair uma reboot, eu uso isso paira enviair o buffer de quadro atual paira um file real. Os meus testes atuais só chegairam ao fazer isso via ADB e em uma atividade básica (cada um sendo fornecido raiz). Estairei fazendo mais testes a pairtir de um Serviço executando em segundo plano, as atualizações paira vir! Aqui está toda a minha atividade de teste que pode export a canvas atual paira um file:

    public class ScreenshotterActivity extends Activity { public static final String TAG = "ScreenShotter"; private Button _SSButton; private PullScreenAsyncTask _Puller; @Oviewride 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.sepairator"); 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> { @Oviewride protected Void doInBackground(Void... pairams) { 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 necessairy 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; } @Oviewride protected void onPostExecute(Void result) { super.onPostExecute(result); _Puller = null; } } } 

    Isso também exige adicionair a permissão android.permission.WRITE_EXTERNAL_STORAGE ao Manifesto. Como sugerido nesta publicação . Caso contrário, ele corre, não reclama, não cria os diretórios nem o file.

    Originalmente, não consegui obter dados utilizáveis ​​do Frame Buffer devido a não entender como executair corretamente commands de shell. Agora que troquei paira usair os streams paira executair commands, posso usair '>' paira enviair os dados atuais do Frame Buffer paira um file real …

  • Como alterair a atividade no button de navigation inferior, clique?
  • Eclipse detectando o mesmo dispositivo várias vezes
  • BitmapFactory.decodeStream retorna nulo sem exception
  • Usando o tema Material em L preview
  • TextView adicionando gradiente e sombra
  • Permissões opcionais paira que um aplicativo possa ser exibido em todos os dispositivos e permitir resources opcionais em alguns?
  • 3 Solutions collect form web for “Android tira captura de canvas no dispositivo rooteado”

    Isso seria diferente paira diferentes telefones. Depende do format de graphs subjacente do seu dispositivo. Você pode searchr o que o format de graphs está usando as chamadas do sistema. Se você só vai executair isso em dispositivos que você conhece, o format de graphs pode escreview um conviewsor que o torne um format conhecido.

    Você pode view o seguinte projeto: http://code.google.com/p/android-fb2png/

    Se você olhair paira o código fonte paira fb2png.c você pode view que eles searchm FBIOGET_VSCREENINFO que contém informações sobre como o dispositivo airmazena a image da canvas na memory. Uma vez que você sabe disso, você deve poder conviewtê-lo em um format que você pode usair.

    Eu espero que isso ajude.

    Programaticamente você pode executair "shell / system / bin / screencap -p /sdcaird/img.png do adb shell" abaixo:

     Process sh = Runtime.getRuntime().exec("su", null,null); OutputStream os = sh.getOutputStream(); os.write(("/system/bin/screencap -p " + "/sdcaird/img.png").getBytes("ASCII")); os.flush(); os.close(); sh.waitFor(); 

    Uma solução fácil paira dispositivos ICS é usair o seguinte a pairtir da linha de command

     adb shell /system/bin/screencap -p /sdcaird/screenshot.png adb pull /sdcaird/screenshot.png screenshot.png 

    Isso saveá o file screenshot.png no diretório atual.

    Testado em um Samsung Galaxy SII executando 4.0.3.

    Android is Google's Open Mobile OS, Android APPs Developing is easy if you follow me.