webyonet / react-native-android-location-services-dialog-box

React Native Android Location Services Dialog Box
MIT License
182 stars 50 forks source link

The callback checkLocationServicesIsEnabled() exists in module LocationServicesDialogBox but only one callback may be registered to a function in a native module #9

Closed bashlk closed 7 years ago

bashlk commented 7 years ago

Hello So I was using your module (1.1.8) along with several other native modules (namely react-native-image-picker and react-native-image-resizer) and when I ran a native function on that module (ImagePicker.launchImageLibrary({}, (response) => {}), I kept getting this error.

The callback checkLocationServicesIsEnabled() exists in module LocationServicesDialogBox but only one callback may be registered to a function in a native module

According to here, http://stackoverflow.com/questions/40785625/only-one-callback-may-be-registered-to-a-function-in-a-native-module-react-nativ , a registered callback could only be called once and for some reason calling the other native function causes the function in this module to run again, causing the callback to be called twice. So I tried placing a boolean to track whether the code has run once or not and that seemed to fix the problem.

class LocationServicesDialogBoxModule extends ReactContextBaseJavaModule implements ActivityEventListener {
...
private Boolean hasRun = false;
...
private void checkLocationService(Boolean activityResult) {
        // Robustness check
       if (currentActivity == null || map == null || promiseCallback == null || hasRun) return;
       ...
      hasRun = true;
}
...
}

Not sure whether this is right place to post this or whether the problem is in this module, but just thought of putting this out there.

Also here is the specific code related to this issue index.android.js

getLocation(){
    LocationServicesDialogBox.checkLocationServicesIsEnabled({
      message: "<h3>Location off</h3> Around needs your location to continue. Would you like to turn on Location?",
      ok: "YES",
      cancel: "NO"
    }).then(success => {
      navigator.geolocation.getCurrentPosition(position => {
        var user = this.state.user;
        user.location = {
            lat: position.coords.latitude,
            lon: position.coords.longitude
        }
        this.setState({user, triedLocation: true});
      }, error => {
        this.setState({triedLocation: true, isLoading: false});
      }, {
        enableHighAccuracy: true,
        timeout: 20000
      })
    }).catch(error => {
      this.setState({triedLocation: true, isLoading: false});
    })
  }

addPost.js

import ImagePicker from 'react-native-image-picker';
import ImageResizer from 'react-native-image-resizer';
...
addAttachment(){
        ImagePicker.launchImageLibrary({}, (response)  => {
            if(response.didCancel){
                return;
            }
            if(response.error){
                ToastAndroid.show('An error occurred while selecting photo');
                return;
            }

            ImageResizer.createResizedImage(response.uri, 1000, 500, 'JPEG', 80).then((attachment)=>{
                this.setState({attachment})
            });
        });
}
peresbruno commented 7 years ago

Same problem here...

Cody-G-G commented 7 years ago

The issue is that: a) there is no check for the request code in onActivityResult b) request code used is 1...which for me conflicted with a request code used in react-native-ble-manager. And I'm sure many others would choose 1, so the solution would be changing it to something more random, like 1009.

I'll submit a pull request for it shortly.

bashlk commented 7 years ago

Just tried out Cody-G-G's pull request and the issue is resolved

pratikghosalkar commented 6 years ago

The issue still persists. It happens when I goto next screen and come back to the previous screen where LocationServicesDialogBox is used.

webyonet commented 6 years ago

@pratikghosalkar
android version ? react native version ? react-native-android-location-services-dialog-box version ? and code sample ?

pratikghosalkar commented 6 years ago

android version tested on 5.1.1 and 7.0 react-native version - 0.55.4 react-native-android-location-services-dialog-box version - 2.5.0

componentWillUnmount() {
LocationServicesDialogBox.stopListener(); // Stop the "locationProviderStatusChange" listener
}

checkLocationServiceStatus() {
LocationServicesDialogBox.checkLocationServicesIsEnabled({
message: '<h2>Use Location ?</h2>This app wants to change your device settings:<br/><br/>Use GPS, Wi-Fi, and cell network for location<br/><br/>',
ok: 'YES',
cancel: 'NO',
enableHighAccuracy: true, // true => GPS AND NETWORK PROVIDER, false => GPS OR NETWORK PROVIDER
showDialog: true, // false => Opens the Location access page directly
openLocationServices: true, // false => Directly catch method is called if location services are turned off
preventOutSideTouch: false, // true => To prevent the location services window from closing when it is clicked outside
preventBackClick: false, // true => To prevent the location services popup from closing when it is clicked back button
providerListener: false // true ==> Trigger locationProviderStatusChange listener when the location state changes
}).then((success) => {
console.log('checkLocationServiceStatus_Success: ' + JSON.stringify(success)); // success => {alreadyEnabled: false, enabled: true, status: "enabled"}
this.getCurrentLocation();
}).catch((error) => {
console.log('checkLocationServiceStatus_Error: ' + error.message); // error.message => "disabled"
Alert.alert(
'Turn on the location',
'Please turn on location from settings to continue',
[
{
text: 'Ok',
onPress: () => this.checkLocationServiceStatus(),
style: 'cancel'
}
],
{ cancelable: false }
);
});
}
webyonet commented 6 years ago

@pratikghosalkar which navigator you are using (module name ?)

pratikghosalkar commented 6 years ago

I am using react-navigation 1.5.7

https://github.com/react-navigation/react-navigation

webyonet commented 6 years ago

@pratikghosalkar LocationServicesDialogBox.stopListener(); there is no need to use this method. because providerListener: false

webyonet commented 6 years ago

@pratikghosalkar I will test it with react-navigation

pratikghosalkar commented 6 years ago

still app is crashing even if we don't use LocationServicesDialogBox.stopListener();

Ok test it and see if are you able to reproduce.

webyonet commented 6 years ago

if i find an error fix it i deploy

webyonet commented 6 years ago

@pratikghosalkar I did not find any problems. please check your own code