LocationManager


Source link: https://github.com/yayaa/LocationManager

LocationManager

To get location on Android Devices, there are 'some' steps you need to go through! What are those? Let's see...

  • Check whether the application has required permission or now
  • If not, ask runtime permissions from user
  • Check whether user granted the permissions or not

Let's assume we got the permission, now what? We have this cool Google Play Services optimised location provider FusedLocationProviderApi which provides a common location pool that any application use this api can retrieve location in which interval they require. It reduces battery usage, and decreases waiting time (most of the time) for location. YES, we want that! Right?

  • Check whether Google Play Services is available on device
  • If not, see if user can handle this problem?
  • If so, ask user to do it
  • Then, check again to see if user actually did it or not
  • If user did actually handle it, then start location update request
  • Of course, handle GoogleApiClient connection issues first
  • And have a fallback plan, if you're not able to get location in certain time period

Ouu and yes, this new even cooler SettingsApi, that user doesn't need to go to settings to activate GPS or Wifi. Isn't that cool, let's implement that too!

  • Call SettingsApi to adapt device settings up to your location requirement
  • Wait for the result and check your options
  • Is current settings are enough to get required location?
  • Or can you ask user to adapt them?
  • Maybe it is not even possible to use it.
  • Let's assume we asked user to adapt, but he/she didn't want to do it.

Well whatever we tried to optimise, right? But till now, all depends on GooglePlayServices what happens if user's device doesn't have GooglePlayServices, or user didn't want to handle GooglePlayServices issue or user did everything and waited long enough but somehow GooglePlayServices weren't able to return any location. What now? Surely we still have good old times GPS and Network Providers, right? Let's switch to them and see what we need to do!

  • Check whether GPS Provider is enabled or not
  • If it is not, ask user to enable it
  • Check again whether user actually did enable it or not
  • If it is enabled, start location update request
  • But switch to network if GPS is not retrieving location after waiting long enough
  • Check whether Network Provider is enabled or not
  • If it is, start location update request
  • If none of these work, then fail

All of these steps, just to retrieve user's current location. And in every application, you need to reconsider what you did and what you need to add for this time.

With this library you just need to provide a Configuration object with your requirements, and you will receive a location or a fail reason with all the stuff are described above handled.

This library requires quite a lot of lifecycle information to handle all the steps between onCreate - onResume - onPause - onDestroy - onActivityResult - onRequestPermissionsResult. You can simply use one of LocationBaseActivity, LocationBaseFragment, LocationBaseService or you can manually call those methods as required.

See the sample application for detailed usage!

Configuration

All those settings below are optional. Use only those you really want to customize. Please do not copy-paste this configuration directly. If you want to use pre-defined configurations, see Configurations.

LocationConfiguration awesomeConfiguration = new LocationConfiguration.Builder()
  .keepTracking(false)
  .askForPermission(new PermissionConfiguration.Builder()

.permissionProvider(new YourCustomPermissionProvider())

.rationalMessage("Gimme the permission!")

.rationaleDialogProvider(new YourCustomDialogProvider())

.requiredPermissions(new String[] {
 permission.ACCESS_FINE_LOCATION 
}
)

.build())
  .useGooglePlayServices(new GooglePlayServicesConfiguration.Builder()

.locationRequest(YOUR_CUSTOM_LOCATION_REQUEST_OBJECT)

.fallbackToDefault(true)

.askForGooglePlayServices(false)

.askForSettingsApi(true)

.failOnConnectionSuspended(true)

.failOnSettingsApiSuspended(false)

.ignoreLastKnowLocation(false)

.setWaitPeriod(20 * 1000)

.build())
  .useDefaultProviders(new DefaultProviderConfiguration.Builder()

.requiredTimeInterval(5 * 60 * 1000)

.requiredDistanceInterval(0)

.acceptableAccuracy(5.0f)

.acceptableTimePeriod(5 * 60 * 1000)

.gpsMessage("Turn on GPS?")

.gpsDialogProvider(new YourCustomDialogProvider())

.setWaitPeriod(ProviderType.GPS, 20 * 1000)

.setWaitPeriod(ProviderType.NETWORK, 20 * 1000)

.build())
  .build();

