Android的" GPS需要ACCESS_FINE_LOCATION"错误,即使我的清单文件中包含此 [英] Android "gps requires ACCESS_FINE_LOCATION" error, even though my manifest file contains this

查看:7876
本文介绍了Android的" GPS需要ACCESS_FINE_LOCATION"错误,即使我的清单文件中包含此的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我每次运行应用程序,我SecurityException异常被抛出,并从​​调试器的错误读取,因此:

java.lang.SecurityException异常:GPS定位提供商要求ACCESS_COARSE_LOCATION或ACCESS_FINE_LOCATION许可

这似乎是一个简单的错误,但是,我的清单文件是完全正确的。在这儿,这里是我MapActivity code,以及:

 < XML版本=1.0编码=UTF-8&GT?;
 

 <使用-权限的Andr​​oid:名称=android.permission.INTERNET对/>
<使用-权限的Andr​​oid:名称=android.permission.ACCESS_COARSE_LOCATION/>
<使用-权限的Andr​​oid:名称=android.permission.ACCESS_FINE_LOCATION/>
<使用-权限的Andr​​oid:名称=android.permission.ACCESS_NETWORK_STATE/>
<使用-权限的Andr​​oid:名称=android.permission.WRITE_EXTERNAL_STORAG​​E/>
<使用-权限的Andr​​oid:名称=com.google.android.providers.gsf.permission.READ_GSERVICES/>
<使用-权限的Andr​​oid:名称=com.dev.cromer.jason.coverme.permission.MAPS_RECEIVE/>

<应用
    机器人:allowBackup =真
    机器人:图标=@纹理映射/ ic_launcher
    机器人:标签=@字符串/ APP_NAME
    机器人:主题=@风格/ AppTheme>
    <活动
        机器人:名称=。MainActivity
        机器人:标签=@字符串/ APP_NAME>
        <意向滤光器>
            <作用机器人:名称=android.intent.action.MAIN/>

            <类机器人:名称=android.intent.category.LAUNCHER/>
        &所述; /意图滤光器>
    < /活性GT;

    &所述;元数据
        机器人:名称=com.google.android.gms.version
        机器人:值=@整数/ google_play_services_version/>
    &所述;元数据
        机器人:名称=com.google.android.maps.v2.API_KEY
        机器人:值=@字符串/ google_maps_key/>

    <活动
        机器人:名称=。MapActivity
        机器人:标签=@字符串/ title_activity_map>
    < /活性GT;
< /用途>
 

我的活动:

 包com.dev.cromer.jason.coverme;

进口android.location.Criteria;
进口android.location.Location;
进口android.location.LocationListener;
进口android.location.LocationManager;
进口android.support.v4.app.FragmentActivity;
进口android.os.Bundle;
进口android.util.Log;

进口com.google.android.gms.common.ConnectionResult;
进口com.google.android.gms.common.api.GoogleApiClient;
进口com.google.android.gms.location.LocationServices;
进口com.google.android.gms.maps.CameraUpdateFactory;
进口com.google.android.gms.maps.GoogleMap;
进口com.google.android.gms.maps.SupportMapFragment;
进口com.google.android.gms.maps.model.LatLng;
进口com.google.android.gms.maps.model.MarkerOptions;

公共类MapActivity扩展FragmentActivity实现LocationListener的{

    私人GoogleMap的MMAP; //可能为空,如果谷歌Play业务APK不可用。

    @覆盖
    保护无效的onCreate(包savedInstanceState){
        super.onCreate(savedInstanceState);
        的setContentView(R.layout.activity_map);

        setUpMapIfNeeded();
    }

    @覆盖
    保护无效onResume(){
        super.onResume();
        setUpMapIfNeeded();
    }



    私人无效setUpMapIfNeeded(){
        //做一个空检查确认,我们还没有实例化的地图。
        如果(MMAP == NULL){
            //尝试获取来自SupportMapFragment地图。
            MMAP =((SupportMapFragment)getSupportFragmentManager()。findFragmentById(R.id.map))
                    .getMap();

            //检查如果我们成功取得地图。
            如果(MMAP!= NULL){
                //mMap.setMyLocationEnabled(true);
                //mMap.setOnMyLocationChangeListener(this);
                setUpMap();
            }
        }
    }


    私人无效setUpMap(){
        mMap.addMarker(新MarkerOptions()位置(新的经纬度(0,0))标题(标记));
        mMap.setMyLocationEnabled(真正的);

        LocationManager locationManager =(LocationManager)getSystemService(LOCATION_SERVICE);

        尝试 {
            位置myLocation = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);

            如果(myLocation!= NULL){
                Log.d(TAG,不空);
            }
            其他 {
                Log.d(TAG,空);
                locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER,0,0,这一点);
            }
        }
        赶上(SecurityException异常SE){
            Log.d(TAG,SE中招);
            se.printStackTrace();
        }
    }


    @覆盖
    公共无效onLocationChanged(位置定位){
        Log.d(更改,位置更新的);

    }

    @覆盖
    公共无效onStatusChanged(字符串商,INT地位,捆绑演员){

    }

    @覆盖
    公共无效onProviderEnabled(字符串提供商){

    }

    @覆盖
    公共无效onProviderDisabled(字符串提供商){

    }
}
 

