“gps”定位服务在Android 6.0中需要ACCESS_FINE_LOCATION权限。

35

在 Android 清单文件中,我已添加以下权限以让 GPS 访问位置信息。

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

我正在使用位置管理器类获取以下位置更新:

 private static final long MIN_DISTANCE_CHANGE_FOR_UPDATES = 10; // 10 meters
 private static final long MIN_TIME_BW_UPDATES = 1000 * 60 * 1; // 1 minute
 locationManager.requestLocationUpdates(
                    LocationManager.GPS_PROVIDER,
                    MIN_TIME_BW_UPDATES,
                    MIN_DISTANCE_CHANGE_FOR_UPDATES, 
                    this
                );

但是以上代码行会出现异常,提示:

"gps" location provider requires ACCESS_FINE_LOCATION permission

这件事情只会在targetSDKVersion 23(也就是Android 6.0)上发生,并且我还在Android 5.1上进行了测试,那个正常运行。

请求帮助!!提前致谢。


你是否已经将<uses-permission...标签添加到AndroidManifest.xml文件的清单节点中了?例如,请参考https://dev59.com/AHLYa4cB1Zd3GeqPXWlp#16691500。 - RookieGuy
1
是的,我按照清单节点所需的方式完成了它。请注意,这里的问题仅在Android 6.0上存在。 - bhanu.cs
4个回答

68

自从6.0版以来,一些权限被认为是“危险的”(FINE_LOCATION就是其中之一)。

为了保护用户,在运行时必须进行授权,这样用户才知道它是否与他的操作相关。

要做到这一点:

 ActivityCompat.requestPermissions(this,new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, 1);

它将显示一个对话框,用户将选择是否授权您的应用程序使用位置。

然后可以使用此函数获取用户的答案:

public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
    switch (requestCode) {
        case 1: {
            // If request is cancelled, the result arrays are empty.
            if (grantResults.length > 0
            && grantResults[0] == PackageManager.PERMISSION_GRANTED) {

            } else {
                // permission denied, boo! Disable the
                // functionality that depends on this permission.
            }
        return;
        }
            // other 'case' lines to check for other
            // permissions this app might request
    }
}
如果用户接受一次,你的应用程序就会记住它,你就不需要再发送这个 DialogBox 了。请注意,如果用户后来决定禁用它,则需要在请求位置之前测试权限是否仍然被授予:
public boolean checkLocationPermission()
{
    String permission = "android.permission.ACCESS_FINE_LOCATION";
    int res = this.checkCallingOrSelfPermission(permission);
    return (res == PackageManager.PERMISSION_GRANTED);
}

关于这个问题,Android文档中已经有详细解释,其中包括onRequestPermissionsResult方法的说明: http://developer.android.com/training/permissions/requesting.html


很好,回答详细,太棒了!我也会尝试一下,但还没有在Android Marshmallow上检查过。这会破坏许多应用程序的兼容性,所以它们不会快速推出到使用先前版本的设备上吗? - RookieGuy
我最近在开发一个应用程序时没有考虑到这一点 :) 我想在此更新之前授予的危险权限将继续被授予,即使它们是在安装时授予的。 - Sebastien FERRAND
请注意,用户现在可以在应用程序的Android设置中决定禁用权限。 - Sebastien FERRAND
谢谢你的回答。但我想补充一下,Manifest.permission应该小心选择Manifest文件。因为在我的Android Studio中,我有3个或更多的Manifest文件。 - Andrew Indayang
为什么不需要请求ACCESS_COARSE_LOCATION权限? - DAVIDBALAS1
可能确实需要,关键是要指出新的权限系统。 - Sebastien FERRAND

6
请尝试此代码。
private void marshmallowGPSPremissionCheck() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M
                && getActivity().checkSelfPermission(
                Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED
                && getActivity().checkSelfPermission(
                Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
            requestPermissions(
                    new String[]{Manifest.permission.ACCESS_COARSE_LOCATION,
                            Manifest.permission.ACCESS_FINE_LOCATION},
                    MY_PERMISSION_LOCATION);
        } else {
            //   gps functions.
        }
    }

请添加以下内容..................

@Override
    public void onRequestPermissionsResult(int requestCode,
                                           String[] permissions, int[] grantResults) {
        if (requestCode == MY_PERMISSION_LOCATION
                && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
            //  gps functionality
        }
    }

1
这里的getActivity()是什么?实际上发生了什么?你能解释一下吗? - bhanu.cs
这个人的代码必须在一个片段中,或者类似的东西。如果你在一个扩展Fragment而不是Activity的类中,可以使用getActivity()来获取上下文。 - Fustigador
这段代码对你有效吗?如果你在activity中使用它,请删除getActivity()。这段代码实际上是在运行时检查位置权限。 - Nivedh

0

自 Android 版本 6 起,我们对权限进行了一些更改。您必须在使用权限时同意它们,而不是在安装应用程序时。如果您使用的是 BuildTools 版本 23,则可能会出现一些问题。请查看此链接以了解详情。转到设备设置>应用程序,选择您的应用程序,然后手动接受权限并检查是否解决了问题。


0

我最近也遇到了这个问题。在Android 6.0中,当您在应用程序中使用权限时,您需要明确地请求所需的权限。如果您不这样做,则位置权限将自动被拒绝。

    // Here, thisActivity is the current activity
    if (ContextCompat.checkSelfPermission(thisActivity,
                    Manifest.permission.READ_CONTACTS)
            != PackageManager.PERMISSION_GRANTED) {

        // Should we show an explanation?
        if (ActivityCompat.shouldShowRequestPermissionRationale(thisActivity,
                Manifest.permission.ACCESS_FINE_LOCATION)) {

            // Show an expanation to the user *asynchronously* -- don't block
            // this thread waiting for the user's response! After the user
            // sees the explanation, try again to request the permission.

        } else {

            // No explanation needed, we can request the permission.

            ActivityCompat.requestPermissions(thisActivity,
                    new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
                    MY_PERMISSIONS_REQUEST_FINE_LOCATION);

            // MY_PERMISSIONS_REQUEST_FINE_LOCATION is an
            // app-defined int constant. The callback method gets the
            // result of the request.
        }
    }

更多信息请参见:http://developer.android.com/training/permissions/requesting.html


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接