Library is modular enough to let you create your own way for Permission request, Dialog display, or even a whole LocationProvider process. (Custom LocationProvider implementation is described below in LocationManager section)

You can create your own PermissionProvider implementation and simply set it to PermissionConfiguration, and then library will use your implementation. Your custom PermissionProvider implementation will receive your configuration requirements from PermissionConfiguration object once it's built. If you don't specify any PermissionProvider to PermissionConfiguration DefaultPermissionProvider will be used. If you don't specify PermissionConfiguration to LocationConfiguration StubPermissionProvider will be used instead.

You can create your own DialogProvider implementation to display rationale message or gps request message to user, and simply set them to required configuration objects. If you don't specify any SimpleMessageDialogProvider will be used as default.

LocationManager

Ok, we have our configuration object up to requirements, now we need a manager configured with it.

// LocationManager MUST be initialized with Application context in order to prevent MemoryLeaks LocationManager awesomeLocationManager = new LocationManager.Builder(getApplicationContext())
  .activity(activityInstance) // Only required to ask permission and/or GoogleApi - SettingsApi
  .fragment(fragmentInstance) // Only required to ask permission and/or GoogleApi - SettingsApi
  .configuration(awesomeConfiguration)
  .locationProvider(new YourCustomLocationProvider())
  .notify(new LocationListener() {
 ... 
}
)
  .build();

LocationManager doesn't keep strong reference of your activity OR fragment in order not to cause any memory leak. They are required to ask for permission and/or GoogleApi - SettingsApi in case they need to be resolved.

You can create your own LocationProvider implementation and ask library to use it. If you don't set any, library will use DispatcherLocationProvider, which will do all the stuff is described above, as default.

Enough, gimme the location now!

awesomeLocationManager.get();

Done! Enjoy :)

Logging

Library has a lot of log implemented, in order to make tracking the process easy, you can simply enable or disable it. It is highly recommended to disable in release mode.

LocationManager.enableLog(false);

Restrictions

If you are using LocationManager in a

  • Fragment, you need to redirect your onActivityResult to fragment manually, because GooglePlayServices Api and SettingsApi calls startActivityForResult from activity. For the sample implementation please see SampleFragmentActivity.
  • Service, you need to have the permission already otherwise library will fail immediately with PermissionDenied error type. Because runtime permissions can be asked only from a fragment or an activity, not from a context. For the sample implementation please see SampleService.

AndroidManifest

Library requires 3 permission;

  • 2 of them ACCESS_NETWORK_STATE and INTERNET are not in Dangerous Permissions and they are required in order to use Network Provider. So if your configuration doesn't require them, you don't need to define them, otherwise they need to be defined.
  • The other one is ACCESS_FINE_LOCATION and it is marked as Dangerous Permissions, so you need to define it in Manifest and library will ask runtime permission for that if the application is running on Android M or higher OS version. If you don't specify in Manifest, library will fail immediately with PermissionDenied when location is required.
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <uses-permission android:name="android.permission.INTERNET" />  <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />

You might also need to consider information below from the location guide page.

Caution: If your app targets Android 5.0 (API level 21) or higher, you must declare that your app uses the android.hardware.location.network or android.hardware.location.gps hardware feature in the manifest file, depending on whether your app receives location updates from NETWORK_PROVIDER or from GPS_PROVIDER. If your app receives location information from either of these location provider sources, you need to declare that the app uses these hardware features in your app manifest. On devices running versions prior to Android 5.0 (API 21), requesting the ACCESS_FINE_LOCATION or ACCESS_COARSE_LOCATION permission includes an implied request for location hardware features. However, requesting those permissions does not automatically request location hardware features on Android 5.0 (API level 21) and higher.

Download

Add library dependency to your build.gradle file:

dependencies {

 compile 'com.yayandroid:LocationManager:x.y.z' 
}

License

Copyright 2016 yayandroid  Licensed under the Apache License, Version 2.0 (the "License");
 you may not use this file except in compliance with the License. You may obtain a copy of the License at
  http://www.apache.org/licenses/LICENSE-2.0  Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. 

Resources

