2

I'm using expo to build a react-native app. I'm trying to implement the expo imagePicker so the user can pick an image from their gallery or camera roll and use it on the app however after the ImagePicker ahs asked for permissions and I allow them, nothing else happens. Thee user isn't taken to their gallery or cameraRoll. There are no errors currently however imagePicker isn't working correctly. What changes do I need to make to my code?

ImageSelector.js file

import * as React from 'react';
import { Button, Image, View } from 'react-native';
import * as ImagePicker from 'expo-image-picker';
import * as Permissions from 'expo-permissions';
import * as Constants from 'expo-Constants';

export default class ImageSelector extends React.Component {
  state = {
    image: null,
  };

  render() {
    let { image } = this.state;

    return (
      <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
        <Button
          title="Pick an image from camera roll"
          onPress={this._pickImage}
        />
        {image &&
          <Image source={{ uri: image }} style={{ width: 200, height: 200 }} />}
      </View>
    );
  }

  componentDidMount() {
    this.getPermissionAsync();
  }

  getPermissionAsync = async () => {
    if (Constants.platform.android) {
      const { status } = await Permissions.askAsync(Permissions.CAMERA_ROLL);
      if (status !== 'granted') {
        alert('Sorry, we need camera roll permissions to make this work!');
      }
    }
  }

  _pickImage = async () => {
    let result = await ImagePicker.launchImageLibraryAsync({
      mediaTypes: ImagePicker.MediaTypeOptions.All,
      allowsEditing: true,
      aspect: [4, 3],
    });

    console.log(result);

    if (!result.cancelled) {
      this.setState({ image: result.uri });
    }
  };
}
SK1dev
  • 1,049
  • 1
  • 20
  • 52
  • Do you have all the permissions? As the doc says, "You will also need to add UsageDescription on iOS and some permissions on Android, refer to the Install doc. " – Sujil Maharjan Aug 05 '19 at 15:22
  • @SujilMaharjan I don't have an AndroidManifest.xml file already to store the permissions, do I need to create this first? I'm using expo app. – SK1dev Aug 05 '19 at 15:30
  • For that, refer to the expo doc: https://docs.expo.io/versions/latest/sdk/permissions/ – Sujil Maharjan Aug 05 '19 at 15:36

2 Answers2

2

If you use Expo, you don't have to use it. And you need the right to storage space.

You can run expo install expo-image-picker expo-permissions and get Permission Permissions.CAMERA_ROL

Example

import * as React from 'react';
import { Button, Image, View } from 'react-native';
import * as ImagePicker from 'expo-image-picker';
import * as Permissions from 'expo-permissions';
import * as Constants from 'expo-Constants';

export default class ImagePickerExample extends React.Component {
  state = {
    image: null,
  };

  render() {
    let { image } = this.state;

    return (
      <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
        <Button
          title="Pick an image from camera roll"
          onPress={this._pickImage}
        />
        {image &&
          <Image source={{ uri: image }} style={{ width: 200, height: 200 }} />}
      </View>
    );
  }

  componentDidMount() {
    this.getPermissionAsync();
  }

  getPermissionAsync = async () => {
    if (Constants.platform.ios) {
      const { status } = await Permissions.askAsync(Permissions.CAMERA_ROLL);
      if (status !== 'granted') {
        alert('Sorry, we need camera roll permissions to make this work!');
      }
    }
  }

  _pickImage = async () => {
    let result = await ImagePicker.launchImageLibraryAsync({
      mediaTypes: ImagePicker.MediaTypeOptions.All,
      allowsEditing: true,
      aspect: [4, 3],
    });

    console.log(result);

    if (!result.cancelled) {
      this.setState({ image: result.uri });
    }
  };
}
hong developer
  • 13,291
  • 4
  • 38
  • 68
  • Thank you for your help. Should I replace my code with this? @hong develop – SK1dev Aug 05 '19 at 15:55
  • @RJDdev This code is a simple example that I created to help you because you are using Expo. You can refer to what is helpful to you. – hong developer Aug 05 '19 at 15:56
  • I can't up-vote it because I am new to stackoverflow although I've just ticked it. I tried to add code from your example in order to get the permissions and I've updated my question with the new code. I am getting the error: Identifier 'ImagePicker' has already been declared so maybe there's something wrong with my code still. @hong develop – SK1dev Aug 05 '19 at 16:40
  • @RJDdev The module you called up has the same class name as you defined. The computer makes an error because it thinks it redefines the module you have brought in. – hong developer Aug 06 '19 at 00:33
  • @hong-developer I see, I've changed the class name and import statement and updated my question with the error I'm seeing. There was ImagePicker stated many other times in my code but I didn't think I should change it in the other places because I think it's referring to the 'expo-image-picker'. – SK1dev Aug 06 '19 at 05:36
  • You didn't install Constants. You can run `expo install expo-Constants` – hong developer Aug 06 '19 at 05:48
  • My example is using a module that I didn't tell you to install. To follow my example, you need to install a module. – hong developer Aug 06 '19 at 05:49
  • Thank you for your response. I've installed it now but it still gives the same error. – SK1dev Aug 06 '19 at 05:57
  • Can you show me your package.json and the code you used? – hong developer Aug 06 '19 at 06:10
  • I've added screenshots to my question. I used npm to install expo-constants because yarn wouldn't install it but it seems to be installed correctly. – SK1dev Aug 06 '19 at 06:21
  • As I said in the comments, I didn't ask you to install it using npm. you remove `expo-constants` and run `expo install expo-Constants` – hong developer Aug 06 '19 at 06:25
  • I did that because the command you told me to use didn't work. I believe the expo install expo-Constants command has just worked because I have a different error now. Maybe I'll open a new question with the new error because I seem to have had several problems with my code. – SK1dev Aug 06 '19 at 06:34
  • @RJDdev Why did you cancel the check in my reply? Didn't you answer your question? The current problem is different from the one you asked. – hong developer Aug 07 '19 at 01:29
0

For some reason, this didn't work for me:

Permissions.askAsync(Permissions.CAMERA_ROLL);

I kept getting the following error:

Unhandled promise rejection: Error: Failed to get permissions

So, what finally worked for me, this function is used to pick an image from the media library:

const showImagePicker = async () => {
// Ask the user for the permission to access the media library 
const permissionResult = await ImagePicker.requestMediaLibraryPermissionsAsync();

if (permissionResult.granted === false) {
  alert("You've refused to allow this appp to access your photos!");
  return;
}

const result = await ImagePicker.launchImageLibraryAsync();

// Explore the result
console.log(result);

if (!result.cancelled) {
  setPickedImagePath(result.uri);
      console.log(result.uri);
    }
  }

This function is used to take a photo with the camera:

  const openCamera = async () => {
    // Ask the user for the permission to access the camera
    const permissionResult = await ImagePicker.requestCameraPermissionsAsync();

    if (permissionResult.granted === false) {
      alert("You've refused to allow this appp to access your camera!");
      return;
    }

    const result = await ImagePicker.launchCameraAsync();

    // Explore the result
    console.log(result);

    if (!result.cancelled) {
      setPickedImagePath(result.uri);
      console.log(result.uri);
    }
  }

Get the full code and full explanation here: https://www.kindacode.com/article/image-picker-in-react-native/