React-native-image-picker: [Android] ShowImagePicker callback not triggered for takePhoto and chooseFromLibrary

Created on 6 Apr 2016  ·  27Comments  ·  Source: react-native-image-picker/react-native-image-picker

Console won't show any log message for response content when back from take photo session and choose from library session, but only display console log content in cancel and custom button case.

I implementing it on React Native 0.22 and android phone using 4.4.4.
Any idea what happened?
I followed the guide for Android Installation.
I get the npm package via
npm install react-native-image-picker@latest --save

I tried launchCamera() and launchImageLibrary() also cannot trigger callback in my development phone. thanks.

Most helpful comment

Try to add the super method in it

@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
  super.onActivityResult(requestCode, resultCode, data);
  mCallbackManager.onActivityResult(requestCode, resultCode, data);
}

All 27 comments

I saw npm package latest release is 0.18.6 which is published 11 hours ago, may be I will try
npm install react-native-image-picker --save

After tried,
Same problem happened in 0.18.6 package.

Please post some code.

The following code is my component class that makes use of react-native-image-picker

import React, {
  NativeModules,
  Component,
  View,
  TouchableOpacity,
  Text,
  StyleSheet,
} from 'react-native';

const ImagePickerManager = NativeModules.ImagePickerManager;

const styles = StyleSheet.create({
  fullWidthText: {
    padding: 8,
    alignSelf: 'stretch',
    textAlign: 'center',
  },
});

const options = {
  title: 'Select Avatar',
  cancelButtonTitle: 'Cancel',
  takePhotoButtonTitle: 'Take Photo...',
  chooseFromLibraryButtonTitle: 'Choose from Library...',
  customButtons: {
    'Choose Photo from Facebook': 'fb',
  },
  cameraType: 'back',
  mediaType: 'photo',
  maxWidth: 100,
  maxHeight: 100,
  aspectX: 2,
  aspectY: 1,
  quality: 0.2,
  angle: 0,
  allowsEditing: false,
  noData: false,
};

class PhotoShare extends Component {
  constructor(props) {
    super(props);
    this.showImagePicker = this.showImagePicker.bind(this);
    this.state = {
      avatarSource: {},
    };
  }

  showImagePicker() {
    ImagePickerManager.showImagePicker(options, (response) => {
      alert('response');
      console.log('Response = ', response);

      if (response.didCancel) {
        console.log('User cancelled image picker');
      } else if (response.error) {
        console.log('ImagePickerManager Error: ', response.error);
      } else if (response.customButton) {
        console.log('User tapped custom button: ', response.customButton);
      } else { //never trigger this branch of statement in my case
        console.log(response.data);
        const source = { uri: response.uri, isStatic: true };
        console.log(response.uri);
        this.setState({
          avatarSource: source,
        });
      }
    });
  }

  render() {
    return (
      <View>
        <TouchableOpacity onPress={this.showImagePicker}>
          <View>
            <Text style={styles.fullWidthText}>Choose photo to share</Text>
          </View>
        </TouchableOpacity>
      </View>
    );
  }
}

export default PhotoShare;

or even I simplified the function to

  showImagePicker() {
    ImagePickerManager.showImagePicker(options, (response) => {
      alert(response.uri);
      const source = { uri: response.uri, isStatic: true };
      this.setState({
        avatarSource: source,
      });
    });
  }

also can't be triggered for takePhoto and chooseFromLibrary.

And what are you experiencing? Nothing happens at all? Did you follow the readme to add the native code to your android project?

Can you console.log(ImagePickerManager)?

I put the console.log(ImagePickerManager) at first line of showImagePicker() and I get this

Object {}
launchCamera
:
()
launchImageLibrary
:
()
showImagePicker
:
()
__proto__
:
Object

and I double checked I added the native code to my android project.
I can go to choose photo or take photo instance, but after it goes back from them, it won't go to the callback response function. For cancel and fb custom button, the callback response function will be triggered.

I'm not sure then. Put some breakpoints in the Android code and find where it's going wrong is all I can suggest.

Emulation with genymotion also has same problem. Thank for your suggestion.

When I did some Log in Android code, I found after
currentActivity.startActivityForResult(libraryIntent, requestCode);
onActivityResult() event won't be triggered after back from takePhoto and chooseFromLibrary.

Can you run the example project and see if it works? Then, compare your project to the Example. Something is incorrect in your codebase outside of this library.

When I tried my Sony Xperia Z with example project,

  • takePhoto
    is stop at default camera instance and keep halt there
    is okay for another creative effect camera instance
  • chooseFromLibrary
    always stop app from continue running with sony photo app
  • take video
    is okay

Ok well, I can run the Example project with no issues on my Galaxy S6, and no one else has reported this issue so this seems like it's isolated to your Sony Xperia Z. You mention things like "creative effect camera instance" and "sony photo app" - I have no idea what those are. I'm sorry I can't help you more...I only have the Galaxy S6 and I am not very familiar with Android in general. If you figure it out, please submit a pull request.

Hi ! I just put a litte @Override above onActivityResult in Android code, since i'm not able to reproduce i hope this will fix your issue.

