Kotlin - 从网络提供商获取位置的问题

Posted

技术标签:

【中文标题】Kotlin - 从网络提供商获取位置的问题【英文标题】:Kotlin - Issue in getting location from Network provider 【发布时间】:2020-04-26 23:53:18 【问题描述】:

我必须在我的 android 应用程序中从用户设备获取位置。

我做了以下事情:

首先,我检查了运行时位置权限。拍摄成功。

第二,检查 GPS 是否启用,如果 GPS PROVIDER 工作正常,可以从 GPS Provider 获取纬度和经度。

第三,如果 GPS 已关闭,我正在尝试从 NETWORK Provider 获取位置。 但是,在这种情况下,有时无法成功获取位置。

所以,我必须让用户打开 GPS,打开 GPS 后必须获取位置。

我很困惑,因为许多演示都提供了打开 GPS 的意图。 如何动态打开 GPS? 如何在用户打开 GPS 时收到通知?

谢谢。

【问题讨论】:

【参考方案1】:

这是 Gradle 插件,在我的例子中,它是版本:'17.0.0'

implementation "com.google.android.gms:play-services-location:$parent.ext.playServicesVersion"

这是GpsUtils 类,

import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Context;
import android.content.IntentSender;
import android.location.LocationManager;
import android.util.Log;
import android.widget.Toast;

import androidx.annotation.NonNull;

import com.google.android.gms.common.api.ApiException;
import com.google.android.gms.common.api.ResolvableApiException;
import com.google.android.gms.location.LocationRequest;
import com.google.android.gms.location.LocationServices;
import com.google.android.gms.location.LocationSettingsRequest;
import com.google.android.gms.location.LocationSettingsResponse;
import com.google.android.gms.location.LocationSettingsStatusCodes;
import com.google.android.gms.location.SettingsClient;
import com.google.android.gms.tasks.OnFailureListener;
import com.google.android.gms.tasks.OnSuccessListener;

public class GpsUtils 

    private Context context;
    private SettingsClient mSettingsClient;
    private LocationSettingsRequest mLocationSettingsRequest;
    private LocationManager locationManager;
    private static final String TAG = GpsUtils.class.getSimpleName();

    public GpsUtils(Context context) 

        this.context = context;
        locationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
        mSettingsClient = LocationServices.getSettingsClient(context);

        LocationRequest locationRequest = LocationRequest.create();
        locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
        locationRequest.setInterval(2 * 1000);
        locationRequest.setFastestInterval(2 * 1000);
        LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder()
                .addLocationRequest(locationRequest);
        mLocationSettingsRequest = builder.build();

        //**************************
        builder.setAlwaysShow(true); //this is the key ingredient
        //**************************
    

    // method for turn on GPS
    public void turnGPSOn(onGpsListener onGpsListener) 

        if (locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)) 
            if (onGpsListener != null) 
                onGpsListener.gpsStatus(true);
            
         else 
            mSettingsClient
                    .checkLocationSettings(mLocationSettingsRequest)
                    .addOnSuccessListener((Activity) context, new OnSuccessListener<LocationSettingsResponse>() 
                        @SuppressLint("MissingPermission")
                        @Override
                        public void onSuccess(LocationSettingsResponse locationSettingsResponse) 

                            //  GPS is already enable, callback GPS status through listener
                            if (onGpsListener != null) 
                                onGpsListener.gpsStatus(true);
                            
                        
                    )
                    .addOnFailureListener((Activity) context, new OnFailureListener() 
                        @Override
                        public void onFailure(@NonNull Exception e) 
                            int statusCode = ((ApiException) e).getStatusCode();
                            switch (statusCode) 
                                case LocationSettingsStatusCodes.RESOLUTION_REQUIRED:

                                    try 
                                        ResolvableApiException rae = (ResolvableApiException) e;
                                        rae.startResolutionForResult((Activity) context, Appconstants.GPS_REQUEST);
                                     catch (IntentSender.SendIntentException sie) 
                                        Log.i(TAG, "PendingIntent unable to execute request.");
                                    
                                    break;
                                case LocationSettingsStatusCodes.SETTINGS_CHANGE_UNAVAILABLE:
                                    String errorMessage = "Location settings are inadequate, and cannot be " +
                                        "fixed here. Fix in Settings.";

                                    Toast.makeText((Activity) context, errorMessage, Toast.LENGTH_LONG).show();
                            
                        
                    );
        
    

    public interface onGpsListener 
        void gpsStatus(boolean isGPSEnable);
    

您可以从您的活动中调用以下函数来让用户启用 GPS。我将 GPSUtils 类保留在 java 本身中,因为它是可互操作的。

  GpsUtils(this).turnGPSOn  isGPSEnable ->
                isGPS = isGPSEnable  // You can get the callback here..
            

您可以从here 阅读有关SettingsClient 的更多信息。

【讨论】:

您好,先生,我找到了显示 GPS 对话框的方法。现在,问题是如何通知用户按下 OK 或 NOT NOW ? 如果他们按OK,最终您将启用 GPS,反之亦然,对吗?您想通过单击“是”或“否”Btn 来实现什么?无论如何,addOnSuccessListeneraddOnFailureListener 可以帮助你吗?

以上是关于Kotlin - 从网络提供商获取位置的问题的主要内容,如果未能解决你的问题,请参考以下文章

从网络提供商处获取准确的当前位置

仅从 GPRS 网络提供商 Android 获取位置

如何在swift ios中从移动网络获取纬度和经度[关闭]

Android获取当前位置的最佳方式[重复]

如何从 Kotlin Android 中的 LinkedHashMap 手动获取第一和第二位置的对象?

在 Kotlin 中获取新用户位置不起作用