如何显示启用位置对话框,如谷歌地图?

Posted

技术标签:

【中文标题】如何显示启用位置对话框,如谷歌地图?【英文标题】:How to show enable location dialog like Google maps? 【发布时间】:2015-06-30 08:03:05 【问题描述】:

我使用最新版本的 Google Play 服务 (7.0) 并按照他们指南中给出的步骤操作,并启用了如下所示的位置对话框,其中有一个“从不”按钮。我的应用程序需要强制定位,所以我不想向用户显示“从不”,因为一旦用户点击“从不”,我就无法再次获取位置或请求位置。

由于 Google 地图只有 yes 和 no 按钮而没有 never 按钮,知道如何实现相同的功能吗?

我的应用的图片

谷歌地图的图片

【问题讨论】:

这是我为 kotlin 用户提供的解决方案:***.com/questions/31235564/… 【参考方案1】:

LocationSettingsRequest.Builder 有一个方法setAlwaysShow(boolean show)虽然文档表明它目前什么都不做(2015 年 7 月 5 日更新:更新的 Google 文档已删除此措辞),但设置 builder.setAlwaysShow(true); 将启用 Google 地图行为:

这是让它工作的代码:

if (googleApiClient == null) 
    googleApiClient = new GoogleApiClient.Builder(getActivity())
            .addApi(LocationServices.API)
            .addConnectionCallbacks(this)
            .addOnConnectionFailedListener(this).build();
    googleApiClient.connect();

    LocationRequest locationRequest = LocationRequest.create();
    locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
    locationRequest.setInterval(30 * 1000);
    locationRequest.setFastestInterval(5 * 1000);
    LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder()
            .addLocationRequest(locationRequest);

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

    PendingResult<LocationSettingsResult> result =
            LocationServices.SettingsApi.checkLocationSettings(googleApiClient, builder.build());
    result.setResultCallback(new ResultCallback<LocationSettingsResult>() 
        @Override
        public void onResult(LocationSettingsResult result) 
            final Status status = result.getStatus();
            final LocationSettingsStates state = result.getLocationSettingsStates();
            switch (status.getStatusCode()) 
                case LocationSettingsStatusCodes.SUCCESS:
                    // All location settings are satisfied. The client can initialize location
                    // requests here.
                    break;
                case LocationSettingsStatusCodes.RESOLUTION_REQUIRED:
                    // Location settings are not satisfied. But could be fixed by showing the user
                    // a dialog.
                    try 
                        // Show the dialog by calling startResolutionForResult(),
                        // and check the result in onActivityResult().
                        status.startResolutionForResult(
                                getActivity(), 1000);
                     catch (IntentSender.SendIntentException e) 
                        // Ignore the error.
                    
                    break;
                case LocationSettingsStatusCodes.SETTINGS_CHANGE_UNAVAILABLE:
                    // Location settings are not satisfied. However, we have no way to fix the
                    // settings so we won't show the dialog.
                    break;
            
        
    );

From android Documentation

对于 Kotlin,请参见此处:https://***.com/a/61868985/12478830

【讨论】:

@MarianPaździoch 很确定您不需要,因为 Google 自己的 SettingsApi 示例代码不需要它。 @Kai 是的,代码在 Nexus 5 上未修改。使用日志,我看到当位置服务最初关闭时,它总是点击 RESOLUTION_REQUIRED。然后,一旦我接受并启用位置,它会点击SUCCESS,并完全跳过onActivityResult()。按No 或返回会使对话框消失一秒钟,然后重新加载并再次点击RESOLUTION_REQUIRED。摆脱对话框的唯一方法是接受或关闭并重新打开应用程序。 @pez 在 Galaxy S4 上使用 Google Play 服务 7.5.74 进行了测试,它可以工作,取消不会导致调用 RESOLUTION_REQUIRED。我的建议是更新播放服务并重试。如果失败,请提出一个新的 *** 问题,看看其他人是否遇到并解决了这个问题。 @Kai 它对我有用,但是如果用户按下 no 怎么办。如果按下 no,如何再次显示对话框或添加一些代码。任何帮助将不胜感激。 注意:您的活动的launchMode 不能设置为singleInstance,否则这将不起作用。该对话框将永远不会出现,onActivityResult 将被自动调用。在AndroidManifest 中的活动没有android:launchMode="singleInstance"。 3 小时后,我非常努力地学会了这一点【参考方案2】:

对于那些正在寻找处理是/否按钮的人,我想为 kai 的答案添加一些更改。

在你的活动中声明这个常量

protected static final int REQUEST_CHECK_SETTINGS = 0x1;

在你的 onStart() 中调用 settingsrequest()

public void settingsrequest()
    
        LocationRequest locationRequest = LocationRequest.create();
        locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
        locationRequest.setInterval(30 * 1000);
        locationRequest.setFastestInterval(5 * 1000);
        LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder()
                .addLocationRequest(locationRequest);
        builder.setAlwaysShow(true); //this is the key ingredient

        PendingResult<LocationSettingsResult> result =
                LocationServices.SettingsApi.checkLocationSettings(mGoogleApiClient, builder.build());
        result.setResultCallback(new ResultCallback<LocationSettingsResult>() 
            @Override
            public void onResult(LocationSettingsResult result) 
                final Status status = result.getStatus();
                final LocationSettingsStates state = result.getLocationSettingsStates();
                switch (status.getStatusCode()) 
                    case LocationSettingsStatusCodes.SUCCESS:
                        // All location settings are satisfied. The client can initialize location
                        // requests here.
                        break;
                    case LocationSettingsStatusCodes.RESOLUTION_REQUIRED:
                        // Location settings are not satisfied. But could be fixed by showing the user
                        // a dialog.
                        try 
                            // Show the dialog by calling startResolutionForResult(),
                            // and check the result in onActivityResult().
                            status.startResolutionForResult(MainActivity.this, REQUEST_CHECK_SETTINGS);
                         catch (IntentSender.SendIntentException e) 
                            // Ignore the error.
                        
                        break;
                    case LocationSettingsStatusCodes.SETTINGS_CHANGE_UNAVAILABLE:
                        // Location settings are not satisfied. However, we have no way to fix the
                        // settings so we won't show the dialog.
                        break;
                
            
        );
    
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) 
        switch (requestCode) 
// Check for the integer request code originally supplied to startResolutionForResult().
            case REQUEST_CHECK_SETTINGS:
                switch (resultCode) 
                    case Activity.RESULT_OK:
                        startLocationUpdates();
                        break;
                    case Activity.RESULT_CANCELED:
                        settingsrequest();//keep asking if imp or do whatever
                        break;
                
                break;
        
    

【讨论】:

来自官方文档:developers.google.com/android/reference/com/google/android/gms/… 如果您只需要添加地图,那么您必须添加这些库(无需导入整个播放服务库):compile 'com.google. android.gms:play-services-maps:9.0.2' 编译 'com.google.android.gms:play-services-location:9.0.2' 如何处理此对话框的点击事件,我绝不能在对话框中显示从不按钮 从 ActivityOnResult 中的 switch case 中删除 settingsrequest() 行。这就是你要问的吗??? 如果我没有点击对话框的按钮,对话框仍然持续出现。我已经从 ActivityOnResult 的 switch case 中删除了 settingsrequest() 行。那么为什么它会持续显示? 可能你需要清理构建项目。【参考方案3】:

LocationServices.SettingsApi 现已弃用,因此我们使用 SettingsClient

    LocationRequest mLocationRequest = new LocationRequest();
        mLocationRequest.setInterval(10);
        mLocationRequest.setSmallestDisplacement(10);
        mLocationRequest.setFastestInterval(10);
        mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
        LocationSettingsRequest.Builder builder = new 
        LocationSettingsRequest.Builder();
        builder.addLocationRequest(mLocationRequest);

然后检查当前位置设置是否满足。 创建 LocationSettingsResponse 任务:

        Task<LocationSettingsResponse> task=LocationServices.getSettingsClient(this).checkLocationSettings(builder.build());

然后添加监听器