https://github.com/marcshilling/react-native-image-picker/commit/f134b9158cb29144fc12f9112f690c0bdef8ea79#diff-e2ac0feb8ce151bd872a7c4ab6b4801dR292

@vshy108 can you install 0.18.9 from npm and see if that fixes your issue?

For my project,
I tried 0.18.9 and also 0.18.10 with my Sony Xperia Z , still have the same problem as title.
I even tried with Sony Xperia T2 Ultra with Android version 5.1.1 and Samsung Galaxy Ace 4 with Android version 4.4.4. All have the same problem in my project as title.

For Example project,
Sorry, the correct name for sony app should be Picture effect, this works well with takePhoto but the Sony Camera app always halt at the Camera app instance and cannot come back from there.

I think the most obvious difference in the build.gradle is I enabled multiDexEnabled in my project because multiDex needed in another package.

I also meet the same problem in android 4.4.4 , the file is available without data in the path '/storage/emulated/0/pictiures', the project touch file in the directory but no data write in. at last , the
reponse return 'didcacel : true' when takephoto or read the library which just make a Blank file。

this.options = {

      title: '修改头像',

      cancelButtonTitle: '取消',

      takePhotoButtonTitle: '拍照',

      chooseFromLibraryButtonTitle: '相册', 

      cameraType: 'back', // 'front' or 'back'

      mediaType: 'photo', // 'photo' or 'video'

      videoQuality: 'high', // 'low', 'medium', or 'high'

      maxWidth: 1000, 

      maxHeight: 1000,

      aspectX: 1,

      aspectY: 1,

      quality: 1, // 0 ~ 1

      angle: 0, // 0 ~ 360

      allowsEditing: true,

      noData: false,

    };
 this.ImagePickerManager.showImagePicker(this.options, (response) => {

      if (response.didCancel) {

        //  it work   when take photo or   read  libaray

        console.log('User cancelled image picker');

      }

      else if (response.error) {

        console.log('ImagePickerManager Error: ', response.error);

      }

      else if (response.customButton) {

        console.log('User tapped custom button: ', response.customButton)

      }else {

          return this.uploadImage(options);

      }

@AkiraXue i feel like your issue is more related to #165. I just push a fix can you try now ?

@vshy108 i just found a couple of thing :

  • make sure you don't have android:launchMode="singleInstance" in your manifest
  • make sure you don't have `noHistory="true"`` in your manifest

Try removing both/one and tell me if it solve your issue

If it still don't work

try to replace (in react-native-image-picker/android/src/main/java/com/imagepicker/ImagePickerModule.java)

currentActivity.startActivityForResult(libraryIntent, requestCode);

with

startActivityForResult(libraryIntent, requestCode);

_line 283_

and

currentActivity.startActivityForResult(cameraIntent, requestCode);

with

startActivityForResult(cameraIntent, requestCode);

_line 227_

Make sure to re-run your project with react-native run-android

I checked those configurations do not exist in my manifest.
I tried to remove the currentActivity at those lines @yfuks mentioned, I fail to re-run project because

error: cannot find symbol startActivityForResult

I just discovered that I override the onActivityResult function in MainActivity.java because of react-native-fbsdk package as following,

    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        mCallbackManager.onActivityResult(requestCode, resultCode, data);
    }

Is it possible the reason I can't have correct onActivityResult for react-native-image-picker package? If yes, any hints to compatible with this change? thanks

Try to add the super method in it

@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
  super.onActivityResult(requestCode, resultCode, data);
  mCallbackManager.onActivityResult(requestCode, resultCode, data);
}

Finally, the problem solved with adding this line
super.onActivityResult(requestCode, resultCode, data);
to onActivityResult() in MainActivity.java
with v0.18.10
Thanks @yfuks and @marcshilling for all the efforts to solve this issue.
In my opinion, this issue can be closed.

I have just came here to report the same issue. Wasted hours to debug.

But adding super does not solve my issue, it leads to another error.

Here is the full error output. Somehow it triggers com.facebook.reactnative.androidsdk.FBSDKDialogBaseJavaModule.onActivityResult(FBSDKDialogBaseJavaModule.java:46)

