- 概述:
以前刚接触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();
}
}
}
}