task.addOnCompleteListener(new OnCompleteListener<LocationSettingsResponse>() 
            @Override
                    public void onComplete(Task<LocationSettingsResponse> task) 
                        try 
                            LocationSettingsResponse response = task.getResult(ApiException.class);
                            // All location settings are satisfied. The client can initialize location
                            // requests here.

                         catch (ApiException exception) 
                            switch (exception.getStatusCode()) 
                                case LocationSettingsStatusCodes.RESOLUTION_REQUIRED:
                                    // Location settings are not satisfied. But could be fixed by showing the
                                    // user a dialog.
                                    try 
                                        // Cast to a resolvable exception.
                                        ResolvableApiException resolvable = (ResolvableApiException) exception;
                                        // Show the dialog by calling startResolutionForResult(),
                                        // and check the result in onActivityResult().
                                        resolvable.startResolutionForResult(
                                                HomeActivity.this,
                                                101);
                                     catch (IntentSender.SendIntentException e) 
                                        // Ignore the error.
                                     catch (ClassCastException e) 
                                        // Ignore, should be an impossible error.
                                    
                                    break;
                                case LocationSettingsStatusCodes.SETTINGS_CHANGE_UNAVAILABLE:
                                    // Location settings are not satisfied. However, we have no way to fix the
                                    // settings so we won't show the dialog.
                                    break;
                            
                        
                    
                );

添加 onActivityResult

@Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) 
        final LocationSettingsStates states = LocationSettingsStates.fromIntent(data);
        switch (requestCode) 
            case 101:
                switch (resultCode) 
                    case Activity.RESULT_OK:
                        // All required changes were successfully made
                        Toast.makeText(HomeActivity.this,states.isLocationPresent()+"",Toast.LENGTH_SHORT).show();
                        break;
                    case Activity.RESULT_CANCELED:
                        // The user was asked to change settings, but chose not to
                        Toast.makeText(HomeActivity.this,"Canceled",Toast.LENGTH_SHORT).show();
                        break;
                    default:
                        break;
                
                break;
        
    

Refer the link SettingsClient

【讨论】:

使用 SettingsClient 检查 ***.com/a/53277287 @BadLoser 要导入的依赖的名称是什么?无法解析符号任务。 我找到了:实现 'com.google.android.gms:play-services-tasks:16.0.1' @Denis,我可以改用implementation 'com.google.android.gms:play-services-location:16.0.0'【参考方案4】:

它的工作方式类似于谷歌地图? 源码:https://drive.google.com/open?id=0BzBKpZ4nzNzUOXM2eEhHM3hOZk0

在 build.gradle 文件中添加依赖:

compile 'com.google.android.gms:play-services:8.3.0'

compile 'com.google.android.gms:play-services-location:10.0.1'

