Android动态权限,EasyPermissions 介绍及使用
来源:互联网 发布:知乎评价奚梦瑶 编辑:程序博客网 时间:2024/06/05 00:39
转载请注明出处,谢谢:http://blog.csdn.net/harryweasley/article/details/72928860
Android M(6.0)以上是动态权限,google官方推出了一个开源项目EasyPermissions 来方便集成动态权限的功能。
本篇博客先翻译一下github的内容,然后给出一个例子,看看具体怎么使用EasyPermissions 。
EasyPermissions 的github地址是:https://github.com/googlesamples/easypermissions
附上DEMO源码下载地址:https://github.com/HarryWeasley/DynamicPermissionDemo
在Android M(6.0)或更高版本,EasyPermissions 是一个封装好的用来简化基本系统权限逻辑的库。
安装
EasyPermissions 通过在build.gradle写入下面的依赖,来进行安装。
dependencies { compile 'pub.devrel:easypermissions:0.4.0'}
用法
基本用法
为了开始使用EasyPermissions,你需要在你的Activity (或者Fragment)中重写onRequestPermissionsResult 方法:
public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); } @Override public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) { super.onRequestPermissionsResult(requestCode, permissions, grantResults); // Forward results to EasyPermissions //将结果传入EasyPermissions中 EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this); }}
请求权限
下面的例子展示了如何获取权限,通过一个方法获取CAMERA和ACCESS_FINE_LOCATION权限,有几个点需要注意:
- 用EasyPermissions#hasPermissions(…)来检查是否这个应用已经获取到需要请求的权限,这个方法可以接收任意数量的权限作为它的最后一个参数。
- 用EasyPermissions#requestPermissions来获取权限。该方法将会获取到系统权限,如果需要的话还可以展示提供的rationale字符串内容,requestCode应该是唯一的来标识请求权限,该方法如同hasPermissions,也可以接收任意数量的权限作为他的最后一个参数。
- AfterPermissionGranted 注解的用处。它是可选的,是为了开发方便才提供的。如果所有的请求权限都已经被授权,任何一个通过正确的requestCode注解的方法都将执行。在所有权限都被授权后,通过注解描述的该方法,将会自动执行。当然,你也可以不用AfterPermissionGranted 注解,你可以将该方法放入onPermissionsGranted 这个回调方法里面来执行。
@AfterPermissionGranted(RC_CAMERA_AND_LOCATION)private void methodRequiresTwoPermission() { String[] perms = {Manifest.permission.CAMERA, Manifest.permission.ACCESS_FINE_LOCATION}; if (EasyPermissions.hasPermissions(this, perms)) { // Already have permission, do the thing //如果已经获取权限,在这里做一些事情 // ... } else { // Do not have permissions, request them now //如果没有获取到权限,在这里获取权限,其中RC_CAMERA_AND_LOCATION是自己定义的一个唯一标识int值 EasyPermissions.requestPermissions(this, getString(R.string.camera_and_location_rationale), RC_CAMERA_AND_LOCATION, perms); }}
当然,为了一个更好的控制,可以让Activity / Fragment实现PermissionCallbacks 接口,如下所示:
public class MainActivity extends AppCompatActivity implements EasyPermissions.PermissionCallbacks { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); } @Override public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) { super.onRequestPermissionsResult(requestCode, permissions, grantResults); // Forward results to EasyPermissions EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this); } @Override public void onPermissionsGranted(int requestCode, List<String> list) { // Some permissions have been granted // 请求权限已经被授权 // ... } @Override public void onPermissionsDenied(int requestCode, List<String> list) { // Some permissions have been denied // 请求权限被拒绝 // ... }}
必需权限
有一些案例,如果你的应用没有这些权限,有些功能将不能正常使用。如果用户点击了“不再询问”框,并且拒绝授权权限,你的应用将不能从用户那里获取到权限,除非用户去应用设置里更改状态。在这种情况下,你可以用EasyPermissions.somePermissionPermanentlyDenied(…)这个方法来判断,最终展示一个Dialog,指导用户去系统设置界面,为你的应用开启权限。
@Overridepublic void onPermissionsDenied(int requestCode, List<String> perms) { Log.d(TAG, "onPermissionsDenied:" + requestCode + ":" + perms.size()); // (Optional) Check whether the user denied any permissions and checked "NEVER ASK AGAIN." // This will display a dialog directing them to enable the permission in app settings. //(可选的)检查用户是否拒绝授权权限,并且点击了“不再询问” //下面的语句,展示一个对话框指导用户在应用设置里授权权限 if (EasyPermissions.somePermissionPermanentlyDenied(this, perms)) { new AppSettingsDialog.Builder(this).build().show(); }}@Overridepublic void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if (requestCode == AppSettingsDialog.DEFAULT_SETTINGS_REQ_CODE) { // Do something after user returned from app settings screen, like showing a Toast. // 当用户从应用设置界面返回的时候,可以做一些事情,比如弹出一个土司。 Toast.makeText(this, R.string.returned_from_app_settings_to_activity, Toast.LENGTH_SHORT) .show(); }}
普通实例
下面是EasyPermissions的通用动态获取权限的实现方法,文末有源码下载地址:
package demo.lgx.com.dynamicpermissiondemo;import android.Manifest;import android.graphics.Bitmap;import android.graphics.drawable.BitmapDrawable;import android.os.Bundle;import android.os.Handler;import android.os.Message;import android.support.annotation.NonNull;import android.support.annotation.Nullable;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.File;import java.io.FileNotFoundException;import java.io.FileOutputStream;import java.io.IOException;import java.util.List;import pub.devrel.easypermissions.AfterPermissionGranted;import pub.devrel.easypermissions.AppSettingsDialog;import pub.devrel.easypermissions.EasyPermissions;/** * Created by Harry on 2017/6/8. */public class DynamicActivity extends AppCompatActivity implements EasyPermissions.PermissionCallbacks{ ImageView imageView; /** * 随便赋值的一个唯一标识码 */ public static final int WRITE_EXTERNAL_STORAGE=100; Handler handler = new Handler() { @Override public void handleMessage(Message msg) { super.handleMessage(msg); if (msg.what == 1) { Toast.makeText(DynamicActivity.this, "保存成功", Toast.LENGTH_LONG).show(); } } }; @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_dynamit); Button save = (Button) findViewById(R.id.save); imageView = (ImageView) findViewById(R.id.image); save.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { checkPerm(); } }); } /** * 检查权限 */ @AfterPermissionGranted(WRITE_EXTERNAL_STORAGE) private void checkPerm() { String[] params={Manifest.permission.WRITE_EXTERNAL_STORAGE}; if(EasyPermissions.hasPermissions(this,params)){ saveImage(); }else{ EasyPermissions.requestPermissions(this,"需要读写本地权限",WRITE_EXTERNAL_STORAGE,params); } } private void saveImage() { //请忽略我这个子线程的优化问题,这里主要是为了实现动态权限的功能,哈哈! new Thread(new Runnable() { @Override public void run() { //获取到bitmap BitmapDrawable drawable = (BitmapDrawable) imageView.getDrawable(); Bitmap bitmap = drawable.getBitmap(); //创建文件夹保存图片 File file = DynamicActivity.this.getExternalFilesDir(null).getAbsoluteFile(); String imageName = "test.jpg"; File imageFile = new File(file, imageName); FileOutputStream fos = null; try { fos = new FileOutputStream(imageFile); bitmap.compress(Bitmap.CompressFormat.JPEG, 100, fos); fos.flush(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } finally { if (fos != null) { try { fos.close(); } catch (IOException e) { e.printStackTrace(); } } } //保存成功后发送message handler.sendEmptyMessage(1); } }).start(); } @Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { super.onRequestPermissionsResult(requestCode, permissions, grantResults); EasyPermissions.onRequestPermissionsResult(requestCode,permissions,grantResults,this); } @Override public void onPermissionsGranted(int requestCode, List<String> perms) { //如果checkPerm方法,没有注解AfterPermissionGranted,也可以在这里调用该方法。 } @Override public void onPermissionsDenied(int requestCode, List<String> perms) { if (EasyPermissions.somePermissionPermanentlyDenied(this, perms)) { //这里需要重新设置Rationale和title,否则默认是英文格式 new AppSettingsDialog.Builder(this) .setRationale("没有该权限,此应用程序可能无法正常工作。打开应用设置屏幕以修改应用权限") .setTitle("必需权限") .build() .show(); } }}
复杂实例
之前看过一些app的功能,如果用户拒绝该权限,那么该app将不允许用户使用,直接退出,下面这个例子来实现这样的一个功能。
如果用户拒绝权限授权,则app退出该页面,如下图所示:
package demo.lgx.com.dynamicpermissiondemo;import android.Manifest;import android.content.Intent;import android.os.Bundle;import android.os.Handler;import android.os.Message;import android.support.annotation.NonNull;import android.support.annotation.Nullable;import android.support.v7.app.AppCompatActivity;import android.util.Log;import android.view.View;import android.widget.Button;import android.widget.ImageView;import android.widget.Toast;import java.util.List;import pub.devrel.easypermissions.AfterPermissionGranted;import pub.devrel.easypermissions.AppSettingsDialog;import pub.devrel.easypermissions.EasyPermissions;/** * Created by Harry on 2017/6/8. */public class MustPermissionActivity extends AppCompatActivity implements EasyPermissions.PermissionCallbacks { ImageView imageView; /** * 随便赋值的一个唯一标识码 */ public static final int WRITE_EXTERNAL_STORAGE = 100; private boolean isFirst = false; //权限参数 String[] params = {Manifest.permission.WRITE_EXTERNAL_STORAGE}; Handler handler = new Handler() { @Override public void handleMessage(Message msg) { super.handleMessage(msg); if (msg.what == 1) { Toast.makeText(MustPermissionActivity.this, "保存成功", Toast.LENGTH_LONG).show(); } } }; @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); Log.i("MustPermissionActivity", "onCreate执行"); setContentView(R.layout.activity_dynamit); isFirst = true; Button save = (Button) findViewById(R.id.save); imageView = (ImageView) findViewById(R.id.image); save.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { checkPerm(); } }); } @Override protected void onResume() { super.onResume(); if (isFirst) { //因为要通过一个Fragment来弹出弹出框,所以activity这里的onResume执行了两次,这里进行判断 isFirst = false; if (!EasyPermissions.hasPermissions(this, params)) { EasyPermissions.requestPermissions(this, "需要读写本地权限", WRITE_EXTERNAL_STORAGE, params); } } } /** * 检查权限 */ @AfterPermissionGranted(WRITE_EXTERNAL_STORAGE) private void checkPerm() { if (EasyPermissions.hasPermissions(this, params)) { //已经获取到权限 Toast.makeText(MustPermissionActivity.this, "获取到权限,正常进入", Toast.LENGTH_LONG).show(); } else { EasyPermissions.requestPermissions(this, "需要读写本地权限", WRITE_EXTERNAL_STORAGE, params); } } @Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { super.onRequestPermissionsResult(requestCode, permissions, grantResults); EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this); } @Override public void onPermissionsGranted(int requestCode, List<String> perms) { } @Override public void onPermissionsDenied(int requestCode, List<String> perms) { if (EasyPermissions.somePermissionPermanentlyDenied(this, perms)) { //这个方法有个前提是,用户点击了“不再询问”后,才判断权限没有被获取到 new AppSettingsDialog.Builder(this) .setRationale("没有该权限,此应用程序可能无法正常工作。打开应用设置界面以修改应用权限") .setTitle("必需权限") .build() .show(); } else if (!EasyPermissions.hasPermissions(this, params)) { //这里响应的是除了AppSettingsDialog这个弹出框,剩下的两个弹出框被拒绝或者取消的效果 finish(); } } @Override public void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if (requestCode == AppSettingsDialog.DEFAULT_SETTINGS_REQ_CODE) { if (!EasyPermissions.hasPermissions(this, params)) { //这里响应的是AppSettingsDialog点击取消按钮的效果 finish(); } } }}
两点说明
1.一定要记得要先在AndroidManifest.xml声明权限。
2.例子中的Context.getExternalFilesDir()的绝对路径是SDCard/Android/data/应用包名/files/,在api<19的时候,需要写入权限,但是在api>=19后,就不需要写入权限,也可以写入数据了。本篇文章例子,是为了写easyPermissions的功能,所以不要在意Context.getExternalFilesDir()该路径。关于该权限官网链接是https://developer.android.com/reference/android/content/Context.html#getExternalFilesDir(java.lang.String)
附上源码下载地址:https://github.com/HarryWeasley/DynamicPermissionDemo
- Android动态权限,EasyPermissions 介绍及使用
- Andorid6.0动态权限及开源项目EasyPermissions使用介绍
- Android 6.0动态权限框架EasyPermissions的使用
- Android 权限检查EasyPermissions
- Android 6.0运行时权限的申请使用及EasyPermissions的使用
- Android 6.0运行时权限的申请使用及EasyPermissions的使用
- 安卓学习笔记--- Android 6.0运行时权限的申请使用及EasyPermissions的使用
- 使用EasyPermissions 来打造简单的android6.0动态权限
- Android权限处理——第三方库easypermissions使用
- Android EasyPermissions官方库,高效处理权限
- Android 6.0多个权限申请,教你使用Google easypermissions框架,100%申请成功
- easypermissions使用
- Easypermissions使用
- Android 6.0+ 运行时权限——EasyPermissions源码解析
- EasyPermissions android 权限框架 简单易用 稳定
- 安卓动态获取权限及权限介绍
- Android6.0------权限申请~easypermissions
- googlesamples之easypermissions使用
- Mac安装nginx
- Dates and Times
- Pentaho-A Comprehensive Data Integration and Business Analytics Platform
- 离散余弦变换_原理及应用
- 整数排序 II
- Android动态权限,EasyPermissions 介绍及使用
- 【剑指offer-解题系列(53)】正则表达式匹配
- ButterKnife 框架的使用(一)
- 使用bootstrap-select插件来实现下拉菜单搜索匹配功能
- Protocol Buffer原理
- virtualenv、virtualenvwrapper安装使用
- mfc访问控件的多种方法
- 视图模板____Freemarker入门demo
- 464.整数排序 II