04-10 16:17:46.898 10030-10030/com.myapp E/AndroidRuntime: FATAL EXCEPTION: main
 Process: com.myapp, PID: 10030
 java.lang.RuntimeException: Failure delivering result ResultInfo{who=null, request=2, result=-1, data=Intent { act=com.htc.HTCAlbum.action.ITEM_PICKER_FROM_COLLECTIONS (has extras) }} to activity {com.myapp/com.myapp.MainActivity}: java.lang.NullPointerException
     at android.app.ActivityThread.deliverResults(ActivityThread.java:3942)
     at android.app.ActivityThread.handleSendResult(ActivityThread.java:3992)
     at android.app.ActivityThread.access$1300(ActivityThread.java:156)
     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1403)
     at android.os.Handler.dispatchMessage(Handler.java:102)
     at android.os.Looper.loop(Looper.java:157)
     at android.app.ActivityThread.main(ActivityThread.java:5872)
     at java.lang.reflect.Method.invokeNative(Native Method)
     at java.lang.reflect.Method.invoke(Method.java:515)
     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:858)
     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:674)
     at dalvik.system.NativeStart.main(Native Method)
  Caused by: java.lang.NullPointerException
     at com.facebook.reactnative.androidsdk.FBSDKDialogBaseJavaModule.onActivityResult(FBSDKDialogBaseJavaModule.java:46)
     at com.facebook.react.bridge.ReactContext.onActivityResult(ReactContext.java:189)
     at com.facebook.react.ReactInstanceManagerImpl.onActivityResult(ReactInstanceManagerImpl.java:597)
     at com.facebook.react.ReactActivity.onActivityResult(ReactActivity.java:180)
     at com.myapp.MainActivity.onActivityResult(MainActivity.java:48)
     at android.app.Activity.dispatchActivityResult(Activity.java:5535)
     at android.app.ActivityThread.deliverResults(ActivityThread.java:3938)
     at android.app.ActivityThread.handleSendResult(ActivityThread.java:3992) 
     at android.app.ActivityThread.access$1300(ActivityThread.java:156) 
     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1403) 
     at android.os.Handler.dispatchMessage(Handler.java:102) 
     at android.os.Looper.loop(Looper.java:157) 
     at android.app.ActivityThread.main(ActivityThread.java:5872) 
     at java.lang.reflect.Method.invokeNative(Native Method) 
     at java.lang.reflect.Method.invoke(Method.java:515) 
     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:858) 
     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:674) 
     at dalvik.system.NativeStart.main(Native Method) 

Full output of my MainActivity.java

package com.myapp;

import android.content.Intent;
import android.os.Bundle;
import com.facebook.react.ReactActivity;
import com.facebook.react.ReactPackage;
import com.facebook.react.shell.MainReactPackage;
import com.brentvatne.react.ReactVideoPackage;
import com.imagepicker.ImagePickerPackage;

import com.facebook.CallbackManager;
import com.facebook.FacebookSdk;
import com.facebook.reactnative.androidsdk.FBSDKPackage;

import java.util.Arrays;
import java.util.List;

public class MainActivity extends ReactActivity {

    CallbackManager mCallbackManager;

    /**
     * Returns the name of the main component registered from JavaScript.
     * This is used to schedule rendering of the component.
     */
    @Override
    protected String getMainComponentName() {
        return "MyApp";
    }

    /**
     * Returns whether dev mode should be enabled.
     * This enables e.g. the dev menu.
     */
    @Override
    protected boolean getUseDeveloperSupport() {
        return BuildConfig.DEBUG;
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        FacebookSdk.sdkInitialize(getApplicationContext());
    }

    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        mCallbackManager.onActivityResult(requestCode, resultCode, data);
    }

    /**
     * A list of packages used by the app. If the app uses additional views
     * or modules besides the default ones, add more packages here.
     */
    @Override
    protected List<ReactPackage> getPackages() {
        return Arrays.<ReactPackage>asList(
            new MainReactPackage(),
            new ReactVideoPackage(),
            new ImagePickerPackage(),
            new FBSDKPackage(mCallbackManager)
        );
    }
}

Well i don't really know what to say. From your stack trace i can tell that you have a java.lang.NullPointerException at _line 48_ of your _MainActivity_.

Are you sure @Override the onActivityResult directly in the _MainActivity_ is a good things to do ?

There is a module that use FacebookSDK and don't override onActivityResult directly in the _MainActivity_
https://github.com/magus/react-native-facebook-login/tree/master/android/src/main/java/com/magus/fblogin

I use this package because it is the official one from Facebook itself.
Anyway I will switch to the one that doesn't override directly in MainActivity.

did u override the onActivityResult method,so checkout....and call super.onActivityResult(...),it works for me

Hi,
I ran into the same situation, where response callback is not called for takePhoto and chooseFromLibrary.

I used a test app just for this the code is very simple:
```import React, {Component} from 'react';
import { AppRegistry,
Dimensions,
Platform
} from 'react-native';
import ImagePicker from 'react-native-image-picker';
export class AppEntry extends Component{

 options = {

title: 'Select Avatar',
customButtons: [{ name: 'fb', title: 'Choose Photo from Facebook' }],
storageOptions: {
skipBackup: true,
path: 'images',
},
};
render(){
ImagePicker.showImagePicker(this.options, (response) => {
console.log('Response = ', response);

if (response.didCancel) {
console.log('User cancelled image picker');
} else if (response.error) {
console.log('ImagePicker Error: ', response.error);
} else if (response.customButton) {
console.log('User tapped custom button: ', response.customButton);
} else {
const source = { uri: response.uri };

// You can also display the image using data:
// const source = { uri: 'data:image/jpeg;base64,' + response.data };

this.setState({
  avatarSource: source,
});

}
});
return (
null
);
}
}

AppRegistry.registerComponent('AppEntry', ()=> AppEntry);
```

In the Android app I'm using a MainActivity with the view that points the index.bundle, nothing else.
Followed the install.md to add a permission listener. Still I'm not able to get the response call back, only cancel event would return a call back.

Was this page helpful?
0 / 5 - 0 ratings