dpa99c / cordova-plugin-request-location-accuracy

Cordova/Phonegap plugin for Android and iOS to request enabling/changing of Location Services by triggering a native dialog
96 stars 62 forks source link

Concurrent request using canRequest() don't trigger a callback #69

Open douglasgsouza opened 4 years ago

douglasgsouza commented 4 years ago

I'm submitting a ... (check one with "x"):

Bug report

Current behavior:

I am using the plugin to prompt the user to enable GPS device.

The plugin is called through a method to retrieve the user's location. My method is a set of implementations that checks and requests (when needed) the required permissions (via diagnostic plugin) and GPS activation (via request accuracy plugin).

There are manual calls that occur through button clicks and automatic calls that occur in the background at each time interval.

I detected the problem when the user clicks the button while the background call occurs. If the dialog is already open, calbacks are not executed.

This occurs when using canRequest() concurrent. If you call canRequest () while the dialog is already open, callbacks are not executed.

Expected behavior:

Run all callbacks in any order they were called.

Steps to reproduce:

Using @ionic-native/location-accuracy: 5.17.1. The examples below are for debugging purposes, similar to what I have in my project:

To debug: Run with cordova on device, open DevTools, when dialog open on device, choice No/Cancel.

Example 1: The request callback of the frst call that open dialog never called.

  1. First call open dialog
  2. Second call run error callback with message: A request is already in progress
  3. First call never run any callback.
        // first call
        this.locationAccuracy.canRequest().then(canRequest1 => {
            console.log('canRequest1: ', canRequest1); // canRequest1 = true
            if (canRequest1) {
                // call request and dialog open
                this.locationAccuracy.request(this.locationAccuracy.REQUEST_PRIORITY_HIGH_ACCURACY).then(requestResult1 => {
                    console.log('request1: ', requestResult1); // never called
                }, requestError1 => {
                    console.error('request1: ', requestError1);  // never called
                });
            } else {
                console.error('request1: cant request');
            }
        }, error1 => {
            console.error('canRequest1: ', error1);
        });

        // second call (concurrent)
        setTimeout(() => {
            this.locationAccuracy.canRequest().then(canRequest2 => {
                console.log('canRequest2: ', canRequest2);  // canRequest2 = true
                if (canRequest2) {
                    // call request and dialog dont open, ok
                    this.locationAccuracy.request(this.locationAccuracy.REQUEST_PRIORITY_HIGH_ACCURACY).then(requestResult2 => {
                        console.log('request2: ', requestResult2);
                    }, requestError2 => {
                        console.error('request2: ', requestError2); // called with error {code: -1, message: "A request is already in progress"}
                    });
                } else {
                    console.error('request2: cant request');
                }
            }, error2 => {
                console.error('canRequest2: ', error2);
            });
        }, 1000);

Example 2: Without canRequest() works.

  1. First call open dialog.
  2. Second call run error callback with message: A request is already in progress
  3. First call run a callback.

       // first call
        this.locationAccuracy.request(this.locationAccuracy.REQUEST_PRIORITY_HIGH_ACCURACY).then(requestResult1 => {
            console.log('request1: ', requestResult1);
        }, requestError1 => {
            console.error('request1: ', requestError1);
        });
    
        // second call (concurrent)
        setTimeout(() => {
            this.locationAccuracy.request(this.locationAccuracy.REQUEST_PRIORITY_HIGH_ACCURACY).then(requestResult2 => {
                console.log('request2: ', requestResult2);
            }, requestError2 => {
                console.error('request2: ', requestError2);
            });
        }, 1000);

Environment information

Runtime issue

Android build issue:

If using an [Ionic Native Typescript wrapper]() for this plugin:

Cordova:

Cordova CLI : not installed Cordova Platforms : android 8.0.0, browser 6.0.0 Cordova Plugins : not available

Utility:

cordova-res : 0.6.0 (update available: 0.8.1) native-run : 0.2.8 (update available: 0.3.0)

System:

