Android中屏幕截图变黑的原因是什么?

5

我一直在探索如何在Android中通过编程方式截屏,但是当进行截屏时,我只能够截取到工具栏和黑色屏幕,而没有真正呈现在屏幕上的内容。

我还尝试着截取我为谷歌地图创建的自定义信息窗口布局中的特定TextView。但是,下面第二行代码返回了一个空指针异常。

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

有没有办法在不安装Android截图库的情况下实际截取屏幕上的内容,或者截取自定义InfoWindow布局中的TextView?以下是我的截图方法:
/**
 * 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();
    }
}

编辑:我已经改用源代码提供的方法。

如何在程序中同时截取Google地图v2和XML布局的屏幕截图并合并?

然而,它并没有截屏任何东西。

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

1
你想要的是这个吗?链接 - calvinfly
请检查您的权限是否包括<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />。 - Lips_coder
@CrazyAndroid,这已经在清单文件中了。 - user3586417
@calvinfly,我已经尝试实现那段代码了,但现在它不会截取任何东西。 - user3586417
4个回答

1
使用这段代码。
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();
}

希望这能帮到您。

在这段代码中,出现了“必须从UI线程调用getRootView方法,当前推断的线程是worker”的错误提示,具体出现在以下几行:View v1 = getWindow().getDecorView().getRootView(); v1.setDrawingCacheEnabled(true); Bitmap bitmapscreen_shot = Bitmap.createBitmap(v1 .getDrawingCache()); v1.setDrawingCacheEnabled(false); - user3586417
是的,但在我的端上它运行良好,我得到了完美的屏幕截图和良好的质量。 - Sukhbir

1
我已经想通了!
/**
 * 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");
    }
}

我已经从这个链接中修改了代码,使其不共享而只保存图像。

捕获GoogleMap Android API V2的屏幕截图

谢谢大家的帮助。

0

我遇到了这个问题。在调用v1.setDrawingCacheEnabled(true);之后,我添加了以下代码,

v1.buildDrawingCache();

并且在调用takeScreenshot()方法时加入一些延迟。

问题已经解决。


0
请尝试使用以下代码:
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();
    }
}

对我来说,这仍然会产生一个黑色的截图。这是在截图被拍摄时的Android监视器。http://pastebin.com/Tx5q9AHV - user3586417

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接