【问题标题】:take screenshot from layout and share via android从布局中截取屏幕截图并通过 android 分享
【发布时间】:2015-06-11 19:18:39
【问题描述】:

我使用下面的代码从我的布局中截取屏幕截图并通过 android Intent 共享它,但在所选应用中捕获的屏幕截图没有显示任何内容。

@Override
public void onClick(View view) {

           shareBitmap(this,takeScreenshot());

}

public Bitmap takeScreenshot() {
    try{
        View rootView = getWindow().getDecorView().findViewById(R.id.lyt_main_report_activity);
        rootView.setDrawingCacheEnabled(true);
        return rootView.getDrawingCache();
    }catch (Exception ex){
        ex.printStackTrace();
    }

    return null;

}
public static void shareBitmap(Context context, Bitmap bitmap){

    //save to sd card
    try {

        File cachePath = new File(context.getCacheDir(), "images");
        cachePath.mkdirs(); // don't forget to make the directory
        FileOutputStream stream = new FileOutputStream(cachePath + "/image.png"); // overwrites this image every time
        bitmap.compress(Bitmap.CompressFormat.PNG, 100, stream);
        stream.close();

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

    try{
        //start share activity
        File imagePath = new File(context.getCacheDir(), "images");
        File newFile = new File(imagePath, "image.png");
        Uri contentUri = Uri.fromFile(newFile); //FileProvider.getUriForFile(context, "com.persianswitch.apmb.app.fileprovider", newFile);

        if (contentUri != null) {
            Intent shareIntent = new Intent();
            shareIntent.setAction(Intent.ACTION_SEND);
            //shareIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); // temp permission for receiving app to read this file
           // shareIntent.setDataAndType(contentUri, context. getContentResolver().getType(contentUri));
            shareIntent.putExtra(Intent.EXTRA_STREAM, contentUri);
            shareIntent.setType("image/*");
            context.startActivity(Intent.createChooser(shareIntent, context.getResources().getString(R.string.share_using)));

        }
    }catch (Exception ex){
        ex.printStackTrace();
    }
}

【问题讨论】:

  • 这条线shareBitmap(this,takeScreenshot());不会给你带来问题吗?
  • 问题是生成的位图缓冲区只包含0
  • 所以你的意思是rootView.getDrawingCache();返回一个成功的位图?
  • 返回成功的位图,但位图的缓冲区只包含 0 值
  • 最后一个问题你有没有开启硬件加速?

标签: android android-intent bitmap


【解决方案1】:

请使用此代码这是经过测试的代码:

public static void takeScreenshot(Context context, View view) {

    String path = Environment.getExternalStorageDirectory().toString() +
        "/" + "test.png";

    View v = view.findViewById(android.R.id.content).getRootView();
    v.setDrawingCacheEnabled(true);

    v.setDrawingCacheEnabled(true);
    Bitmap bitmap = Bitmap.createBitmap(v.getDrawingCache());
    v.setDrawingCacheEnabled(false);

    OutputStream out = null;
    File imageFile = new File(path);

    try {
        out = new FileOutputStream(imageFile);
        // choose JPEG format
        bitmap.compress(Bitmap.CompressFormat.JPEG, 90, out);
        out.flush();
    } catch (FileNotFoundException e) {
        // manage exception
    } catch (IOException e) {
        // manage exception
    } finally {

        try {
            if (out != null) {
                out.close();
            }

        } catch (Exception exc) {}

    }

    // onPauseVideo();
    Intent share = new Intent(Intent.ACTION_SEND);

    share.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(imageFile));
    share.setType("image/png");
    ((Activity) context).startActivityForResult(
        Intent.createChooser(share, "Share Drawing"), 111);

}

【讨论】:

    【解决方案2】:

    由于 DrawingCache() 在 28 以上已弃用,因此使用 Canvas 将解决许多问题。以下答案可用于共享屏幕截图,包括文本,无需请求权限。

    截图

        private Bitmap takeScreenShot(View view) {
        Bitmap bitmap = Bitmap.createBitmap(view.getWidth(), view.getHeight(), Bitmap.Config.ARGB_8888);
        Canvas canvas = new Canvas(bitmap);
        view.draw(canvas);
        return bitmap;
    }
    

    分享截图

     private void shareContent(Bitmap bitmap) {
        String bitmapPath = MediaStore.Images.Media.insertImage(
                binding.getRoot().getContext().getContentResolver(), bitmap, "title", "");
        Uri uri = Uri.parse(bitmapPath);
        Intent shareIntent = new Intent(Intent.ACTION_SEND);
        shareIntent.setType("image/*");
        shareIntent.putExtra(Intent.EXTRA_SUBJECT, "App");
        shareIntent.putExtra(Intent.EXTRA_TEXT, "Currently a new version of KiKi app is available.");
        shareIntent.putExtra(Intent.EXTRA_STREAM, uri);
        binding.getRoot().getContext().startActivity(Intent.createChooser(shareIntent, "Share"));
    }
    

    【讨论】:

      【解决方案3】:

      如果没有任何反应,这意味着您的 Bitmapnull 请检查一下。或者您也可以使用View.buildDrawingCache();,它将视图绘制到位图,然后调用您的View.getDrawingCache();

      另外,当硬件加速打开时,启用绘图缓存对渲染没有影响,因为系统使用了不同的加速机制,它忽略了标志。如果您想为视图使用位图,即使启用了硬件加速,请参阅setLayerType(int, android.graphics.Paint) 了解有关如何启用软件和硬件层的信息。

      引用来自documented page

      希望对你有帮助

      【讨论】:

        【解决方案4】:

        提示:当您的设备具有外部存储时,选中的答案有效。例如,在三星 6 上,它没有。因此,您需要使用文件提供程序。

        以防有人像我一样掉进这个陷阱。问题是您将图像的名称输入了两次。

        FileOutputStream stream = new FileOutputStream(cachePath + "/image.png"); 
        

        然后再一次。

         File newFile = new File(imagePath, "image.png");
        

        将第二个改为

        File newFile = new File(imagePath);
        

        否则 contentUri 会为您提供屏幕截图的位图。我希望这可以帮助别人。我花了 3 个小时才弄明白:)

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2016-03-30
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2014-03-18
          相关资源
          最近更新 更多