Android Geolocation GooglePlay Service(Kotlin)
Google Play Service
These days, google play service separates component.(In the past, all features are combined).
And it provides helper functions for Android Development.
Geolocation
Android supports geolocation acquisition by default(Android API).
To support it, we need GPS or Internet(4G, 3G).
GPS is more accurate than Internet.
Permission
To get geolocation, we need additional permission
<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_COARSE_UPDATES" /> <uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.WRITE_SETTINGS" /> <uses-feature android:name="android.hardware.location.gps" />
First 3 are for GPS.
INTERNET is to use INTERGET geolocation function.
The last is for Android 5 above.
Google Play Service(Google Location and Activity Recognition)
dependencies { compile 'com.google.android.gms:play-services:11.0.4' }
Example
This is a simple example.
Prepare google play API in onCreate.
Connect API in onStart
Start getting geolocation in onResume.
activity_geo_location.xml
<?xml version="1.0" encoding="utf-8"?> <android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="com.atmarkplant.locationlogger.MainActivity"> <TextView android:id="@+id/geoTextView" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Hello World!" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toRightOf="parent" app:layout_constraintTop_toTopOf="parent" /> <Button android:id="@+id/geoGetButton" android:text="Get" android:layout_width="match_parent" android:layout_height="wrap_content" app:layout_constraintTop_toBottomOf="@+id/geoTextView" /> </android.support.constraint.ConstraintLayout>
GooglePlayGeoLocationActivity.kt
class GooglePlayGeoLocationActivity : AppCompatActivity(), GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener, LocationListener { lateinit var textView : TextView var googleApiClient : GoogleApiClient? = null lateinit var locationRequest : LocationRequest lateinit var locationSettingRequest : LocationSettingsRequest var currentLocation : Location? = null override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_geo_location) this.textView = findViewById(R.id.geoTextView) as TextView val button : Button = findViewById(R.id.geoGetButton) as Button button.setOnClickListener { try { startLocationUpdates() } catch (e : SecurityException) { } } initGoogleAPIClient() createLocationRequest() createLocationSettings() } override fun onStart() { super.onStart() this.googleApiClient?.connect() } override fun onResume() { super.onResume() if (isLocationEnabled(this)) { if (googleApiClient != null && googleApiClient!!.isConnected()) { startLocationUpdates(); } } } private fun updateUI() { // Location Update UI if (currentLocation != null) { textView.text = String.format("Latitude:%f Longitude:%f", currentLocation?.latitude, currentLocation?.longitude) } } private fun initGoogleAPIClient() { this.googleApiClient = GoogleApiClient.Builder(applicationContext) .addConnectionCallbacks(this) .addOnConnectionFailedListener(this) .addApi(LocationServices.API) .build() } private fun createLocationRequest() { locationRequest = LocationRequest() locationRequest.interval = 5000 locationRequest.fastestInterval = 5000 locationRequest.priority = LocationRequest.PRIORITY_HIGH_ACCURACY } private fun createLocationSettings() { val builder : LocationSettingsRequest.Builder = LocationSettingsRequest.Builder() if (this.locationRequest != null) { builder.addLocationRequest(locationRequest) this.locationSettingRequest = builder.build() } } private fun isLocationEnabled(context : Context) : Boolean { var locationMode: Int = 0 var locationProviders: String? if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { try { locationMode = Settings.Secure.getInt(context.contentResolver, Settings.Secure.LOCATION_MODE) return locationMode != Settings.Secure.LOCATION_MODE_OFF } catch(e: Settings.SettingNotFoundException) { e.printStackTrace() } return locationMode != Settings.Secure.LOCATION_MODE_OFF } else { locationProviders = Settings.Secure.getString(context.contentResolver, Settings.Secure.LOCATION_PROVIDERS_ALLOWED) return locationProviders != null && locationProviders.isNotEmpty() } } @Throws(SecurityException::class) private fun startLocationUpdates() { /* if (checkSelfPermission(Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED)) { if (shouldShowRequestPermissionRationale(Manifest.permission.ACCESS_FINE_LOCATION)) { return } }*/ LocationServices.FusedLocationApi.requestLocationUpdates( googleApiClient, locationRequest, this).setResultCallback { status: Status -> if (status.isSuccess) { print("Success") } else { print("Failed") } } } /* * GoogleApiClient.ConnectionCallbacks */ override fun onConnected(p0: Bundle?) { if (currentLocation == null) { try { // checkselfpermission or SecurityException currentLocation = LocationServices.FusedLocationApi.getLastLocation(googleApiClient) // TODO Update UI updateUI() } catch(e : SecurityException) { } } } /* * GoogleApiClient.OnConnectionFailedListener */ override fun onConnectionSuspended(p0: Int) { } override fun onConnectionFailed(p0: ConnectionResult) { } /* * LocationListener */ override fun onLocationChanged(p0: Location?) { }
Test
This code is kotlin.(Android Preveiw 3)
Ref
Androidアプリ開発 Google Play services Location Serviceで位置情報を取得する
Android check permission for LocationManager