0

I am trying to send base64 image through the Intent. I've read that if the image is big, I need to put it to the internal storage first and then retrieve it from its path to send it by Intent. The problem is that android is giving me toast like this:

The upload was unsuccessful because it did not contain data.

I need to say that everything is done in my custom WebView where I passed the context. Maybe that's the issue? My API is 21. I put the code here:

 this.webView.setDownloadListener((new DownloadListener() {
                @Override
                public void onDownloadStart(String url, String userAgent, String contentDisposition, String mimetype, long contentLength) {

                        try {
                            if(url != null) {
                                FileOutputStream fos;
                                fos = context.openFileOutput("image.png", Context.MODE_PRIVATE);
                                byte[] decodedStr = Base64.decode(url, Base64.DEFAULT);
                                fos.write(decodedStr);


                                Intent sendIntent = new Intent();
                                sendIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                                sendIntent.setAction(Intent.ACTION_SEND);
                                sendIntent.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(new File("file://" + context.getFilesDir() + "/chart.png")));
                                sendIntent.setType("image/png");
                                getContext().startActivity(sendIntent);
                                fos.flush();
                                fos.close();
                            }
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }                   
            }));

My base64 looks like this:

data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAArgAAAIACAYAAABpWR83AAAgAElEQVR4Xux9B3xU15X+ESBUEEIVgbpAgCq9V9tg3B1jO3FLcUnsuCa2s7v/TeJksym7yaa6pttOcY2Nu8

It is much longer. I just put here a cut version to make my question more readable.

Thanks for your time!

@EDIT

I have the feeling that it is not clear what he wants to achieve. I'm making use of this tutorial: https://developer.android.com/training/sharing/send.html But the thing which is different is base64 image

**@EDIT 2 **

Changed method to putExtra() but now other apps can't read the image

shurrok
  • 795
  • 2
  • 13
  • 43

2 Answers2

0

You have to keep in mind that there is a transaction limit to the 1 mb when you sending data by intent. Send to the activity only uri, and onCreate method, new started activity load image.

Borko
  • 9
  • 2
  • Hmm, yeah I know. That's why I am not trying to directly send image to Intent but using the Internal storage – shurrok Aug 30 '17 at 14:01
0

There are many bugs in this code:

  • You are writing the image to getFilesDir() via openFileOutput(), but third-party apps have no rights to files in that directory

  • You are using a file: Uri, which will not work on Android 7.0+

  • You are putting the Uri in the Intent via setData(), which is not how ACTION_SEND works (use EXTRA_STREAM)

  • You are not closing the file before calling startActivity() (while this should work in practice, it's the sort of thing that you will get yelled at in code reviews)

- You claim the MIME type is image/png, when the content of your file is not a PNG file

Even if you fix those, I question your premise. There are ~7 billion people on this planet. IMHO, few if any of them will want to put a base64-encoded file into some other app, as those apps will not be able to use the file. If you want to allow the user to share an image, share the image, not a base64-encoded version of the image.

CommonsWare
  • 986,068
  • 189
  • 2,389
  • 2,491
  • Well, the image is not created by me. I got the image in base64 and can't change that – shurrok Aug 30 '17 at 14:25
  • 1
    @soommy12: Sorry, I misunderstood. Your question title is misleading, as you are not trying to "send base64 image through Intent". You have decoded the image. You are trying to "send image through Intent". That eliminates one of my stated bugs plus the concerns in my last paragraph, so I amended them with strikethroughs. – CommonsWare Aug 30 '17 at 14:28
  • It's ok. I've already changed my code and its using `putExtra()`. But know Messanger or Instagram can't read this image. Is it becouse they don't have acces to internal storage, right? How to fix it? – shurrok Aug 30 '17 at 14:30
  • @soommy12: Use `FileProvider` to serve up your file, using `FileProvider.getUriForFile()` to get the `Uri` to put into `EXTRA_STREAM`. That will address the first two bullets from my answer. See: https://stackoverflow.com/a/38858040/115145 – CommonsWare Aug 30 '17 at 14:32
  • Is that solution only for sdk 24+ ? I am using 21 for now – shurrok Aug 30 '17 at 14:35
  • 1
    @soommy12: `FileProvider` works back to API Level 15, and older versions of `FileProvider` (or my `StreamProvider`) work back to older API levels than that. – CommonsWare Aug 30 '17 at 14:38