使用 react-native 和 expo 分享屏幕截图和短信(或链接)

问题描述 投票:0回答:1

我正在尝试有一个分享按钮,它会截取应用程序中当前位置的屏幕截图,并将其与一些文本或链接一起分享到社交平台。

我试过使用 expo-sharing、react-native-view-shot 和 expo-file-system,又尝试使用核心 react-native share 和 react-native-view-shot,要么我分享成功屏幕截图或共享文本,但不能两者兼而有之。 我环顾四周但仍然没有成功。

以下是最成功的 2 次尝试:

第一个带有 expo-sharing、expo-file-system 和 react-native-view-shot 的代码, 分享屏幕截图但不分享短信:

const viewShot = React.useRef();
const onShare = async () => {
  try {
    const uri = await viewShot.current.capture();
    const message = 'Your message here';

    // create a temporary file that contains the image and the message
   const tempFilePath = `${FileSystem.cacheDirectory}TempImage.jpg`;
    await FileSystem.writeAsStringAsync(tempFilePath, message, {
      encoding: FileSystem.EncodingType.UTF8,
    });
    await FileSystem.copyAsync({
      from: uri,
      to: tempFilePath,
    });
 
    // share the temporary file using the `Sharing.shareAsync` method
    //await Sharing.shareAsync(`file://${tempFilePath}`, { message });
    await Sharing.shareAsync(uri, { message });
  } catch (error) {
    console.error('Oops, snapshot failed', error);
  }
};

const viewShot = React.useRef();
const onShare = async () => {
  try {
    const uri = await viewShot.current.capture();
    const message = 'Your message here';

    //await Sharing.shareAsync(`file://${tempFilePath}`, { message });
    await Sharing.shareAsync(uri, { message });
  } catch (error) {
    console.error('Oops, snapshot failed', error);
  }
};
return (
        <ViewShot
        style={{flex:1}}
        ref = {viewShot}
        options={{ format: "png", quality: 0.9 }}
        >
        <NavigationContainer>
            
            <Tab.Navigator
                         ......

第二个代码,包含来自 react-native、expo-file-system 和 react-native-view-shot 的核心共享模块, 分享信息但不分享截图:

const viewShot = useRef(null);

  const onShare = async () => {
    try {
      console.log('Sharing...');
      const uri = await takeScreenshot();
      console.log('URI:', uri);
      await Share.share({
        title: 'Share Screenshot',
        message: 'Check out this screenshot!',
        url: `file://${uri}`,
      });
      console.log('Shared successfully');
    } catch (error) {
      console.log(error.message);
    }
  };

  const takeScreenshot = async () => {
    try {
      console.log('Taking screenshot...');
      const uri = await viewShot.current.capture();
      console.log('Screenshot taken:', uri);
      const temporaryDirectory = FileSystem.documentDirectory + 'screenshot.png';
      await FileSystem.copyAsync({ from: uri, to: temporaryDirectory });
      console.log('Screenshot saved to:', temporaryDirectory);
      return temporaryDirectory;
    } catch (error) {
      console.log(error.message);
      throw error;
    }
  };

这个功能看起来微不足道,但我仍然没有设法让它发挥作用。 谢谢。

react-native expo react-native-share expo-file-system react-native-view-shot
1个回答
0
投票

我已经扩展了博览会截屏示例如下(我的示例):


import { useState, useRef } from 'react';
import { StatusBar } from 'expo-status-bar';
import { StyleSheet, View } from 'react-native';
import * as ImagePicker from 'expo-image-picker';
import { GestureHandlerRootView } from 'react-native-gesture-handler';
import * as MediaLibrary from 'expo-media-library';
import { captureRef } from 'react-native-view-shot';

import Button from './components/Button';
import ImageViewer from './components/ImageViewer';
import CircleButton from './components/CircleButton';
import IconButton from './components/IconButton';
import EmojiPicker from './components/EmojiPicker';
import EmojiList from './components/EmojiList';
import EmojiSticker from './components/EmojiSticker';
import * as Sharing from 'expo-sharing';

const PlaceholderImage = require('./assets/images/background-image.png');

export default function App() {
  const [isModalVisible, setIsModalVisible] = useState(false);
  const [showAppOptions, setShowAppOptions] = useState(false);
  const [pickedEmoji, setPickedEmoji] = useState(null);
  const [selectedImage, setSelectedImage] = useState(null);

  const [status, requestPermission] = MediaLibrary.usePermissions();
  const imageRef = useRef();

  if (status === null) {
    requestPermission();
  }

  const pickImageAsync = async () => {
    let result = await ImagePicker.launchImageLibraryAsync({
      allowsEditing: true,
      quality: 1,
    });

    if (!result.canceled) {
      setSelectedImage(result.assets[0].uri);
      setShowAppOptions(true);
    } else {
      alert('You did not select any image.');
    }
  };

  const onReset = () => {
    setShowAppOptions(false);
  };

  const onAddSticker = () => {
    setIsModalVisible(true);
  };

  const onModalClose = () => {
    setIsModalVisible(false);
  };

  const onShareImageAsync = async () => {
    try {
      const localUri = await captureRef(imageRef, {
        height: 440,
        quality: 1,
      });

      await Sharing.shareAsync(localUri, { mimeType: 'image/gif' });
    } catch (e) {
      alert(e.message);
    }
  };

  const onSaveImageAsync = async () => {
    try {
      const localUri = await captureRef(imageRef, {
        height: 440,
        quality: 1,
      });

      await MediaLibrary.saveToLibraryAsync(localUri);
      if (localUri) {
        alert('Saved!');
      }
    } catch (e) {
      console.log(e);
    }
  };

  return (
    <GestureHandlerRootView style={styles.container}>
      <View style={styles.imageContainer}>
        <View ref={imageRef} collapsable={false}>
          <ImageViewer
            ref={imageRef}
            placeholderImageSource={PlaceholderImage}
            selectedImage={selectedImage}
          />
          {pickedEmoji !== null ? (
            <EmojiSticker imageSize={40} stickerSource={pickedEmoji} />
          ) : null}
        </View>
      </View>
      {showAppOptions ? (
        <View style={styles.optionsContainer}>
          <View style={styles.optionsRow}>
            <IconButton icon="refresh" label="Reset" onPress={onReset} />
            <CircleButton onPress={onAddSticker} />
            <IconButton
              icon="save-alt"
              label="Save"
              onPress={onSaveImageAsync}
            />
            <IconButton
              icon="share"
              label="Share"
              onPress={onShareImageAsync}
            />
          </View>
        </View>
      ) : (
        <View style={styles.footerContainer}>
          <Button
            theme="primary"
            label="Choose a photo"
            onPress={pickImageAsync}
          />
          <Button
            label="Use this photo"
            onPress={() => setShowAppOptions(true)}
          />
        </View>
      )}
      <EmojiPicker isVisible={isModalVisible} onClose={onModalClose}>
        <EmojiList onSelect={setPickedEmoji} onCloseModal={onModalClose} />
      </EmojiPicker>
      <StatusBar style="auto" />
    </GestureHandlerRootView>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#25292e',
    alignItems: 'center',
  },
  imageContainer: {
    flex: 1,
    paddingTop: 58,
  },
  footerContainer: {
    flex: 1 / 3,
    alignItems: 'center',
  },
  optionsContainer: {
    position: 'absolute',
    bottom: 80,
  },
  optionsRow: {
    alignItems: 'center',
    flexDirection: 'row',
    justifyContent: 'center',
  },
});

© www.soinside.com 2019 - 2024. All rights reserved.