位置中的权限问题

Permission problems in Location

package com.example.khatrimann.map_activity;

import android.*;
import android.Manifest;
import android.content.pm.PackageManager;
import android.location.Location;
import android.os.Build;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.annotation.RequiresApi;
import android.support.v4.app.ActivityCompat;
import android.support.v4.app.FragmentActivity;
import android.support.v4.content.ContextCompat;
import android.widget.Toast;

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.OnMapReadyCallback;
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 MapsActivity extends FragmentActivity implements OnMapReadyCallback, GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener {

private static final int LOCATION_REQUEST_CODE = 101;
private static final int LOCATION_REQUEST_CODE_2 = 102;
//private   String  TAG = “MapDemo” ;
private GoogleMap mMap;
GoogleApiClient mGoogleApiClient;
Location mLastLocation;

protected void requestPermission(String permissionType, int
        requestCode) {
    int permission = ContextCompat.checkSelfPermission(this,
            permissionType);

    if (permission != PackageManager.PERMISSION_GRANTED) {
        ActivityCompat.requestPermissions(this,
                new String[]{permissionType}, requestCode
        );
    }
}

@Override
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
    switch (requestCode) {
        case LOCATION_REQUEST_CODE: {
            if (grantResults.length == 0
                    || grantResults[0] != PackageManager.PERMISSION_GRANTED) {
                Toast.makeText(this, "Unable to show loaction permissions", Toast.LENGTH_LONG).show();
            }
            return;
        }

    }
}

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

    requestPermission(android.Manifest.permission.ACCESS_FINE_LOCATION,
            LOCATION_REQUEST_CODE);

    SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
            .findFragmentById(R.id.map);
    mapFragment.getMapAsync(this);
}

//@RequiresApi(api = Build.VERSION_CODES.M)
@Override
public void onMapReady(GoogleMap googleMap) {
    mMap = googleMap;

    /*// Add a marker in Sydney, Australia, and move the camera.
    LatLng sydney = new LatLng(-34, 151);
    mMap.addMarker(new MarkerOptions().position(sydney).title("Marker in Sydney"));
    mMap.moveCamera(CameraUpdateFactory.newLatLng(sydney));*/


    if (mMap != null) {
        if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION)
                == PackageManager.PERMISSION_GRANTED) {
            //mMap.setMyLocationEnabled(true);

            mLastLocation = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);

        }
        else {
            requestPermission(android.Manifest.permission.ACCESS_FINE_LOCATION, LOCATION_REQUEST_CODE);
        }

    }
}

@Override
public void onConnected(@Nullable Bundle bundle) {
    Toast.makeText(this, "Online", Toast.LENGTH_SHORT).show();

}

@Override
public void onConnectionSuspended(int i) {

}

@Override
public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {

    }
}

我在清单文件中添加了适当的权限,检查了 运行 时间权限,一切正常,除了 mLastLocation = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient)

启动 activity 后强制停止,studio 中没有错误播种。

当 activity 首次启动时(由工作室),它给出代码中编写的 toast "Unable to show location permissions" 当 activity 第二次(手动)启动时,它会强制停止并出现以下错误:

E/AndroidRuntime: FATAL EXCEPTION: main
                                                                                 Process: com.example.khatrimann.map_activity, PID: 17785
                                                                                 java.lang.IllegalArgumentException: GoogleApiClient parameter is required.
                                                                                     at com.google.android.gms.common.internal.zzac.zzb(Unknown Source)
                                                                                     at com.google.android.gms.location.LocationServices.zzj(Unknown Source)
                                                                                     at com.google.android.gms.internal.zzarl.getLastLocation(Unknown Source)
                                                                                     at com.example.khatrimann.map_activity.MapsActivity.onMapReady(MapsActivity.java:95)
                                                                                     at com.google.android.gms.maps.SupportMapFragment$zza.zza(Unknown Source)
                                                                                     at com.google.android.gms.maps.internal.zzt$zza.onTransact(Unknown Source)
                                                                                     at android.os.Binder.transact(Binder.java:499)
                                                                                     at zu.a(:com.google.android.gms.DynamiteModulesB:82)
                                                                                     at maps.ad.t.run(Unknown Source)
                                                                                     at android.os.Handler.handleCallback(Handler.java:751)
                                                                                     at android.os.Handler.dispatchMessage(Handler.java:95)
                                                                                     at android.os.Looper.loop(Looper.java:154)
                                                                                     at android.app.ActivityThread.main(ActivityThread.java:6126)
                                                                                     at java.lang.reflect.Method.invoke(Native Method)
                                                                                     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886)
                                                                                     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776)

