eclipsesource / tabris

Tabris for Eclipse RAP
https://eclipsesource.com/products/tabris
54 stars 18 forks source link

Geolocation tracking does not work on iOS11 and Android 6 #462

Open PatrickNass opened 7 years ago

PatrickNass commented 7 years ago

Hello Tabris team, after successfully testing the gelocation service with iOS 10.3.3 (even tough the update rate was very fluctuating), I tested it with Android 6.0.1 and iOS 11.0.3 and stated that it is not working. The GeolocationListener is not called at all.

Used Tabris version: 2.0.0

mpost commented 7 years ago

@PatrickNass Could the problem be missing permissions?

PatrickNass commented 7 years ago

@mpost Hi, on Android all location permissions are granted: <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" /> <uses-permission android:name="android.permission.ACCESS_LOCATION_EXTRA_COMMANDS" I tested it with an App build targeting API 22. I also tested it with Android 4.4.2 and there it works. But not on 6.0.1.

You were right with the permissions on iOS. In the Info.plist was the permission string NSLocationAlwaysUsageDescription which was sufficient for iOS 10. After some researching, testing and reading the device log I found out that for iOS 11 the new strings NSLocationAlwaysAndWhenInUseUsageDescription and NSLocationWhenInUseUsageDescription are needed. So on iOS everything works fine now, but I don't know how to deal with Android 6.

mpost commented 7 years ago

When you have the permissions declared in the manifest you will also need to deal with the runtime permissions. Could you switch the permission on in the installed apps settings and check if that would work?

PatrickNass commented 7 years ago

Hi, I don't know how to ask for runtime permissions on Tabris Java. I did not know that they are needed when targeting < API 23. I opened the settings and saw that all permissions are already granted. But surprisingly, on opening the setting view, the app began to send locations. I am wondering whats going on? Do I have to open the settings on every installed version of the app if the device runs on >= API 23? Or has it something to do with the app install process, I mean that it was installed by debuging from Android Studio?

mpost commented 7 years ago

You can see here when the user would need to grant the permission at runtime: https://developer.android.com/training/permissions/requesting.html

On all versions of Android, your app needs to declare both the normal and the dangerous permissions it needs in its app manifest, as described in Declaring Permissions. However, the effect of that declaration is different depending on the system version and your app's target SDK level:

If the device is running Android 5.1 or lower, or your app's target SDK is 22 or lower: If you list a dangerous permission in your manifest, the user has to grant the permission when they install the app; if they do not grant the permission, the system does not install the app at all.

If the device is running Android 6.0 or higher, and your app's target SDK is 23 or higher: The app has to list the permissions in the manifest, and it must request each dangerous permission it needs while the app is running. The user can grant or deny each permission, and the app can continue to run with limited capabilities even if the user denies a permission request.

PatrickNass commented 7 years ago

I have read this article before and I thought that

If the device is running Android 6.0 or higher, and your app's target SDK is 23 or higher

means I dont need to ask for runtime permissions when the app's target SDK is below 23, like in this case. Neither I changed a single setting nor the app asked for a permission.

After reinstalling the app by generated apk, no geolocations are sent. After opening the settings still no geolocations are sent. I don't know why it worked before. This is how the settings window looks: screenshot_2017-10-26-16-00-03

So does this mean that I have to derive the TabrisActivity class and implement following code // Here, thisActivity is the current activity if (ContextCompat.checkSelfPermission(thisActivity, Manifest.permission.READ_CONTACTS) != PackageManager.PERMISSION_GRANTED) {

// Should we show an explanation?
if (ActivityCompat.shouldShowRequestPermissionRationale(thisActivity,
        Manifest.permission.READ_CONTACTS)) {

    // Show an explanation to the user *asynchronously* -- don't block
    // this thread waiting for the user's response! After the user
    // sees the explanation, try again to request the permission.

} else {

    // No explanation needed, we can request the permission.

    ActivityCompat.requestPermissions(thisActivity,
            new String[]{Manifest.permission.READ_CONTACTS},
            MY_PERMISSIONS_REQUEST_READ_CONTACTS);

    // MY_PERMISSIONS_REQUEST_READ_CONTACTS is an
    // app-defined int constant. The callback method gets the
    // result of the request.
}

} and the @Override public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) { ... }

method mentioned in the article? Is there a way to initate the asking for the permission server side? I am a little confused then where to place the code, because everything like the geocode part is initiated by the server and the code seems to me to be placed there, where the call for the geocode api is done.

Thanks for your help and the fast replys!