背景
安卓开放经常需要获取地理位置,所以对获取地理位置做了下整理,方便大家使用。
解决方案:
源代码:https://gitee.com/cxyzy1/locationDemo
GPSUtils.java
package com.cxyzy.demo;
import android.annotation.SuppressLint;
import android.content.Context;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.util.Log;
public class GPSUtils {
private static String TAG = GPSUtils.class.getSimpleName();
private static GPSUtils mInstance;
private Context mContext;
private static LocationListener mLocationListener = new LocationListener() {
// Provider的状态在可用、暂时不可用和无服务三个状态直接切换时触发此函数
@Override
public void onStatusChanged(String provider, int status, Bundle extras) {
Log.d(TAG, "onStatusChanged");
}
// Provider被enable时触发此函数,比如GPS被打开
@Override
public void onProviderEnabled(String provider) {
Log.d(TAG, "onProviderEnabled");
}
// Provider被disable时触发此函数,比如GPS被关闭
@Override
public void onProviderDisabled(String provider) {
Log.d(TAG, "onProviderDisabled");
}
//当坐标改变时触发此函数,如果Provider传进相同的坐标,它就不会被触发
@Override
public void onLocationChanged(Location location) {
}
};
private GPSUtils(Context context) {
this.mContext = context;
}
public static GPSUtils getInstance(Context context) {
if (mInstance == null) {
mInstance = new GPSUtils(context.getApplicationContext());
}
return mInstance;
}
/**
* 获取地理位置,先根据GPS获取,再根据网络获取
*
* @return
*/
@SuppressLint("MissingPermission")
public Location getLocation() {
Location location = null;
try {
if (mContext == null) {
return null;
}
LocationManager locationManager = (LocationManager) mContext.getSystemService(Context.LOCATION_SERVICE);
if (locationManager == null) {
return null;
}
if (locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)) { //从gps获取经纬度
location = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
if (location == null) {//当GPS信号弱没获取到位置的时候再从网络获取
location = getLocationByNetwork();
}
} else { //从网络获取经纬度
location = getLocationByNetwork();
}
} catch (Exception e) {
Log.e(TAG, e.getMessage());
}
return location;
}
/**
* 判断是否开启了GPS或网络定位开关
*
* @return
*/
public boolean isLocationProviderEnabled() {
boolean result = false;
LocationManager locationManager = (LocationManager) mContext.getSystemService(Context.LOCATION_SERVICE);
if (locationManager == null) {
return result;
}
if (locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER) || locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER)) {
result = true;
}
return result;
}
/**
* 获取地理位置,先根据GPS获取,再根据网络获取
*
* @return
*/
@SuppressLint("MissingPermission")
private Location getLocationByNetwork() {
Location location = null;
LocationManager locationManager = (LocationManager) mContext.getSystemService(Context.LOCATION_SERVICE);
try {
if (locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER)) {
locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 1000, 0, mLocationListener);
location = locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
}
} catch (Exception e) {
Log.e(TAG, e.getMessage());
}
return location;
}
}
调用样例(Kotlin):
package com.cxyzy.demo
import android.app.AlertDialog
import android.content.Intent
import android.os.Bundle
import android.provider.Settings
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import com.blankj.utilcode.constant.PermissionConstants
import com.blankj.utilcode.util.PermissionUtils
import kotlinx.android.synthetic.main.activity_main.*
class MainActivity : AppCompatActivity() {
private val REQUEST_LOCATION_PERMISSION_CODE = 100
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
getLocationBtn.setOnClickListener { showLocation() }
}
private fun showLocation() {
PermissionUtils.permission(PermissionConstants.LOCATION)
.callback(object : PermissionUtils.FullCallback {
override fun onGranted(permissionsGranted: List<String>) {
if (GPSUtils.getInstance([email protected]).isLocationProviderEnabled) {
showLocationWithToast()
} else {
requestLocation()
}
}
override fun onDenied(permissionsDeniedForever: List<String>, permissionsDenied: List<String>) {
Toast.makeText([email protected], "未获得地理位置权限", Toast.LENGTH_LONG).show()
}
})
.request()
}
private fun showLocationWithToast() {
val location = GPSUtils.getInstance([email protected]).location
Toast.makeText(
[email protected],
"地理位置:lon:${location.longitude};lat:${location.latitude}",
Toast.LENGTH_LONG
).show()
}
/**
* 检查地理位置开关是否打开,如果未打开,则提示用户打开地理位置开关。
* 如果已打开,则显示地理位置;如果被拒绝,直接关闭窗口。
*/
private fun requestLocation() {
val message = "本应用需要获取地理位置,请打开获取位置的开关"
val alertDialog = AlertDialog.Builder(this).setMessage(message).setCancelable(false)
.setPositiveButton(android.R.string.ok)
{ dialog, _ ->
dialog.dismiss()
gotoSysLocationSettingsPage()
}
.setNegativeButton(android.R.string.cancel) { dialog, _ -> dialog.dismiss() }
.create()
alertDialog.show()
}
private fun gotoSysLocationSettingsPage() {
val intent = Intent()
intent.action = Settings.ACTION_LOCATION_SOURCE_SETTINGS
startActivityForResult(intent, REQUEST_LOCATION_PERMISSION_CODE)
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
when (requestCode) {
REQUEST_LOCATION_PERMISSION_CODE -> showLocation()
else -> {
}
}
}
}
备注:调用样例使用了第三方库,需要提前添加依赖:implementation 'com.blankj:utilcode:1.22.10'
效果图:
安卓开发技术分享: https://blog.****.net/yinxing2008/article/details/84555061