Android SDK Tools : 26.1.1 (C:\android-sdk) NodeJS : v10.16.3 (C:\Program Files\nodejs\node.exe) npm : 6.9.0 OS : Windows 10

- Installed Ionic Native modules and versions
    - `npm list | grep "@ionic-native"`

+-- @ionic-native/android-permissions@5.8.0 +-- @ionic-native/app-minimize@5.8.0 +-- @ionic-native/call-number@5.8.0 +-- @ionic-native/camera@5.8.0 +-- @ionic-native/core@5.8.0 +-- @ionic-native/diagnostic@5.18.0 +-- @ionic-native/file@5.8.0 +-- @ionic-native/google-maps@5.5.0 +-- @ionic-native/ionic-webview@5.8.0 +-- @ionic-native/launch-navigator@5.8.0 +-- @ionic-native/location-accuracy@5.17.1 +-- @ionic-native/native-audio@5.8.0 +-- @ionic-native/splash-screen@5.8.0 +-- @ionic-native/status-bar@5.8.0

Saqib92 commented 2 years ago

I can Confirm this issue. canRequest() not working. it always return 0. But this is only happening when application do not have location permission(like first time application running). after giving location permission it is now checking for location accuracy.

AntoscencoVladimir commented 2 years ago

Who stacked on issue like Saqib92 🤨

To have success response from canRequest() method, you need to ask user for ACCESS_COARSE_LOCATION or ACCESS_FINE_LOCATION permission first, there is a check for that in plugin code and also it described in plugin documentation

https://github.com/dpa99c/cordova-plugin-request-location-accuracy#canrequest

On Android, this will return true if the app has authorization to use location.

Authorization means those permissions

Hope this will help someone

Saqib92 commented 2 years ago

Who stacked on issue like Saqib92 🤨

To have success response from canRequest() method, you need to ask user for ACCESS_COARSE_LOCATION or ACCESS_FINE_LOCATION permission first, there is a check for that in plugin code and also it described in plugin documentation

https://github.com/dpa99c/cordova-plugin-request-location-accuracy#canrequest

On Android, this will return true if the app has authorization to use location.

Authorization means those permissions

Hope this will help someone

Who stacked on issue like Saqib92 🤨

To have success response from canRequest() method, you need to ask user for ACCESS_COARSE_LOCATION or ACCESS_FINE_LOCATION permission first, there is a check for that in plugin code and also it described in plugin documentation

https://github.com/dpa99c/cordova-plugin-request-location-accuracy#canrequest

On Android, this will return true if the app has authorization to use location.

Authorization means those permissions

Hope this will help someone

i already have permission for ACCESS_COARSE_LOCATION and ACCESS_FINE_LOCATION in my AndroidMenifest.xml but the issue still persist.

AntoscencoVladimir commented 2 years ago

Who stacked on issue like Saqib92 🤨 To have success response from canRequest() method, you need to ask user for ACCESS_COARSE_LOCATION or ACCESS_FINE_LOCATION permission first, there is a check for that in plugin code and also it described in plugin documentation https://github.com/dpa99c/cordova-plugin-request-location-accuracy#canrequest On Android, this will return true if the app has authorization to use location. Authorization means those permissions Hope this will help someone

Who stacked on issue like Saqib92 🤨 To have success response from canRequest() method, you need to ask user for ACCESS_COARSE_LOCATION or ACCESS_FINE_LOCATION permission first, there is a check for that in plugin code and also it described in plugin documentation https://github.com/dpa99c/cordova-plugin-request-location-accuracy#canrequest On Android, this will return true if the app has authorization to use location. Authorization means those permissions Hope this will help someone

i already have permission for ACCESS_COARSE_LOCATION and ACCESS_FINE_LOCATION in my AndroidMenifest.xml but the issue still persist.

It's not enough to have permissions in AndroidManifest.xml file you should explicitly ask user for it with https://capacitorjs.com/docs/apis/geolocation#requestpermissions plugin for example, first you need to ask user by requestPermissions() method and then check if user accepted it then you ask for accuracy