Android6.0許可權問題,並撰寫常用許可權工具類
阿新 • • 發佈:2019-02-03
在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;
}
}
工具類如下:
一、統一進行許可權申請:
<pre name="code" class="java">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;
/**
* 檢查許可權的工具類
* <p/>
* 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<permissions.length;i++){
if (lacksPermission(permissions[i])) {//無許可權
return true;
}
}
return false;
}
// 判斷是否缺少許可權 無許可權返回true
private boolean lacksPermission(String permission) {
return ContextCompat.checkSelfPermission(context, permission) ==
PackageManager.PERMISSION_DENIED;
}
}
使用: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<grantResults.length;i++){
if (grantResults[i]== PackageManager.PERMISSION_GRANTED){
Toast.makeText(MainActivity.this,getDeviceInfo(MainActivity.this),Toast.LENGTH_SHORT).show();
}
}
}
break;
}
}
public static String getDeviceInfo(Context context) {
TelephonyManager tm = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
if (tm!=null) {
return tm.getDeviceId();
}else{
return null;
}
}
}