解决方案

ACCESS_COARSE_LOCATION ACCESS_FINE_LOCATION WRITE_EXTERNAL_STORAG​​E 了Android 6.0运行时许可系统。除了有他们为你做的清单,你的的必须从用户要求他们在运行时(使用 requestPermissions())和看看你是否有他们(使用 checkSelfPermission())。

在短期内一个解决方法是删除你的 targetSdkVersion 低于23。

但是,最终,你将需要更新您的应用程序要使用的运行许可制度。

例如,本次活动的工作具有五个权限。四是运行时的权限,尽管它是presently只处理三(我以前 WRITE_EXTERNAL_STORAG​​E 写它被添加到运行时允许名册)。

  / ***
 版权所有(C)2015年CommonsWare,LLC
 Apache许可证下授权,版本2.0(以下简称许可证);你不可以
 使用本文件除了符合许可。你可以得到一个副本
 许可在http://www.apache.org/licenses/LICENSE-2.0的。除非需要
 适用法律或书面同意,在分布式软件
 许可分布在原样的基础,没有担保或条件
 任何形式的,无论是前preSS或暗示的保证。查看许可证的具体
 语言的管理许可和限制的授权。

 从用英语翻译忙codeR指南到Android Development_
 https://commonsware.com/Android
 * /

包com.commonsware.android.permmonger;

进口android.Manifest;
进口android.app.Activity;
进口android.content.pm.PackageManager;
进口android.os.Bundle;
进口android.view.Menu;
进口android.view.MenuItem;
进口android.widget.TextView;
进口android.widget.Toast;

