yayaa / LocationManager

Simplify getting user's location for Android
806 stars 187 forks source link

Permissions issue #48

Closed swratten closed 7 years ago

swratten commented 7 years ago

Hi,

I have had 20 different client devices crash on various device manufacturers with error:

Client must have ACCESS_COARSE_LOCATION or ACCESS_FINE_LOCATION permission to perform any location operations. at com.yayandroid.locationmanager.providers.locationprovider.GooglePlayServicesLocationSource.requestLocationUpdate(SourceFile:96) at com.yayandroid.locationmanager.providers.locationprovider.GooglePlayServicesLocationProvider.requestLocationUpdate(SourceFile:227) at com.yayandroid.locationmanager.providers.locationprovider.GooglePlayServicesLocationProvider.onResult(SourceFile:160) at com.yayandroid.locationmanager.providers.locationprovider.GooglePlayServicesLocationSource.onResult(SourceFile:131) at com.yayandroid.locationmanager.providers.locationprovider.GooglePlayServicesLocationSource.onResult(SourceFile:26)

I have all the necessary permissions in manifest:

<uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
    <uses-feature android:name="android.hardware.location.gps" />

And my location configuration:

return new LocationConfiguration.Builder().askForPermission(new PermissionConfiguration.Builder().build())
                .useGooglePlayServices(new GooglePlayServicesConfiguration.Builder()
                        .askForGooglePlayServices(true)
                        .setWaitPeriod(5 * 1000)
                        .build())
                .useDefaultProviders(new DefaultProviderConfiguration.Builder()
                        .acceptableTimePeriod(2 * 60 * 60 * 1000)
                        .setWaitPeriod(ProviderType.GPS, 10 * 1000)
                        .setWaitPeriod(ProviderType.NETWORK, 5 * 1000)
                        .gpsMessage("Would you mind to turn GPS on?").build())
                .build();

Please advise on how to avoid this issue.

yayaa commented 7 years ago

Could you share also OS versions and manufacturer info? Because from the configuration, everything looks fine. And unless, user gives permission and then goes to settings and removes it even before library starts requesting location.

If you are able to reproduce this issue, please also share the logs. So that i can see what are the steps library follows.

swratten commented 7 years ago

Yeah I understand how it shouldn't really be happening logically, but it does seem to somehow. Manufacturer devices listed in crashlytics are:

Samsung - Galaxy S7 (SM-G930F, SAMSUNG-SM-G930A), Galaxy S6 Edge (SM-G925F), Galaxy S5 (SM-G900F, SM-G900I, SM-G900V), Galaxy S7 Edge SM-G935T, Galaxy A3(2016) (SM-A310F) HUAWEI - MHA-L29, Nexus 6P Motorola - Moto G (5) Sony - Xperia Z5 (E6653) OnePlus - ONE A2003

Im unable to reproduce the issue, I've tested on 7 different devices with no luck.

yayaa commented 7 years ago

Could you please try to set PermissionConfiguration as below;

new PermissionConfiguration.Builder()
.requiredPermissions(new String[] {Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION })
.build()

Normally asking only for ACCESS_FINE_LOCATION should be fine, that is why as default library asks only that one. But this might be a case that different manufacturers processes differently for permission groups.

ncapdevi commented 7 years ago

@yayaa Getting the same issue on the Galaxy S5, had both permissions allowed in the manifest. Changing to include both permissions like so .requiredPermissions(new String[] {Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION }) function didn't fix this issue.

yayaa commented 7 years ago

Thanks for the feedback @ncapdevi will take a look. Can you also share OS version please? And if you are able to reproduce, please share the usecase as well.

ncapdevi commented 7 years ago

@yayaa So sorry for the delay, The OS is 6.0.1. Model Number SM-G900V

