使用google地图定位

使用Google地图,需要手机支持google服务 (国产手机很多都不支持),如果不支持可以手动安装:

 

 

如果还是不能定位,可以安装下google地图App,然后定个位 ,不出意外这样就可以了

 

集成:

implementation 'com.google.android.gms:play-services-maps:17.0.0'//谷歌地图
implementation 'com.google.android.gms:play-services-places:17.0.0' //基础包
implementation 'com.google.android.gms:play-services-location:17.0.0'//谷歌定位
<!--  application标签里添加
             基于Google Maps的API的API密钥定义为字符串资源。
             (请参见文件“ res / values / google_maps_api.xml”)。
             请注意,API密钥链接到用于对APK签名的加密密钥。
             每个加密密钥都需要一个不同的API密钥,包括用于
             在APK上签名以发布。
             您可以在src / debug /和src / release /中定义调试和发布目标的键。
        -->
        <meta-data
            android:name="com.google.android.geo.API_KEY"
            android:value="@string/google_maps_key" />

<resources>
    <!--

    为此,您可以将发布密钥凭据添加到现有的
    密钥,或创建一个新密钥。

    请注意,此文件为发布构建目标指定API密钥。
    如果您之前已使用调试签名证书为调试目标设置了密钥,
    您还需要为发布证书设置密钥。

    请按照以下说明进行操作:

    https://developers.google.com/maps/documentation/android/signup

    拥有密钥(以“ AIza”开头)后,请替换“ google_maps_key”
    该文件中的字符串。
    -->
    <string name="google_maps_key" templateMergeStrategy="preserve" translatable="false">
        AIzaSyC_-_ze8LEqnFhf12bat6J2BQ5M0fDGpNE
    </string>
</resources>

 

使用:

import android.annotation.SuppressLint
import android.app.Activity
import android.content.Context
import android.location.Location
import android.os.Looper
import com.google.android.gms.common.api.ApiException
import com.google.android.gms.common.api.ResolvableApiException
import com.google.android.gms.location.*


