5

I have image in assets folder and need to share it with whatsapp application

I tried this code , it keeps give me sharing failed try again ! what's wrong ?!

         Intent share = new Intent(Intent.ACTION_SEND);
      share.setType("image/*");
      share.setPackage("com.whatsapp"); 
    //  share.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(new File("file:///assets/epic/adv.png"))); 
      share.putExtra(Intent.EXTRA_STREAM, Uri.parse("file:///assets/epic/adv.png"));
      this.startActivity(Intent.createChooser(share, "share_via"));
Shymaa Othman
  • 239
  • 1
  • 3
  • 16

3 Answers3

10

This code for share image via whatsapp worked fine for me .

public void shareImageWhatsApp() {

    Bitmap adv = BitmapFactory.decodeResource(getResources(), R.drawable.adv);
    Intent share = new Intent(Intent.ACTION_SEND);
    share.setType("image/jpeg");
    ByteArrayOutputStream bytes = new ByteArrayOutputStream();
    adv.compress(Bitmap.CompressFormat.JPEG, 100, bytes);
    File f = new File(Environment.getExternalStorageDirectory()
            + File.separator + "temporary_file.jpg");
    try {
        f.createNewFile();
        new FileOutputStream(f).write(bytes.toByteArray());
    } catch (IOException e) {
        e.printStackTrace();
    }
    share.putExtra(Intent.EXTRA_STREAM,
            Uri.parse( Environment.getExternalStorageDirectory()+ File.separator+"temporary_file.jpg"));
    if(isPackageInstalled("com.whatsapp",this)){
          share.setPackage("com.whatsapp"); 
          startActivity(Intent.createChooser(share, "Share Image"));

    }else{

        Toast.makeText(getApplicationContext(), "Please Install Whatsapp", Toast.LENGTH_LONG).show();
    }

}

private boolean isPackageInstalled(String packagename, Context context) {
    PackageManager pm = context.getPackageManager();
    try {
        pm.getPackageInfo(packagename, PackageManager.GET_ACTIVITIES);
        return true;
    } catch (NameNotFoundException e) {
        return false;
    }
}
Shymaa Othman
  • 239
  • 1
  • 3
  • 16
6

You have several problems.

First, file:///assets/ is not a valid Uri on any version of Android. Your own application can refer to its own assets via file:///android_asset/.

Second, only you can access your own assets via file:///android_asset/ -- you cannot pass such a Uri to third-party apps. Either copy the file from assets into internal storage and use FileProvider, or you can try my StreamProvider and try to share the data straight out of assets/.

Third, there is no guarantee that com.whatsapp exists on the device, or that com.whatsapp will support ACTION_SEND of file:/// Uri values with a MIME type of image/*, and so you may crash with an ActivityNotFoundException.

Fourth, the user might want to share this image via some other means than WhatsApp. Please allow the user to share where the user wants, by removing the setPackage() call from your Intent.

CommonsWare
  • 986,068
  • 189
  • 2,389
  • 2,491
  • What about a uri of an image in the resources or from a URL ? For resource, I tried to use Uri.parse("android.resource://" + getPackageName() + "/" + imageResId) , but it doesn't seem to work for WhatsApp and for any other app I tried. Looking here: http://stackoverflow.com/q/18502598/878126 , I see it's not possible this way. Is it maybe possible by using FileProvider? Is there an easy way to do it? – android developer Jan 30 '17 at 15:33
  • @androiddeveloper: I do not recommend attempting to share resources that are configuration-dependent (e.g., drawables that vary by density). How `android.resource` handles this is undocumented AFAIK, and it's not like the WhatsApp recipient wants the specific drawable that the sender might send (e.g., a low-res image for an `ldpi` or `mdpi` device). My `StreamProvider` supports raw resources, and you can create your own `ContentProvider` to serve whatever you want. `FileProvider` does not serve resources at all. – CommonsWare Jan 30 '17 at 15:38
  • Well I could put the image in the assets folder or the drawable-nodpi if I wish... Are any of those good alternatives? What about url (of somewhere on the Internet) ? – android developer Jan 30 '17 at 15:41
  • @androiddeveloper: Unless you need the image in your UI, I'd use `assets`. My `StreamProvider` supports serving from assets, or you can create a `ContentProvider` yourself that handles this. "What about url (of somewhere on the Internet) ?" -- some apps might support this, others might not. `file` had been the safest scheme, up until 7.0. `ACTION_SEND` responders *should* support at least `file` and `content`. Whether they support `https` or `http` or `android.resource` will vary. Unfortunately, we cannot filter on this, so YMMV. – CommonsWare Jan 30 '17 at 15:44
  • I see. Can you please share the link to your StreamProvider? Is it easy to import via gradle and start using it? Can you show a tiny snippet of how to use it for assets ? I remember I've handled a similar issue in the past (for APKs), and used my own ContentProvider implementation, so if it will get too complex, I will do it again :) – android developer Jan 30 '17 at 16:02
  • 1
    @androiddeveloper: My CWAC-Provider library is [here](https://github.com/commonsguy/cwac-provider), with instructions and a demo app that, among other things, demonstrates serving assets. You will also see it used in some of my book samples, such as [this one for drag-and-drop](https://github.com/commonsguy/cw-omnibus/tree/master/DragDrop/Permissions). – CommonsWare Jan 30 '17 at 16:41
  • ok. thanks. The sample seems to work fine for sending the asset file, but the viewing of pdf doesn't work for some reason. Is there also a way to use it for resources and/or URL ? I've noticed the repo says it's supported, but I don't see it being demonstrated or explained. I will write on the repo about it, because here it's not related... :) – android developer Jan 31 '17 at 09:07
3

This worked for me

Bitmap imgBitmap=BitmapFactory.decodeResource(getResources(),R.drawable.image);
String imgBitmapPath= MediaStore.Images.Media.insertImage(getContentResolver(),imgBitmap,"title",null);
Uri imgBitmapUri=Uri.parse(imgBitmapPath);
Intent shareIntent=new Intent(Intent.ACTION_SEND);
shareIntent.setType("image/*");
shareIntent.putExtra(Intent.EXTRA_STREAM,imgBitmapUri);
startActivity(Intent.createChooser(shareIntent,"share image using"));
Raunak Verma
  • 211
  • 1
  • 2
  • 9