react-native-image-picker: [🐛] When select any image crash app

How to repeat issue and example

1.- Lauch method launchImageLibrary 2.- Select any image 3.- Confirm & crash

Solution

What needs to be done to address this issue? No crash app when select any image.

Additional Information

FATAL EXCEPTION: main
Process: com.copymaster, PID: 7518
java.lang.RuntimeException: Failure delivering result ResultInfo{who=null, request=13002, result=-1, data=Intent { flg=0x1 hwFlg=0x10 (has extras) }} to activity {com.copymaster/com.copymaster.MainActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String android.net.Uri.getLastPathSegment()' on a null object reference
	at android.app.ActivityThread.deliverResults(ActivityThread.java:5471)
	at android.app.ActivityThread.handleSendResult(ActivityThread.java:5512)
	at android.app.servertransaction.ActivityResultItem.execute(ActivityResultItem.java:51)
	at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:149)
	at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:103)
	at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2386)
	at android.os.Handler.dispatchMessage(Handler.java:107)
	at android.os.Looper.loop(Looper.java:213)
	at android.app.ActivityThread.main(ActivityThread.java:8178)
	at java.lang.reflect.Method.invoke(Native Method)
	at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:513)
	at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1101)
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String android.net.Uri.getLastPathSegment()' on a null object reference
	at com.imagepicker.Utils.getResponseMap(Utils.java:330)
	at com.imagepicker.ImagePickerModule.onImageObtained(ImagePickerModule.java:145)
	at com.imagepicker.ImagePickerModule.onActivityResult(ImagePickerModule.java:176)
	at com.facebook.react.bridge.ReactContext.onActivityResult(ReactContext.java:308)
	at com.facebook.react.ReactInstanceManager.onActivityResult(ReactInstanceManager.java:758)
	at com.facebook.react.ReactDelegate.onActivityResult(ReactDelegate.java:90)
	at com.facebook.react.ReactActivityDelegate.onActivityResult(ReactActivityDelegate.java:112)
	at com.facebook.react.ReactActivity.onActivityResult(ReactActivity.java:68)
	at android.app.Activity.dispatchActivityResult(Activity.java:8413)
	at android.app.ActivityThread.deliverResults(ActivityThread.java:5464)
	... 11 more

Environment: “react”: “16.13.1”, “react-native”: “0.63.3”, “react-native-image-picker”: “^3.3.2”,

Phone Test:

  • Huawei

About this issue

  • Original URL
  • State: closed
  • Created 3 years ago
  • Reactions: 10
  • Comments: 27 (1 by maintainers)

Most upvoted comments

It may be obvious but be sure your button handle double taps. It’s ease to reproduce this issue double tapping the button. With android, native modules can be mounted many times, it’s not the case with iOS. Maybe your customers tap the button, the native modal take to many time to show and clicked again. Or maybe your UI is not good enough and the “is tapping” state is not very clear for the user.

Issue still unresolved.

Per my comment above, it was actually double-tapping the button to open the image library that was causing the issue (@ludovicj44 was right on).

There are many ways to resolve this but I did so by adding a property on the button’s local state: isDisabledAfterFirstPress and then after the first press it sets this to true. In my case, the button unmounts after press as well which is important otherwise the button could get into a stuck state.

Hope this helps.

Having the same problem here. App crashes when I select the picture on Android.

Any workaround ?

@Maddumage @Dem0n13 try to recheck WRITE_EXTERNAL_STORAGE permission? in my project is use "react-native-permissions": "^2.2.2" to check WRITE_EXTERNAL_STORAGE permission. follow is my select image code:

import {Alert,Platform} from 'react-native'
import ImagePicker from "react-native-image-picker";
import { PERMISSIONS, RESULTS, request } from 'react-native-permissions';

