android - 为什么在外部存储中保存位图失败,即使位图已正确创建并且可以在 imageView 中显示?

标签 android share screenshot android-external-storage

我可以从文件位置“file:///sdcard/temporary_file.jpg”成功运行 Intent 共享屏幕截图(位图)。但现在我无法将位图保存到该位置。

我在 list 中包含了以下内容

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

还有这个函数来检查权限:

@Override
public void onRequestPermissionsResult(int requestCode,
                                       String[] permissions, int[] grantResults) {
    switch (requestCode) {
        case MY_PERMISSIONS_REQUEST_READ_EXTERNAL_STORAGE:
            if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                // do your stuff
            } else {
                Toast.makeText(iv_ScoreBoard.this, "GET_ACCOUNTS Denied",
                        Toast.LENGTH_SHORT).show();
            }
            break;
        default:
            super.onRequestPermissionsResult(requestCode, permissions,
                    grantResults);
    }
}

点击分享按钮:

    View rootView = getWindow().getDecorView().findViewById(android.R.id.content);
    Bitmap bitmaptest = getScreenShot(rootView);

    Intent share = new Intent(Intent.ACTION_SEND);
    share.putExtra(Intent.EXTRA_TEXT, "@Share from App \"XXYY\"");
    share.setType("image/jpeg");
    ByteArrayOutputStream bytes = new ByteArrayOutputStream();
    bitmaptest.compress(Bitmap.CompressFormat.JPEG, 100, bytes);

    File f = new File(Environment.getExternalStorageDirectory() + File.separator + "temporary_file.jpg");
            try {
                f.createNewFile();
                FileOutputStream fo = new FileOutputStream(f);
                fo.write(bytes.toByteArray());
            } catch (IOException e) {
                e.printStackTrace();
            }
            share.putExtra(Intent.EXTRA_STREAM, Uri.parse("file:///sdcard/temporary_file.jpg"));
            startActivity(Intent.createChooser(share, "Share Image"));

            return true;

getScreenShot(查看 View )

public static Bitmap getScreenShot(View view) {
    View screenView = view.getRootView();
    screenView.setDrawingCacheEnabled(true);
    Bitmap bitmap = Bitmap.createBitmap(screenView.getDrawingCache());
    screenView.setDrawingCacheEnabled(false);
    return bitmap;
}

当点击分享按钮时,它会产生一个黑色的屏幕帽作为图片...... 没有创建文件,没有发现错误。

最佳答案

将文件共享到另一个应用程序时,您需要提供 Uri 权限。

为此,您首先必须在您的 Manifest 中创建一个提供者,如下所示:

<provider
    android:name="android.support.v4.content.FileProvider"
    android:authorities="${applicationId}.provider"
    android:exported="false"
    android:grantUriPermissions="true">
    <meta-data
        android:name="android.support.FILE_PROVIDER_PATHS"
        android:resource="@xml/provider_paths" />
</provider>

@xml/provider_paths 将如下所示:

<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
    <external-path name="SavedImages" path="Android/data/com.yourpackagename.yourappname/files/SavedImages/"/>
</paths>

您必须在您的res->xml 文件夹中创建上面的内容,我将其命名为provider_paths.xml

如果您没有 xml 文件夹,请创建一个。


然后当您共享您的文件时,您应该提供权限:

Uri imageUri;
Intent share = new Intent(Intent.ACTION_SEND);
if (android.os.Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) {
    imageUri = Uri.parse("file:///sdcard/temporary_file.jpg");
}else {
    File newFile = new File(Environment.getExternalStorageDirectory() + File.separator + "temporary_file.jpg");
    imageUri = FileProvider.getUriForFile(getContext(), getContext().getPackageName() + ".provider", newFile);
    share.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
}
share.setType("image/jpeg");
share.putExtra(Intent.EXTRA_STREAM, imageUri);
share(Intent.createChooser(share, "Share image using"));

老实说,我认为您的问题与运行时权限无关。如果是这样,您会崩溃并且不会创建文件。正如您在问题中所述,单击共享按钮时,它会产生一个黑色屏幕帽作为图片...没有创建文件,也没有发现错误。

另一方面,当不提供 Uri 权限时,很可能会产生 Uri 暴露异常。

该文件仍将被创建,但它将是空的。就像您正在经历的那样。

关于android - 为什么在外部存储中保存位图失败,即使位图已正确创建并且可以在 imageView 中显示?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53572410/

相关文章:

Android Phonegap 版本 2.0 或更高版本 facebook、twitter、消息等共享插件的任何更新

.net - 用于屏幕阅读的OCR引擎

asp.net - 使用ASP.Net,是否可以通过编程方式获取浏览器内容的屏幕截图?

android - JSONException : Value of type java. lang.String 无法转换为 JSONObject

android - 如何使用 kotlin 在构造函数中创建传递方法引用的泛型类实例

javascript - 如何在加载时自动更改外部js文件的url

java - 读取网络共享上的文件

android - 移动设备上的程序化屏幕捕获

android - 带有分页的房间实时数据在某些设备中出现 IndexOutOfBoundsException

Fragment 中的 Android ListView 被切断