Delete file after sharing via intent

前端 未结 4 770
轮回少年
轮回少年 2021-01-17 12:13

I\'m trying to delete a temporary file after sharing it via android\'s Intent.ACTION_SEND feature. Right now I am starting the activity for a result and in OnActivityResult,

相关标签:
4条回答
  • 2021-01-17 12:28

    What I did is the following.

    I used the:

    myfile.deleteOnExit();
    

    However, as D.R. mentioned in the comment below correct answer, this does not guarantee the file deletion. This is why I am also deleting the file after the Shared Activity returns. I delete the file if file exists. Because the app crashed sometimes, I put it inside try{} and it works.

    I do not know why it does not work for you, but for me it works at least for Gmail attachement, TextSecure, Hangouts.

    In class delcaration:

    static File file;
    

    In method that calles the Intent:

            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
    

    In an extra method:

    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?");
            }
    
        }
    
    0 讨论(0)
  • 2021-01-17 12:39

    Another potential answer would be to create a new thread when your app resumes, immediately mark the current time, sleep the thread for however long you feel is reasonable for the file to be sent, and when the thread resumes, only delete files created before the previously marked time. This will give you the ability to only delete what was in the storage location at the time your app was resumed, but also give time to gmail to get the email out. Code snippet: (I'm using C#/Xamarin, but you should get the idea)

    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 This answer is a different solution that handles multiple questions. If anything, the other questions that I posted on, should be marked as duplicates because they are the same question. I posted on each of them to ensure that whoever has this problem, can find the solution.

    0 讨论(0)
  • 2021-01-17 12:45

    I noticed the same behavior with a similar approach. While watching logcat for errors I saw gmail complaining that it couldnt find the attachment. So, yes, it seems the intent returns BEFORE gmail has actually read the file for attachment.

    I havent gotten around to a solution yet but it's likely going to be something like:

    • move the file to some directory so I know it's one I've decided to send
    • send it as attachment via ACTION_SEND
    • at next onResume for my start screen activity, delete files in the "sent" directory that are older than some time frame that's reasonably long enough for the send to actually have happened

    Choosing an appropriate time frame might be tricky since it's probably the case that gmail (or other ACTION_SEND providers) dont actually read the file until it has a network connection. I'm thinking 24 hours should be reasonable and in my case I'm dealing with diagnostic logs so there's no real harm in deleting one too soon if the user has been off network for a long period of time.

    If the content of your file is text and it's not obscenely large a simpler approach may be to read the contents of the file and use Intent.putExtra(android.content.Intent.EXTRA_TEXT, yourText) to inline it into the body of the message.

    0 讨论(0)
  • 2021-01-17 12:52

    I have managed to get it to work with:

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

    This seems to delete the file when the activity closes.

    0 讨论(0)
提交回复
热议问题