Come a livello di prendere uno screenshot su Android?

Come posso prendere uno screenshot di un’area selezionata di telefono schermo non da nessun programma, ma da codice?

  • Non da emulatore. Ho bisogno di fare screenshot di una parte del mio programma, e fare qualcosa con lo stesso programma.
  • Un altro buon di riferimento: stackoverflow.com/a/10296881/439171

 

24 Replies
  1. 422

    Qui è il codice che ha permesso il mio screenshot per essere memorizzati su una scheda SD e utilizzato in seguito per qualunque necessità:

    Primo luogo, è necessario aggiungere una corretta permesso di salvare il file:

    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

    E questo è il codice (l’esecuzione di un’Attività):

    private void takeScreenshot() {
        Date now = new Date();
        android.text.format.DateFormat.format("yyyy-MM-dd_hh:mm:ss", now);
    
        try {
            //image naming and path  to include sd card  appending name you choose for file
            String mPath = Environment.getExternalStorageDirectory().toString() + "/" + now + ".jpg";
    
            //create bitmap screen capture
            View v1 = getWindow().getDecorView().getRootView();
            v1.setDrawingCacheEnabled(true);
            Bitmap bitmap = Bitmap.createBitmap(v1.getDrawingCache());
            v1.setDrawingCacheEnabled(false);
    
            File imageFile = new File(mPath);
    
            FileOutputStream outputStream = new FileOutputStream(imageFile);
            int quality = 100;
            bitmap.compress(Bitmap.CompressFormat.JPEG, quality, outputStream);
            outputStream.flush();
            outputStream.close();
    
            openScreenshot(imageFile);
        } catch (Throwable e) {
            //Several error may come out with file handling or DOM
            e.printStackTrace();
        }
    }

    E questo è come si può aprire la recente immagine generata:

    private void openScreenshot(File imageFile) {
        Intent intent = new Intent();
        intent.setAction(Intent.ACTION_VIEW);
        Uri uri = Uri.fromFile(imageFile);
        intent.setDataAndType(uri, "image/*");
        startActivity(intent);
    }

    Se si desidera utilizzare sul frammento di vista, quindi, utilizzare:

    View v1 = getActivity().getWindow().getDecorView().getRootView();

    invece di

    View v1 = getWindow().getDecorView().getRootView();

    su takeScreenshot() funzione

    Nota:

    Questa soluzione non funziona se la finestra di dialogo contiene una visione di superficie. Per i dettagli, si prega di controllare la risposta alla seguente domanda:

    Android Screenshot di Superficie Mostra Schermo Nero

    • questo vuole solo uno screenshot del vostro programma (giusto?)
    • Cosa succede se l’immagine di sfondo del catturati vista è in parte trasparente..? Nel mio caso il colore di sfondo viene catturato troppo.. Do u hanno idea di come non catturare altre cose sotto, diciamo, semi-trasparente in vista? 10q
    • Ha funzionato, ma sto passando la radice di vista di immagine esistente vista, ma l’intera attività è sempre salvato nella sdcard.Si prega di aiutare e sono molto vicino.Voglio salvare l’istantanea di immagine non l’intera vista.
    • Ewoks: ho avuto lo stesso problema, a rendere il testo nero su sfondo nero, perché questo metodo non disegnare lo sfondo (in quanto non hanno accesso a tali punti di vista. Ho trovato una soluzione, almeno, uso il tema di sfondo (io dopo che un’altra risposta)
    • io sono impressionato a questo… non è in grado di prendere la schermata di visualizzazione specificata ( l’ImageView)
    • questo ha funzionato per me, ma ho problemi con javaoutofmemory eccezione. perché io non cancellare la cache come posso fare per cancellare la cache
    • può suddetto codice è eseguito su android senza radici dispositivi?
    • Ciao, Puoi descrivere che cosa è mCurrentUrlMask? Ho provato questo codice ma è sempre mi dà NullPointerException at Bitmap.createBitmap(v1.getDrawingCache()), nessuno Può dire che cosa sto facendo di sbagliato.? Ogni aiuto è apprezzato. Grazie.
    • deve essere un View dal momento che è l’unica classe in API di Android che ha il getRootView() metodo. Probabilmente è una vista dell’interfaccia utente.
    • b.comprimere(Bitmap.CompressFormat.PNG, 90, nuovo BufferedOutputStream( fout ));È meglio avvolgere il FileOutputStream con un BufferedStream:
    • Sto diventando Nullpointerexception problema qui la Vista v1 = mCurrentUrlMask.getRootView(); ho dichiarato mCurrentUrlMask come un punto di vista, ma come faccio a inizializzare il vista, quello che dovrebbe essere quella vista, si prega di aiuto
    • Mi potete dire che cosa è, mCurrentUrlMask?
    • Prova questo : Vista v1= findViewById(R. id.LayoutID); v1.getRootView();
    • mCurrentUrlMask è una visione che il poster originale aveva dichiarato altrove nel suo codice. Non servono a nulla qui a getRootView() chiamato su di esso. La parte importante è che v1 è la vista che avrà la sua immagine scattata così fintanto che è la vista principale dovrebbe essere ok. Se il vostro xml ha un LinearLayout chiamato mainLinearLayout quindi si potrebbe sostituire il codice con v1 = (LinearLayout)findViewByID(R. id.mainLinearLayout); E fintanto che la mainLinearLayout sia visibile e dentro lo schermo avrà la sua immagine, preso, altrimenti è necessario per gonfiare/misura di voi stessi.
    • Invece di View v1 = mCurrentUrlMask.getRootView(); ho usato View v1 = getWindow().getDecorView().getRootView(); e funziona per me.
    • per chiunque altro che sta chiedendo stesso, qui si può andare..
    • Sto usando lo stesso codice di prendere screenshot in un ciclo, questo codice è solo la generazione di 13-14 immagini al secondo, mentre io ho bisogno del 24 e 25 immagini al secondo, così dopo che sarò in grado di creare un video.
    • Se si ottiene EACCES (Permission denied) errore, aggiungere il seguente AndroidManifest.xml: <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    • Che cosa succede se il mio punto di vista è scrollview? vi è anche la possibilità di catturare il contenuto non è visibile? C’è un modo per ottenere dati?
    • Non dimenticate di riciclare bitmap per evitare la PERDITA di MEMORIA! public static void recycleInBackground(finale Bitmap bitmapToRecycle) { if(bitmapToRecycle==null || bitmapToRecycle.isRecycled()) { return; } nuovo Thread(new Runnable() { @Override public void run() { bitmapToRecycle.riciclare(); } }); }
    • il cellulare ha la necessità di essere radicato per fare questo?
    • Questo metodo non funziona in tutti i casi. Per esempio non riesce a catturare un Google Maps (MapView v2) o una finestra di dialogo. (Probabilmente è perché utilizza la mappa per glsurfaceview).
    • è possibile memorizzare le foto nella galleria? questo funziona bene, ma aprire l’immagine da altre applicazioni è molto difficile in quanto l’immagine non è memorizzato nella sezione gallery.
    • Fa questo lavoro quando l’app è in background così?
    • Questa risposta prende uno screenshot del proprio app – non il “schermo del telefono”, come chiesto nella domanda – o sto facendo qualcosa di sbagliato.
    • Molto bello il tutorial. grazie per la condivisione
    • Questo non prendere snapshot della barra di stato. Come posso Includere anche?
    • non è un bene per tempo reale quando si desidera registrare in un video
    • voglio corrente di qualsiasi schermata di catturare una schermata come sistema di screenshot durante l’avvio del mobile . quindi, per favore fatemi sapere come vi è –
    • Il setDrawingCache() il metodo è deprecato in API 28. Controllare la mia risposta che mostra come utilizzare le nuove API per il salvataggio di immagini: stackoverflow.com/a/51875893/2380518
    • L’elevazione è saltato !!
    • Come posso prendere screenshot con barra di stato? Io solo in grado di prendere screenshot della mia app .Voglio prendere screenshot con domare anddate con battry di stato ,che viene visualizzato nella parte superiore della app nella barra di stato.

  2. 117

    Chiamare questo metodo, passando il più esterno ViewGroup che si desidera che la schermata di:

    public Bitmap screenShot(View view) {
        Bitmap bitmap = Bitmap.createBitmap(view.getWidth(),
                view.getHeight(), Config.ARGB_8888);
        Canvas canvas = new Canvas(bitmap);
        view.draw(canvas);
        return bitmap;
    }
    • Questo sembra essere più pulito il codice di accettato di rispondere. Si esegue così?
    • Io l’ho usato per un po ‘ in un paio di diverse applicazioni e non ho avuto problemi.
    • Se si desidera ottenere uno screenshot del telefono, dove l’app è in background, cosa che gli passi come view?`
    • Passando getWindow().getDecorView().getRootView() come visualizzare i risultati nel prendere uno screenshot solo app – non lo schermo.
    • Questa risposta prende uno screenshot del proprio app – non il “schermo del telefono”, come chiesto nella domanda – o sto facendo qualcosa di sbagliato.
    • No, non è per prendere uno screenshot, non importa in quale app. Per questo, c’è una speciale API, ma non riesco a scoprire come si usa: stackoverflow.com/q/32513379/878126
    • quando sto cercando questa generazione schermata con le cattive qualità. come posso ovviare a questo?
    • C’è un piccolo problema, questo non sembra catturare l’attività del colore di sfondo. Tutte le idee?
    • per prendere uno screenshot della Schermata getActivity().getWindow().getDecorView() ma richiede api 21
    • Nel mio caso ho una WebView in cui mi carico di animazione url dell’immagine. Dopo la creazione di bitmap, cattura tutto, tranne l’animazione di oggetti. Possiamo fare qualcosa per questo?
    • voglio corrente di qualsiasi schermata di cattura screenshot durante l’avvio di telefonia mobile e quindi per favore fatemi sapere come vi è –

  3. 42

    Nota: funziona solo per telefono radicata

    A livello di programmazione, è possibile eseguire adb shell /system/bin/screencap -p /sdcard/img.png come di seguito

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

    quindi leggere img.png come Bitmap e utilizzare come si desidera.

    • È necessario l’accesso di root?
    • Sì, è necessario l’accesso di root. Si prega di controllare la Nota al titolo
    • Ciao, ho avuto un System.err : java.io.IOException: Error running exec(). Command: [su] Working Directory: null Environment: null , il mio dispositivo è android 5.0
    • Dipende dal vostro dispositivo
    • C’è un modo per leggere l’output direttamente senza salvare il risultato in un file, quindi la lettura è di nuovo? stackoverflow.com/questions/43914035
    • Non so qualche modo un processo di comunicare direttamente con la nostra applicazione. Sarà controllare e tornare a voi su questo.

  4. 33

    EDIT: abbi pietà con le downvotes. Era vero, nel 2010, quando ho risposto alla domanda.

    Tutti i programmi che consentono di effettuare screenshot funziona solo su telefoni radicata.

    • Sembra che in questi giorni è possibile su Android con Tegra basato su chipset
    • Come è possibile.. si prega di elaborare..
    • Il mio tablet in esecuzione 4.0.3 permette di colpi di schermo, non radicata, Acer Iconia A500…
    • 4.0.3 – allora è probabilmente una di queste new-scuola di tegra tablet
    • Per quanto ne so, quando i dispositivi hanno uno stock di app per catturare screenshot è un’app con speciale firma privilegi che permettono di catturare il framebuffer (un buffer contiene i pixel dello schermo). Quindi è vero, se la tua ROM è un app, non avrete bisogno di essere radicato, ma solo che l’app è in grado di catturare, non il vostro.
    • A rigor di termini, lungo il root con ADB shell” account utente ha sempre avuto il permesso di fare ciò che è stata la destinazione d’uso caso. Ciò che non è stato storicamente (ad eccezione di occasionali costruisce come un errore) era un modo per applicazione id utente a farlo.

  5. 22

    No autorizzazioni di root o grandi codifica è necessaria per questo metodo.


    Su adb shell utilizzando il seguente comando è possibile prendere screenshot.

    input keyevent 120

    Questo comando non è richiesto alcun permesso root così che è possibile eseguire da codice java dell’applicazione per android anche.

    Process process;
    process = Runtime.getRuntime().exec("input keyevent 120");

    Di più su keyevent codice di android, vedere http://developer.android.com/reference/android/view/KeyEvent.html

    Qui abbiamo usato. KEYCODE_SYSRQ il suo valore è di 120 e utilizzato per il Sistema di Richiesta /tasto “Stampa Schermo”.


    Come CJBS detto, L’immagine di output verrà salvato in /sdcard/Immagini/Screenshot

    • L’immagine di output verranno salvate qui: /sdcard/Pictures/Screenshots
    • non sembra funzionare su Android 5
    • non richiede autorizzazioni di root??
    • No, non richiede autorizzazioni di root
    • si funziona su marshmallow ? o si lavora in background servizio @JeegarPatel
    • non ha funzionato a livello di programmazione, ma funziona da shell. Provato con torrone.
    • su -c "input keyevent 120" è ok!!
    • Si tratta di lavorare da terminale, ma non a livello di programmazione..Qualche idea…?
    • Non funziona su di marshmallow troppo. e non anche lanciare un’eccezione !

  6. 17

    Mualig risposta è molto buona, ma ho avuto lo stesso problema Ewoks descrive, non ricevo lo sfondo. Così a volte è abbastanza buono e a volte ho il testo nero su sfondo nero (a seconda del tema).

    Questa soluzione è fortemente basato in Mualig codice e il codice che ho trovato in Robotium. Sto scartando l’uso del disegno cache chiamando direttamente il metodo draw. Prima che cercherò di ottenere lo sfondo drawable da correnti attività per disegnare prima.

    //Some constants
    final static String SCREENSHOTS_LOCATIONS = Environment.getExternalStorageDirectory().toString() + "/screenshots/";
    
    //Get device dimmensions
    Display display = getWindowManager().getDefaultDisplay();
    Point size = new Point();
    display.getSize(size);
    
    //Get root view
    View view = mCurrentUrlMask.getRootView();
    
    //Create the bitmap to use to draw the screenshot
    final Bitmap bitmap = Bitmap.createBitmap(size.x, size.y, Bitmap.Config.ARGB_4444);
    final Canvas canvas = new Canvas(bitmap);
    
    //Get current theme to know which background to use
    final Activity activity = getCurrentActivity();
    final Theme theme = activity.getTheme();
    final TypedArray ta = theme
        .obtainStyledAttributes(new int[] { android.R.attr.windowBackground });
    final int res = ta.getResourceId(0, 0);
    final Drawable background = activity.getResources().getDrawable(res);
    
    //Draw background
    background.draw(canvas);
    
    //Draw views
    view.draw(canvas);
    
    //Save the screenshot to the file system
    FileOutputStream fos = null;
    try {
        final File sddir = new File(SCREENSHOTS_LOCATIONS);
        if (!sddir.exists()) {
            sddir.mkdirs();
        }
        fos = new FileOutputStream(SCREENSHOTS_LOCATIONS
                + System.currentTimeMillis() + ".jpg");
        if (fos != null) {
            if (!bitmap.compress(Bitmap.CompressFormat.JPEG, 90, fos)) {
                Log.d(LOGTAG, "Compress/Write failed");
            }
            fos.flush();
            fos.close();
        }
    
    } catch (FileNotFoundException e) {
        //TODO Auto-generated catch block
        e.printStackTrace();
    } catch (IOException e) {
        //TODO Auto-generated catch block
        e.printStackTrace();
    }
    • Ho una listview con android:cacheColorHint=”#00000000″ nella mia attività , e io uso questo codice per schermata , io ne ho ancora uno sfondo nero , perché ho scoperto che il background che ottenere dal tema è nero , come posso fare con questo listview?
    • Attività attività = getCurrentActivity mi Eroor metodo non definito.
  7. 16
    private void captureScreen() {
        View v = getWindow().getDecorView().getRootView();
        v.setDrawingCacheEnabled(true);
        Bitmap bmp = Bitmap.createBitmap(v.getDrawingCache());
        v.setDrawingCacheEnabled(false);
        try {
            FileOutputStream fos = new FileOutputStream(new File(Environment
                    .getExternalStorageDirectory().toString(), "SCREEN"
                    + System.currentTimeMillis() + ".png"));
            bmp.compress(CompressFormat.PNG, 100, fos);
            fos.flush();
            fos.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    Aggiungere l’autorizzazione nel manifesto

    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

    Per il Sostegno Marshmallow o versioni precedenti, si prega di aggiungere il seguente codice nell’attività metodo onCreate

    ActivityCompat.requestPermissions(this,new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},00);
    • Ha funzionato bene per me.
    • Richiede : <uses-permission android:name=”android.il permesso.WRITE_EXTERNAL_STORAGE”/>
    • Questa risposta prende uno screenshot del proprio app – non il “schermo del telefono”, come chiesto nella domanda – o sto facendo qualcosa di sbagliato?
    • Che cosa succede Se ho bisogno di uno screenshot di un elemento della listview?
    • voglio catturare da adattatore qualche idea di come posso fare?
  8. 15

    Come un riferimento, un modo per catturare lo schermo (e non solo l’app di attività) è quello di catturare il framebuffer (dispositivo /dev/grafica/fb0). Per fare questo è necessario avere i privilegi di root o la vostra applicazione deve essere un app con firma le autorizzazioni (“Un’autorizzazione che il sistema concede solo se la richiesta è firmata con lo stesso certificato dell’applicazione che ha dichiarato l’autorizzazione”) – che è molto improbabile a meno che non hai compilato la tua ROM.

    Ogni framebuffer cattura, da un paio di dispositivi che ho provato, contenute esattamente uno screenshot. Le persone hanno riferito a contenere di più, credo che dipende da telaio/dimensione del display.

    Ho provato a leggere il framebuffer di continuo, ma sembra di tornare per un importo fisso di byte letti. Nel mio caso (3 410 432) di byte, che è sufficiente per memorizzare un telaio del display di 854*480 RGBA (3 279 360 byte). Sì, il telaio, in binario, in uscita da fb0 è RGBA nel mio dispositivo. Questo sarà molto probabilmente dipende da dispositivo a dispositivo. Questo sarà importante per voi per la decodifica =)

    Nel mio dispositivo /dev/grafica/fb0 autorizzazioni in modo che solo l’utente root e utenti dal gruppo di grafica in grado di leggere il fb0.

    grafica è un gruppo ristretto, quindi si avrà probabilmente solo l’accesso fb0 con una radicata telefono utilizzando il comando “su”.

    Applicazioni Android hanno la user id (uid) = app_## e group id (guid) = app_## .

    adb shell ha uid = shell e guid = shell, che ha molto di più autorizzazioni di un’app. Si può effettivamente controllare le autorizzazioni all’ /system/permissions/platform.xml

    Questo significa che si sarà in grado di leggere fb0 in adb shell senza root ma non leggerete all’interno della app senza root.

    Anche, dando READ_FRAME_BUFFER e/o ACCESS_SURFACE_FLINGER autorizzazioni AndroidManifest.xml non fa nulla per regolare l’applicazione perché questi funzionano solo per i ‘firma‘ app.

    Verificare anche questo chiuso il thread per ulteriori dettagli.

    • Questo funziona (funzionava?) su alcuni telefoni, ma nota che la GPU basato telefoni non necessariamente lineare framebuffer per le applicazioni del processore.
  9. 13

    La mia soluzione è:

    public static Bitmap loadBitmapFromView(Context context, View v) {
        DisplayMetrics dm = context.getResources().getDisplayMetrics(); 
        v.measure(MeasureSpec.makeMeasureSpec(dm.widthPixels, MeasureSpec.EXACTLY),
                MeasureSpec.makeMeasureSpec(dm.heightPixels, MeasureSpec.EXACTLY));
        v.layout(0, 0, v.getMeasuredWidth(), v.getMeasuredHeight());
        Bitmap returnedBitmap = Bitmap.createBitmap(v.getMeasuredWidth(),
                v.getMeasuredHeight(), Bitmap.Config.ARGB_8888);
        Canvas c = new Canvas(returnedBitmap);
        v.draw(c);
    
        return returnedBitmap;
    }

    e

    public void takeScreen() {
        Bitmap bitmap = ImageUtils.loadBitmapFromView(this, view); //get Bitmap from the view
        String mPath = Environment.getExternalStorageDirectory() + File.separator + "screen_" + System.currentTimeMillis() + ".jpeg";
        File imageFile = new File(mPath);
        OutputStream fout = null;
        try {
            fout = new FileOutputStream(imageFile);
            bitmap.compress(Bitmap.CompressFormat.JPEG, 90, fout);
            fout.flush();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            fout.close();
        }
    }

    Le immagini vengono salvate nella memoria esterna cartella.

    • Si dovrebbe chiudere la FileOutputStream in un blocco finally. Se si verifica un’eccezione, ora il flusso non sarà chiusa.
    • Qual è la view si sta passando da ImageUtils.loadBitmapFromView(this, view)?
    • perché non si utilizza v. layout(0, 0, v. getMeasuredWidth(), v. getMeasuredHeight()); ? Non che modifica la visualizzazione (v) ?
  10. 11

    Si può provare la seguente libreria:
    http://code.google.com/p/android-screenshot-library/
    Android Screenshot Biblioteca (ASL) consente a livello di programmazione di catturare screenshot da dispositivi Android senza obbligo di avere i privilegi di accesso principali. Invece, l’ASL si avvale di un servizio nativo in esecuzione in background, avviato tramite l’Android Debug Bridge (ADB) una volta per dispositivo di avvio.

    • Ho provato questo.ma ci vuole screenshot dell’app in esecuzione da solo. La sua cant aiutare se voglio prendere screenshot della schermata principale. non è come prendere screenshot della schermata principale withthat codice?
    • Questo è ciò che la domanda si chiede di fare. Si può elaborare con una nuova risposta, invece di chiedere una questione a parte.
    • ho installato questa app, ma mostra nativo di servizio non trovato. Help me please.
    • Stesso Problema anche per me.. “Nativi Servizio Non è in Esecuzione!!”
    • Stesso con me “Nativi Servizio Non è in Esecuzione!!”…. chiunque può aggiungere il testo della guida qui?
    • stesso qui! “Native Servizio Non È In Esecuzione!!” e nella loro ultima versione 1.2 che utilizzano API di LIVELLO 19 classi, come Presa ad esempio.
    • necessario attivare il servizio tramite pc ogni volte che il telefono si riavvia. 🙁

  11. 8
    public class ScreenShotActivity extends Activity{
    
    private RelativeLayout relativeLayout;
    private Bitmap myBitmap;
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    
        relativeLayout = (RelativeLayout)findViewById(R.id.relative1);
        relativeLayout.post(new Runnable() {
            public void run() {
    
                //take screenshot
                myBitmap = captureScreen(relativeLayout);
    
                Toast.makeText(getApplicationContext(), "Screenshot captured..!", Toast.LENGTH_LONG).show();
    
                try {
                    if(myBitmap!=null){
                        //save image to SD card
                        saveImage(myBitmap);
                    }
                    Toast.makeText(getApplicationContext(), "Screenshot saved..!", Toast.LENGTH_LONG).show();
                } catch (IOException e) {
                    //TODO Auto-generated catch block
                    e.printStackTrace();
                }
    
            }
        });
    
    }
    
    public static Bitmap captureScreen(View v) {
    
        Bitmap screenshot = null;
        try {
    
            if(v!=null) {
    
                screenshot = Bitmap.createBitmap(v.getMeasuredWidth(),v.getMeasuredHeight(), Config.ARGB_8888);
                Canvas canvas = new Canvas(screenshot);
                v.draw(canvas);
            }
    
        }catch (Exception e){
            Log.d("ScreenShotActivity", "Failed to capture screenshot because:" + e.getMessage());
        }
    
        return screenshot;
    }
    
    public static void saveImage(Bitmap bitmap) throws IOException{
    
        ByteArrayOutputStream bytes = new ByteArrayOutputStream();
        bitmap.compress(Bitmap.CompressFormat.PNG, 40, bytes);
        File f = new File(Environment.getExternalStorageDirectory() + File.separator + "test.png");
        f.createNewFile();
        FileOutputStream fo = new FileOutputStream(f);
        fo.write(bytes.toByteArray());
        fo.close();
    }
    
    }

    AGGIUNGERE AUTORIZZAZIONE

    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
    • Questa risposta prende uno screenshot del proprio app – non il “schermo del telefono”, come chiesto nella domanda – o sto facendo qualcosa di sbagliato?
  12. 8

    In base alla risposta di @JustinMorris sopra e @NiravDangi qui https://stackoverflow.com/a/8504958/2232148 dobbiamo prendere lo sfondo e primo piano di una vista e di assemblarle come questo:

    public static Bitmap takeScreenshot(View view, Bitmap.Config quality) {
        Bitmap bitmap = Bitmap.createBitmap(view.getWidth(), view.getHeight(), quality);
        Canvas canvas = new Canvas(bitmap);
    
        Drawable backgroundDrawable = view.getBackground();
        if (backgroundDrawable != null) {
            backgroundDrawable.draw(canvas);
        } else {
            canvas.drawColor(Color.WHITE);
        }
        view.draw(canvas);
    
        return bitmap;
    }

    Il parametro di qualità richiede una costante di Bitmap.Config, tipicamente Bitmap.Config.RGB_565 o Bitmap.Config.ARGB_8888.

    • disegno di tela con il colore bianco in caso di fondo è null ha fatto il trucco per me. Grazie Oliver
  13. 6

    Si può provare a fare qualcosa di simile a questo,

    Ottenere una cache bitmap da un layout o una vista facendo qualcosa del genere
    Prima devi setDrawingCacheEnabled di un layout(un linearlayout o relativelayout, o vista)

    poi

    Bitmap bm = layout.getDrawingCache()

    Poi fai quello che vuoi con il bitmap. Trasformare in un file di immagine o inviare il bitmap uri da qualche altra parte.

    • Questo è il metodo migliore, se è la vostra applicazione che si sta scrivendo una bitmap. Inoltre, fate attenzione di metodi che hanno ritardi prima di prendere la cache… come Notifica…() per la lista di opinioni.
    • Non solo. Il layout deve essere visualizzato sullo schermo prima. E ‘ la “cache” stai ricevendo dopotutto. Cercato di nascondere la visualizzazione e prendere screenshot in background(in teoria), ma non ha funzionato.
    • Gran lunga più efficiente rispetto ad altre soluzioni
  14. 6

    Per chi desidera acquisire una GLSurfaceView, il getDrawingCache o disegno su tela metodo non funziona.

    Devi leggere il contenuto di OpenGL framebuffer dopo che il telaio è stato eseguito il rendering. C’è una buona risposta qui

  15. 6

    Strada più breve è

    FrameLayout layDraw = (FrameLayout) findViewById(R.id.layDraw); /*Your root view to be part of screenshot*/
    layDraw.buildDrawingCache();
    Bitmap bmp = layDraw.getDrawingCache();
  16. 5

    Ho creato una semplice libreria che prende uno screenshot da un View e ti dà un oggetto Bitmap o lo salva direttamente su qualsiasi percorso che si desidera

    https://github.com/abdallahalaraby/Blink

    • Non richiede telefono radicata ?
    • Non tifo richiesto 🙂
    • In uso u menzionato Screenshot.takeScreenshot(view, mPath); imageView.setImageBitmap(Screenshot.getBitmapScreenshot(view, mPath)); Come arrivare visualizzazione delle attività in corso. Io non voglio usare l’id del file xml.
    • utilizzare takeScreenshotForScreen() invece.
  17. 4

    Se si vuole prendere screenshot da fragment di seguire questo:

    1. Ignorare onCreateView():

               @Override
              public View onCreateView(LayoutInflater inflater, ViewGroup container,
                                       Bundle savedInstanceState) {
                  //Inflate the layout for this fragment
                  View view = inflater.inflate(R.layout.fragment_one, container, false);
                  mView = view;
              }
    2. Logica per prendere screenshot:

       button.setOnClickListener(new View.OnClickListener() {
       @Override
       public void onClick(View v) {
           View view =  mView.findViewById(R.id.scrollView1);
            shareScreenShotM(view, (NestedScrollView) view); 
       }
    3. metodo shareScreenShotM)():

      public void shareScreenShotM(View view, NestedScrollView scrollView){
      
           bm = takeScreenShot(view,scrollView);  //method to take screenshot
          File file = savePic(bm);  //method to save screenshot in phone.
          }
    4. metodo takeScreenShot():

               public Bitmap takeScreenShot(View u, NestedScrollView z){
      
                  u.setDrawingCacheEnabled(true);
                  int totalHeight = z.getChildAt(0).getHeight();
                  int totalWidth = z.getChildAt(0).getWidth();
      
                  Log.d("yoheight",""+ totalHeight);
                  Log.d("yowidth",""+ totalWidth);
                  u.layout(0, 0, totalWidth, totalHeight);
                  u.buildDrawingCache();
                  Bitmap b = Bitmap.createBitmap(u.getDrawingCache());
                  u.setDrawingCacheEnabled(false);
                  u.destroyDrawingCache();
                   return b;
              }
    5. metodo savePic():

       public static File savePic(Bitmap bm){
      
              ByteArrayOutputStream bytes = new ByteArrayOutputStream();
              bm.compress(Bitmap.CompressFormat.JPEG, 100, bytes);
               File sdCardDirectory =  new File(Environment.getExternalStorageDirectory() + "/Foldername");
      
             if (!sdCardDirectory.exists()) {
                  sdCardDirectory.mkdirs();
            }
             // File file = new File(dir, fileName);
            try {
               file = new File(sdCardDirectory, Calendar.getInstance()
                  .getTimeInMillis() + ".jpg");
              file.createNewFile();
              new FileOutputStream(file).write(bytes.toByteArray());
              Log.d("Fabsolute", "File Saved::--->" + file.getAbsolutePath());
               Log.d("Sabsolute", "File Saved::--->" + sdCardDirectory.getAbsolutePath());
           } catch (IOException e) {
                e.printStackTrace();
            }
           return file;
         }

    Per l’attività, si può semplicemente utilizzare View v1 = getWindow().getDecorView().getRootView(); invece di mView

  18. 4

    Appena si estende taraloca risposta. È necessario aggiungere le seguenti righe per farlo funzionare. Ho fatto il nome dell’immagine statica. Si prega di assicurarsi di utilizzare taraloca timestamp variabile in caso si necessità dinamico il nome dell’immagine.

        //Storage Permissions
    private static final int REQUEST_EXTERNAL_STORAGE = 1;
    private static String[] PERMISSIONS_STORAGE = {
            Manifest.permission.READ_EXTERNAL_STORAGE,
            Manifest.permission.WRITE_EXTERNAL_STORAGE
    };
    
    private void verifyStoragePermissions() {
        //Check if we have write permission
        int permission = ActivityCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE);
    
        if (permission != PackageManager.PERMISSION_GRANTED) {
            //We don't have permission so prompt the user
            ActivityCompat.requestPermissions(this, PERMISSIONS_STORAGE, REQUEST_EXTERNAL_STORAGE);
        }else{
            takeScreenshot();
        }
    }
    
    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    
        if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
            if (requestCode == REQUEST_EXTERNAL_STORAGE) {
                takeScreenshot();
            }
        }
    }

    E nel AndroidManifest.xml file seguenti voci devono:

    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
  19. 3

    La maggior parte delle risposte a questa domanda l’ Canvas metodo di disegno o disegno cache metodo. Tuttavia, il Vista.setDrawingCache() metodo è deprecato in API 28. Attualmente raccomandato API per fare screenshot è il PixelCopy classe disponibile da API 24 (ma i metodi che accettano Window parametro sono disponibili API 26 == Android 8.0 Oreo). Ecco un esempio di Kotlin codice per il recupero di un Bitmap:

    @RequiresApi(Build.VERSION_CODES.O)
    fun saveScreenshot(view: View) {
        val window = (view.context as Activity).window
        if (window != null) {
            val bitmap = Bitmap.createBitmap(view.width, view.height, Bitmap.Config.ARGB_8888)
            val locationOfViewInWindow = IntArray(2)
            view.getLocationInWindow(locationOfViewInWindow)
            try {
                PixelCopy.request(window, Rect(locationOfViewInWindow[0], locationOfViewInWindow[1], locationOfViewInWindow[0] + view.width, locationOfViewInWindow[1] + view.height), bitmap, { copyResult ->
                    if (copyResult == PixelCopy.SUCCESS) {
                        saveBitmap(bitmap)
                    }
                    //possible to handle other result codes ...
                }, Handler())
            } catch (e: IllegalArgumentException) {
                //PixelCopy may throw IllegalArgumentException, make sure to handle it
            }
        }
    }
    • Problema con PixelCopy oltre il drawingCache soluzione è, che sembra catturare solo pixel visibile. il resto è nero per me. Quindi non è possibile condividere le cose che è scorrevole e, in parte, al di fuori del telaio. Avete una soluzione per questo?
    • Hai ragione. Allo stesso modo si può causare un problema se un altro punto di Vista è mostrato sopra la Vista voglio screenshot (e. g. quando il cassetto è aperto). In questi casi mi basta usare la Tela antica metodo 🙁
    • È possibile prendere screenshot su qualsiasi app in esecuzione utilizzando PixelCopy?
  20. 2

    Il parametro di vista è il principale oggetto layout.

    public static Bitmap screenShot(View view) {
                        Bitmap bitmap = null;
                        if (view.getWidth() > 0 && view.getHeight() > 0) {
                            bitmap = Bitmap.createBitmap(view.getWidth(),
                                    view.getHeight(), Bitmap.Config.ARGB_8888);
                            Canvas canvas = new Canvas(bitmap);
                            view.draw(canvas);
                        }
                        return bitmap;
                    }
  21. 1

    Per le applicazioni di sistema solo!

    Process process;
    process = Runtime.getRuntime().exec("screencap -p " + outputPath);
    process.waitFor();

    Nota: le applicazioni di Sistema non c’è bisogno di correre “su” per eseguire questo comando.

  22. 0

    Prendere screenshot di una vista in android.

    public static Bitmap getViewBitmap(View v) {
        v.clearFocus();
        v.setPressed(false);
    
        boolean willNotCache = v.willNotCacheDrawing();
        v.setWillNotCacheDrawing(false);
    
        int color = v.getDrawingCacheBackgroundColor();
        v.setDrawingCacheBackgroundColor(0);
    
        if (color != 0) {
            v.destroyDrawingCache();
        }
        v.buildDrawingCache();
        Bitmap cacheBitmap = v.getDrawingCache();
        if (cacheBitmap == null) {
            return null;
        }
    
        Bitmap bitmap = Bitmap.createBitmap(cacheBitmap);
    
        v.destroyDrawingCache();
        v.setWillNotCacheDrawing(willNotCache);
        v.setDrawingCacheBackgroundColor(color);
    
        return bitmap;
    }
  23. 0

    Piena Di Scorrimento Pagina Screenshot

    Se si desidera acquisire una visione completa di screenshot (Che contiene una scrollview o giù di lì) quindi avere un controllo presso la libreria

    https://github.com/peter1492/LongScreenshot

    Tutto quello che dovete fare è importare il Gradel, e creare un oggetto di BigScreenshot

    BigScreenshot longScreenshot = new BigScreenshot(this, x, y);

    Un callback viene ricevuto con la bitmap di Screenshot presi mentre automaticamente a scorrere la visualizzazione dello schermo di gruppo e alla fine assemblati insieme.

    @Override public void getScreenshot(Bitmap bitmap) {}

    Che può essere salvato in galleria o qualsiasi tipo di utilizzo è necessario, dopo

  24. -1

    se si desidera catturare una vista o un layout come RelativeLayout o LinearLayout etc.
    basta usare il codice :

    LinearLayout llMain = (LinearLayout) findViewById(R.id.linearlayoutMain);
    Bitmap bm = loadBitmapFromView(llMain);

    ora è possibile salvare questo bitmap su un dispositivo di archiviazione da :

    FileOutputStream outStream = null;
    File f=new File(Environment.getExternalStorageDirectory()+"/Screen Shots/");
    f.mkdir();
    String extStorageDirectory = f.toString();
    File file = new File(extStorageDirectory, "my new screen shot");
    pathOfImage = file.getAbsolutePath();
    try {
        outStream = new FileOutputStream(file);
        bm.compress(Bitmap.CompressFormat.PNG, 100, outStream);
        Toast.makeText(getApplicationContext(), "Saved at "+f.getAbsolutePath(), Toast.LENGTH_LONG).show();
        addImageGallery(file);
        //mail.setEnabled(true);
        flag=true;
    } catch (FileNotFoundException e) {e.printStackTrace();}
    try {
        outStream.flush();
        outStream.close();
    } catch (IOException e) {e.printStackTrace();}
    • e dove si trova loadBitmapFromView codice?

Lascia un commento