如何获得在 Android 中获取 GPS 位置的权限

How to gain permission to get GPS location in Android

我是 Android 的新手,在我当前的项目中,我正在尝试使用 GPS 检索位置。获取位置的代码在单独的非activityclass,因为我显示坐标的fragment塞满了

我尝试使用 developer.android.com 中的指南,但我无法获得任何权限提示,当我按下片段中的按钮时,我只获得经纬度的默认 0 值.

我已经在清单中提供了权限:

<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>

GPS定位器class:

public class LocationProvider implements ActivityCompat.OnRequestPermissionsResultCallback {
    private static final int PERMISSION_REQUEST_LOCATION = 1;
    private Activity activity;

    Location gps_loc;
    Location final_loc;
    double longitude;
    double latitude;
    private LocationManager locationManager;

    public LocationProvider(Activity activity) {
        this.activity =activity;
        locationManager = (LocationManager) activity.getSystemService(Context.LOCATION_SERVICE);
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        if (requestCode == PERMISSION_REQUEST_LOCATION) {
            // Request for permission.
            if (grantResults.length == 1 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                getLocation();
            } else {
                requestLocationPermission();
            }
        }
    }

    private void getLocation() {
        // Check if the permission has been granted
        if (ActivityCompat.checkSelfPermission(activity, Manifest.permission.ACCESS_FINE_LOCATION)
                == PackageManager.PERMISSION_GRANTED) {
            gps_loc = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
            if (gps_loc != null) {
                Log.v("Loc_provider",gps_loc.toString());
                final_loc = gps_loc;
                latitude = final_loc.getLatitude();
                longitude = final_loc.getLongitude();
            }
        } else {
            requestLocationPermission();
        }
    }


    private void requestLocationPermission() {
            ActivityCompat.requestPermissions(activity,
                    new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, PERMISSION_REQUEST_LOCATION);
        }


    public String getCoordinates() {
        return latitude + " "+ longitude;
    }
}

片段中的代码:

FloatingActionButton fab=view.findViewById(R.id.floatingActionButton);
        fab.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                locProvider=new LocationProvider(requireActivity());
                gpsCoordinates.setText(locProvider.getCoordinates());
            }
        });

非常欢迎修复代码的提示和解决方案。

更新 1: 我将代码移到了片段中,如下所示:

fab.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                if (!checkIfAlreadyhavePermission()) {
                    requestPermissions(new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, 1);
                } else {
                    gps_loc = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
                    gpsCoordinates.setText(getCoordinates());
                    }
                }
        });

private String getCoordinates() {
        if (gps_loc != null) {
            Log.v("Loc_provider", gps_loc.toString());
            final_loc = gps_loc;
            latitude = gps_loc.getLatitude();
            longitude = gps_loc.getLongitude();
        }
        return latitude + " " + longitude;
    }

    private boolean checkIfAlreadyhavePermission() {
        int result = ContextCompat.checkSelfPermission(getActivity(), Manifest.permission.ACCESS_FINE_LOCATION);
        return result == PackageManager.PERMISSION_GRANTED;
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        switch (requestCode) {
            case PERMISSION_REQUEST_LOCATION: {
                // If request is cancelled, the result arrays are empty.
                if (grantResults.length > 0
                        && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                    //Log.v("Grant_Results", String.valueOf(grantResults[0]));
                    Toast.makeText(getActivity(), "permission granted", Toast.LENGTH_LONG).show();
                    gpsCoordinates.setText(getCoordinates());
                    } else {
                       Toast.makeText(getActivity(), "permission denied", Toast.LENGTH_LONG).show();
                    }
                break;
                }
            }
    }

我现在得到权限提示,但位置仍然没有更新(我得到0)。

请注意:

  1. 不建议保存 Activity 对象,这可能会导致内存泄漏。 Activity 可能会被销毁并重新创建(例如当屏幕方向改变时)。保留对旧 activity 的引用会给你带来问题。

  2. 实现 ActivityCompat.OnRequestPermissionsResultCallback 接口什么都不做。您的方法将永远不会被调用。您必须从 activity.

    中显式调用它
  3. 您还没有请求权限,因此您的权限提示将永远不会显示,并且会返回 double 的默认值 0。您需要调用 getLocation() 方法,以便控制落在 else 块上并显示您的权限提示

我建议您在 activity 中处理权限。让 activity 获取该位置的坐标。您可以让 activity 使用方法 getCoordinates() 实现一个接口,比如 LocationFetcher。然后你可以像这样在片段中调用它:

LocationFetcher locationFetcher = (LocationFetcher) activity;
gpsCoordinates.setText(locationFetcher.getCoordinates());

通过在 Fragment 中实现 LocationListener 然后添加

修复
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 400, 1, this);

在 onRequestPermissionsResult() 中。