公共类MainActivity延伸活动{
  私有静态最后的String [] INITIAL_PERMS = {
    Manifest.permission.ACCESS_FINE_LOCATION,
    Manifest.permission.READ_CONTACTS
  };
  私有静态最后的String [] CAMERA_PERMS = {
    Manifest.permission.CAMERA
  };
  私有静态最后的String [] CONTACTS_PERMS = {
      Manifest.permission.READ_CONTACTS
  };
  私有静态最后的String [] LOCATION_PERMS = {
      Manifest.permission.ACCESS_FINE_LOCATION
  };
  私有静态最终诠释INITIAL_REQUEST = 1337;
  私有静态最终诠释CAMERA_REQUEST = INITIAL_REQUEST + 1;
  私有静态最终诠释CONTACTS_REQUEST = INITIAL_REQUEST + 2;
  私有静态最终诠释LOCATION_REQUEST = INITIAL_REQUEST + 3;
  私人TextView的位置;
  私人TextView的摄像头;
  私人TextView的互联网;
  私人TextView的联系人;
  私人TextView的存储;

  @覆盖
  保护无效的onCreate(包savedInstanceState){
    super.onCreate(savedInstanceState);
    的setContentView(R.layout.main);

    位置=(TextView中)findViewById(R.id.location_value);
    摄像头=(TextView中)findViewById(R.id.camera_value);
    互联网=(TextView中)findViewById(R.id.internet_value);
    联系人=(TextView中)findViewById(R.id.contacts_value);
    存储=(TextView中)findViewById(R.id.storage_value);

    如果(!canAccessLocation()||!canAccessContacts()){
      requestPermissions(INITIAL_PERMS,INITIAL_REQUEST);
    }
  }

  @覆盖
  保护无效onResume(){
    super.onResume();

    updateTable();
  }

  @覆盖
  公共布尔onCreateOptionsMenu(功能菜单){
    。getMenuInflater()膨胀(R.menu.actions,菜单);

    返程(super.onCreateOptionsMenu(菜单));
  }

  @覆盖
  公共布尔onOptionsItemSelected(菜单项项){
    开关(item.getItemId()){
      案例R.id.camera:
        如果(canAccessCamera()){
          doCameraThing();
        }
        其他 {
          requestPermissions(CAMERA_PERMS,CAMERA_REQUEST);
        }
        返回(真);

      案例R.id.contacts:
        如果(canAccessContacts()){
          doContactsThing();
        }
        其他 {
          requestPermissions(CONTACTS_PERMS,CONTACTS_REQUEST);
        }
        返回(真);

      案例R.id.location:
        如果(canAccessLocation()){
          doLocationThing();
        }
        其他 {
          requestPermissions(LOCATION_PERMS,LOCATION_REQUEST);
        }
        返回(真);
    }

    返程(super.onOptionsItemSelected(项目));
  }

  @覆盖
  公共无效onRequestPermissionsResult(INT申请code,的String []的权限,INT [] grantResults){
    updateTable();

    开关(要求code){
      案例CAMERA_REQUEST:
        如果(canAccessCamera()){
          doCameraThing();
        }
        其他 {
          bzzzt();
        }
        打破;

      案例CONTACTS_REQUEST:
        如果(canAccessContacts()){
          doContactsThing();
        }
        其他 {
          bzzzt();
        }
        打破;

      案例LOCATION_REQUEST:
        如果(canAccessLocation()){
          doLocationThing();
        }
        其他 {
          bzzzt();
        }
        打破;
    }
  }

  私人无效updateTable(){
    location.setText(将String.valueOf(canAccessLocation()));
    camera.setText(将String.valueOf(canAccessCamera()));
    internet.setText(将String.valueOf(hasPermission(Manifest.permission.INTERNET)));
    contacts.setText(将String.valueOf(canAccessContacts()));
    storage.setText(将String.valueOf(hasPermission(Manifest.permission.WRITE_EXTERNAL_STORAG​​E)));
  }

  私人布尔canAccessLocation(){
    返程(hasPermission(Manifest.permission.ACCESS_FINE_LOCATION));
  }

  私人布尔canAccessCamera(){
    返程(hasPermission(Manifest.permission.CAMERA));
  }

  私人布尔canAccessContacts(){
    返程(hasPermission(Manifest.permission.READ_CONTACTS));
  }

  私人布尔hasPermission(字符串烫发){
    返程(PackageManager.PERMISSION_GRANTED == checkSelfPermission(烫发));
  }

  私人无效bzzzt(){
    Toast.makeText(这一点,R.string.toast_bzzzt,Toast.LENGTH_LONG).show();
  }

  私人无效doCameraThing(){
    Toast.makeText(这一点,R.string.toast_camera,Toast.LENGTH_SHORT).show();
  }

  私人无效doContactsThing(){
    Toast.makeText(这一点,R.string.toast_contacts,Toast.LENGTH_SHORT).show();
  }

  私人无效doLocationThing(){
    Toast.makeText(这一点,R.string.toast_location,Toast.LENGTH_SHORT).show();
  }
}
 

