1. 程式人生 > >Android6.0許可權問題,並撰寫常用許可權工具類

Android6.0許可權問題,並撰寫常用許可權工具類

在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;
        }

    }
}