Android 6.0“gps”位置提供程序需要 ACCESS_FINE_LOCATION 权限

Posted

技术标签:

【中文标题】Android 6.0“gps”位置提供程序需要 ACCESS_FINE_LOCATION 权限【英文标题】:Android 6.0 "gps" location provider requires ACCESS_FINE_LOCATION permission 【发布时间】:2016-10-07 20:19:21 【问题描述】:

我在清单中定义了使用 gps 的所有权限。喜欢

"使用权限 android:name="android.permission.ACCESS_FINE_LOCATION" />

"使用权限 android:name="android.permission.ACCESS_COARSE_LOCATION"/>

每次我尝试在 Android 6.0 上打开此活动时,它都会停止并显示此 logcat 消息。但适用于某些手机。有人可以帮我弄清楚,并提供解决方案。我一直在试图解决这个问题以及如何解决它。

Fatal Exception: java.lang.RuntimeException: Unable to start activity ComponentInfoorg.data.smurf/org.data.smurf.Konkurranse: java.lang.SecurityException: "gps" location provider requires ACCESS_FINE_LOCATION permission.
   at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3253)
   at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3349)
   at android.app.ActivityThread.access$1100(ActivityThread.java:221)
   at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1794)
   at android.os.Handler.dispatchMessage(Handler.java:102)
   at android.os.Looper.loop(Looper.java:158)
   at android.app.ActivityThread.main(ActivityThread.java:7224)
   at java.lang.reflect.Method.invoke(Method.java)
   at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1230)
   at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1120)
Caused by java.lang.SecurityException: "gps" location provider requires ACCESS_FINE_LOCATION permission.
   at android.os.Parcel.readException(Parcel.java:1620)
   at android.os.Parcel.readException(Parcel.java:1573)
   at android.location.ILocationManager$Stub$Proxy.requestLocationUpdates(ILocationManager.java:688)
   at android.location.LocationManager.requestLocationUpdates(LocationManager.java:908)
   at android.location.LocationManager.requestLocationUpdates(LocationManager.java:469)
   at org.data.smurf.Konkurranse.onCreate(Konkurranse.java:197)
   at android.app.Activity.performCreate(Activity.java:6876)
   at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1135)
   at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3206)
   at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3349)
   at android.app.ActivityThread.access$1100(ActivityThread.java:221)
   at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1794)
   at android.os.Handler.dispatchMessage(Handler.java:102)
   at android.os.Looper.loop(Looper.java:158)
   at android.app.ActivityThread.main(ActivityThread.java:7224)
   at java.lang.reflect.Method.invoke(Method.java)
   at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1230)
   at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1120)

这是我的 Konkurranse/竞赛活动。我已经删除了与 menu 和 actionbar 等不相关的代码。

