2

I'm sharing image file to WhatsApp. Whatsapp can't read private file so I saved it into public directory.

I want --> when a user shares the image it should be deleted from the storage.

try {
   String uniqueName = System.currentTimeMillis() + "";
   File tempFile = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES), "ABBM-temp");
   if (!tempFile.exists()) {
       tempFile.mkdirs();
   }
   tempFile = new File(tempFile + uniqueName + ".png");

   FileOutputStream fOut = new FileOutputStream(tempFile);
   b.compress(Bitmap.CompressFormat.PNG, 100, fOut);
   fOut.flush();
   fOut.close();

   final Intent intent = new Intent(android.content.Intent.ACTION_SEND);
   intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
   intent.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(tempFile));
   intent.setType("image/png");
   startActivity(Intent.createChooser(intent, "Share image via"));
   //tempFile.delete();

} catch (Exception e) {
   e.printStackTrace();
   Toast.makeText(getApplicationContext(), "Image not shared, please grant storage permission", Toast.LENGTH_SHORT).show();
}

The above code opens sharing intent but deletes file in background and I'm unable to share the file.

Share file and delete it.

Thank you..

frido
  • 13,065
  • 5
  • 42
  • 56
CodingDevil
  • 125
  • 1
  • 9
  • i think you're closing the stream before passing the tempfile to the intent. try closing the stream after the image is passed on to the intent e.g. after the startActivity – Emotional_Goose Aug 15 '19 at 08:42
  • 1
    @al_khalid No that is not the error. The error is that he deletes the file before the user selects whatsapp and shares the file. What he needs to do is share the file then delete the file. – Gaurav Mall Aug 15 '19 at 09:51
  • @al_khalid actually the code is perfect its sharing file, but where to put the code to delete file after sharing? user clicked Share image button, selects whatsapp, image shared, delete it. – CodingDevil Aug 15 '19 at 19:05

1 Answers1

2

Your code is a bit clunky and is guaranteed to have errors in the latest versions of Android. Here are some observations:

Solution 1

1. Use a File Provider and write to private storage area

I know that you are writing to the main storage, so other apps can read the file, but it shouldn't be done that way. Use a file provider and get a Uri from that. Here is the documentation: File Provider Documentation. When you have your file provider set-up(believe me it's easy, you just have to add a snippet to your manifest and add a xml path) you can write privately to the memory. Like this:

FileOutputStream fOut = openFileOutput("the_name_of_file_here", Context.MODE_PRIVATE);
b.compress(Bitmap.CompressFormat.PNG, 100, fOut);
fOut.flush();
fOut.close();

Then using a getUriForFile you can get a Uri usable by any app that you give access to. Like this:

File file = new File(getFilesDir(), "the_name_of_file_here");
Uri uri = getUriForFile(this, "com.yourpackagename.fileprovider", file);

2. Use ShareCompat

When you have set-up the FileProvider, I suggest to you that for sharing files use ShareCompat instead of a regular sharing activity. ShareCompat has the advantage of being officially supported by Google and you can also share a multitude of files with it. Without having to grant URI_PERMISSION to the other app. Here's an example:

Intent shareIntent = ShareCompat.IntentBuilder.from(this)
                    .setType(type) //This is the MIME type
                    .setStream(uri) //This is the uri we got earlier
                    .getIntent();
shareIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
shareIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);

startActivity(shareIntent); //Starting the activity

I advise you to take a look here at this blog: Getting Started with Share-Compat for more information. Hope this helps.

Solution 2

Traditional Solution:

If you still want to use your function, because of preference or because it suits your app better, here is one thing you can do:

Instead of using startActivity(Intent) use startActivityForResult(Intent, int). With that what you can do is pass an integer value which will work as an id. Then when the file is shared and you return back to your app, the onActivityResult() function will be fired. It will have a requestCode. Like this:

//Create your share intent as you do in your code, then:
startActivityForResult(intent, 512); //I passed 512 you can pass anything you want

Then override this function:

@Override
public void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    
    //Check if it is from the same code, if yes delete the temp file
    if(requestCode == 512) {
       tempFile.delete();
    }
}
Community
  • 1
  • 1
Gaurav Mall
  • 2,372
  • 1
  • 17
  • 33
  • thanks for your answer, But the purpose of saving files in public directories because in android 8.0 whatsapp was not receiving the image file, it said "the file format is not supported" but in lollipop version it was fine.. So I tried sharing image from public directory and it worked. but you know every time if user shares an Image it will be saved there and will eat storage,,, so I want to delete image just after user has shared it. thank you. – CodingDevil Aug 15 '19 at 19:02
  • Yes, for that look at the second solution. – Gaurav Mall Aug 16 '19 at 04:54