通过意图共享后删除文件

时间:2011-01-05 21:00:09

标签: android file email android-activity delete-file

我试图通过Android的Intent.ACTION_SEND功能共享它后删除一个临时文件。现在我正在为结果启动活动,在OnActivityResult中,我正在删除该文件。不幸的是,这只有在我使用断点进行调试时才有效,但是当我让它自由运行并说,通过电子邮件发送文件时,电子邮件没有附件。

我认为发生的事情是我的活动是在通过电子邮件发送之前删除该文件。我没有得到的是为什么,不应该只在其他活动完成后调用onActivityResult?

我也尝试删除onResume中的文件,但没有运气。

有更好的方法吗?

4 个答案:

答案 0 :(得分:5)

我注意到了类似方法的相同行为。在看logcat的错误时,我看到gmail抱怨它无法找到附件。所以,是的,似乎意图返回BEFORE之前实际上已经读取了附件文件。

我还没有找到解决方案,但它可能会像:

  • 将文件移动到某个目录,所以我知道这是我决定发送的文件
  • 通过ACTION_SEND
  • 将其作为附件发送
  • 在下一个onResume上为我的开始屏幕活动,删除“已发送”目录中的文件,这些文件比某个时间范围早,该时间范围足够长,以便实际发生发送

选择一个合适的时间框架可能会很棘手,因为gmail(或其他ACTION_SEND提供程序)可能不会实际读取文件,直到它有网络连接。我认为24小时应该是合理的,在我的情况下我正在处理诊断日志,所以如果用户已经离开网络很长一段时间,那么很快就会删除它。

如果您的文件内容是文本并且它不是非常大,则更简单的方法可能是读取文件的内容并使用Intent.putExtra(android.content.Intent.EXTRA_TEXT,yourText)将其内联到正文中消息。

答案 1 :(得分:2)

我做的是以下内容。

我使用了:

myfile.deleteOnExit();

然而,正如D.R.在下面的评论正确答案中提到,这不保证文件删除。这就是我在共享活动返回后也删除文件的原因。如果文件存在,我删除该文件。因为应用程序有时会崩溃,所以我把它放在try{}里面然后就可以了。

我不知道为什么它对您不起作用,但对我而言,它至少适用于Gmail附件,TextSecure,环聊。

课堂退场:

static File file;

在调用意图的方法中

        Intent share = new Intent(Intent.ACTION_SEND);
        share.setType("image/png");

        // Compress the bitmap to PNG
        ByteArrayOutputStream bytes = new ByteArrayOutputStream();
        bitmap.compress(Bitmap.CompressFormat.PNG, 100, bytes);

        // Temporarily store the image to Flash
        File sdCard = Environment.getExternalStorageDirectory();
        File dir = new File (sdCard.getAbsolutePath() + "/FolderName");
        dir.mkdirs();

        // This file is static.
        file = new File(dir, "FileName.png");

        try {
            file.createNewFile();
            FileOutputStream fo = new FileOutputStream(file);
            fo.write(bytes.toByteArray());
            fo.flush();
            fo.close();
        } catch (IOException e) {
            e.printStackTrace();
        }

        // Share compressed image
        share.putExtra(Intent.EXTRA_STREAM, Uri.parse("file:///"+file.getPath()));

        /** START ACTIVITY **/
        startActivityForResult(Intent.createChooser(share,"Share Image"),1);

        // Delete Temporary file
        file.deleteOnExit();     // sometimes works

在额外的方法中:

protected void onActivityResult(int requestCode, int resultCode, Intent data) {   
        // Because app crashes sometimes without the try->catch 
        try {
            // if file exists in memory
            if (file.exists()) {
                file.delete();
            }
        } catch (Exception e) {
            Log.d(LOG,"Some error happened?");
        }

    }

答案 2 :(得分:0)

另一个可能的答案是在你的应用程序恢复时创建一个新线程,立即标记当前时间,让线程休眠多久,你觉得文件发送是合理的,当线程恢复时,只删除文件在之前标记的时间之前创建。这将使您能够仅删除应用程序恢复时存储位置中的内容,还可以为gmail提供时间来收发电子邮件。代码片段:(我使用C#/ Xamarin,但你应该明白这一点)

public static void ClearTempFiles()
{
    Task.Run(() =>
    {

        try
        {
            DateTime threadStartTime = DateTime.UtcNow;
            await Task.Delay(TimeSpan.FromMinutes(DeletionDelayMinutes));
            DirectoryInfo tempFileDir = new DirectoryInfo(TempFilePath);
            FileInfo[] tempFiles = tempFileDir.GetFiles();
            foreach (FileInfo tempFile in tempFiles)
            {
                if (tempFile.CreationTimeUtc < threadStartTime)
                {
                    File.Delete(tempFile.FullName);
                }
            }
        }
        catch { }
    });
}

@Martijn Pieters这个答案是一个处理多个问题的不同解决方案。如果有的话,我发布的其他问题应该标记为重复,因为它们是同一个问题。我发布了每一个以确保有这个问题的人都可以找到解决方案。

答案 3 :(得分:-1)

我设法让它与之合作:

File tbd = new File(sharePath);
tbd.deleteOnExit();

这似乎会在活动关闭时删除文件。