(从此示例项目

  

有关的requestPermissions()函数,如果参数只是ACCESS_COARSE_LOCATION?或者我应该包括全名android.permission.ACCESS_COARSE_LOCATION?

我会用在 Manifest.permission 定义的常量,如上图所示。

  

此外,什么是请求code?

这将传回给你的第一个参数 onRequestPermissionsResult(),所以你可以告诉一个 requestPermissions()调用。

Each time I run the application, my SecurityException gets thrown and the error from the debugger reads as so:

java.lang.SecurityException: "gps" location provider requires ACCESS_COARSE_LOCATION or ACCESS_FINE_LOCATION permission.

This seems like a simple mistake, however, my manifest file is completely correct. Here it is, and here is my MapActivity code as well:

<?xml version="1.0" encoding="utf-8"?>

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="com.google.android.providers.gsf.permission.READ_GSERVICES" />
<uses-permission android:name="com.dev.cromer.jason.coverme.permission.MAPS_RECEIVE" />

<application
    android:allowBackup="true"
    android:icon="@mipmap/ic_launcher"
    android:label="@string/app_name"
    android:theme="@style/AppTheme" >
    <activity
        android:name=".MainActivity"
        android:label="@string/app_name" >
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>

    <meta-data
        android:name="com.google.android.gms.version"
        android:value="@integer/google_play_services_version" />
    <meta-data
        android:name="com.google.android.maps.v2.API_KEY"
        android:value= "@string/google_maps_key" />

    <activity
        android:name=".MapActivity"
        android:label="@string/title_activity_map" >
    </activity>
</application>

My Activity:

    package com.dev.cromer.jason.coverme;

import android.location.Criteria;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.support.v4.app.FragmentActivity;
import android.os.Bundle;
import android.util.Log;

import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.location.LocationServices;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.MarkerOptions;

public class MapActivity extends FragmentActivity implements LocationListener {

    private GoogleMap mMap; // Might be null if Google Play services APK is not available.

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_map);

        setUpMapIfNeeded();
    }

    @Override
    protected void onResume() {
        super.onResume();
        setUpMapIfNeeded();
    }



    private void setUpMapIfNeeded() {
        // Do a null check to confirm that we have not already instantiated the map.
        if (mMap == null) {
            // Try to obtain the map from the SupportMapFragment.
            mMap = ((SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map))
                    .getMap();

            // Check if we were successful in obtaining the map.
            if (mMap != null) {
                //mMap.setMyLocationEnabled(true);
                //mMap.setOnMyLocationChangeListener(this);
                setUpMap();
            }
        }
    }


    private void setUpMap() {
        mMap.addMarker(new MarkerOptions().position(new LatLng(0, 0)).title("Marker"));
        mMap.setMyLocationEnabled(true);

        LocationManager locationManager = (LocationManager) getSystemService(LOCATION_SERVICE);

        try {
            Location myLocation = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);

            if (myLocation != null) {
                Log.d("TAG", "Not null");
            }
            else {
                Log.d("TAG", "NULL");
                locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, this);
            }
        }
        catch (SecurityException se) {
            Log.d("TAG", "SE CAUGHT");
            se.printStackTrace();
        }
    }


    @Override
    public void onLocationChanged(Location location) {
        Log.d("CHANGED", "LOCATION UPDATED");

    }

    @Override
    public void onStatusChanged(String provider, int status, Bundle extras) {

    }

    @Override
    public void onProviderEnabled(String provider) {

    }

    @Override
    public void onProviderDisabled(String provider) {

    }
}

解决方案

ACCESS_COARSE_LOCATION, ACCESS_FINE_LOCATION, and WRITE_EXTERNAL_STORAGE are all part of the Android 6.0 runtime permission system. In addition to having them in the manifest as you do, you also have to request them from the user at runtime (using requestPermissions()) and see if you have them (using checkSelfPermission()).

One workaround in the short term is to drop your targetSdkVersion below 23.

But, eventually, you will want to update your app to use the runtime permission system.

For example, this activity works with five permissions. Four are runtime permissions, though it is presently only handling three (I wrote it before WRITE_EXTERNAL_STORAGE was added to the runtime permission roster).

/***
 Copyright (c) 2015 CommonsWare, LLC
 Licensed under the Apache License, Version 2.0 (the "License"); you may not
 use this file except in compliance with the License. You may obtain a copy
 of the License at http://www.apache.org/licenses/LICENSE-2.0. Unless required
 by applicable law or agreed to in writing, software distributed under the
 License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS
 OF ANY KIND, either express or implied. See the License for the specific
 language governing permissions and limitations under the License.

 From _The Busy Coder's Guide to Android Development_
 https://commonsware.com/Android
 */

package com.commonsware.android.permmonger;

import android.Manifest;
import android.app.Activity;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.TextView;
import android.widget.Toast;