public class LocationOnOff_Similar_To_Google_Maps extends AppCompatActivity 

    protected static final String TAG = "LocationOnOff";


    private GoogleApiClient googleApiClient;
    final static int REQUEST_LOCATION = 199;

    @Override
    protected void onCreate(Bundle savedInstanceState) 
        super.onCreate(savedInstanceState);

        this.setFinishOnTouchOutside(true);

        // Todo Location Already on  ... start
        final LocationManager manager = (LocationManager) LocationOnOff_Similar_To_Google_Maps.this.getSystemService(Context.LOCATION_SERVICE);
        if (manager.isProviderEnabled(LocationManager.GPS_PROVIDER) && hasGPSDevice(LocationOnOff_Similar_To_Google_Maps.this)) 
            Toast.makeText(LocationOnOff_Similar_To_Google_Maps.this,"Gps already enabled",Toast.LENGTH_SHORT).show();
            finish();
        
        // Todo Location Already on  ... end

        if(!hasGPSDevice(LocationOnOff_Similar_To_Google_Maps.this))
            Toast.makeText(LocationOnOff_Similar_To_Google_Maps.this,"Gps not Supported",Toast.LENGTH_SHORT).show();
        

        if (!manager.isProviderEnabled(LocationManager.GPS_PROVIDER) && hasGPSDevice(LocationOnOff_Similar_To_Google_Maps.this)) 
            Log.e("keshav","Gps already enabled");
            Toast.makeText(LocationOnOff_Similar_To_Google_Maps.this,"Gps not enabled",Toast.LENGTH_SHORT).show();
            enableLoc();
        else
            Log.e("keshav","Gps already enabled");
            Toast.makeText(LocationOnOff_Similar_To_Google_Maps.this,"Gps already enabled",Toast.LENGTH_SHORT).show();
        
    


    private boolean hasGPSDevice(Context context) 
        final LocationManager mgr = (LocationManager) context
                .getSystemService(Context.LOCATION_SERVICE);
        if (mgr == null)
            return false;
        final List<String> providers = mgr.getAllProviders();
        if (providers == null)
            return false;
        return providers.contains(LocationManager.GPS_PROVIDER);
    

    private void enableLoc() 

        if (googleApiClient == null) 
            googleApiClient = new GoogleApiClient.Builder(LocationOnOff_Similar_To_Google_Maps.this)
                    .addApi(LocationServices.API)
                    .addConnectionCallbacks(new GoogleApiClient.ConnectionCallbacks() 
                        @Override
                        public void onConnected(Bundle bundle) 

                        

                        @Override
                        public void onConnectionSuspended(int i) 
                            googleApiClient.connect();
                        
                    )
                    .addOnConnectionFailedListener(new GoogleApiClient.OnConnectionFailedListener() 
                        @Override
                        public void onConnectionFailed(ConnectionResult connectionResult) 

                            Log.d("Location error","Location error " + connectionResult.getErrorCode());
                        
                    ).build();
            googleApiClient.connect();

            LocationRequest locationRequest = LocationRequest.create();
            locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
            locationRequest.setInterval(30 * 1000);
            locationRequest.setFastestInterval(5 * 1000);
            LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder()
                    .addLocationRequest(locationRequest);

            builder.setAlwaysShow(true);

            PendingResult<LocationSettingsResult> result =
                    LocationServices.SettingsApi.checkLocationSettings(googleApiClient, builder.build());
            result.setResultCallback(new ResultCallback<LocationSettingsResult>() 
                @Override
                public void onResult(LocationSettingsResult result) 
                    final Status status = result.getStatus();
                    switch (status.getStatusCode()) 
                        case LocationSettingsStatusCodes.RESOLUTION_REQUIRED:
                            try 
                                // Show the dialog by calling startResolutionForResult(),
                                // and check the result in onActivityResult().
                                status.startResolutionForResult(LocationOnOff_Similar_To_Google_Maps.this, REQUEST_LOCATION);

                                finish();
                             catch (IntentSender.SendIntentException e) 
                                // Ignore the error.
                            
                            break;
                    
                
            );
        
    


【讨论】:

这是我的荣幸 查看广播接收器帖子非常有用,喜欢我***.com/questions/15698790/… 完美解决方案。 谢谢拉利特夏尔马 能否更新一下链接,链接失效了,把代码贴在GitHub上吧【参考方案5】:

Ola Cabs 正在使用新发布的设置 API 来实现此功能。根据新 API,用户无需导航到设置页面即可启用位置服务,从而实现无缝集成。详情请阅读以下内容:

https://developers.google.com/android/reference/com/google/android/gms/location/SettingsApi

【讨论】:

这看起来与 veer3383 答案相同。如果我错了,请纠正我 @rakeshkashyap 是的,是一样的 我想知道是否可以执行以下操作: * 设置获取位置的超时时间。 * 检查 GPS 设置 API,如果启用了所有必需的传感器并相应地显示消息。 *如果可能,如何设置超时。?构建 API 时我找不到任何此类设置 您好,我在从关闭状态打开 GPS 后第二次加载地图时遇到问题,请任何人帮助我:***.com/questions/44368960/… 谢谢。 SettingsAPI 已被弃用,现在您使用 SettingsClient developers.google.com/android/reference/com/google/android/gms/…【参考方案6】:

依赖

compile 'com.google.android.gms:play-services-location:10.0.1'

代码

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.IntentSender;
import android.location.LocationManager;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;
import android.widget.Toast;

import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.common.api.PendingResult;
import com.google.android.gms.common.api.ResultCallback;
import com.google.android.gms.common.api.Status;
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.LocationSettingsResult;
import com.google.android.gms.location.LocationSettingsStates;
import com.google.android.gms.location.LocationSettingsStatusCodes;

