Screenshot Black in Android

2019-06-25 09:24发布

I've been working out how to take a screenshot programmatically in android, however when it screenshots I get a toolbar and black screen captured instead of what is actually on the screen.

I've also tried to screenshot a particular TextView within the custom InfoWindow layout I created for the google map. But that creates a null pointer exception on the second line below.

TextView v1 = (TextView)findViewById(R.id.tv_code);
v1.setDrawingCacheEnabled(true);

Is there anyway to either actually screenshot what is on the screen without installing android screenshot library or to screenshot a TextView within a custom InfoWindow layout

This is my screenshot method:

/**
 * Method to take a screenshot programmatically
 */
private void takeScreenshot(){
    try {
        //TextView I could screenshot instead of the whole screen:
        //TextView v1 = (TextView)findViewById(R.id.tv_code);

        View v1 = getWindow().getDecorView().getRootView();
        v1.setDrawingCacheEnabled(true);
        Bitmap bitmap = Bitmap.createBitmap(v1.getDrawingCache());
        v1.setDrawingCacheEnabled(false);


        ByteArrayOutputStream bytes = new ByteArrayOutputStream();
        bitmap.compress(Bitmap.CompressFormat.JPEG, 40, bytes);
        File f = new File(Environment.getExternalStorageDirectory()
                + File.separator + "test.jpg");

        FileOutputStream fo = new FileOutputStream(f);
        fo.write(bytes.toByteArray());
        fo.flush();
        fo.close();

        MediaStore.Images.Media.insertImage(getContentResolver(), f.getAbsolutePath(), f.getName(), f.getName());
        Log.d("debug", "Screenshot saved to gallery");

        Toast.makeText(HuntActivity.this,"Code Saved!",Toast.LENGTH_LONG).show();

    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

EDIT: I have changed the method to the one provided from the source

How can i take/merge screen shot of Google map v2 and layout of xml both programmatically?

However it does not screenshot anything.

public void captureMapScreen() {
    GoogleMap.SnapshotReadyCallback callback = new GoogleMap.SnapshotReadyCallback() {

        @Override
        public void onSnapshotReady(Bitmap snapshot) {
            try {
                View mView = getWindow().getDecorView().getRootView();
                mView.setDrawingCacheEnabled(true);
                Bitmap backBitmap = mView.getDrawingCache();
                Bitmap bmOverlay = Bitmap.createBitmap(
                        backBitmap.getWidth(), backBitmap.getHeight(),
                        backBitmap.getConfig());

                Canvas canvas = new Canvas(bmOverlay);
                canvas.drawBitmap(backBitmap, 0, 0, null);
                canvas.drawBitmap(snapshot, new Matrix(), null);

                FileOutputStream out = new FileOutputStream(
                        Environment.getExternalStorageDirectory()
                                + "/"
                                + System.currentTimeMillis() + ".jpg");

                bmOverlay.compress(Bitmap.CompressFormat.JPEG, 90, out);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    };
    mMap.snapshot(callback);
}

4条回答
爷的心禁止访问
2楼-- · 2019-06-25 09:39

I faced this issue. After v1.setDrawingCacheEnabled(true); I added,

v1.buildDrawingCache();

And put some delay to call the takeScreenshot(); method.

It is fixed.

查看更多
forever°为你锁心
3楼-- · 2019-06-25 09:50

I have figured it out !

/**
 * Method to take a screenshot programmatically
 */
private void takeScreenshot(){
    GoogleMap.SnapshotReadyCallback callback = new GoogleMap.SnapshotReadyCallback() {
        @Override
        public void onSnapshotReady(Bitmap bitmap) {
            Bitmap b = bitmap;
            String timeStamp = new SimpleDateFormat(
                    "yyyyMMdd_HHmmss", Locale.getDefault())
                    .format(new java.util.Date());

            String filepath = timeStamp + ".jpg";

            try{
                OutputStream fout = null;
                fout = openFileOutput(filepath,MODE_WORLD_READABLE);
                bitmap.compress(Bitmap.CompressFormat.JPEG, 90, fout);
                fout.flush();
                fout.close();
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
            saveImage(filepath);
        }
    };
    mMap.snapshot(callback);
}

/**
 * Method to save the screenshot image
 * @param filePath  the file path
 */
public void saveImage(String filePath)
{
    File file = this.getFileStreamPath(filePath);

    if(!filePath.equals(""))
    {
        final ContentValues values = new ContentValues(2);
        values.put(MediaStore.Images.Media.MIME_TYPE, "image/jpeg");
        values.put(MediaStore.Images.Media.DATA, file.getAbsolutePath());
        final Uri contentUriFile = getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
        Toast.makeText(HuntActivity.this,"Code Saved to files!",Toast.LENGTH_LONG).show();
    }
    else
    {
        System.out.println("ERROR");
    }
}

I have adapted the code from this link so it doesn't share and instead just saves the image.

Capture screen shot of GoogleMap Android API V2

Thanks for everyones help

查看更多
Deceive 欺骗
4楼-- · 2019-06-25 09:53

Please try with the code below:

private void takeScreenshot(){
    try {
        //TextView I could screenshot instead of the whole screen:
        //TextView v1 = (TextView)findViewById(R.id.tv_code);
        Bitmap bitmap = null;
        Bitmap bitmap1 = null;
        View v1 = getWindow().getDecorView().getRootView();
        v1.setDrawingCacheEnabled(true);
        bitmap = Bitmap.createBitmap(v1.getDrawingCache());
        try {
        if (bitmap != null)
            bitmap1 = Bitmap.createBitmap(bitmap, 0, 0,
                    v1.getWidth(), v1.getHeight());
        } catch (OutOfMemoryError e) {
            e.printStackTrace();
        }
        v1.setDrawingCacheEnabled(false);


        ByteArrayOutputStream bytes = new ByteArrayOutputStream();
        bitmap1.compress(Bitmap.CompressFormat.JPEG, 40, bytes);
        File f = new File(Environment.getExternalStorageDirectory()
                + File.separator + "test.jpg");

        FileOutputStream fo = new FileOutputStream(f);
        fo.write(bytes.toByteArray());
        fo.flush();
        fo.close();

        MediaStore.Images.Media.insertImage(getContentResolver(), f.getAbsolutePath(), f.getName(), f.getName());
        Log.d("debug", "Screenshot saved to gallery");

        Toast.makeText(HuntActivity.this,"Code Saved!",Toast.LENGTH_LONG).show();

    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }
}
查看更多
三岁会撩人
5楼-- · 2019-06-25 09:57

Use this code

private void takeScreenshot() {
    AsyncTask<Void, Void, Void> asyc = new AsyncTask<Void, Void, Void>() {
        @Override
        protected void onPreExecute() {
            super.onPreExecute();
            objUsefullData.showProgress("Please wait", "");

        }

        @Override
        protected Void doInBackground(Void... params) {
            try {
                // create bitmap screen capture
                View v1 = getWindow().getDecorView().getRootView();
                v1.setDrawingCacheEnabled(true);
                bitmapscreen_shot = Bitmap.createBitmap(v1
                        .getDrawingCache());
                v1.setDrawingCacheEnabled(false);
                String state = Environment.getExternalStorageState();
                File folder = null;
                if (state.contains(Environment.MEDIA_MOUNTED)) {
                    folder = new File(
                            Environment.getExternalStorageDirectory()
                                    + "/piccapella");
                } else {
                    folder = new File(
                            Environment.getExternalStorageDirectory()
                                    + "/piccapella");
                }
                boolean success = true;
                if (!folder.exists()) {
                    success = folder.mkdirs();
                }
                if (success) {
                    // Create a media file name
                    String timeStamp = new SimpleDateFormat(
                            "yyyyMMdd_HHmmss", Locale.getDefault())
                            .format(new java.util.Date());
                    imageFile = new File(folder.getAbsolutePath()
                            + File.separator + "IMG_" + timeStamp + ".jpg");
                    /*
                     * Toast.makeText(AddTextActivity.this,
                     * "saved Image path" + "" + imageFile,
                     * Toast.LENGTH_SHORT) .show();
                     */
                    imageFile.createNewFile();
                } else {
                    /*
                     * Toast.makeText(AddTextActivity.this,
                     * "Image Not saved", Toast.LENGTH_SHORT).show();
                     */
                }
                ByteArrayOutputStream ostream = new ByteArrayOutputStream();
                // save image into gallery
                bitmapscreen_shot.compress(CompressFormat.JPEG, 100,
                        ostream);
                FileOutputStream fout = new FileOutputStream(imageFile);
                fout.write(ostream.toByteArray());
                fout.close();
                Log.e("image_screen_shot", "" + imageFile);
            } catch (Throwable e) {
                // Several error may come out with file handling or OOM
                e.printStackTrace();
            }
            return null;
        }

        @Override
        protected void onPostExecute(Void result) {
            // TODO Auto-generated method stub
            super.onPostExecute(result);
            objUsefullData.dismissProgress();

        }
    };
    asyc.execute();
}

Hope this will help you

查看更多
登录 后发表回答