Android: 在htc Hero手机上选择Gmail应用程序时,Intent.ACTION_SEND和EXTRA_STREAM无法附加任何图像

12

在默认邮件应用程序上,仿真器上的一切都正常。 但是,当我从我的 Hero 使用 Gmail 应用程序发送电子邮件时,接收到的邮件没有附件。 Hero 上的默认邮件应用程序正常工作。

我该如何使此代码与 Hero 上的 Gmail 应用程序配合使用?
您可以在下面看到代码。

    private void startSendIntent() {
        Bitmap bitmap = Bitmap.createBitmap(editableImageView.getWidth(), editableImageView.getHeight(), Bitmap.Config.RGB_565);
        editableImageView.draw(new Canvas(bitmap));
        File png = getFileStreamPath(getString(R.string.file_name));
        FileOutputStream out = null;
        try {
            out = openFileOutput(getString(R.string.file_name), MODE_WORLD_READABLE);
            bitmap.compress(Bitmap.CompressFormat.PNG, 100, out);
            out.flush();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (out != null) out.close();
            }
            catch (IOException ignore) {}
        }
        final Intent emailIntent = new Intent(android.content.Intent.ACTION_SEND);
        emailIntent.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(png));
        emailIntent.setType("image/png");
        startActivity(Intent.createChooser(emailIntent, getString(R.string.send_intent_name)));
}

我在日志中看到以下内容:

02-05 17:03:37.526: DEBUG/Gmail(11511): URI FOUND:file:///sdcard/DCIM/100MEDIA/IMAG0001.jpg
02-05 17:03:37.535: DEBUG/Gmail(11511): ComposeActivity added to message:0 attachment:|IMAG0001.jpg|image/jpeg|0|image/jpeg|LOCAL_FILE|file:///sdcard/DCIM/100MEDIA/IMAG0001.jpg size:0
02-05 17:03:37.585: INFO/Gmail(11511): >>>>> Attachment uri: file:///sdcard/DCIM/100MEDIA/IMAG0001.jpg
02-05 17:03:37.585: INFO/Gmail(11511): >>>>>           type: image/jpeg
02-05 17:03:37.585: INFO/Gmail(11511): >>>>>           name: IMAG0001.jpg
02-05 17:03:37.585: INFO/Gmail(11511): >>>>>           size: 0

谢谢您的回答。


1
你的Hero使用的是哪个版本号?我遇到过几个问题,其中HTC的Sense覆盖层破坏了Android的功能,在某些情况下无法接收OUT_GOING_CALL意图,如果你使用的是最新版本,则可能是另一个问题。 - Donal Rafferty
我已经构建了2.73.411.17和软件版本1.0.0.A6288。 - shinydev
3个回答

32

以下代码解决了我的问题:

Bitmap screenshot = Bitmap.createBitmap(_rootView.getWidth(), _rootView.getHeight(), Bitmap.Config.RGB_565);
_rootView.draw(new Canvas(screenshot));

String path = Images.Media.insertImage(getContentResolver(), screenshot, "title", null);
Uri screenshotUri = Uri.parse(path);

final Intent emailIntent = new Intent(android.content.Intent.ACTION_SEND);
emailIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
emailIntent.putExtra(Intent.EXTRA_STREAM, screenshotUri);
emailIntent.setType("image/png");

startActivity(Intent.createChooser(emailIntent, "Send email using"));

关键在于我将屏幕截图保存到媒体库中,然后可以成功地从那里发送文件。


2
@Aleks N.,这是一个不错的方法(意思是它很有效-我试过了)。但我的唯一问题是-图像是否存储在手机上某个地方?还是临时存储? - Phil
10
之后有没有任何方法可以删除这个文件? - Kevin Coulombe
@KevinCoulombe 你在分享文件后成功删除了文件吗? - AndroidDev
如果我没记错的话,我最终为我发送的每个图像重复使用了相同的文件名。当应用程序被卸载时,它会保留最后发送的图像,但那是我当时能想到的最好办法。如果你找到任何删除它的方法,请在这里发布一个链接,我可能会在某个时候再次处理这个项目,而这是那些永远停留在错误跟踪器中的票之一... - Kevin Coulombe
1
顺便提一下,这需要android.permission.WRITE_EXTERNAL_STORAGE权限。 - Greg Ennis
显示剩余5条评论

7

getFileStreamPath()openFileOutput()会在私有目录中创建文件,其他应用程序(如Gmail)无法访问。请使用外部存储来创建可以公开访问的文件:

private static final int REQUEST_SHARE = 39714;

private File png = null;

private void startSendIntent() {
    png = new File(new File(Environment.getExternalStorageDirectory(), "Pictures"), getString(R.string.file_name));

    FileOutputStream out = null;
    try {
        out = new FileOutputStream(png);
        bitmap.compress(Bitmap.CompressFormat.PNG, 100, out);
        out.flush();
    } catch (Exception e) {
        e.printStackTrace();
    } finally {
        try {
            if (out != null) out.close();
        }
         catch (IOException ignore) {}
        }
        final Intent emailIntent = new Intent(android.content.Intent.ACTION_SEND);
        emailIntent.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(png));
        emailIntent.setType("image/png");
        startActivityForResult(Intent.createChooser(emailIntent, getString(R.string.send_intent_name)), REQUEST_SHARE);
    }
}

当外部存储不可用时,比如它被挂载为USB驱动器,这种方法不起作用。请参考存储API指南了解更多关于检测外部存储是否可用的信息。
如果您的最小API级别是8或以上,则可以使用Context.getExternalCacheDir()Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES)作为父目录。
除非您使用了getExternalCacheDir(),否则确保使用唯一的文件名,以防止意外覆盖其中一个用户的文件。
最后,在分享操作完成后,您可以重写onActivityResult()来删除该文件:
protected void onActivityResult(int requestCode, int resultCode, Intent data) {

    if(requestCode == REQUEST_SHARE) {
        if(this.png == null) {
            return;
        }

        this.png.delete();
    }
}

非常感谢这个技巧。 这是完成工作的最简单方法。 在我的情况下,Context.getExternalCacheDir()无法正常工作,但是Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS)完美地发挥作用。 - Hong

2

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