在android6.0手机调用系统相机的时候,报如下错误:
java.lang.RuntimeException: Unable to start activity ComponentInfo{cn.doolii.shopping/cn.doolii.shopping.view.uploadImage.AlbumUploadActivity}: java.lang.SecurityException: Permission Denial: reading com.android.providers.media.MediaProvider uri content://media/external/images/thumbnails from pid=27138, uid=10103 requires android.permission.READ_EXTERNAL_STORAGE, or grantUriPermission()at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2453)
在拍照的时候报如上问题,原因是没有添加相机权限
<uses-permission android:name="android.permission.CAMERA" />
同时android6.0以上系统新出权限问题
解决方法如下:
一:定义常量
public final static int MY_PERMISSIONS_REQUEST_READ_CONTACTS=1;
二:
在调用需要权限的方法之前,如调用拍照之前先判断是否有权限.
调用如下方法:
@TargetApi(Build.VERSION_CODES.M)
private void getPermission() {
if (ContextCompat.checkSelfPermission(UploadPicActivity.this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
//申请CAMERA的权限
requestPermissions(new String[]{Manifest.permission.CAMERA}, MY_PERMISSIONS_REQUEST_READ_CONTACTS);
} else {
photo();
pop.dismiss();
ll_popup.clearAnimation();
}
}
权限返回结果
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
switch (requestCode) {
case MY_PERMISSIONS_REQUEST_READ_CONTACTS:
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
photo();
} else {
Toast.makeText(UploadPicActivity.this, "请打开相机权限", Toast.LENGTH_LONG).show();
}
break;
}
}
工具类如下:
一、统一进行权限申请:
package cn.doolii.usershopping.utils;
import android.Manifest;
import android.annotation.TargetApi;
import android.app.Activity;
import android.content.Context;
import android.content.pm.PackageManager;
import android.os.Build;
import android.support.v4.app.ActivityCompat;
import android.support.v4.app.Fragment;
import android.support.v4.content.ContextCompat;
import android.util.Log;
import java.util.ArrayList;
import java.util.List;
/**
* Created by lzq on 2016/6/30.
*/
public class PermissionUtils {
static Activity context;
public static final int MY_PERMISSIONS_REQUEST_CALL_PHONE=200;
/**
* 单例对象实例
*/
private static PermissionUtils instance = null;
public static PermissionUtils getInstance(Activity context) {
if (instance == null) {
instance = new PermissionUtils(context);
}
return instance;
}
private PermissionUtils(Activity context) {
this.context=context;
}
public void needPermission(int requestCode)
{
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M){
return;
}
requestAllPermissions(requestCode);
}
/*
*
* 申请授予权限
* CALL_PHONE READ_EXTERNAL_STORAGE CAMERA READ_CONTACTS GET_ACCOUNTS ACCESS_FINE_LOCATION
* */
public void requestAllPermissions( int requestCode)
{
ActivityCompat.requestPermissions(context,
new String[]{ Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.CAMERA,Manifest.permission.READ_PHONE_STATE, Manifest.permission.ACCESS_FINE_LOCATION},
MY_PERMISSIONS_REQUEST_CALL_PHONE);
}
public boolean requesCallPhonePermissions( int requestCode)
{
if (ContextCompat.checkSelfPermission(context,
Manifest.permission.CALL_PHONE)
!= PackageManager.PERMISSION_GRANTED)
{//没有权限
ActivityCompat.requestPermissions(context,
new String[]{Manifest.permission.CALL_PHONE},
MY_PERMISSIONS_REQUEST_CALL_PHONE);
return false;
} else
{
return true;
}
}
public boolean requestReadSDCardPermissions( int requestCode)
{
if (ContextCompat.checkSelfPermission(context,
Manifest.permission.READ_EXTERNAL_STORAGE)
!= PackageManager.PERMISSION_GRANTED)
{//没有权限
ActivityCompat.requestPermissions(context,
new String[]{Manifest.permission.READ_EXTERNAL_STORAGE},
MY_PERMISSIONS_REQUEST_CALL_PHONE);
return false;
} else
{
return true;
}
}
public boolean requestCamerPermissions( int requestCode)
{
if (ContextCompat.checkSelfPermission(context,
Manifest.permission.CAMERA)
!= PackageManager.PERMISSION_GRANTED)
{//没有权限
ActivityCompat.requestPermissions(context,
new String[]{Manifest.permission.CAMERA},
MY_PERMISSIONS_REQUEST_CALL_PHONE);
return false;
} else
{
return true;
}
}
public boolean requestReadConstantPermissions( int requestCode)
{
if (ContextCompat.checkSelfPermission(context,
Manifest.permission.READ_CONTACTS)
!= PackageManager.PERMISSION_GRANTED)
{//没有权限
ActivityCompat.requestPermissions(context,
new String[]{Manifest.permission.READ_CONTACTS},
MY_PERMISSIONS_REQUEST_CALL_PHONE);
return false;
} else
{
return true;
}
}
public boolean requestGET_ACCOUNTSPermissions( int requestCode)
{
if (ContextCompat.checkSelfPermission(context,
Manifest.permission.GET_ACCOUNTS)
!= PackageManager.PERMISSION_GRANTED)
{//没有权限
ActivityCompat.requestPermissions(context,
new String[]{Manifest.permission.GET_ACCOUNTS},
MY_PERMISSIONS_REQUEST_CALL_PHONE);
return false;
} else
{
return true;
}
}
public boolean requestLocationPermissions( int requestCode)
{
if (ContextCompat.checkSelfPermission(context,
Manifest.permission.ACCESS_FINE_LOCATION)
!= PackageManager.PERMISSION_GRANTED)
{//没有权限
ActivityCompat.requestPermissions(context,
new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
MY_PERMISSIONS_REQUEST_CALL_PHONE);
return false;
} else
{
return true;
}
}
}
工具类使用方法如下:
我是在app第一次进入的时候,先判断android的版本,如果大于6.0,不管用户是否给与权限,都调用申请常用权限,防止因为用户不给于权限而导致崩溃,如:
存储,电话,相机,通讯录,位置等。防止用户
if (Build.VERSION.SDK_INT>= Build.VERSION_CODES.M){
new PermissionUtils(this).needPermission(200);
}
然后在接下来的需要调用这些权限时调用相对应的方法,如打电话时调用
requesCallPhonePermissions(200),参数随便传入。注意:此处的200 要与onRequestPermissionsResult中的参数requestCode一致。
重写请求权限后的回调方法:
@Override
public void onRequestPermissionsResult(int requestCode,
String permissions[], int[] grantResults) {
switch (requestCode) {
case 200: {
// If request is cancelled, the result arrays are empty.
if (grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// permission was granted, yay! Do the
// contacts-related task you need to do.
//同意给与权限 可以再此处调用拍照
Log.i("用户同意权限", "user granted the permission!");
} else {
// permission denied, boo! Disable the
// f用户不同意 可以给一些友好的提示
Log.i("用户不同意权限", "user denied the permission!");
}
return;
}
// other 'case' lines to check for other
// permissions this app might request
}
}
二、分别申请,每当使用某项需要权限的功能,就要进行权限申请。
工具类:
package www.doolii.cn.permissiondemo;
import android.Manifest;
import android.app.Activity;
import android.content.Context;
import android.content.pm.PackageManager;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
/**
* 检查权限的工具类
*
* Created by lizhiqaing on 16/7/19.
*/
public class PermissionsChecker {
private final Activity context;
public static final int MY_PERMISSIONS_REQUEST=200;
static PermissionsChecker checker=null;
private PermissionsChecker(Activity context) {
this.context=context;
}
public static PermissionsChecker getInstance(Activity context){
return new PermissionsChecker(context);
}
// 判断权限集合
public boolean lacksPermissions(String... permissions) {
for (int i=0;i
使用:
package www.doolii.cn.permissiondemo;
import android.Manifest;
import android.content.Context;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.os.Build;
import android.support.v4.app.ActivityCompat;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.telephony.TelephonyManager;
import android.view.View;
import android.widget.Toast;
public class MainActivity extends AppCompatActivity {
private PermissionsChecker mPermissionsChecker; // 权限检测器
// 所需的权限
static final String[] PERMISSIONS = new String[]{
Manifest.permission.READ_PHONE_STATE
};
PermissionsChecker checker=PermissionsChecker.getInstance(MainActivity.this);
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
findViewById(R.id.photo).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M){
//拍照的时候要进行权限判断
if (checker.lacksPermissions(PERMISSIONS)){//true 代表无权限
Toast.makeText(MainActivity.this,"无权限了",Toast.LENGTH_SHORT).show();
//申请权限
ActivityCompat.requestPermissions(MainActivity.this,
PERMISSIONS,
200);
}else{
Toast.makeText(MainActivity.this,getDeviceInfo(MainActivity.this),Toast.LENGTH_SHORT).show();
}
}else {
// 如果是6.0以下 不需要权限判断检查版本 直接调用拍照
Toast.makeText(MainActivity.this,"6.0以下不需要主动申请权限哦",Toast.LENGTH_SHORT).show();
}
}
});
}
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
switch (requestCode){
case 200:
if (grantResults.length > 0) {
for (int i=0;i