位置

时间:2017-01-11 23:45:47

标签: android runtime-permissions

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)之外,一切正常。

当活动启动时,它会强制停止,工作室中不会播放任何错误。

当活动第一次启动时(按工作室),它会给予吐司"无法显示位置权限"用代码写的 当活动第二次启动(手动)时,它会停止并出现以下错误:

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$1.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$5.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)

2 个答案:

答案 0 :(得分:1)

如果使用ACCESS_FINE_LOCATION,您必须要求ACCESS_COARSE_LOCATIONGoogleMap,并尝试优化您的代码。

您的完整编辑代码:

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) {

    }
}

答案 1 :(得分:0)

  

从Android 6.0(API级别23)开始,用户授予权限   应用程序运行时的应用程序,而非安装应用程序时的应用程序。这个   方法简化了应用程序安装过程,因为用户没有   需要在安装或更新应用程序时授予权限。它也是   让用户更好地控制应用程序的功能;例如,   用户可以选择让相机应用程序访问相机,但不能   到设备位置。用户可以撤消任何权限   时间,转到应用程序的“设置”屏幕。

<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

中的活动中
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();
        }
    }