Expo BarcodeReader returning different object for Android and IOS

#1

The documentation says that onBarcodeRead will pass an object like { type: string, data: string } as an argument to whatever function we pass as callback to onBarcodeRead.

This works as expected on IOS, and I got

Object {
   "data": "0000000031",
   "target": 224,
   "type": "org.iso.Code128",
} 

To my surprise, running the same code on Android returns me:

Object {
   "data": "CODE 128",
   "type": 1,
}

which doesn’t give me any information on what’s in the barcode.

Anyone has any idea of why this is happening?

#2

Could you post this barcode here? Would be much easier to debug :slight_smile:

1 Like
#3

the barcode itself is just a random barcode from google:

but the code is this:

export default class QRScanner extends Component {
    state = {
        hasCameraPermission: null,
        lastScan: null,
    };

    componentDidMount() {
        this._requestCameraPermission();
    }

    _requestCameraPermission = async () => {
        const { status } = await Permissions.askAsync(Permissions.CAMERA);
        this.setState({
            hasCameraPermission: status === 'granted',
        });
    };

    onSuccessRead = (result) => {
        console.log(result)
        let {type, data} = result;
        if (data !== this.state.lastScan) {
            this.setState({ lastScan: data })
            if (Platform.OS === 'ios')
            {
                type = type.split('.')[2];
            }
            Alert.alert(
                type + ' Detected',
                'Content:\n' + data,
                [{ text: 'Open URL', onPress: () => Linking.openURL(data) },
                { text: 'Cancel', onPress: () => { } }]
            );
        }
    }

    render() {
        return (
            <View style={styles.container}>
                {
                    this.state.hasCameraPermission === null ?
                        <Text>Requesting for camera permission</Text> :
                        this.state.hasCameraPermission === false ?
                            <Text style={{ color: '#fff' }}> Camera permission is not granted </Text> :

                            <BarCodeScanner
                                onBarCodeRead={this.onSuccessRead.bind(this)}
                                style={styles.scanArea}
                                autoFocus={Camera.Constants.AutoFocus.on}
                                focusDepth={1}
                            >
                                <View style={styles.layerTop} />
                                <View style={styles.layerCenter}>
                                    <View style={styles.layerLeft} />
                                    <View style={styles.focused} />
                                    <View style={styles.layerRight} />
                                </View>
                                <View style={styles.layerBottom} />
                            </BarCodeScanner>
                }
                <StatusBar hidden />
            </View>
        );
    }
}

const opacity = 'rgba(0, 0, 0, .6)';
const styles = StyleSheet.create({
    container: {
        flex: 1,
    },

    headerText: {
        fontSize: fontSize.large,
        fontFamily: fontFamily.medium,
        color: color.white,
        padding: 10,
        marginRight: 30 //to center the title, because there's no right component
    },

    headerOuterContainer: {
        backgroundColor: color.dark_blue,
        height: 65,
        padding: 0,
        borderBottomWidth: 0,
    },

    scanArea:{
        height: windowHeight - 65, 
        width: windowWidth
    },
    layerTop: {
        flex: 1,
        backgroundColor: opacity
    },

    layerCenter: {
        flex: 2,
        flexDirection: 'row'
    },

    layerLeft: {
        flex: 1,
        backgroundColor: opacity
    },

    focused: {
        flex: 10
    },

    layerRight: {
        flex: 1,
        backgroundColor: opacity
    },

    layerBottom: {
        flex: 1,
        backgroundColor: opacity
    },
});

UPDATE:

I forgot to add, sometimes it’s returning me just the data:

Object {
    "data": "0000000031",
    "type": 1,
}

But never both data and type correctly like in IOS

#4

Thanks! The type in you previous post is actually correct because if you compare it to BarCodeScanner.Constants.BarCodeType.code128 it should return true. Anyway, I’ll try to investigate why the data is sometimes wrong

2 Likes
#5

So ur saying that “1” actually corresponds directly to BarCodeScanner.Constants.BarCodeType.code128?

If it does, I can just map them manually from the app then or use simple if statement to Iterate a list of possible barcodes…

#6

I’ve confirmed that, thanks so much for the prompt reply that was really helpful, I can’t seem to reproduce the bug ur trying to investigate though, weird…
I swear I didn’t change the code a bit, those 2 results were returned within the same 10 minutes I’m tinkering with this.

Hope u could find the bug soon (if there is any)!

Thanks again! :slight_smile:

1 Like
#7

So I ended up doing this:

            if (Platform.OS === 'ios')
            {
               type = type.split('.')[2];
            }
            else{
                switch (type){
                    case BarCodeScanner.Constants.BarCodeType.aztec: type = "Aztec"; break;
                    case BarCodeScanner.Constants.BarCodeType.codabar: type = "Codabar"; break;
                    case BarCodeScanner.Constants.BarCodeType.code128: type = "Code128"; break;
                    case BarCodeScanner.Constants.BarCodeType.code138: type = "Code138"; break;
                    case BarCodeScanner.Constants.BarCodeType.code39: type = "Code39"; break;
                    case BarCodeScanner.Constants.BarCodeType.code39mod43: type = "Code39mod43"; break;
                    case BarCodeScanner.Constants.BarCodeType.code93: type = "Code93"; break;
                    case BarCodeScanner.Constants.BarCodeType.datamatrix: type = "Datamatrix"; break;
                    case BarCodeScanner.Constants.BarCodeType.ean13: type = "Ean13"; break;
                    case BarCodeScanner.Constants.BarCodeType.ean8: type = "Ean8"; break;
                    case BarCodeScanner.Constants.BarCodeType.interleaved2of5: type = "Interleaved2of5"; break;
                    case BarCodeScanner.Constants.BarCodeType.itf14: type = "Itf14"; break;
                    case BarCodeScanner.Constants.BarCodeType.maxicode: type = "Maxicode"; break;
                    case BarCodeScanner.Constants.BarCodeType.pdf417: type = "Pdf417"; break;
                    case BarCodeScanner.Constants.BarCodeType.qr: type = "QRCode"; break;
                    case BarCodeScanner.Constants.BarCodeType.rss14: type = "Rss14"; break;
                    case BarCodeScanner.Constants.BarCodeType.rssexpanded: type = "Rssexpanded"; break;
                    case BarCodeScanner.Constants.BarCodeType.upc_a: type = "Upc_a"; break;
                    case BarCodeScanner.Constants.BarCodeType.upc_e: type = "Upc_e"; break;
                    case BarCodeScanner.Constants.BarCodeType.upc_ean: type = "Upc_ean"; break;
                }

Not sure if I should ask this here, but should I delete the cases for those barcodes that are not supported by Android or is there any possibilities that the barcodes that are not supported by android now could be supported in the future?

Cheers! :slight_smile:

#8

You don’t even need the ios/android case, you can use the switch for both. We’re not planning to add more types to detect for now as we use third-party lib to detect barcodes and the list of supported types is defined by the library. And no, I think you don’t have to remove extra statements.

1 Like
#9

ah right so the predefined constants work for both android and ios…
I thought the constants are always numbers like the ones printed from Android run.
good to know, thanks so much for the help!

closed #10

This topic was automatically closed 15 days after the last reply. New replies are no longer allowed.