你必须要求 ACCESS_FINE_LOCATIONACCESS_COARSE_LOCATION,如果使用 GoogleMap,也请尝试优化你的代码。

您的完整编辑代码:

package com.example.khatrimann.map_activity;

import android.*;
import android.Manifest;
import android.content.pm.PackageManager;
import android.location.Location;
import android.os.Build;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.annotation.RequiresApi;
import android.support.v4.app.ActivityCompat;
import android.support.v4.app.FragmentActivity;
import android.support.v4.content.ContextCompat;
import android.widget.Toast;

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.OnMapReadyCallback;
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 MapsActivity extends FragmentActivity implements OnMapReadyCallback, GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener {

private static final int LOCATION_REQUEST_CODE = 101;
private static final int LOCATION_REQUEST_CODE_2 = 102;
//private   String  TAG = “MapDemo” ;
private GoogleMap mMap;
GoogleApiClient mGoogleApiClient;
Location mLastLocation;

protected void requestPermission() {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M){

        if (ActivityCompat.checkSelfPermission
                (this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED
                &&
                ActivityCompat.checkSelfPermission
                        (this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED)
        {
            requestPermissions(new String[]{
                    Manifest.permission.ACCESS_COARSE_LOCATION,
                    Manifest.permission.ACCESS_FINE_LOCATION
            }, LOCATION_REQUEST_CODE);
        }
    }
}

@Override
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
    switch (requestCode) {
        case LOCATION_REQUEST_CODE: 
            if (grantResults.length == 0
                    || grantResults[0] != PackageManager.PERMISSION_GRANTED) {
                Toast.makeText(this, "Permission denied", Toast.LENGTH_LONG).show();

            break;
        }

    }
}

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_maps);
    SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
            .findFragmentById(R.id.map);
    mapFragment.getMapAsync(this);

}

//@RequiresApi(api = Build.VERSION_CODES.M)
@Override
public void onMapReady(GoogleMap googleMap) {
    mMap = googleMap;

    /*// Add a marker in Sydney, Australia, and move the camera.
    LatLng sydney = new LatLng(-34, 151);
    mMap.addMarker(new MarkerOptions().position(sydney).title("Marker in Sydney"));
    mMap.moveCamera(CameraUpdateFactory.newLatLng(sydney));*/


    if (mMap != null) {
        if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION)
                == PackageManager.PERMISSION_GRANTED &&  &&
                ActivityCompat.checkSelfPermission
                        (this, Manifest.permission.ACCESS_COARSE_LOCATION) == PackageManager.PERMISSION_GRANTED)) {
            //mMap.setMyLocationEnabled(true);

            mLastLocation = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
            // fetch location lat lng

        }
        else {
            requestPermission();
        }

    }
}

@Override
public void onConnected(@Nullable Bundle bundle) {
    Toast.makeText(this, "Online", Toast.LENGTH_SHORT).show();

}

@Override
public void onConnectionSuspended(int i) {

}

@Override
public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {

    }
}

Beginning in Android 6.0 (API level 23), users grant permissions to apps while the app is running, not when they install the app. This approach streamlines the app install process since the user does not need to grant permissions when they install or update the app. It also gives the user more control over the app's functionality; for example, a user could choose to give a camera app access to the camera but not to the device location. The user can revoke the permissions at any time, by going to the app's Settings screen.

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.myapp" >
  ...
  <uses-permission 
android:name="android.permission.ACCESS_COARSE_LOCATION"/> android:name="android.permission.ACCESS_FINE_LOCATION"/>

android:name="android.permission.ACCESS_COARSE_LOCATION"/>

...

在 OnCreate

中将此代码添加到您的 activity
askForPermission(Manifest.permission.ACCESS_FINE_LOCATION,LOCATION);
///call this method

 private void askForPermission(String permission, Integer requestCode) {
        if (ContextCompat.checkSelfPermission(MainActivity.this, permission) != PackageManager.PERMISSION_GRANTED) {

            // Should we show an explanation?
            if (ActivityCompat.shouldShowRequestPermissionRationale(MainActivity.this, permission)) {

                //This is called if user has denied the permission before
                //In this case I am just asking the permission again
                ActivityCompat.requestPermissions(MainActivity.this, new String[]{permission}, requestCode);

            } else {

                ActivityCompat.requestPermissions(MainActivity.this, new String[]{permission}, requestCode);
            }
        } else {
            Toast.makeText(this, "" + permission + " is already granted.", Toast.LENGTH_SHORT).show();
        }
    }