如何摆脱“允许Expo Go修改这张照片”?Android 中的警报

Tha*_*nda 5 android media-library react-native expo imagepicker

我正在开发 React Native expo 应用程序,该应用程序使用expo-image-picker拍摄照片,并使用expo-media-library将该图像保存到不同的位置。

一切似乎都工作正常,但每次用户捕获图像时都会弹出此弹出窗口。这种情况在 Android 上不断发生。它正在影响用户体验。

如果你们能帮我解决这个问题,那就太好了。谢谢

允许 Expo Go 修改这张照片吗?

版本

“反应本机”:“0.64.3”

“世博会”:“〜44.0.0”

"expo-image-picker": "~12.0.2"

"expo-media-library": "~14.0.0"

这是我用来存档提到的功能的代码。

import * as ImagePicker from "expo-image-picker";
import * as MediaLibrary from "expo-media-library";

const savePhoto = async (data, onSucess) => {
  const asset = await MediaLibrary.createAssetAsync(data?.uri);
  const album = await MediaLibrary.createAlbumAsync(
    "TEST_FOLDER",
    asset,
    false
  );
  const albumAssets = await MediaLibrary.getAssetsAsync({
    album: album,
    first: 1,
    sortBy: [[MediaLibrary.SortBy.creationTime, false]],
  });
  if (albumAssets?.assets[0]) {
    onSucess(albumAssets.assets[0], data);
  }
};

const takePicture = async (onSucess, onError) => {
  let data = await ImagePicker.launchCameraAsync({
    mediaTypes: ImagePicker.MediaTypeOptions.Images,
    quality: 0.8,
    allowsEditing: true,
    base64: true,
  });
  if (data.cancelled === false) {
    savePhoto(data, onSucess);
  } else {
    onError();
  }
};
Run Code Online (Sandbox Code Playgroud)

这是app.json文件。

{
  "expo": {
    "name": "product",
    "slug": "product_frontend",
    "version": "1.0.0",
    "orientation": "landscape",
    "icon": "./assets/images/icon.png",
    "userInterfaceStyle": "automatic",
    "splash": {
      "image": "./assets/images/splash.png",
      "resizeMode": "contain",
      "backgroundColor": "#ffffff"
    },
    "plugins": [
      [
        "expo-media-library",
        {
          "photosPermission": "Allow $(PRODUCT_NAME) to access your photos.",
          "savePhotosPermission": "Allow $(PRODUCT_NAME) to save photos.",
          "isAccessMediaLocationEnabled": "true"
        }
      ],
      [
        "expo-image-picker",
        {
          "cameraPermission": "Allow $(PRODUCT_NAME) to access your camera",
          "photosPermission": "The app accesses your photos to let you share them with your friends."
        }
      ]
    ],
    "updates": {
      "fallbackToCacheTimeout": 0
    },
    "assetBundlePatterns": ["**/*"],
    "ios": {
      "supportsTablet": true
    },
    "android": {
      "package": "com.comapny.product",
      "adaptiveIcon": {
        "foregroundImage": "./assets/images/adaptive-icon.png",
        "backgroundColor": "#FFFFFF"
      },
      "softwareKeyboardLayoutMode": "pan",
      "permissions": []
    },
    "web": {
      "favicon": "./assets/images/favicon.png"
    },
    "scheme": "product"
  }
}
Run Code Online (Sandbox Code Playgroud)

如果你们能帮我解决这个问题,那就太好了。谢谢。

小智 1

我也遇到了这个问题,并相信我找到了解决方法。

当你打电话时createAlbumAsync你可以过去true。这将复制资产数据,而不是移动或修改它,这会导致 android 弹出窗口。然后,您可以导入并使用expo-file-system删除原始图像(如果这对您来说很重要)。请参阅下面我的代码:

import * as ImagePicker from 'expo-image-picker';
import * as MediaLibrary from 'expo-media-library';
import * as FileSystem from 'expo-file-system';

const takePhoto = async () => {
    let asset = {};
    let data = await ImagePicker.launchCameraAsync();
    const permission = await MediaLibrary.requestPermissionsAsync();
    if (!data.cancelled) {
      if (permission.granted) {
        try {
          // create an asset using the imagePicker data uri, on android a folder cannot be created without a pre-existing asset
          asset = await MediaLibrary.createAssetAsync(data.uri);
          // getAlbumAsync returns null if no album is found
          const existingFolder = await MediaLibrary.getAlbumAsync(
            'AlbumName'
          );
          // if the album doesn't exist, create it
          if (!existingFolder) {
              await MediaLibrary.createAlbumAsync(
              'AlbumName',
              asset,
              // passing true copies the file and doesn't move it, moving it is what triggers the android modify popup
              true
            );
            // since the file is copied and not moved we can then delete the original after
            await FileSystem.deleteAsync(data.uri);
          } else {
            // if the album exists add the asset to it
            // similar to createAlbumAsync, passing true copies the file and doesn't move it, so again we delete the original after
            MediaLibrary.addAssetsToAlbumAsync(asset, existingFolder.id, true);
            await FileSystem.deleteAsync(data.uri);
          }
        } catch (error) {
          console.log(error);
        }
      } else {
        console.log('Storage permissions must be enabled to save file');
      }
  }
}
Run Code Online (Sandbox Code Playgroud)

希望这可以帮助!