Public class Konkurranse Extends Activity 

    /**
     * Called when the activity is first created.
     */
    @Override
    public void onCreate(Bundle savedInstanceState) 
        super.onCreate(savedInstanceState);
        FacebookSdk.sdkInitialize(getApplicationContext());
        Fresco.initialize(getApplicationContext());
        setContentView(R.layout.activity_konkurranse);
        LocationManager locationManager = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE);



        final com.facebook.Profile profile = com.facebook.Profile.getCurrentProfile();
        final ProfilePictureView profilePictureView = (ProfilePictureView) findViewById(R.id.profilepic);
        final TextView name = (TextView) findViewById(R.id.name);
        simpleDraweeView = (SimpleDraweeView) findViewById(R.id.profilePicture);
        RoundingParams roundingParams = RoundingParams.fromCornersRadius(50f);
        roundingParams.setRoundAsCircle(true);
        simpleDraweeView.getHierarchy().setRoundingParams(roundingParams);


        /// Logged IN \\\
        if (profile != null) 
            profilePictureView.getProfileId();
            profilePictureView.setProfileId(profile.getId());
            name.setText(profile.getName());
            simpleDraweeView.setImageURI(profile.getProfilePictureUri(100, 100));
        


        final SharedPreferences sharedPrefs = getSharedPreferences("details", MODE_PRIVATE);
        //After referencing your Views, add this.
        final String nameStr = sharedPrefs.getString("name", null);
        final String idStr = sharedPrefs.getString("id", null);
        AccessToken token = AccessToken.getCurrentAccessToken();
        if (token != null) 
            if (nameStr != null) name.setText(nameStr);
            if (idStr != null) profilePictureView.setProfileId(idStr);
            simpleDraweeView.setImageURI(profile.getProfilePictureUri(100, 100));
        

        //.. Do the same for other profile data


        mobilnummer = (EditText) findViewById(R.id.mobilnummer);

        buttongps = (Button) findViewById(R.id.gps);
        buttongps.setOnClickListener(onButtongpsClick);

        buttonblue = (Button) findViewById(R.id.bluetooth);
        buttonblue.setOnClickListener(onButtonblueClick);


        final LocationManager manager;
        manager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
        final ImageView gpsImg = (ImageView) findViewById(R.id.gpsstatus);
        if (manager.isProviderEnabled(LocationManager.GPS_PROVIDER)) 
            gpsImg.setImageResource(R.drawable.ok);
         else 
            gpsImg.setImageResource(R.drawable.notok);  //not ok
        

        // Register bluettoth listener
        bluetoothListener = new BluetoothListener() 
            @Override
            public void onBluetoothOff() 
                btImg.setImageResource(R.drawable.notok);  //not ok
            

            @Override
            public void onBluetoothOn() 
                btImg.setImageResource(R.drawable.ok);
            
        ;
        IntentFilter filter = new IntentFilter(BluetoothAdapter.ACTION_STATE_CHANGED);
        registerReceiver(bluetoothListener, filter);

        gpsListener = new GPSListener(this) 
            @Override
            public void onGPSOff() 
                gpsImg.setImageResource(R.drawable.notok);  //not ok

            

            @Override
            public void onGPSOn() 
                gpsImg.setImageResource(R.drawable.ok);
            
        ;

        // Henter fra SharedPrefs
        SharedPreferences prefs = getSharedPreferences(PREFS_NAME, MODE_PRIVATE);
        String savedMobileNumber = prefs.getString("mobilnummer", "");
        mobilnummer.setText(savedMobileNumber);


        final ImageView tlfstatus = (ImageView) findViewById(R.id.tlfstatus);
        if (mobilnummer.getText().toString().length() >= 8) 
            tlfstatus.setImageResource(R.drawable.ok);
         else 
            tlfstatus.setImageResource(R.drawable.notok); //not ok
        





        // OnCreate ends here.
    



    public View.OnClickListener onButtongpsClick = new View.OnClickListener() 
        @Override
        public void onClick(View v) 
            Intent gpsOptionsIntent = new Intent(android.provider.Settings.ACTION_LOCATION_SOURCE_SETTINGS);
            startActivity(gpsOptionsIntent);
        
    ;


    public View.OnClickListener onButtonblueClick = new View.OnClickListener() 
        @Override
        public void onClick(View v) 
            BluetoothAdapter mBluetoothAdapter;
            mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
            if (!mBluetoothAdapter.isEnabled()) mBluetoothAdapter.enable();
            ImageView img = (ImageView) findViewById(R.id.bluestatus);
            img.setImageResource(R.drawable.ok);
        
    ;

【问题讨论】:

【参考方案1】:

Serg 的回答是正确的。随着 Marshmallow(Android 6.0,API 级别 23)的权限系统发生了变化,现在您需要通过在运行时请求权限来处理 Marshmallow 设备。有一些库可以使这个过程更容易。

Easy Permissions 就是其中之一。

【讨论】:

【参考方案2】:

请参阅https://developer.android.com/training/permissions/requesting.html 了解新的权限策略以及如何在运行时请求权限。

【讨论】:

即使我不针对 Api 23 (marshmallow) 也需要这样做吗? 不,你不需要。这是一个从 Marshmallow(Android 6.0, API Level 23) 开始的新功能。

以上是关于Android 6.0“gps”位置提供程序需要 ACCESS_FINE_LOCATION 权限的主要内容,如果未能解决你的问题,请参考以下文章

标准类 - Android 位置 - 为啥选择 GPS 提供程序?

GPS定位研究之gps位置改变监听源码分析(Android10)

Android:如何使用 GPS 提供程序获取离线当前位置?

Android 6.0 默认关闭定位和GPS,开启后默认选省电

在 Android 中同时使用 GPS 和 Network Provider

如何同时使用 GPS 和网络提供商在 Android 中获取当前位置的纬度和经度值