public class MainActivity extends AppCompatActivity implements GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener 

    public static final int REQUEST_LOCATION=001;

    GoogleApiClient googleApiClient;

    LocationManager locationManager;
    LocationRequest locationRequest;
    LocationSettingsRequest.Builder locationSettingsRequest;
    Context context;


    PendingResult<LocationSettingsResult> pendingResult;


    @Override
    protected void onCreate(Bundle savedInstanceState) 
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        context = this;

        locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
        if (locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)) 
            Toast.makeText(this, "Gps is Enabled", Toast.LENGTH_SHORT).show();

         else 
            mEnableGps();
        

    

    public void mEnableGps() 
        googleApiClient = new GoogleApiClient.Builder(context)
                .addApi(LocationServices.API).addConnectionCallbacks(this)
                .addOnConnectionFailedListener(this)
                .build();
        googleApiClient.connect();
        mLocationSetting();
    

    public void mLocationSetting() 
        locationRequest = LocationRequest.create();
        locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
        locationRequest.setInterval(1 * 1000);
        locationRequest.setFastestInterval(1 * 1000);

        locationSettingsRequest = new LocationSettingsRequest.Builder().addLocationRequest(locationRequest);

        mResult();

    

    public void mResult() 
        pendingResult = LocationServices.SettingsApi.checkLocationSettings(googleApiClient, locationSettingsRequest.build());
        pendingResult.setResultCallback(new ResultCallback<LocationSettingsResult>() 
            @Override
            public void onResult(@NonNull LocationSettingsResult locationSettingsResult) 
                Status status = locationSettingsResult.getStatus();


                switch (status.getStatusCode()) 
                    case LocationSettingsStatusCodes.SUCCESS:
                        // All location settings are satisfied. The client can initialize location
                        // requests here.

                        break;
                    case LocationSettingsStatusCodes.RESOLUTION_REQUIRED:

                        try 

                            status.startResolutionForResult(MainActivity.this, REQUEST_LOCATION);
                         catch (IntentSender.SendIntentException e) 

                        
                        break;
                    case LocationSettingsStatusCodes.SETTINGS_CHANGE_UNAVAILABLE:
                        // Location settings are not satisfied. However, we have no way to fix the
                        // settings so we won't show the dialog.


                        break;
                
            

        );
    


    //callback method
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) 
        final LocationSettingsStates states = LocationSettingsStates.fromIntent(data);
        switch (requestCode) 
            case REQUEST_LOCATION:
                switch (resultCode) 
                    case Activity.RESULT_OK:
                        // All required changes were successfully made
                        Toast.makeText(context, "Gps enabled", Toast.LENGTH_SHORT).show();
                        break;
                    case Activity.RESULT_CANCELED:
                        // The user was asked to change settings, but chose not to
                        Toast.makeText(context, "Gps Canceled", Toast.LENGTH_SHORT).show();
                        break;
                    default:
                        break;
                
                break;
        
    


    @Override
    public void onConnected(@Nullable Bundle bundle) 

    

    @Override
    public void onConnectionSuspended(int i) 

    

    @Override
    public void onConnectionFailed(@NonNull ConnectionResult connectionResult) 

    

【讨论】:

【参考方案7】:

您还可以为 Builder 添加多个 LocationRequest 以实现“使用 GPS、Wi-Fi 和移动网络进行定位”对话框,而不是仅“使用 GPS 进行定位”

LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder()
                .addLocationRequest(createLocationRequest(LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY))
                .addLocationRequest(createLocationRequest(LocationRequest.PRIORITY_HIGH_ACCURACY))
                .setAlwaysShow(true);

PendingResult<LocationSettingsResult> result =
                LocationServices.SettingsApi.checkLocationSettings(mGoogleApiClient, builder.build());

【讨论】:

在我的情况下,使用 PRIORITY_HIGH_ACCURACY 来获得句子“使用 GPS、Wi-Fi 和移动网络进行定位”就足够了。但奇怪的是它可以在真实设备上运行,但在模拟器中却不行。尽管我看到模拟器设备有 GPS,但在模拟器中的句子开头总是没有“使用 GPS”。【参考方案8】:

在 Kotlin 中,使用以下代码:

import android.app.Activity
import android.content.Intent
import android.content.IntentSender
import android.os.Bundle
import android.util.Log
import androidx.appcompat.app.AppCompatActivity
import com.google.android.gms.common.api.GoogleApiClient
import com.google.android.gms.common.api.PendingResult
import com.google.android.gms.common.api.Status
import com.google.android.gms.location.*

class MainActivity : AppCompatActivity() 
    private var googleApiClient: GoogleApiClient? = null
    private val REQUESTLOCATION = 199
    override fun onCreate(savedInstanceState: Bundle?) 
        super.onCreate(savedInstanceState)
        enableLoc()
    
    private fun enableLoc() 
        googleApiClient = GoogleApiClient.Builder(this)
            .addApi(LocationServices.API)
            .addConnectionCallbacks(object : GoogleApiClient.ConnectionCallbacks 
                override fun onConnected(bundle: Bundle?) 
                override fun onConnectionSuspended(i: Int) 
                    googleApiClient?.connect()
                
            )
            .addOnConnectionFailedListener 
            .build()
        googleApiClient?.connect()
        val locationRequest = LocationRequest.create()
        locationRequest.priority = LocationRequest.PRIORITY_HIGH_ACCURACY
        locationRequest.interval = 30 * 1000.toLong()
        locationRequest.fastestInterval = 5 * 1000.toLong()
        val builder = LocationSettingsRequest.Builder()
            .addLocationRequest(locationRequest)
        builder.setAlwaysShow(true)
        val result: PendingResult<LocationSettingsResult> =
            LocationServices.SettingsApi.checkLocationSettings(googleApiClient, builder.build())
        result.setResultCallback  result ->
            val status: Status = result.status
            when (status.statusCode) 
                LocationSettingsStatusCodes.RESOLUTION_REQUIRED -> try 
                    status.startResolutionForResult(
                        this@MainActivity,
                        REQUESTLOCATION
                    )
                 catch (e: IntentSender.SendIntentException) 
                
            
        
    
    override fun onActivityResult(
        requestCode: Int,
        resultCode: Int,
        data: Intent?
    ) 
        super.onActivityResult(requestCode, resultCode, data)
        when (requestCode) 
            REQUESTLOCATION -> when (resultCode) 
                Activity.RESULT_OK -> Log.d("abc","OK")
                Activity.RESULT_CANCELED -> Log.d("abc","CANCEL")
            
        
    

【讨论】:

GoogleApiClient 已弃用。用什么?【参考方案9】:

GoogleApiClient 已弃用。 Kotlin 中的新实现如下。

依赖关系

// Google Maps Location Services
implementation 'com.google.android.gms:play-services-location:17.1.0'
implementation 'com.google.android.gms:play-services-maps:17.0.0'

代码

val locationRequest = LocationRequest.create()
    .setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY)
    .setInterval(30 * 1000)
    .setFastestInterval(5 * 1000)

val builder = LocationSettingsRequest.Builder()
    .addLocationRequest(locationRequest)
    .setAlwaysShow(true)

val pendingResult = LocationServices
    .getSettingsClient(activity)
    .checkLocationSettings(builder.build())

pendingResult.addOnCompleteListener  task ->
    if (task.isSuccessful.not()) 
        task.exception?.let 
            if (it is ApiException && it.statusCode == LocationSettingsStatusCodes.RESOLUTION_REQUIRED) 
                // Show the dialog by calling startResolutionForResult(),
                // and check the result in onActivityResult().
                (it as ResolvableApiException).startResolutionForResult(activity,
                    MainActivity.REQUEST_CODE_LOCATION)
            
        
    

【讨论】:

这个答案也可以查:***.com/a/31816683/4308897【参考方案10】:

请检查我的非常简单的解决方案,以获取前台的用户位置。

    GPS 设置对话框 具有实时数据的用户位置。 Lo​​cationUtility 类可感知活动生命周期以暂停/恢复位置更新。 具有最新 FusedLocationProviderClient 的位置

https://github.com/Maqsood007/UserLocation-Android/blob/master/app/src/main/java/jetpack/skill/userlocation_android/utils/LocationUtility.kt

【讨论】:

【参考方案11】:

这是我的 Kotlin 示例-

  private fun enableLocation() 
    val locationRequest = LocationRequest.create()
    locationRequest.apply 
        priority =LocationRequest.PRIORITY_HIGH_ACCURACY
        interval = 30 * 1000.toLong()
        fastestInterval = 5 * 1000.toLong()
    
    val builder = LocationSettingsRequest.Builder()
            .addLocationRequest(locationRequest)
    builder.setAlwaysShow(true)
    val result=
            LocationServices.getSettingsClient(requireContext()).checkLocationSettings(builder.build())
    result.addOnCompleteListener 
        try 
            val response: LocationSettingsResponse = it.getResult(ApiException::class.java)
            println("location>>>>>>> $response.locationSettingsStates.isGpsPresent")
            if(response.locationSettingsStates.isGpsPresent)
                //do something
        catch (e: ApiException)
            when (e.statusCode) 
                LocationSettingsStatusCodes.RESOLUTION_REQUIRED -> try 
                    val intentSenderRequest =
                        IntentSenderRequest.Builder(e.status.resolution).build()
                    launcher.launch(intentSenderRequest)
                 catch (e: IntentSender.SendIntentException) 
                
            
        
    

并使用下面的get Result方法

 private var launcher=  registerForActivityResult(ActivityResultContracts.StartIntentSenderForResult()) result->
  if (result.resultCode == Activity.RESULT_OK) 
      Log.d(TAG, "OK")
      
   else 
      Log.d(TAG, "CANCEL")
      requireContext().toast("Please Accept Location enable for use this App.")
  

【讨论】:

代码正在使用最新代码.. !!【参考方案12】:

2020 年 8 月更新的新答案 enter link description here

如果你在你的活动中使用,我的片段就像​​这个更新

 import android.app.Activity;
import android.content.Intent;
import android.content.IntentSender;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;


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.tasks.OnCompleteListener;
import com.google.android.gms.tasks.Task;

public class FragmentSearch extends Fragment


    View SearchFragmentview;
    protected static final int REQUEST_CHECK_SETTINGS = 0x1;


    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState)
    
        SearchFragmentview=inflater.inflate(R.layout.fragment_search,container,false);

           getLocationDialog();

        return  SearchFragmentview;

    

    private void getLocationDialog()
    
        LocationRequest locationRequest = LocationRequest.create();
        locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
        locationRequest.setInterval(30 * 1000);
        locationRequest.setFastestInterval(5 * 1000);

        LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder()
                .addLocationRequest(locationRequest);
        builder.setAlwaysShow(true); //this is the key ingredient

        Task<LocationSettingsResponse> result =
                LocationServices.getSettingsClient(getContext()).checkLocationSettings(builder.build());



        result.addOnCompleteListener(new OnCompleteListener<LocationSettingsResponse>()
        
            @Override
            public void onComplete(Task<LocationSettingsResponse> task)
            
                try 
                    LocationSettingsResponse response = task.getResult(ApiException.class);
                    // All location settings are satisfied. The client can initialize location
                    // requests here.

                
                catch (ApiException exception)
                
                    switch (exception.getStatusCode())
                    
                        case LocationSettingsStatusCodes.RESOLUTION_REQUIRED:
                            // Location settings are not satisfied. But could be fixed by showing the
                            // user a dialog.
                            try 
                                // Cast to a resolvable exception.
                                ResolvableApiException resolvable = (ResolvableApiException) exception;
                                // Show the dialog by calling startResolutionForResult(),
                                // and check the result in onActivityResult().


                                resolvable.startResolutionForResult(
                                      getActivity(),
                                        REQUEST_CHECK_SETTINGS);

                            
                            catch (IntentSender.SendIntentException e)
                            
                                // Ignore the error.
                            
                            catch (ClassCastException e)
                            
                                // Ignore, should be an impossible error.
                            
                            break;
                           case LocationSettingsStatusCodes.SETTINGS_CHANGE_UNAVAILABLE:
                            // Location settings are not satisfied. However, we have no way to fix the
                            // settings so we won't show the dialog.

                            break;
                    
                
            
        );


    



    public void onActivityResult(int requestCode, int resultCode, Intent data)
    
        switch (requestCode)
        
            case REQUEST_CHECK_SETTINGS:
                switch (resultCode)
                
                    case Activity.RESULT_OK:
                        // All required changes were successfully made

                        break;
                    case Activity.RESULT_CANCELED:
                        // The user was asked to change settings, but chose not to

                        break;
                    default:
                        break;
                
                break;
        
    [enter image description here][2]




