Android6.0运行时权限解析

- 概述:

以前刚接触Android6.0的时候,比如扫描本机图片并现显示在界面上时,当涉及到读写权限时,我也像以前一样,在Manifest中开启权限,但当启动程序时,在6.0的机子上,一片空白,而在4.x上,完全能实现,百思不得其解。

当时问了问师兄,给我的回答是6.0之后开启权限的方式不一样了。但具体哪儿不一样,他也没跟我讲,直到前段时间的一次面试,当面试官问到我有没有用6.0版本进行开发,我便趁势问了问我的困惑,后来他详细的给我讲了讲,说现在的权限申请是在类文件中进行的,还有其他的一些细节。后来,我便找到了鸿洋大神的博客http://blog.csdn.net/lmj623565791/article/details/50709663; 写得特别详细。

下面,进入正题,Android6.0之后,将权限分为两类,一类是Normal Permisson,这类权限不涉及用户隐私,不需要进行授权,比如手机震动、访问网络等;另一类是Dangerous Permisson,涉及到用户隐私,需要用户进行授权,比如读写权限等。具体的可以去看看鸿洋大神的博客。接下来自己总结一下,以后再用到了便就方便了,接下来便开始一个简单的例子——申请读写权限:

  • 在Manifest中注册,声明读写权限;
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
  • 在类中,检查是否该权限已被授权,若已授权,便进行其他的操作,反之,变申请授权;

    检查权限是否被授予,需要利用ActivityCompat的checkSelfPermisson即可实现,需要传入两个参数,一个是Context,另一个便是权限名称,如下:

ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION)

该方法返回的是int型,得到value之后,与PackageManager.PERMISSION_GRANTED比较,若相等,说明该权限已被授予,反之则该权限未被授予。

针对未被授予的情况,需要申请用户授权,利用ActivityCompat.requestPermissions方法申请授权,需传入三个参数,Context、String[] 的权限集合,以及请求码:

ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION}, REQUEST_LOCATE);
  • 重写onRequestPermissonResult,类似于onActivityResult,根据requestCode进行判断,以便为用户提供一些相应信息;

通过switch判断requestCode,为用户返回相应信息:

 @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        switch (requestCode) {
            case REQUEST_LOCATE:
                if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                } else {
                    Toast.makeText(this, "无法获取GPS权限!", Toast.LENGTH_LONG).show();
                }
                break;
            default:
                break;
        }
    }

全部的步骤如下:

package com.danger.Activity;

import android.Manifest;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.Toast;

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

public class MainActivity extends AppCompatActivity implements View.OnClickListener{

    private ImageView imageView;
    private Button crop_button;
    private static final String path = Environment.getExternalStorageDirectory() + "/Download/left.jpg";
    private static final int WRITE_REQUEST_CODE = 1;
    private static final int READ_REQUEST_CODE = 2;
    private static final int CROP_CODE = 111;

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

        initView();
        initEvent();
    }

    private void initView(){
        crop_button = (Button) findViewById(R.id.crop_button);
        imageView = (ImageView) findViewById(R.id.imageView);
        Bitmap bitmap = getLocalBitmap(path);
        if(bitmap != null) {
            imageView.setImageBitmap(bitmap);
        }
    }

    private void initEvent(){
        crop_button.setOnClickListener(this);
    }

    @Override
    public void onClick(View view) {
        switch (view.getId()){
            case R.id.crop_button:
                crop();
                break;
            default:
                break;
        }
    }

    private void crop(){
        if(ContextCompat.checkSelfPermission(this,Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED){
            ActivityCompat.requestPermissions(this,new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},WRITE_REQUEST_CODE);
        }
        if(ContextCompat.checkSelfPermission(this,Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
            ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, READ_REQUEST_CODE);
        } else {
            Intent intent = new Intent();
            intent.setAction("com.android.camera.action.CROP");
            intent.setDataAndType(Uri.parse("file://" + path),"image/*");
            intent.putExtra("crop",true);
            //默认图片裁剪起始位置的X值
            intent.putExtra("aspectX",1);
            //默认图片裁剪起始位置的Y值
            intent.putExtra("aspectY",1);
            //默认图片裁剪终止位置的X值
            intent.putExtra("outputX",150);
            //默认图片裁剪终止位置的Y值
            intent.putExtra("outputY",150);
            intent.putExtra("return-data",true);
            startActivityForResult(intent,CROP_CODE);
        }
    }

    private Bitmap getLocalBitmap(String path){
        FileInputStream inputStream = null;
        try {
            inputStream = new FileInputStream(path);
            return BitmapFactory.decodeStream(inputStream);
        } catch (IOException e){
            e.printStackTrace();
        } finally {
            try {
                inputStream.close();
            } catch (IOException e){
                e.printStackTrace();
            }
        }
        return null;
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
        switch (requestCode){
            case WRITE_REQUEST_CODE:
                if(grantResults[0] != PackageManager.PERMISSION_GRANTED){
                    Toast.makeText(MainActivity.this,"无法获取写权限",Toast.LENGTH_SHORT).show();
                }
                break;
            case READ_REQUEST_CODE:
                if(grantResults[0] != PackageManager.PERMISSION_GRANTED){
                    Toast.makeText(MainActivity.this,"无法获取读写权限",Toast.LENGTH_SHORT).show();
                }
                break;
            default:
                break;
        }
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        if(requestCode == CROP_CODE && resultCode == RESULT_OK && data != null){
            Bundle bundle = data.getExtras();
            if(bundle != null){
                Bitmap bitmap = bundle.getParcelable("data");
                imageView.setImageBitmap(bitmap);
            }
        }
    }

    private void saveAsFile(Bitmap bitmap, String fileName){
        String path = Environment.getExternalStorageDirectory() + "/myImages/";
        File dirFile = new File(path);
        if(!dirFile.exists()){
            dirFile.mkdir();
        }
        File file = new File(path + fileName);
        FileOutputStream outputStream = null;
        BufferedOutputStream bufferedOutputStream = null;
        try {
            outputStream = new FileOutputStream(file);
            bufferedOutputStream = new BufferedOutputStream(outputStream);
            bitmap.compress(Bitmap.CompressFormat.JPEG,80,bufferedOutputStream);
        } catch (IOException e){
            e.printStackTrace();
        } finally {
            try {
                bufferedOutputStream.flush();
                outputStream.close();
                bufferedOutputStream.close();
            } catch (IOException e){
                e.printStackTrace();
            }
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值