原文地址:http://blog.magicer.xyz/2017/01/android-api-23-permission/

前言

在Android 6.0之前,开发Android应用程序的时,开发者需要使用什么权限只需要在AndroidManifest.xml文件中显示的声明即可。如下:

    <uses-permission android:name="android.permission.INTERNET"/>    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>

但是,在Android 6.0之后,Android对应用程序的权限进行了进一步的规范。分出来危险权限和一般权限,当我们需要危险权限的时候需要在运行时进行授权。这样做也有好处。对于一些应用用户的选择更多了。

权限分类

官方权限教程
当我们需要用到危险权限时,我们就需要动态的申请权限,那么危险权限有哪些呢?

危险权限

一般权限

对于常规的权限我们只需要在清单文件中注册即可,比如网络权限。

动态注册权限

如果您的应用需要危险权限,则每次执行需要这一权限的操作时您都必须检查自己是否具有该权限。用户始终可以自由调用此权限,因此,即使应用昨天使用了相机,它不能假设自己今天仍具有该权限。

要检查您是否具有某项权限,请调用ContextCompat.checkSelfPermission() 方法。例如,以下代码段显示了如何检查 Activity 是否具有在日历中进行写入的权限:

// Assume thisActivity is the current activityint permissionCheck = ContextCompat.checkSelfPermission(thisActivity,        Manifest.permission.WRITE_CALENDAR);

如果应用具有此权限,方法将返回 PackageManager.PERMISSION_GRANTED,并且应用可以继续操作。如果应用不具有此权限,方法将返回 PERMISSION_DENIED,且应用必须明确向用户要求权限。

以上是官方文档中关于检测权限的说明。
先来个小demo。看下怎么动态的请求权限,也可以看官方文档中的介绍。

    private static final int PERMISSION_REQUEST_CODE = 1; //权限请求码    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        if (checkPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE)) {            //获取权限后的操作。读取文件        }else {            //请求权限            ActivityCompat.requestPermissions(this,                    new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},                    PERMISSION_REQUEST_CODE);        }    }    /**     * 检测权限是否授权     * @return     */    private boolean checkPermission(Context context, String permission) {        return PackageManager.PERMISSION_GRANTED == ContextCompat.checkSelfPermission(context,permission);    }    @Override    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {        super.onRequestPermissionsResult(requestCode, permissions, grantResults);        switch (requestCode){            case PERMISSION_REQUEST_CODE:                if (grantResults.length >0 &&                        grantResults[0] == PackageManager.PERMISSION_GRANTED){                    //得到了授权                    Toast.makeText(this, "授权成功", Toast.LENGTH_SHORT).show();                }else {                    //未授权                    Toast.makeText(this, "授权失败", Toast.LENGTH_SHORT).show();                }                break;            default:                break;        }    }

当用户点击了禁止按钮后,当我们下次还需要该权限怎么办? shouldShowRequestPermissionRationale()函数会在用户点击了禁止后返回true,我们可以在该方法返回true时在提示用户开启权限。
代码跟上面的差不多。可以简要看一下。

 private static final int PERMISSION_REQUEST_CODE = 1; //权限请求码    private Button mButton;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        mButton = (Button) findViewById(R.id.activity_main_storage_btn);        mButton.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                storagePermission();            }        });    }    private void storagePermission() {        if (checkPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE)) {            //获取权限后的操作。读取文件        }else {//            //请求权限//            ActivityCompat.requestPermissions(this,//                    new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},//                    PERMISSION_REQUEST_CODE);            if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.WRITE_EXTERNAL_STORAGE)) {                Toast.makeText(this, "需要开启存储权限", Toast.LENGTH_SHORT).show();                showRequestPermissionDialog(new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},PERMISSION_REQUEST_CODE);            }else {                ActivityCompat.requestPermissions(this,                        new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},                        PERMISSION_REQUEST_CODE);            }        }    }    private void showRequestPermissionDialog(final String[] permissions, final int requestCode) {        AlertDialog.Builder builder = new AlertDialog.Builder(this);        builder.setMessage("使用该功能需要使用SD卡权限\n是否再次开启权限");        builder.setPositiveButton("是", new DialogInterface.OnClickListener() {            @Override            public void onClick(DialogInterface dialog, int which) {                ActivityCompat.requestPermissions(MainActivity.this,permissions,requestCode);            }        });        builder.setNegativeButton("否",null);        builder.setCancelable(true);        builder.show();    }    /**     * 检测权限是否授权     * @return     */    private boolean checkPermission(Context context, String permission) {        return PackageManager.PERMISSION_GRANTED == ContextCompat.checkSelfPermission(context,permission);    }    @Override    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {        super.onRequestPermissionsResult(requestCode, permissions, grantResults);        switch (requestCode){            case PERMISSION_REQUEST_CODE:                if (grantResults.length >0 &&                        grantResults[0] == PackageManager.PERMISSION_GRANTED){                    //得到了授权                    Toast.makeText(this, "授权成功", Toast.LENGTH_SHORT).show();                }else {                    //未授权                    Toast.makeText(this, "授权失败", Toast.LENGTH_SHORT).show();                }                break;            default:                break;        }    }

更多相关文章

  1. Android 线程操作之线程池
  2. Android 数据操作之SQLiteDatabase
  3. Android 应用程序获得系统权限
  4. Android采用操作xml
  5. 巨人的崛起 Android操作系统发展历程
  6. android 玩转ContentProvider之二--实现多个ContentProvider对多张
  7. android SQLite数据库的基本操作

随机推荐

  1. Android心得3--拨号器
  2. Android练习项目 Mp3播放器实现(一)
  3. Android(安卓)HAL实现的三种方式(1) - 基
  4. 关于Android(安卓)intent的知识 隐式意图
  5. Android(安卓)Develop Training——Andro
  6. 几点Android(安卓)开发中的小技巧
  7. android 新浪微博客户端的表情功能的实现
  8. 从CM刷机过程和原理分析Android系统结构
  9. Android笔记_2013_02_21
  10. Android练习项目 Mp3播放器实现(一)