diff --git a/README.md b/README.md index bdd3fac..73e0182 100644 --- a/README.md +++ b/README.md @@ -13,6 +13,7 @@ Lost operates by making calls directly to the [LocationManger][1]. Lost can run Set up: - [Installation](https://github.com/mapzen/lost/blob/master/docs/installation.md) - [Upgrading 1.x to 2.0](https://github.com/mapzen/lost/blob/master/docs/upgrade-1x-2.md) +- [Upgrading 2.x to 3.0](https://github.com/mapzen/lost/blob/master/docs/upgrade-2x-3.md) - [Getting Started](https://github.com/mapzen/lost/blob/master/docs/getting-started.md) - [Getting the Last Known Location](https://github.com/mapzen/lost/blob/master/docs/last-known-location.md) - [Receiving Location Updates](https://github.com/mapzen/lost/blob/master/docs/location-updates.md) diff --git a/docs/upgrade-2x-3.md b/docs/upgrade-2x-3.md new file mode 100644 index 0000000..27833e0 --- /dev/null +++ b/docs/upgrade-2x-3.md @@ -0,0 +1,128 @@ +# Upgrading from Lost 2.x + +### Explicitly Unregister Location Updates +`LocationRequest`s are no longer automatically removed when a client disconnects, therefore you should ensure that you unregister all requests registered: + +2.x +``` +// onConnected + +LocationServices.FusedLocationApi.requestLocationUpdates(client, locationRequest, listener); + +client.disconnect(); +``` + +3.x +``` +// onConnected + +LocationServices.FusedLocationApi.requestLocationUpdates(client, locationRequest, listener); + +// when disconnecting and shutting down client +LocationServices.FusedLocationApi.removeLocationUpdates(client, listener); // NOW REQUIRED + +client.disconnect(); +``` + +### Remove Deprecated Methods +`onProviderDisabled` and `onProviderEnabled` have been removed from `LocationListener`: + +2.x +``` +LocationListener listener = new LocationListener() { + @Override public void onLocationChanged(Location location) { + + } + + @Override public void onProviderDisabled(Location location) { + + } + + @Override public void onProviderEnabled(Location location) { + + } + }; +``` + +3.x +``` +LocationListener listener = new LocationListener() { + @Override public void onLocationChanged(Location location) { + + } + }; +``` + +`isProviderEnabled` has been removed from `FusedLocationProviderApi` in favor of `SettingsApi#checkLocationSettings(LostApiClient, LocationSettingsRequest)` + +2.x +``` +boolean enabled = LocationServices.FusedLocationProviderApi.isProviderEnabled(client, GPS_PROVIDER); +``` + +3.x +``` +PendingResult result = LocationServices.SettingsApi.checkLocationSettings(apiClient, request); + +LocationSettingsResult locationSettingsResult = result.await(); + +LocationSettingsStates states = locationSettingsResult.getLocationSettingsStates(); + +boolean enabled = states.isGpsUsable(); +``` + +### Ensure Application Process + +The underlying Lost `Service` now runs in it's own process. Because of this, `Application` subclasses will receive two calls to `onCreate`(https://developer.android.com/reference/android/app/Application.html#onCreate()). To ensure unnecessary initialization isn't done, you should use the current `Context` to determine if `onCreate` is being called for the `Service` and if so, handle flow accordingly. + +LeakCanary(https://github.com/square/leakcanary) uses this method: + +``` +public static boolean isInServiceProcess(Context context, Class serviceClass) { + PackageManager packageManager = context.getPackageManager(); + PackageInfo packageInfo; + try { + packageInfo = packageManager.getPackageInfo(context.getPackageName(), GET_SERVICES); + } catch (Exception e) { + CanaryLog.d(e, "Could not get package info for %s", context.getPackageName()); + return false; + } + String mainProcess = packageInfo.applicationInfo.processName; + + ComponentName component = new ComponentName(context, serviceClass); + ServiceInfo serviceInfo; + try { + serviceInfo = packageManager.getServiceInfo(component, 0); + } catch (PackageManager.NameNotFoundException ignored) { + // Service is disabled. + return false; + } + + if (serviceInfo.processName.equals(mainProcess)) { + CanaryLog.d("Did not expect service %s to run in main process %s", serviceClass, mainProcess); + // Technically we are in the service process, but we're not in the service dedicated process. + return false; + } + + int myPid = android.os.Process.myPid(); + ActivityManager activityManager = + (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE); + ActivityManager.RunningAppProcessInfo myProcess = null; + List runningProcesses = + activityManager.getRunningAppProcesses(); + if (runningProcesses != null) { + for (ActivityManager.RunningAppProcessInfo process : runningProcesses) { + if (process.pid == myPid) { + myProcess = process; + break; + } + } + } + if (myProcess == null) { + CanaryLog.d("Could not find running process for %d", myPid); + return false; + } + + return myProcess.processName.equals(serviceInfo.processName); + } +```