Bash script that exports content provider's data to raw and CSV format. It can be your own content provider or any other provider that android decided not to block with permissions.

Android Studio Support for Additional File Types (CSS & JavaScript).

Current File Types Added:

  • CSS ( Cascading Style Sheet )
  • JavaScript

This plugin help you to set material design icons to your Android project.

Small Android library for use the Interactor (use case) and Executor for running code on a ThreadPool Thread or UI Thread. Normally this library is used for implement the Clean Architecture.

Use easily the database SQLite on Android using the DAO and transformer design patterns. Basic methods are already implemented in the class SQLiteDelegate, if you need further queries you should extend from it.

This is a nice and simple color picker for Android. It allows to show any number of different palettes with any (reasonable) number of colors. Palettes can be stored in an array or generated on the fly.

Topics


2D Engines   3D Engines   9-Patch   Action Bars   Activities   ADB   Advertisements   Analytics   Animations   ANR   AOP   API   APK   APT   Architecture   Audio   Autocomplete   Background Processing   Backward Compatibility   Badges   Bar Codes   Benchmarking   Bitmaps   Bluetooth   Blur Effects   Bread Crumbs   BRMS   Browser Extensions   Build Systems   Bundles   Buttons   Caching   Camera   Canvas   Cards   Carousels   Changelog   Checkboxes   Cloud Storages   Color Analysis   Color Pickers   Colors   Comet/Push   Compass Sensors   Conferences   Content Providers   Continuous Integration   Crash Reports   Credit Cards   Credits   CSV   Curl/Flip   Data Binding   Data Generators   Data Structures   Database   Database Browsers   Date &   Debugging   Decompilers   Deep Links   Dependency Injections   Design   Design Patterns   Dex   Dialogs   Distributed Computing   Distribution Platforms   Download Managers   Drawables   Emoji   Emulators   EPUB   Equalizers &   Event Buses   Exception Handling   Face Recognition   Feedback &   File System   File/Directory   Fingerprint   Floating Action   Fonts   Forms   Fragments   FRP   FSM   Functional Programming   Gamepads   Games   Geocaching   Gestures   GIF   Glow Pad   Gradle Plugins   Graphics   Grid Views   Highlighting   HTML   HTTP Mocking   Icons   IDE   IDE Plugins   Image Croppers   Image Loaders   Image Pickers   Image Processing   Image Views   Instrumentation   Intents   Job Schedulers   JSON   Keyboard   Kotlin   Layouts   Library Demos   List View   List Views   Localization   Location   Lock Patterns   Logcat   Logging   Mails   Maps   Markdown   Mathematics   Maven Plugins   MBaaS   Media   Menus   Messaging   MIME   Mobile Web   Native Image   Navigation   NDK   Networking   NFC   NoSQL   Number Pickers   OAuth   Object Mocking   OCR Engines   OpenGL   ORM   Other Pickers   Parallax List   Parcelables   Particle Systems   Password Inputs   PDF   Permissions   Physics Engines   Platforms   Plugin Frameworks   Preferences   Progress Indicators   ProGuard   Properties   Protocol Buffer   Pull To   Purchases   Push/Pull   QR Codes   Quick Return   Radio Buttons   Range Bars   Ratings   Recycler Views   Resources   REST   Ripple Effects   RSS   Screenshots   Scripting   Scroll Views   SDK   Search Inputs   Security   Sensors   Services   Showcase Views   Signatures   Sliding Panels   Snackbars   SOAP   Social Networks   Spannable   Spinners   Splash Screens   SSH   Static Analysis   Status Bars   Styling   SVG   System   Tags   Task Managers   TDD &   Template Engines   Testing   Testing Tools   Text Formatting   Text Views   Text Watchers   Text-to   Toasts   Toolkits For   Tools   Tooltips   Trainings   TV   Twitter   Updaters   USB   User Stories   Utils   Validation   Video   View Adapters   View Pagers   Views   Watch Face   Wearable Data   Wearables   Weather   Web Tools   Web Views   WebRTC   WebSockets   Wheel Widgets   Wi-Fi   Widgets   Windows   Wizards   XML   XMPP   YAML   ZIP Codes