/**
每2秒 定一次位 */ class LocationUtil { private val mLocationRequest: LocationRequest private var mFusedLocationClient: FusedLocationProviderClient? = null private var mLocationCallback = object : LocationCallback() { override fun onLocationResult(p0: LocationResult?) { super.onLocationResult(p0) LogUtil.e("定位结果:po = ${p0}") } } constructor(){ mLocationRequest = LocationRequest() mLocationRequest.priority = LocationRequest.PRIORITY_HIGH_ACCURACY //高精度定位 mLocationRequest.interval = 2000 //2秒 定位一次 定位间隔 mLocationRequest.fastestInterval = 2000 //最快的定位间隔 } /** * 开始定位 */ fun requestLocationUpdate(context: Context) { if(mFusedLocationClient == null){ if (context is Activity) { mFusedLocationClient = LocationServices.getFusedLocationProviderClient(context) } else { mFusedLocationClient = LocationServices.getFusedLocationProviderClient(context) } } // 使用位置请求创建LocationSettingsRequest对象 val builder = LocationSettingsRequest.Builder() builder.addLocationRequest(mLocationRequest) val locationSettingsRequest = builder.build() val settingsClient: SettingsClient // 检查是否满足位置设置 // https://developers.google.com/android/reference/com/google/android/gms/location/SettingsClient if (context is Activity) { settingsClient = LocationServices.getSettingsClient(context) } else { settingsClient = LocationServices.getSettingsClient(context) } settingsClient .checkLocationSettings(locationSettingsRequest) .addOnSuccessListener { LogUtil.e("可以定位-----------------------------") //权限检测 没有权限 定位失败 谷歌定位不回调 //if(有权限){ startLocationUpdates() //}else{ // //} } .addOnCompleteListener{ LogUtil.e("条件检测完成-----------------------------${it.isSuccessful}") } .addOnFailureListener { e -> LogUtil.e("不可定位---------------------------- ${e.message}") if(e is ApiException){ when (e.statusCode) { LocationSettingsStatusCodes.RESOLUTION_REQUIRED -> { LogUtil.e("不满足定位要求,请求设置") if (context is Activity) { try { // 通过调用startResolutionForResult()显示对话框,然后检查 产生onActivityResult()。 val rae = e as ResolvableApiException rae.startResolutionForResult(context, 789) } catch (sie: Exception) { LogUtil.e("PendingIntent无法执行请求。") } } } LocationSettingsStatusCodes.SETTINGS_CHANGE_UNAVAILABLE -> { LogUtil.e("无法更改设置") } } } } } @SuppressLint("MissingPermission") private fun startLocationUpdates() { mFusedLocationClient?.requestLocationUpdates( mLocationRequest, mLocationCallback, Looper.myLooper() ) } fun stopLocation() { mFusedLocationClient?.removeLocationUpdates(mLocationCallback) } } interface MyLocationCallback{ fun locationFailure() fun locationSuccess(location: Location) }

手动检测手机是否支持google服务:

/**
         * 是否支持Google Play服务
         */
        fun isHaveGooglePlay(activity: Activity, requestCode: Int): Boolean {
            val googleApiAvailability = GoogleApiAvailability.getInstance();
            val resultCode = googleApiAvailability.isGooglePlayServicesAvailable(activity);
            if(resultCode != ConnectionResult.SUCCESS) {
                /**
                 * 通过isUserResolvableError来确定是否可以通过用户操作解决错误
                 */
                if (GoogleApiAvailability.getInstance().isUserResolvableError(resultCode)) {
                    /**
                     * 返回一个对话框,用于解决提供的errorCode。
                     * @param activity  用于创建对话框的父活动
                     * @param code      通过调用返回的错误代码
                     * @param activity  调用startActivityForResult时给出的requestCode
                     */
                    GoogleApiAvailability.getInstance().getErrorDialog(activity, resultCode, requestCode).show();
                }
                return false
            }
            return true
        }

定位成功后,通过经纬度获取更加详细的地址信息:

/**
     * https://maps.googleapis.com/maps/api/geocode/json?latlng=37.422,-122.084&language=zh-CN&sensor=false
     */
    @GET
    fun getGoogleLocationInfo(@Url url: String): Observable<JsonObject>
fun locationToStr(location: Location) {
        val url = Uri.parse("https://maps.googleapis.com/maps/api/geocode/json").buildUpon().let {
            it.appendQueryParameter("latlng","${location.latitude},${location.longitude}")
            it.appendQueryParameter("language","zh-CN")// language=en-US 返回是英文,language=cn-ZH 返回是中文,默认是返回中文
            it.appendQueryParameter("key","AIzaSyC_-_ze8LEqnFhf12bat6J2BQ5M0fDGpNE")
            it.appendQueryParameter("sensor","false")
                .toString()
        }
        addDdisposable(
            ApiRetrofitClient.service.getGoogleLocationInfo(url)
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .map {
                    //var address = it.get("results").asJsonArray.get(0).asJsonObject.get("formatted_address").asString
                    //最后一组,只有国家信息
                    var components = it.get("results").asJsonArray.get(it.get("results").asJsonArray.size() - 1).asJsonObject.get("address_components").asJsonArray
                    val countryCode = components[0].asJsonObject.get("short_name").asString
                    //LogUtil.e("国家编码 = $countryCode   地址 = $address")
                    if(countryCode == null){
                        throw Exception()
                    }else{
                        return@map countryCode
                    }
                }
                .subscribeWith(object : HttpObserver<String>(loginView){
                    override fun onNext(t: String) {
                        super.onNext(t)
 
                    }
                })
        )
    }

 

 

posted @ 2019-11-04 09:27  ts-android  阅读(2641)  评论(1编辑  收藏  举报