【问题标题】:How to enable Location access programmatically in android?如何在android中以编程方式启用位置访问?
【发布时间】:2014-09-30 06:46:10
【问题描述】:

我正在开发与地图相关的 android 应用程序,如果未启用位置服务,我需要在客户端开发中检查位置访问是否启用,显示对话框提示。

如何在android中以编程方式启用“位置访问”?

【问题讨论】:

    标签: android gps location-services


    【解决方案1】:

    使用以下代码进行检查。如果禁用,则会生成对话框

    public void statusCheck() {
        final LocationManager manager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
    
        if (!manager.isProviderEnabled(LocationManager.GPS_PROVIDER)) {
            buildAlertMessageNoGps();
    
        }
    }
    
    private void buildAlertMessageNoGps() {
        final AlertDialog.Builder builder = new AlertDialog.Builder(this);
        builder.setMessage("Your GPS seems to be disabled, do you want to enable it?")
                .setCancelable(false)
                .setPositiveButton("Yes", new DialogInterface.OnClickListener() {
                    public void onClick(final DialogInterface dialog, final int id) {
                        startActivity(new Intent(android.provider.Settings.ACTION_LOCATION_SOURCE_SETTINGS));
                    }
                })
                .setNegativeButton("No", new DialogInterface.OnClickListener() {
                    public void onClick(final DialogInterface dialog, final int id) {
                        dialog.cancel();
                    }
                });
        final AlertDialog alert = builder.create();
        alert.show();
    }
    

    【讨论】:

    • 您好,上面的代码工作正常,但是启用位置服务后的一个小问题如何重定向我的当前页面?
    • 使用 Intent 如下 - Intent i = new Intent(Yourclassname.this,ClassToReach.class); startActivity(i);
    • 非常感谢您分享信息..它工作正常
    • 我认为,这不是正确的答案,因为@NarasimhaKolla 想要激活定位服务。首先,您需要编写真正要激活网络或 GPS 提供商的内容?这个解决方案,检查是否激活了 GPS,但是如果用户激活了“仅设备”模式怎么办。如果用户在 Wi-Fi 上并且他在建筑物内,你会尝试通过 GPS 提供商找到位置,我认为用户永远不会收到位置,只有当用户离窗口如此之近时......我的回答:在“移动数据”检查GPS 和网络提供商,在“WiFi”检查中仅需要网络提供商。对不起英语:)
    • 您不能自动将用户重定向到您的活动,但在大多数情况下,用户将按下后退按钮,如果您使用 - startActivityForResult(new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS) , 1); & 检查 onActivityResult 中的结果代码。希望它能消除你的疑问
    【解决方案2】:

    这是一种以编程方式启用位置(如地图应用)的简单方法:

    protected void enableLocationSettings() {
           LocationRequest locationRequest = LocationRequest.create()
                 .setInterval(LOCATION_UPDATE_INTERVAL)
                 .setFastestInterval(LOCATION_UPDATE_FASTEST_INTERVAL)
                 .setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
    
            LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder()
                    .addLocationRequest(locationRequest);
    
            LocationServices
                    .getSettingsClient(this)
                    .checkLocationSettings(builder.build())
                    .addOnSuccessListener(this, (LocationSettingsResponse response) -> {
                        // startUpdatingLocation(...);
                    })
                    .addOnFailureListener(this, ex -> {
                        if (ex instanceof ResolvableApiException) {
                            // Location settings are NOT satisfied,  but this can be fixed  by showing the user a dialog.
                            try {
                                // Show the dialog by calling startResolutionForResult(),  and check the result in onActivityResult().
                                ResolvableApiException resolvable = (ResolvableApiException) ex;
                                resolvable.startResolutionForResult(TrackingListActivity.this, REQUEST_CODE_CHECK_SETTINGS);
                            } catch (IntentSender.SendIntentException sendEx) {
                                // Ignore the error.
                            }
                        }
                    });
     }
    

    和onActivityResult:

    @Override
    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        if (REQUEST_CODE_CHECK_SETTINGS == requestCode) {
            if(Activity.RESULT_OK == resultCode){
                //user clicked OK, you can startUpdatingLocation(...);
    
            }else{
                //user clicked cancel: informUserImportanceOfLocationAndPresentRequestAgain();
            }
        }
    }
    

    您可以在此处查看文档:https://developer.android.com/training/location/change-location-settings

    【讨论】:

    • 是的!这类似于谷歌地图应用程序显示带有确定和取消按钮的小对话框以启用 GPS 而无需离开应用程序。
    • 谢谢它正在工作。如何从对话框中禁用“不,谢谢”按钮?我只想限制是选择选项或自动启用定位服务?有可能吗?
    • @TejpalBh 用这种方法是不可能的!而且,你正在寻找的是一个糟糕的设计......
    【解决方案3】:

    您可以尝试以下方法:

    检查是否启用了 GPS 和网络提供商:

    public boolean canGetLocation() {
        boolean result = true;
        LocationManager lm;
        boolean gpsEnabled = false;
        boolean networkEnabled = false;
    
        lm = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
    
        // exceptions will be thrown if provider is not permitted.
        try {
            gpsEnabled = lm.isProviderEnabled(LocationManager.GPS_PROVIDER);
        } catch (Exception ex) {
        }
    
        try {
            networkEnabled = lm
                    .isProviderEnabled(LocationManager.NETWORK_PROVIDER);
        } catch (Exception ex) {
        }
    
        return gpsEnabled && networkEnabled;
    }
    

    如果上面的代码返回 false,则警告对话框:

    public void showSettingsAlert() {
        AlertDialog.Builder alertDialog = new AlertDialog.Builder(this);
    
        // Setting Dialog Title
        alertDialog.setTitle("Error!");
    
        // Setting Dialog Message
        alertDialog.setMessage("Please ");
    
        // On pressing Settings button
        alertDialog.setPositiveButton(
                getResources().getString(R.string.button_ok),
                new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int which) {
                        Intent intent = new Intent(
                                Settings.ACTION_LOCATION_SOURCE_SETTINGS);
                        startActivity(intent);
                    }
                });
    
        alertDialog.show();
    }
    

    如何使用以上两种方法:

    if (canGetLocation()) {     
        //DO SOMETHING USEFUL HERE. ALL GPS PROVIDERS ARE CURRENTLY ENABLED                 
    } else {
        //SHOW OUR SETTINGS ALERT, AND LET THE USE TURN ON ALL THE GPS PROVIDERS                                
        showSettingsAlert();
    }
    

    【讨论】:

    • 少一点代码怎么样:return gps_enabled || network_enabled;。此外,您可能希望遵循命名准则并改用 camelCase:return gpsEnabled || networkEnabled;
    • @MichelJung 我想应该是return gps_enabled && network_enabled;
    【解决方案4】:

    只需检查以下线程: How to check if Location Services are enabled? 它提供了一个很好的例子来说明如何检查位置服务是否启用。

    【讨论】:

    • 此项目不再可用
    【解决方案5】:
    private ActivityResultLauncher<IntentSenderRequest> resolutionForResult;
    
    resolutionForResult = registerForActivityResult(new ActivityResultContracts.StartIntentSenderForResult(), result -> {
            if(result.getResultCode() == RESULT_OK){
                //Granted
            }else {
                //Not Granted
            }
        });
    
        private void enableLocationSettings() {
        LocationRequest locationRequest = LocationRequest.create()
                .setInterval(10 * 1000)
                .setFastestInterval(2 * 1000)
                .setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
    
        LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder()
                .addLocationRequest(locationRequest);
    
        LocationServices
                .getSettingsClient(requireActivity())
                .checkLocationSettings(builder.build())
                .addOnSuccessListener(requireActivity(), (LocationSettingsResponse response) -> {
                    // startUpdatingLocation(...);
                })
                .addOnFailureListener(requireActivity(), ex -> {
                    if (ex instanceof ResolvableApiException) {
                        try{
                            IntentSenderRequest intentSenderRequest = new IntentSenderRequest.Builder(((ResolvableApiException) ex).getResolution()).build();
                            resolutionForResult.launch(intentSenderRequest);
                        }catch (Exception exception){
                            Log.d(TAG, "enableLocationSettings: "+exception);
                        }
                    }
                });
    }
    

    【讨论】:

    • 正如目前所写,您的答案尚不清楚。请edit 添加其他详细信息,以帮助其他人了解这如何解决所提出的问题。你可以找到更多关于如何写好答案的信息in the help center
    【解决方案6】:

    在最近的 Marshmallow 更新中,即使启用了位置设置,您的应用也需要明确请求许可。推荐的方法是显示应用程序的权限部分,用户可以在其中根据需要切换权限。执行此操作的代码 sn-p 如下:

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
    
        if (this.checkSelfPermission(Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
    
            final AlertDialog.Builder builder = new AlertDialog.Builder(this);
            builder.setTitle("Location Permission");
            builder.setMessage("The app needs location permissions. Please grant this permission to continue using the features of the app.");
            builder.setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialogInterface, int i) {
                    requestPermissions(new String[]{Manifest.permission.ACCESS_COARSE_LOCATION}, PERMISSION_REQUEST_COARSE_LOCATION);
    
                }
            });
            builder.setNegativeButton(android.R.string.no, null);
            builder.show();
        }
    } else {
        LocationManager locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
        boolean isGpsProviderEnabled, isNetworkProviderEnabled;
        isGpsProviderEnabled = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
        isNetworkProviderEnabled = locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
    
        if(!isGpsProviderEnabled && !isNetworkProviderEnabled) {
            final AlertDialog.Builder builder = new AlertDialog.Builder(this);
            builder.setTitle("Location Permission");
            builder.setMessage("The app needs location permissions. Please grant this permission to continue using the features of the app.");
            builder.setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialogInterface, int i) {
                    Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
                    startActivity(intent);
                }
            });
            builder.setNegativeButton(android.R.string.no, null);
            builder.show();
        }
    }
    

    并重写onRequestPermissionsResult方法如下:

    @Override
    public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
        switch (requestCode) {
            case PERMISSION_REQUEST_COARSE_LOCATION: {
                if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                    Log.d(TAG, "coarse location permission granted");
                } else {
                    Intent intent = new Intent();
                    intent.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
                    Uri uri = Uri.fromParts("package", getPackageName(), null);
                    intent.setData(uri);
                    startActivity(intent);
                }
            }
        }
    }
    

    另一种方法是您也可以使用SettingsApi 来查询启用了哪些位置提供程序。如果没有启用,您可以提示一个对话框从应用程序内更改设置。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-04-30
      • 2016-09-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多