我使用Kotlin而不是Java编写了这个谷歌Android / Java示例项目的kotlin分支 在此处(未经测试,可能会有错误)
下面的字符串和尺寸值文件被排除。您可以硬编码您自己的文件或查看分支
MainActivity.kt
package com.google.android.gms.location.sample.locationupdatespendingintent
import android.Manifest
import android.app.PendingIntent
import android.content.Intent
import android.content.SharedPreferences
import android.content.pm.PackageManager
import android.net.Uri
import android.os.Bundle
import android.preference.PreferenceManager
import android.provider.Settings
import android.support.design.widget.Snackbar
import android.support.v4.app.ActivityCompat
import android.support.v4.app.FragmentActivity
import android.util.Log
import android.view.View
import android.widget.Button
import android.widget.TextView
import com.google.android.gms.location.FusedLocationProviderClient
import com.google.android.gms.location.LocationRequest
import com.google.android.gms.location.LocationServices
class MainActivity : FragmentActivity(), SharedPreferences.OnSharedPreferenceChangeListener {
val mLocationRequest = LocationRequest()
private var mFusedLocationClient: FusedLocationProviderClient? = null
private var mRequestUpdatesButton: Button? = null
private var mRemoveUpdatesButton: Button? = null
private var mLocationUpdatesResultView: TextView? = null
private val pendingIntent: PendingIntent
get() {
val intent = Intent(this, LocationUpdatesBroadcastReceiver::class.java)
intent.action = LocationUpdatesBroadcastReceiver.ACTION_PROCESS_UPDATES
return PendingIntent.getBroadcast(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT)
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
mFusedLocationClient = LocationServices.getFusedLocationProviderClient(this)
mRequestUpdatesButton = findViewById(R.id.remove_updates_button)
mRemoveUpdatesButton = findViewById(R.id.request_updates_button)
mLocationUpdatesResultView = findViewById(R.id.location_updates_result)
if (!checkPermissions()) {
requestPermissions()
}
createLocationRequest()
}
override fun onStart() {
super.onStart()
PreferenceManager.getDefaultSharedPreferences(this)
.registerOnSharedPreferenceChangeListener(this)
}
override fun onResume() {
super.onResume()
updateButtonsState(Utils.getRequestingLocationUpdates(this))
mLocationUpdatesResultView?.text = Utils.getLocationUpdatesResult(this)
}
override fun onStop() {
PreferenceManager.getDefaultSharedPreferences(this)
.unregisterOnSharedPreferenceChangeListener(this)
super.onStop()
}
private fun createLocationRequest() {
mLocationRequest.interval = UPDATE_INTERVAL
mLocationRequest.fastestInterval = FASTEST_UPDATE_INTERVAL
mLocationRequest.priority = LocationRequest.PRIORITY_HIGH_ACCURACY
mLocationRequest.maxWaitTime = MAX_WAIT_TIME
}
private fun checkPermissions(): Boolean {
val permissionState = ActivityCompat.checkSelfPermission(this,
Manifest.permission.ACCESS_FINE_LOCATION)
return permissionState == PackageManager.PERMISSION_GRANTED
}
private fun requestPermissions() {
val shouldProvideRationale = ActivityCompat.shouldShowRequestPermissionRationale(this,
Manifest.permission.ACCESS_FINE_LOCATION)
if (shouldProvideRationale) {
Log.i(TAG, "Displaying permission rationale to provide additional context.")
Snackbar.make(
findViewById(R.id.activity_main),
R.string.permission_rationale,
Snackbar.LENGTH_INDEFINITE)
.setAction(R.string.ok) {
ActivityCompat.requestPermissions(this@MainActivity,
arrayOf(Manifest.permission.ACCESS_FINE_LOCATION),
REQUEST_PERMISSIONS_REQUEST_CODE)
}
.show()
} else {
Log.i(TAG, "Requesting permission")
ActivityCompat.requestPermissions(this@MainActivity,
arrayOf(Manifest.permission.ACCESS_FINE_LOCATION),
REQUEST_PERMISSIONS_REQUEST_CODE)
}
}
override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<String>,
grantResults: IntArray) {
Log.i(TAG, "onRequestPermissionResult")
if (requestCode == REQUEST_PERMISSIONS_REQUEST_CODE) {
if (grantResults.size <= 0) {
Log.i(TAG, "User interaction was cancelled.")
} else if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
requestLocationUpdates(null)
} else {
Snackbar.make(
findViewById(R.id.activity_main),
R.string.permission_denied_explanation,
Snackbar.LENGTH_INDEFINITE)
.setAction(R.string.settings) {
val intent = Intent()
intent.action = Settings.ACTION_APPLICATION_DETAILS_SETTINGS
val uri = Uri.fromParts("package",
BuildConfig.APPLICATION_ID, null)
intent.data = uri
intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK
startActivity(intent)
}
.show()
}
}
}
override fun onSharedPreferenceChanged(sharedPreferences: SharedPreferences, s: String) {
if (s == Utils.KEY_LOCATION_UPDATES_RESULT) {
mLocationUpdatesResultView?.text = Utils.getLocationUpdatesResult(this)
} else if (s == Utils.KEY_LOCATION_UPDATES_REQUESTED) {
updateButtonsState(Utils.getRequestingLocationUpdates(this))
}
}
fun requestLocationUpdates(view: View?) {
try {
Log.i(TAG, "Starting location updates")
Utils.setRequestingLocationUpdates(this, true)
mFusedLocationClient?.requestLocationUpdates(mLocationRequest, pendingIntent)
} catch (e: SecurityException) {
Utils.setRequestingLocationUpdates(this, false)
e.printStackTrace()
}
}
fun removeLocationUpdates(view: View) {
Log.i(TAG, "Removing location updates")
Utils.setRequestingLocationUpdates(this, false)
mFusedLocationClient?.removeLocationUpdates(pendingIntent)
}
private fun updateButtonsState(requestingLocationUpdates: Boolean) {
if (requestingLocationUpdates) {
mRequestUpdatesButton?.isEnabled = false
mRemoveUpdatesButton?.isEnabled = true
} else {
mRequestUpdatesButton?.isEnabled = true
mRemoveUpdatesButton?.isEnabled = false
}
}
companion object {
private val TAG = MainActivity::class.java.getSimpleName()
private val REQUEST_PERMISSIONS_REQUEST_CODE = 34
private val UPDATE_INTERVAL: Long = 60000
private val FASTEST_UPDATE_INTERVAL: Long = 30000
private val MAX_WAIT_TIME = UPDATE_INTERVAL * 5
}
}
activity_main.xml中的监听器会触发MainActivity.kt中的方法。
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="com.google.android.gms.location.sample.locationupdatespendingintent.MainActivity">
<TextView
android:id="@+id/using_batched_location_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/batched_location_updates"
android:layout_marginBottom="@dimen/default_margin"
android:textSize="@dimen/text_large" />
<Button
android:id="@+id/request_updates_button"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:onClick="requestLocationUpdates"
android:text="@string/request_updates" />
<Button
android:id="@+id/remove_updates_button"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:onClick="removeLocationUpdates"
android:layout_marginBottom="@dimen/default_margin"
android:text="@string/remove_updates" />
<TextView
android:id="@+id/location_updates_result"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
LocationUpdatesIntentService.kt
package com.google.android.gms.location.sample.locationupdatespendingintent
import android.app.IntentService
import android.content.Context
import android.content.Intent
import android.location.Location
import android.util.Log
import com.google.android.gms.location.LocationResult
class LocationUpdatesIntentService : IntentService(TAG) {
override fun onHandleIntent(intent: Intent?) {
if (intent != null) {
val action = intent.action
if (ACTION_PROCESS_UPDATES == action) {
val result = LocationResult.extractResult(intent)
if (result != null) {
val locations = result.locations
Utils.setLocationUpdatesResult(this, locations)
Utils.sendNotification(this, Utils.getLocationResultTitle(this, locations))
Log.i(TAG, Utils.getLocationUpdatesResult(this))
}
}
}
}
companion object {
private val ACTION_PROCESS_UPDATES = "com.google.android.gms.location.sample.locationupdatespendingintent.action" + ".PROCESS_UPDATES"
private val TAG = LocationUpdatesIntentService::class.java.simpleName
}
}
LocationUpdatesBroadcastReceiver.kt
package com.google.android.gms.location.sample.locationupdatespendingintent
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.location.Location
import android.util.Log
import com.google.android.gms.location.LocationResult
class LocationUpdatesBroadcastReceiver : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent?) {
if (intent != null) {
val action = intent.action
if (ACTION_PROCESS_UPDATES == action) {
val result = LocationResult.extractResult(intent)
if (result != null) {
val locations = result.locations
Utils.setLocationUpdatesResult(context, locations)
Utils.sendNotification(context, Utils.getLocationResultTitle(context, locations))
Log.i(TAG, Utils.getLocationUpdatesResult(context))
}
}
}
}
companion object {
private val TAG = "LUBroadcastReceiver"
internal val ACTION_PROCESS_UPDATES = "com.google.android.gms.location.sample.locationupdatespendingintent.action" + ".PROCESS_UPDATES"
}
}
AndroidManifest.xml 在这里定义服务和接收器。
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.google.android.gms.location.sample.locationupdatespendingintent">
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service
android:name=".LocationUpdatesIntentService"
android:exported="false" />
<receiver android:name=".LocationUpdatesBroadcastReceiver"
android:exported="true">
<intent-filter>
<action android:name="com.google.android.gms.location.sample.locationupdatespendingintent.LocationUpdatesBroadcastReceiver.ACTION_PROCESS_UPDATES" />
</intent-filter>
</receiver>
</application>
</manifest>