E/AndroidRuntime: FATAL EXCEPTION: main
                                                            Process: com.roqbot.client.beta, PID: 13744
                                                            java.lang.SecurityException: Client must have ACCESS_COARSE_LOCATION or ACCESS_FINE_LOCATION permission to perform any location operations.
                                                                at android.os.Parcel.readException(Parcel.java:1620)
                                                                at android.os.Parcel.readException(Parcel.java:1573)
                                                                at com.google.android.gms.internal.zzase$zza$zza.zza(Unknown Source)
                                                                at com.google.android.gms.internal.zzasg.zza(Unknown Source)
                                                                at com.google.android.gms.internal.zzash.zza(Unknown Source)
                                                                at com.google.android.gms.internal.zzary$1.zza(Unknown Source)
                                                                at com.google.android.gms.internal.zzary$1.zza(Unknown Source)
                                                                at com.google.android.gms.internal.zzaad$zza.zzb(Unknown Source)
                                                                at com.google.android.gms.internal.zzaaq.zze(Unknown Source)
                                                                at com.google.android.gms.internal.zzaaq.zzb(Unknown Source)
                                                                at com.google.android.gms.internal.zzaav.zzb(Unknown Source)
                                                                at com.google.android.gms.internal.zzaat.zzb(Unknown Source)
                                                                at com.google.android.gms.internal.zzary.requestLocationUpdates(Unknown Source)
                                                                at com.yayandroid.locationmanager.providers.locationprovider.GooglePlayServicesLocationSource.requestLocationUpdate(GooglePlayServicesLocationSource.java:92)
                                                                at com.yayandroid.locationmanager.providers.locationprovider.GooglePlayServicesLocationProvider.requestLocationUpdate(GooglePlayServicesLocationProvider.java:236)
                                                                at com.yayandroid.locationmanager.providers.locationprovider.GooglePlayServicesLocationProvider.onResult(GooglePlayServicesLocationProvider.java:169)
                                                                at com.yayandroid.locationmanager.providers.locationprovider.GooglePlayServicesLocationSource.onResult(GooglePlayServicesLocationSource.java:128)
                                                                at com.yayandroid.locationmanager.providers.locationprovider.GooglePlayServicesLocationSource.onResult(GooglePlayServicesLocationSource.java:26)
                                                                at com.google.android.gms.internal.zzaaf$zza.zzb(Unknown Source)
                                                                at com.google.android.gms.internal.zzaaf$zza.handleMessage(Unknown Source)
                                                                at android.os.Handler.dispatchMessage(Handler.java:102)
                                                                at android.os.Looper.loop(Looper.java:158)
                                                                at android.app.ActivityThread.main(ActivityThread.java:7224)
                                                                at java.lang.reflect.Method.invoke(Native Method)
                                                                at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1230)
                                                                at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1120)
                                                                at de.robv.android.xposed.XposedBridge.main(XposedBridge.java:102)
ncapdevi commented 7 years ago

I'm also getting this on a Nexus 6P on first load on a device that's running the Android O Developer Preview 2. The manifest definitely has both permissions set

yayaa commented 7 years ago

@swratten & @ncapdevi

I am unable to reproduce this issue, please point me out if you can find any further information about. My only idea would be; the changes within Android O about permissions.

That is why i thought setting both permission would solve, but since that doesn't solve the issue and i am unable to reproduce, i cannot solve it.

Please re-open the issue if you can find anything.

ncapdevi commented 7 years ago

I am able to consistently replicate this issue. These are the settings I'm using

import android.Manifest;

import com.yayandroid.locationmanager.LocationManager;
import com.yayandroid.locationmanager.configuration.DefaultProviderConfiguration;
import com.yayandroid.locationmanager.configuration.GooglePlayServicesConfiguration;
import com.yayandroid.locationmanager.configuration.LocationConfiguration;
import com.yayandroid.locationmanager.configuration.PermissionConfiguration;
import com.yayandroid.locationmanager.constants.ProviderType;
import com.yayandroid.locationmanager.listener.LocationListener;
public class LocationService implements LocationListener {
    private final ActivityListener mActivityListener;
    private final LocationManager mLocationManager;

    private LocationService(ActivityListener ActivityListener){
        this.mActivityListener = ActivityListener;
        mLocationManager = GetLocationManager(ActivityListener, this);
        mLocationManager.get();
    }

    public static LocationManager GetLocationManager(ActivityListener ActivityListener, LocationListener locationListener){
        LocationManager locationManager = new LocationManager.Builder(ActivityListener.getActivity().getApplicationContext())
                .activity(ActivityListener.getActivity())
                .configuration(GetLocationConfiguration()).notify(locationListener).build();
        return locationManager;
    }

