“无法附加空文件” - 将图像从内存共享到Gmail时

时间:2016-04-22 20:40:06

标签: java android

我正在尝试使用Intent共享存储在内部存储器中的图像。过程如下

  • 生成布局的位图
  • 将此位图保存到内部
  • 中的文件
  • memory使用intent(到Gmail)
  • 分享此文件

执行时似乎只生成空文件(因此无法附加到Gmail)。我不确定代码在哪里变得凌乱。所以,这里是代码

生成和保存位图的方法

    public void generateAndSaveBitmap(View layout) {
//Generate bitmap
        layout.setDrawingCacheEnabled(true);
        layout.buildDrawingCache();
        Bitmap imageToSave = layout.getDrawingCache();
        layout.destroyDrawingCache();

//Create a file and path
        File directory = layout.getContext().getDir("images", Context.MODE_PRIVATE);
        File fileName = new File(directory, "sharableImage.jpg");
        if (fileName.exists())
            fileName.delete();

//Compress and save bitmap under the mentioned fileName
        FileOutputStream fos = null;
        try {
            fos = new FileOutputStream(fileName);
            imageToSave.compress(Bitmap.CompressFormat.JPEG, 100, fos);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (fos != null) {
                try {
                    fos.flush();
                    fos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
//    return directory.getAbsolutePath();
    }

分享图片的方法

public void moreShareOptions(Context context) {
    Intent shareIntent = new Intent(Intent.ACTION_SEND);
    shareIntent.setType("image/jpg");
    File photoFile = new File("sharableImage.jpg");
    shareIntent.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(photoFile));
    context.startActivity(Intent.createChooser(shareIntent, context.getResources().getText(R.string.opsh_share_this)));
}

这两个方法放在onClickListener中,如下所示

    case R.id.more_share_options:
        Thread t = new Thread(new Runnable() {
            @Override
            public void run() {
                optionsShareThis.generateAndSaveBitmap(toolbarWebView);
            }
        });

        t.start();
        optionsShareThis.moreShareOptions(this);
        break;

试图找到问题。我错过了什么吗? 另外,我很想听听改进代码的建议(如果有的话)。

此致

修改

感谢您提及FileProvider。很高兴知道getCacheDir。但是,即使使用FileProvider后,我的代码仍继续返回空文件。我一直在探索多种资源,但无法使用上述布局的实际图像生成文件。

generateAndSaveBitmap(视图布局) - 此方法未进行任何更改(上述代码)。

以下是与FileProvider相关的代码

AndroidManifest.xml - 无需讨论新内容

<provider
    android:name="android.support.v4.content.FileProvider"
    android:authorities="com.example.android"
    android:exported="false"
    android:grantUriPermissions="true">

    <meta-data
        android:name="android.support.FILE_PROVIDER_PATHS"
        android:resource="@xml/file_path" />

</provider>

file_path.xml - 用于提及文件名及其路径

<?xml version="1.0" encoding="utf-8"?>

<paths>
    <files-path name="sharableImage" path="images/"/>
</paths>

moreShareOptions() -

    public void moreShareOptions(Context context) {

// concatenate the internal cache folder with the document its path and filename
        final File file = new File(context.getFilesDir(), "images/sharableImage.jpg");
// let the FileProvider generate an URI for this private file
        final Uri uri = FileProvider.getUriForFile(context, "com.example.android", file);
// create an intent, so the user can choose which application he/she wants to use to share this file

        final Intent intent;
        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP) {
            intent = ShareCompat.IntentBuilder.from((Activity) context)
                    .setType("image/jpg")
                    .setStream(uri)
                    .createChooserIntent()
                    .addFlags(Intent.FLAG_ACTIVITY_NEW_DOCUMENT)
                    .addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);

            context.startActivity(intent);
        }else {
        intent = ShareCompat.IntentBuilder.from((Activity) context)
                .setType("image/jpg")
                .setStream(uri)
                .createChooserIntent()
                .addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET)
                .addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);

            context.startActivity(intent);
        }
    }

我失踪了什么?我花了几个小时寻找获得必要结果的方法。没什么好吃的。因此,我发布此代码时希望其他人可以指出我出错的地方。

1 个答案:

答案 0 :(得分:0)

第三方应用无法访问您的内部存储空间。而且,特别是从Android N开始,sharing files is strongly discouraged in general

相反,use FileProvider to share the content。这也包含在the documentation中。