export const showImagePicker = (title:string): Promise<{
    customButton: string;
    didCancel: boolean;
    error: string;
    data: string;
    uri: string;
    origURL?: string;
    isVertical: boolean;
    width: number;
    height: number;
    fileSize: number;
    type?: string;
    fileName?: string;
    path?: string;
    latitude?: number;
    longitude?: number;
    timestamp?: string;
}> => {
    const options = {
        ...you options...

        cameraType: 'back',
        mediaType: 'photo',
        videoQuality: 'high',
        angle: 0,
        allowsEditing: false,
        noData: false,
        saveToPhotos: true,
        includeBase64: false,
    };
    return new Promise(async (resolve, reject) => {

        const requestPermission = (camera: boolean) => {
            return request(
                Platform.select({
                    android: camera ? PERMISSIONS.ANDROID.CAMERA : PERMISSIONS.ANDROID.READ_EXTERNAL_STORAGE,
                    ios: camera ? PERMISSIONS.IOS.CAMERA : PERMISSIONS.IOS.PHOTO_LIBRARY,
                })).then(res => {
                    return res == RESULTS.GRANTED
                })
        }

        const requestWritePermission = () => {
            return request(
                Platform.select({
                    android: PERMISSIONS.ANDROID.WRITE_EXTERNAL_STORAGE,
                    ios: PERMISSIONS.IOS.MEDIA_LIBRARY
                })).then(res => {
                    return res == RESULTS.GRANTED
                })
        }



        Alert.alert(title, '', [
            {
                text: 'cancel',
                style: 'cancel',
                onPress: () => {
                    reject(new Error('user cancled'))
                }
            },
            {
                text: "Library",
                onPress: async () => {

                    const per = await requestPermission(false)
                    const per1 = await requestWritePermission()
                    if (!per || !per1) return resolve(null)
                    ImagePicker.launchImageLibrary(options, (response: any) => {
                        if (!response || response.errorCode) {
                            return resolve(null)
                        }
                        resolve(response)
                    })
                }
            },
            {
                text: "Camera",
                onPress: async () => {
                    const per = await requestPermission(true)
                    const per1 = await requestWritePermission()
                    if (!per || !per1) return resolve(null)
                    ImagePicker.launchCamera(options, (response: any) => {
                        if (!response || response.errorCode) {
                            return resolve(null)
                        }
                        resolve(response)
                    })
                }
            }
        ])
    });

};

Hope useful

The same issue:

Fatal Exception: java.lang.RuntimeException: Failure delivering result ResultInfo{who=null, request=13002, result=-1, data=Intent { dat=content://media/external/images/media/298663 flg=0x1 }} to activity {com.starbyface/com.starbyface.MainActivity}: java.lang.RuntimeException: Illegal callback invocation from native module. This callback type only permits a single invocation from native code.
       at android.app.ActivityThread.deliverResults(ActivityThread.java:4192)
       at android.app.ActivityThread.handleSendResult(ActivityThread.java:4235)
       at android.app.ActivityThread.-wrap20(ActivityThread.java)
       at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1584)
       at android.os.Handler.dispatchMessage(Handler.java:102)
       at android.os.Looper.loop(Looper.java:154)
       at android.app.ActivityThread.main(ActivityThread.java:6317)
       at java.lang.reflect.Method.invoke(Method.java)
       at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:872)
       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:762)

Caused by java.lang.RuntimeException: Illegal callback invocation from native module. This callback type only permits a single invocation from native code.
       at com.facebook.react.bridge.CallbackImpl.invoke(CallbackImpl.java:26)
       at com.imagepicker.ImagePickerModule.onImageObtained(ImagePickerModule.java:145)
       at com.imagepicker.ImagePickerModule.onActivityResult(ImagePickerModule.java:176)
       at com.facebook.react.bridge.ReactContext.onActivityResult(ReactContext.java:308)
       at com.facebook.react.ReactInstanceManager.onActivityResult(ReactInstanceManager.java:758)
       at com.facebook.react.ReactDelegate.onActivityResult(ReactDelegate.java:90)
       at com.facebook.react.ReactActivityDelegate.onActivityResult(ReactActivityDelegate.java:112)
       at com.facebook.react.ReactActivity.onActivityResult(ReactActivity.java:68)
       at android.app.Activity.dispatchActivityResult(Activity.java:7010)
       at android.app.ActivityThread.deliverResults(ActivityThread.java:4188)
       at android.app.ActivityThread.handleSendResult(ActivityThread.java:4235)
       at android.app.ActivityThread.-wrap20(ActivityThread.java)
       at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1584)
       at android.os.Handler.dispatchMessage(Handler.java:102)
       at android.os.Looper.loop(Looper.java:154)
       at android.app.ActivityThread.main(ActivityThread.java:6317)
       at java.lang.reflect.Method.invoke(Method.java)
       at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:872)
       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:762)

