react-native-view-shot icon indicating copy to clipboard operation
react-native-view-shot copied to clipboard

On Android, captured image cannot be shared (empty share dialog)

Open jordanwegener opened this issue 1 year ago • 1 comments

Captured image cannot be shared on Android

After a capture, trying to share using the resultant URI results in an empty message which is rejected by the elected app to share to.

  const captureReceipt = async () => {
    if (!viewShotRef.current?.capture) {
      console.error('Failed to capture receipt: viewShotRef is not defined');
      return;
    }

    try {
      const uri = await captureRef(viewShotRef, {
        fileName: `payment-receipt-${new Date().toISOString()}`,
        format: 'png',
        quality: 0.9,
      });

      console.log(uri);
      Share.share({url: `file://${uri}`});
    } catch (error) {
      console.error('Failed to capture receipt', error);
    }
  };
file:///data/user/0/<censored-application-name>/cache/payment-receipt-2024-08-01T02%3A20%3A37.614Z839463387167296804.png

Version & Platform

"react-native-view-shot": "^3.8.0" "react-native": "0.74.1"

npm ls react-native react-native-view-shot
<censored-application-name>.../src
├─┬ @apolloeagle/[email protected]
│ └── [email protected] deduped
├─┬ @okta/[email protected]
│ └── [email protected] deduped
├─┬ @react-native-async-storage/[email protected]
│ └── [email protected] deduped
├─┬ @react-native-firebase/[email protected]
│ └── [email protected] deduped
├─┬ @react-navigation/[email protected]
│ ├─┬ @react-navigation/[email protected]
│ │ └── [email protected] deduped
│ └── [email protected] deduped
├─┬ @react-navigation/[email protected]
│ └── [email protected] deduped
├─┬ @react-navigation/[email protected]
│ └── [email protected] deduped
├─┬ @testing-library/[email protected]
│ └── [email protected] deduped
├─┬ @testing-library/[email protected]
│ └── [email protected] deduped
├─┬ [email protected]
│ └── [email protected] deduped
├─┬ [email protected]
│ └── [email protected] deduped
├─┬ [email protected]
│ └── [email protected] deduped
├─┬ [email protected]
│ └── [email protected] deduped
├─┬ [email protected]
│ └── [email protected] deduped
├─┬ [email protected]
│ └── [email protected] deduped
├─┬ [email protected]
│ └── [email protected] deduped
├─┬ [email protected]
│ └── [email protected] deduped
├─┬ [email protected]
│ └── [email protected] deduped
├─┬ [email protected]
│ └── [email protected] deduped
├─┬ [email protected]
│ └── [email protected] deduped
├─┬ [email protected]
│ └── [email protected] deduped
├─┬ [email protected]
│ └── [email protected] deduped
├─┬ [email protected]
│ └── [email protected] deduped
├─┬ [email protected]
│ └── [email protected] deduped
├─┬ [email protected]
│ └── [email protected] deduped
├─┬ [email protected]
│ └── [email protected] deduped
├─┬ [email protected]
│ └── [email protected] deduped
├─┬ [email protected]
│ └── [email protected] deduped
└─┬ [email protected] overridden
  └─┬ @react-native/[email protected]
    └── [email protected] deduped

Platform: Android

Expected behavior

The image URI doesn't produce an empty message when shared.

Actual behavior

Share bottom sheet has no content, only contacts/apps: image

If an app is selected: image

Steps to reproduce the behavior

See code above

jordanwegener avatar Aug 01 '24 02:08 jordanwegener

Looked further into this and it seems that react native's Share and the Share provided by react-native-share are both unable to access the file created by ViewShot. After copying it out of the app's cache and into external storage using react-native-fs it can be shared from there.

import RNFS from 'react-native-fs';
import Share from 'react-native-share';
import {captureRef} from 'react-native-view-shot';

const filename = 'capture';

try {
  const uri = await captureRef(screenCaptureRef, {
    format,
    quality: 0.8,
  });
  const filePath = `${RNFS.DocumentDirectoryPath}/${filename}.${format}`;
  await RNFS.moveFile(uri, filePath);
  await Share.open({
    url: `file://${filePath}`,
    failOnCancel: false,
  });
} catch (error) {
  console.error('Error capturing viewshot:', error);
}

Not sure if this is specific to the app I'm working on or a broader issue with ongoing android compat. As it's not mentioned anywhere in docs (where sharing the resultant file is mentioned) I assume it's not the expected outcome so I'm inclined to leave this open until a maintainer can comment

jordanwegener avatar Aug 02 '24 08:08 jordanwegener