public class MainActivity extends Activity {
  private static final String[] INITIAL_PERMS={
    Manifest.permission.ACCESS_FINE_LOCATION,
    Manifest.permission.READ_CONTACTS
  };
  private static final String[] CAMERA_PERMS={
    Manifest.permission.CAMERA
  };
  private static final String[] CONTACTS_PERMS={
      Manifest.permission.READ_CONTACTS
  };
  private static final String[] LOCATION_PERMS={
      Manifest.permission.ACCESS_FINE_LOCATION
  };
  private static final int INITIAL_REQUEST=1337;
  private static final int CAMERA_REQUEST=INITIAL_REQUEST+1;
  private static final int CONTACTS_REQUEST=INITIAL_REQUEST+2;
  private static final int LOCATION_REQUEST=INITIAL_REQUEST+3;
  private TextView location;
  private TextView camera;
  private TextView internet;
  private TextView contacts;
  private TextView storage;

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    location=(TextView)findViewById(R.id.location_value);
    camera=(TextView)findViewById(R.id.camera_value);
    internet=(TextView)findViewById(R.id.internet_value);
    contacts=(TextView)findViewById(R.id.contacts_value);
    storage=(TextView)findViewById(R.id.storage_value);

    if (!canAccessLocation() || !canAccessContacts()) {
      requestPermissions(INITIAL_PERMS, INITIAL_REQUEST);
    }
  }

  @Override
  protected void onResume() {
    super.onResume();

    updateTable();
  }

  @Override
  public boolean onCreateOptionsMenu(Menu menu) {
    getMenuInflater().inflate(R.menu.actions, menu);

    return(super.onCreateOptionsMenu(menu));
  }

  @Override
  public boolean onOptionsItemSelected(MenuItem item) {
    switch(item.getItemId()) {
      case R.id.camera:
        if (canAccessCamera()) {
          doCameraThing();
        }
        else {
          requestPermissions(CAMERA_PERMS, CAMERA_REQUEST);
        }
        return(true);

      case R.id.contacts:
        if (canAccessContacts()) {
          doContactsThing();
        }
        else {
          requestPermissions(CONTACTS_PERMS, CONTACTS_REQUEST);
        }
        return(true);

      case R.id.location:
        if (canAccessLocation()) {
          doLocationThing();
        }
        else {
          requestPermissions(LOCATION_PERMS, LOCATION_REQUEST);
        }
        return(true);
    }

    return(super.onOptionsItemSelected(item));
  }

  @Override
  public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
    updateTable();

    switch(requestCode) {
      case CAMERA_REQUEST:
        if (canAccessCamera()) {
          doCameraThing();
        }
        else {
          bzzzt();
        }
        break;

      case CONTACTS_REQUEST:
        if (canAccessContacts()) {
          doContactsThing();
        }
        else {
          bzzzt();
        }
        break;

      case LOCATION_REQUEST:
        if (canAccessLocation()) {
          doLocationThing();
        }
        else {
          bzzzt();
        }
        break;
    }
  }

  private void updateTable() {
    location.setText(String.valueOf(canAccessLocation()));
    camera.setText(String.valueOf(canAccessCamera()));
    internet.setText(String.valueOf(hasPermission(Manifest.permission.INTERNET)));
    contacts.setText(String.valueOf(canAccessContacts()));
    storage.setText(String.valueOf(hasPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE)));
  }

  private boolean canAccessLocation() {
    return(hasPermission(Manifest.permission.ACCESS_FINE_LOCATION));
  }

  private boolean canAccessCamera() {
    return(hasPermission(Manifest.permission.CAMERA));
  }

  private boolean canAccessContacts() {
    return(hasPermission(Manifest.permission.READ_CONTACTS));
  }

  private boolean hasPermission(String perm) {
    return(PackageManager.PERMISSION_GRANTED==checkSelfPermission(perm));
  }

  private void bzzzt() {
    Toast.makeText(this, R.string.toast_bzzzt, Toast.LENGTH_LONG).show();
  }

  private void doCameraThing() {
    Toast.makeText(this, R.string.toast_camera, Toast.LENGTH_SHORT).show();
  }

  private void doContactsThing() {
    Toast.makeText(this, R.string.toast_contacts, Toast.LENGTH_SHORT).show();
  }

  private void doLocationThing() {
    Toast.makeText(this, R.string.toast_location, Toast.LENGTH_SHORT).show();
  }
}

(from this sample project)

For the requestPermissions() function, should the parameters just be "ACCESS_COARSE_LOCATION"? Or should I include the full name "android.permission.ACCESS_COARSE_LOCATION"?

I would use the constants defined on Manifest.permission, as shown above.

Also, what is the request code?

That will be passed back to you as the first parameter to onRequestPermissionsResult(), so you can tell one requestPermissions() call from another.

这篇关于Android的&QUOT; GPS需要ACCESS_FINE_LOCATION&QUOT;错误,即使我的清单文件中包含此的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