    public static LocationConfiguration GetLocationConfiguration(){
        return new LocationConfiguration.Builder().keepTracking(false)
                .askForPermission(new PermissionConfiguration.Builder().requiredPermissions(new String[]{Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION})
                        .rationaleMessage("Needs permission to access your location in order to provide a more localized experience.").build())
                .useGooglePlayServices(new GooglePlayServicesConfiguration.Builder()
                        .askForGooglePlayServices(true)
                        .askForSettingsApi(true)
                        .failOnConnectionSuspended(true)
                        .failOnSettingsApiSuspended(false)
                        .ignoreLastKnowLocation(false)
                        .setWaitPeriod(20 * 1000)
                        .build())
                .useDefaultProviders(new DefaultProviderConfiguration.Builder()
                        .acceptableAccuracy(500.0f)
                        .acceptableTimePeriod(5 * 60 * 1000)
                        .gpsMessage("Turn on GPS?")
                        .setWaitPeriod(ProviderType.GPS, 20 * 1000)
                        .setWaitPeriod(ProviderType.NETWORK, 20 * 1000)
                        .build())
                .build();
    }
}

This is a big problem for me and renders the library unusable

On Android M I receive the error log I posted above, on O I receive a slightly different one

E/AndroidRuntime: FATAL EXCEPTION: main
                                         Process: com.roqbot.client.beta, PID: 23131
                                         java.lang.SecurityException: Client must have ACCESS_COARSE_LOCATION or ACCESS_FINE_LOCATION permission to perform any location operations.
                                             at android.os.Parcel.readException(Parcel.java:1620)
                                             at android.os.Parcel.readException(Parcel.java:1573)
                                             at com.google.android.gms.internal.zzase$zza$zza.zza(Unknown Source)
                                             at com.google.android.gms.internal.zzasg.zza(Unknown Source)
                                             at com.google.android.gms.internal.zzash.zza(Unknown Source)
                                             at com.google.android.gms.internal.zzary$1.zza(Unknown Source)
                                             at com.google.android.gms.internal.zzary$1.zza(Unknown Source)
                                             at com.google.android.gms.internal.zzaad$zza.zzb(Unknown Source)
                                             at com.google.android.gms.internal.zzaaq.zze(Unknown Source)
                                             at com.google.android.gms.internal.zzaaq.zzb(Unknown Source)
                                             at com.google.android.gms.internal.zzaav.zzb(Unknown Source)
                                             at com.google.android.gms.internal.zzaat.zzb(Unknown Source)
                                             at com.google.android.gms.internal.zzary.requestLocationUpdates(Unknown Source)
                                             at com.yayandroid.locationmanager.providers.locationprovider.GooglePlayServicesLocationSource.requestLocationUpdate(GooglePlayServicesLocationSource.java:92)
                                             at com.yayandroid.locationmanager.providers.locationprovider.GooglePlayServicesLocationProvider.requestLocationUpdate(GooglePlayServicesLocationProvider.java:236)
                                             at com.yayandroid.locationmanager.providers.locationprovider.GooglePlayServicesLocationProvider.onResult(GooglePlayServicesLocationProvider.java:169)
                                             at com.yayandroid.locationmanager.providers.locationprovider.GooglePlayServicesLocationSource.onResult(GooglePlayServicesLocationSource.java:128)
                                             at com.yayandroid.locationmanager.providers.locationprovider.GooglePlayServicesLocationSource.onResult(GooglePlayServicesLocationSource.java:26)
                                             at com.google.android.gms.internal.zzaaf$zza.zzb(Unknown Source)
                                             at com.google.android.gms.internal.zzaaf$zza.handleMessage(Unknown Source)
                                             at android.os.Handler.dispatchMessage(Handler.java:102)
                                             at android.os.Looper.loop(Looper.java:158)
                                             at android.app.ActivityThread.main(ActivityThread.java:7224)
                                             at java.lang.reflect.Method.invoke(Native Method)
                                             at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1230)
                                             at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1120)
                                             at de.robv.android.xposed.XposedBridge.main(XposedBridge.java:102)
ncapdevi commented 7 years ago

Ah! I seem to have found the root cause of it, but still unsure why the library didn't handle it. I was essentially calling the code above twice very close to each other. So it would create a LocationManager in one instance, and try to get a location, and then immediately create a new locationManger and try again. Fixing this double call seemed to alleviate the issue. If you create two managers and call .get() you should be able to replicate the issue and track down a way to fix it.