【讨论】:

【参考方案13】:

设置 api 不推荐使用 this。

   private void openDeviceLocationRequest() 
        if (!locationPermissionGranted)
            return;

        LocationRequest locationRequest = LocationRequest.create();
        locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
        LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder()
                .addLocationRequest(locationRequest);
        builder.setAlwaysShow(true); //this is the key ingredient

        Task<LocationSettingsResponse> result =
                LocationServices.getSettingsClient(this).checkLocationSettings(builder.build());
        result.addOnCompleteListener(task -> 
            try 
                LocationSettingsResponse response = task.getResult(ApiException.class);
                // All location settings are satisfied. The client can initialize location
                // requests here.
                if(lastKnownLocation == null)
                getDeviceLocation();

             catch (ApiException exception) 
                switch (exception.getStatusCode()) 
                    case LocationSettingsStatusCodes.RESOLUTION_REQUIRED:
                        // Location settings are not satisfied. But could be fixed by showing the
                        // user a dialog.
                        try 
                            // Cast to a resolvable exception.
                            ResolvableApiException resolvable = (ResolvableApiException) exception;
                            // Show the dialog by calling startResolutionForResult(),
                            // and check the result in onActivityResult().
                            resolvable.startResolutionForResult(
                                    MapAddressActivity.this,
                                    REQUEST_CHECK_SETTINGS);
                         catch (IntentSender.SendIntentException e) 
                            // Ignore the error.
                         catch (ClassCastException e) 
                            // Ignore, should be an impossible error.
                        
                        break;
                    case LocationSettingsStatusCodes.SETTINGS_CHANGE_UNAVAILABLE:
                        // Location settings are not satisfied. However, we have no way to fix the
                        // settings so we won't show the dialog.
                        break;
                
            
        );
    

【讨论】:

【参考方案14】:

实现 'com.google.android.gms:play-services-location:18.0.0'

private SettingsClient mSettingsClient;
    private LocationSettingsRequest mLocationSettingsRequest;
    private static final int REQUEST_CHECK_SETTINGS = 214;
    private static final int REQUEST_ENABLE_GPS = 516;



 LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder();
        builder.addLocationRequest(new LocationRequest().setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY));
        builder.setAlwaysShow(true);
        mLocationSettingsRequest = builder.build();

        mSettingsClient = LocationServices.getSettingsClient(MainActivity.this);

        mSettingsClient
                .checkLocationSettings(mLocationSettingsRequest)
                .addOnSuccessListener(new OnSuccessListener<LocationSettingsResponse>() 
                    @Override
                    public void onSuccess(LocationSettingsResponse locationSettingsResponse) 
                        //Success Perform Task Here
                    
                )
                .addOnFailureListener(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(MainActivity.this, REQUEST_CHECK_SETTINGS);
                                 catch (IntentSender.SendIntentException sie) 
                                    Log.e("GPS","Unable to execute request.");
                                
                                break;
                            case LocationSettingsStatusCodes.SETTINGS_CHANGE_UNAVAILABLE:
                                Log.e("GPS","Location settings are inadequate, and cannot be fixed here. Fix in Settings.");
                        
                    
                )
                .addOnCanceledListener(new OnCanceledListener() 
                    @Override
                    public void onCanceled() 
                        Log.e("GPS","checkLocationSettings -> onCanceled");
                    
                );

【讨论】:

以上是关于如何显示启用位置对话框,如谷歌地图?的主要内容,如果未能解决你的问题,请参考以下文章

使用自己的地图,如谷歌地图。当访问者点击地图上的点时收集和处理数据

启用位置后刷新谷歌地图

谷歌地图怎么测距离?

如何使用谷歌地图 Api 获得最精确的位置 [重复]

Android 谷歌地图使用 GPS 定位而不是网络

安卓。谷歌地图API实现标记点击