0

I have saved a Bitmap to internal storage with:

private String saveToInternalSorage(Bitmap bitmapImage){
    ContextWrapper cw = new ContextWrapper(mContext);
     // path to /data/data/yourapp/app_data/imageDir
    File directory = cw.getDir("imageDir", Context.MODE_PRIVATE);
    // Create imageDir
    File mypath=new File(directory,"profile.jpg");

    FileOutputStream fos = null;
    try {           

        fos = new FileOutputStream(mypath);

   // Use the compress method on the BitMap object to write image to the OutputStream
        bitmapImage.compress(Bitmap.CompressFormat.PNG, 100, fos);
        fos.close();
    } catch (Exception e) {
        e.printStackTrace();
    }
    return directory.getAbsolutePath();
}

And now I want to share it with:

Intent sharingIntent = new Intent(Intent.ACTION_SEND);
        sharingIntent.putExtra(Intent.EXTRA_STREAM, file);
        sharingIntent.setType("image/jpeg");
        getContext().startActivity(Intent.createChooser(sharingIntent,"Erfolg teilen!"));

How can I get the Bitmap of the internal Storage and "make it" to a "file", which I can share?

I try to load it with:

        ContextWrapper cw = new ContextWrapper(mContext);
        File directory = cw.getFilesDir();
        File file = new File(directory, "profile.jpg");

But this doesn't work it shows no picture if I want to share it (At Facebook it says it couldn't load the image). Is the saving Method correct?

L3n95
  • 1,505
  • 3
  • 25
  • 49

4 Answers4

1

Change mode_private to mode_world_readable

Also Change :

File directory = cw.getFilesDir();

To :

cw.getDir ("profile.jpg", Context.MODE_WORLD_READABLE);
  • This is deprecated and same problem that it cannot be loaded. – L3n95 Apr 09 '14 at 20:23
  • In theory this will make it possible, and the alleged deprecation is a bit absurd. However, some 3rd party apps will not bother to check if they can actually read the file, but simply *assume* that they can't read a private storage file belonging to someone else, and only accept literal files that are located on the External Storage. This was commonly seen with at least some version of Gmail for example when trying to provide an attachment. – Chris Stratton Apr 09 '14 at 20:23
  • But sending it via Bluetooth isnt possible too. Is the saving and loading method correct? – L3n95 Apr 09 '14 at 20:26
  • If you want to work around the lazy assumptions of other apps, then either put it on the External Storage or be a content provider rather than trying to hand off a literal file. – Chris Stratton Apr 09 '14 at 20:28
  • How can I save and load it from external storage? I tried it with: String path1 = Images.Media.insertImage(getContext().getContentResolver(), cs, "profile.jpg", null); Uri file = Uri.parse(path1); This worked perfectly but then I had the problem that the App closed, when the smartphone had no sd-card. – L3n95 Apr 09 '14 at 20:33
  • Don‘t forget to add external storage permessions –  Apr 09 '14 at 22:33
  • I tried this but still it says it couldn't load the image. – L3n95 Apr 10 '14 at 06:16
  • @Lars3n95 can you check if you have added this permissions –  Apr 10 '14 at 08:20
  • I have done that but same problem. Can I check if the image is saved there correctly? – L3n95 Apr 10 '14 at 09:56
  • @Lars3n95 yes, Window -> Show View (Other..) -> File Explore /mnt/sdcard –  Apr 10 '14 at 10:01
  • @Lars3n95 but befor you must creat the SD card ? –  Apr 10 '14 at 10:07
  • I don't want to save it on the sd card, because not every smartphone has a sd card and then the app crashes. – L3n95 Apr 10 '14 at 10:59
  • @Lars3n95 check out this http://stackoverflow.com/questions/11239202/list-of-files-of-saved-to-the-internal-storage –  Apr 10 '14 at 11:02
0

I have saved a Bitmap to internal storage with

There is no obvious value to your ContextWrapper.

How can I get the Bitmap of the internal Storage and "make it" to a "file", which I can share?

You already have it as a file. That is what saveToInternalSorage() does.

To make it shareable, use FileProvider. However, you may need to switch from getDir("imageDir", Context.MODE_PRIVATE) to use something rooted at getFilesDir().

CommonsWare
  • 986,068
  • 189
  • 2,389
  • 2,491
  • I tried to load it now with: ContextWrapper cw = new ContextWrapper(mContext); File directory = cw.getFilesDir(); File file = new File(directory, "profile.jpg"); I have to say i really don't know why this contextWrapper is there. – L3n95 Apr 09 '14 at 20:04
  • @Lars3n95: "I have to say i really don't know why this contextWrapper is there" -- neither do I. BTW, here is a sample app demonstrating the use of `FileProvider`: https://github.com/commonsguy/cw-omnibus/tree/master/ContentProvider/V4FileProvider – CommonsWare Apr 09 '14 at 20:57
0

According to the documentation EXTRA_STREAM should contain a URI holding a stream of data associated with the Intent.

So, in your example replace file with Uri.fromFile(file):

Intent sharingIntent = new Intent(Intent.ACTION_SEND);
sharingIntent.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(file));
sharingIntent.setType("image/jpeg");

You might also need to grant the recipient of this intent permission to perform read operations on the URI:

sharingIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); 
ihuk
  • 1,336
  • 9
  • 15
  • 2
    The file on internal storage is private; the recipient will not be able to read it. – CommonsWare Apr 09 '14 at 19:58
  • How can I change that it is not private? – L3n95 Apr 09 '14 at 20:03
  • Yeah, he might need to add FLAG_GRANT_READ_URI_PERMISSION to the intent. Thanks, updated. – ihuk Apr 09 '14 at 20:06
  • Did this but still doesn't work perfectly (see updated question) – L3n95 Apr 09 '14 at 20:12
  • @Lars3n95 not sure why you need a file? What happens when you call startActivity with the code above? – ihuk Apr 09 '14 at 20:27
  • It opens the dialog where I can choose an App for sharing it. And when I choose Bluetooth it tells me that it was not possible to send it and at Facebook it says it couldn't load the Image. – L3n95 Apr 09 '14 at 20:31
0

I ran into this issue. I was using Context.getFilesDir() to save my bitmap (and avoid request write permissions). You need use a file provider in your manifest This is my file provider

 <provider
            android:name="android.support.v4.content.FileProvider"
            android:authorities="${applicationId}"
            android:exported="false"
            android:grantUriPermissions="true">
            <meta-data
                android:name="android.support.FILE_PROVIDER_PATHS"
                android:resource="@xml/file_paths" />
        </provider>

My paths, Im using a subfolder called Screenshots

<paths>
    <files-path
        name="my_images"
        path="Screenshots/" />
</paths>

And then you can use this intent to share the bitmap (Im suing kotlin)

val shareIntent = Intent(Intent.ACTION_SEND)
                .apply {
                    type = "image/jpeg"
                    putExtra(Intent.EXTRA_STREAM, FileProvider.getUriForFile(applicationContext, BuildConfig.APPLICATION_ID, file))
                    addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
                }
        startActivity(Intent.createChooser(shareIntent, "Share Image"));

More info here: https://developer.android.com/reference/android/support/v4/content/FileProvider.html#Permissions

Javier
  • 1,469
  • 2
  • 20
  • 38