DEV Community

Kiran Lakhotia
Kiran Lakhotia

Posted on

Sharing GIF via Intent from React Native

I had a GIF, loaded via a URL (the image is stored in a S3 bucket), that I wanted to be sharable from my (react-native) app, via WhatsApp for example.

At first I thought I could simply use the URL in the Intent call to share the GIF, but that didn't work. Turns out you have to download and save the image locally. Then you can share it via an Intent.

Our app uses the Fresco library, so the below code is based on that. The first step was to get a reference to the image pipeline and build an image request to download the GIF.

//final Activity activity = ...;
//final Context context = ...;
//final String message = ...;
//final String imageUrl = ...;
//final String tempFileName = ...;

ImagePipeline imagePipeline = Fresco.getImagePipeline();
ImageRequest imageRequest = ImageRequestBuilder
     .newBuilderWithSource(Uri.parse(imageUrl))
     .setRequestPriority(Priority.HIGH)              
     .setLowestPermittedRequestLevel(ImageRequest.RequestLevel.FULL_FETCH)
     .build();

Next we start downloading the GIF and wait until the download is complete (you can also do this asynchronously).

DataSource<CloseableReference<PooledByteBuffer>> dataSource = imagePipeline.fetchEncodedImage(imageRequest, context);

CloseableReference<PooledByteBuffer> result = DataSources.waitForFinalResult(dataSource);

Assuming the GIF was downloaded OK, I had to save the image on the local file system and then create a URI to that file so it can be used in the share Intent.

if (result != null) {
   final PooledByteBuffer buffer = result.get();
   if (buffer != null) {
      final byte[] data = new byte[buffer.size()];
      buffer.read(0, data, 0, data.length);

      final File localFile = new File(context.getExternalFilesDir(null), tempFileName);

      try(OutputStream os = new FileOutputStream(localFile)) {
         os.write(data);
         os.flush();
      } catch(Exception e) {
         //handle error...
      }

      Uri contentUri = FileProvider.getUriForFile(activity, context.getPackageName() + ".provider", localFile);

      Intent intent = new Intent();
      Intent actionIntent = intent;
      intent.setAction(Intent.ACTION_SEND);
      actionIntent = Intent.createChooser(intent, "Select an app to share");
      //Add text and then Image URI
      intent.putExtra(Intent.EXTRA_TEXT, message);
      intent.putExtra(Intent.EXTRA_STREAM, contentUri);
      intent.setType("*/*");
      intent.setFlags(FLAG_GRANT_READ_URI_PERMISSION);
      activity.startActivity(actionIntent);
   }
}

And that's it. The above code requires (at least) the following permissions

<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

Top comments (2)

Collapse
 
gohan_b82aa4c1be2122176cb profile image
Gohan

Fescobilling removes the inconvenience of traditional bill payment methods by allowing consumers to conveniently check their fesco bill check online from the comfort of their home.

Collapse
 
kris profile image
0xAirdropfarmer

Exactly the article I have been looking for. Thank you for this. The integration information is on point. The use of GIF in React Native and sharing it with intent using the Fresco library. Simple and easy to understand.