As I investigated: any android versions (7-10), any vendors. It comes from the next call:

ImagePicker.launchImageLibrary({ mediaType: 'photo', includeBase64: false }, response => {})

My idea is the cause of problem is null returning from getAppSpecificStorageUri. Here are some examples of ResultInfo’s from Crash reports:

{who=null, request=13001, result=-1, data=null}
{who=null, request=13002, result=-1, data=Intent { dat=content://com.miui.gallery.open/raw//storage/emulated/0/Snapchat/Snapchat-164691440.jpg typ=image/jpeg flg=0x1 }}
{who=null, request=13002, result=-1, data=Intent { dat=content://media/external/images/media/298663 flg=0x1 }}
{who=null, request=13002, result=0, data=null}
{who=null, request=13002, result=-1, data=Intent { dat=content://media/external/images/media/2058 flg=0x1 (has extras) }}
{who=null, request=13002, result=-1, data=Intent { dat=content://media/external/images/media/1441 flg=0x1 (has extras) }}
{who=null, request=13002, result=-1, data=Intent { dat=content://media/external/images/media/2571 flg=0x1 (has extras) }}
{who=null, request=13002, result=-1, data=Intent { dat=content://media/external/images/media/2038 flg=0x1 (has extras) }}

It’s strange to see this reports from “result=-1”. Note that I’ve already throttle button clicks by 1 second (I tried to prevent button multiclicking). Hope that it will be useful. Note 2 that this report come from Firebase Crashlytics.

Similar issue is occurring with Redmi phones also.

This happens for me too. Here is the Stack Trace from Sentry:

java.lang.RuntimeException: Illegal callback invocation from native module. This callback type only permits a single invocation from native code.
    at com.facebook.react.bridge.CallbackImpl.invoke(CallbackImpl.java:26)
    at com.imagepicker.ImagePickerModule.onActivityResult(ImagePickerModule.java:153)
    at com.facebook.react.bridge.ReactContext.onActivityResult(ReactContext.java:308)
    at com.facebook.react.ReactInstanceManager.onActivityResult(ReactInstanceManager.java:758)
    at com.facebook.react.ReactDelegate.onActivityResult(ReactDelegate.java:90)
    at com.facebook.react.ReactActivityDelegate.onActivityResult(ReactActivityDelegate.java:112)
    at com.facebook.react.ReactActivity.onActivityResult(ReactActivity.java:68)
    at android.app.Activity.dispatchActivityResult(Activity.java:7797)
    at android.app.ActivityThread.deliverResults(ActivityThread.java:5071)
    at android.app.ActivityThread.handleSendResult(ActivityThread.java:5120)
    at android.app.servertransaction.ActivityResultItem.execute(ActivityResultItem.java:49)
    at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:108)
    at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:68)
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2199)
    at android.os.Handler.dispatchMessage(Handler.java:112)
    at android.os.Looper.loop(Looper.java:216)
    at android.app.ActivityThread.main(ActivityThread.java:7625)
    at java.lang.reflect.Method.invoke(Method.java)
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:524)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:987)

java.lang.RuntimeException: Failure delivering result ResultInfo{who=null, request=13002, result=0, data=null} to activity {app.myapp/app.myapp.MainActivity}: java.lang.RuntimeException: Illegal callback invocation from native module. This callback type only permits a single invocation from native code.
    at android.app.ActivityThread.deliverResults(ActivityThread.java:5078)
    at android.app.ActivityThread.handleSendResult(ActivityThread.java:5120)
    at android.app.servertransaction.ActivityResultItem.execute(ActivityResultItem.java:49)
    at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:108)
    at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:68)
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2199)
    at android.os.Handler.dispatchMessage(Handler.java:112)
    at android.os.Looper.loop(Looper.java:216)
    at android.app.ActivityThread.main(ActivityThread.java:7625)
    at java.lang.reflect.Method.invoke(Method.java)
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:524)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:987)

Here is the breadcrumbs…

Screen Shot 2021-03-23 at 2 51 11 AM

Here is the distribution of the devices and other details. Of course, this issue only occurs on Android devices of every model. You can see that we have over 55 unique devices which have faced this issue @ravirajn22

Screen Shot 2021-03-23 at 2 51 55 AM