博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Android6.0-运行时权限处理
阅读量:5905 次
发布时间:2019-06-19

本文共 4996 字,大约阅读时间需要 16 分钟。

大家都知道在Android6.0之前,权限在应用安装过程中只询问一次,以列表的形式展现给用户,如果点击取消(即不认可应用所申请的权限),则会取消应用的安装。而用户出于安装应用的需求,一般都会点击同意,而应用就有可能在后台进行一些非法操作。(同时,因为这个原因,应用可能会出现申请一大堆权限的情况,说不定以后有用呢,hhhhh)

而正是认识到这个问题,在Android6.0版本以后,推出了运行时权限功能。即用户不需要在安装应用的时候一次性授权,而是可以在应用的使用过程中对某一项权限进行授权。

当然并不是所有的权限都不需要手动动态申请,Android将权限分为了普通权限和高危权限。对于普通权限,系统会自动完成授权,我们只需要处理高危权限的授权即可。下面就是Android的危险权限表。

Permission Group

Permissions

CALENDAR

  • READ_CALENDAR

  • WRITE_CALENDAR

CAMERA

  • CAMERA

CONTACTS

  • READ_CONTACTS

  • WRITE_CONTACTS

  • GET_ACCOUNTS

LOCATION

  • ACCESS_FINE_LOCATION

  • ACCESS_COARSE_LOCATION

MICROPHONE

  • RECORD_AUDIO

PHONE

  • READ_PHONE_STATE

  • CALL_PHONE

  • READ_CALL_LOG

  • WRITE_CALL_LOG

  • ADD_VOICEMAIL

  • USE_SIP

  • PROCESS_OUTGOING_CALLS

SENSORS

  • BODY_SENSORS

SMS

  • SEND_SMS

  • RECEIVE_SMS

  • READ_SMS

  • RECEIVE_WAP_PUSH

  • RECEIVE_MMS

STORAGE

  • READ_EXTERNAL_STORAGE

  • WRITE_EXTERNAL_STORAGE

 

注意:表格中的每一个危险权限都属于一个权限组,我们在进行运行时权限处理时使用的是权限名,但当用户一旦同意授权,那么该权限所对应的权限组的所有其他权限都会被同时授权。

即一旦READ_CALENDAR被授权了,应用也有WRITE_CALENDAR权限了。

2.运行时权限处理

  对于运行在API23系统的应用,如果它的targetAPI大于等于23,则需要对运行时权限进行申请,否则会出现抛出异常,导致程序crash。

  而在现有的 代码中加入运行时权限处理也很简单,只需要在需要申请危险权限的地方嵌套权限申请的代码即可,下面就是一个典型的运行时权限申请的代码。

  

package com.pignet.runtimepermissiondemo;import android.Manifest;import android.content.DialogInterface;import android.content.Intent;import android.content.pm.PackageManager;import android.net.Uri;import android.support.annotation.NonNull;import android.support.v7.app.AlertDialog;import android.support.v7.app.AppCompatActivity;import android.os.Bundle;import android.view.View;import android.widget.Button;import android.widget.Toast;public class MainActivity extends AppCompatActivity {    private final static String CALL_PERMISSION=Manifest.permission.CALL_PHONE;    private final static int REQUEST_CODE_ASK_PERMISSIONS = 1;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        Button btnCall= (Button) findViewById(R.id.btn_call);        btnCall.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {               callWrapper();            }        });    }    /**     * 若没有权限,则申请,否则调用call     */    private void callWrapper() {        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M) {            int hasCallPhonePermission = checkSelfPermission(CALL_PERMISSION);            //是否已经拥有指定权限            if(hasCallPhonePermission!=PackageManager.PERMISSION_GRANTED){                /**                 * 检查是否需要弹出请求权限的提示对话框                 * shouldShowRequestPermissionRationale(permission)默认返回false                 * 当用户拒绝赋予权限后,返回值为true,这里的思路就是当用户拒绝了一次权限后                 * 需要弹出一个提示框,告诉用户这个权限的用途,以更好地申请到权限                 */                if(shouldShowRequestPermissionRationale(CALL_PERMISSION)){                    showMessageOKCancel("您需要允许拨打电话的权限", new DialogInterface.OnClickListener() {                        @Override                        public void onClick(DialogInterface dialog, int which) {                            requestPermissions(new String[]{CALL_PERMISSION},REQUEST_CODE_ASK_PERMISSIONS);                        }                    });                    return;                }                requestPermissions(new String[]{CALL_PERMISSION},REQUEST_CODE_ASK_PERMISSIONS);                return;            }            call();        }else            call();    }    private void showMessageOKCancel(String message, DialogInterface.OnClickListener okListener) {        new AlertDialog.Builder(MainActivity.this)                .setMessage(message)                .setPositiveButton("OK", okListener)                .setNegativeButton("Cancel", null)                .create()                .show();    }    /**     * 要完成的操作     */    private void call() {        try{            Intent intent = new Intent(Intent.ACTION_CALL);            intent.setData(Uri.parse("tel:110"));            startActivity(intent);        }catch (SecurityException e){            e.printStackTrace();        }    }    /**     *     * @param requestCode 权限申请请求码 这边对应前面的1     * @param permissions 需要申请的权限     * @param grantResults 请求结果   -1:Denied  0:Granted     */    @Override    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {        switch (requestCode){            case 1:                if(grantResults.length>0&&grantResults[0]==PackageManager.PERMISSION_GRANTED)                    call();                else                    //当用户第一次选择拒绝授权后,再次申请权限时,这时授权对话框会多一个”不再提醒“的提示,如果选择了拒绝授权                    //并且勾选了不再授权,那么在下次读取时就不会去申请授权,而是直接在回调中说明用户已经拒绝授权                    //所以在这边给出提示,提示用户去“设置”里手动授权,或者可以发一个广播打开设置界面。                    Toast.makeText(this,"您没有授予该权限,请在设置中打开授权",Toast.LENGTH_SHORT).show();                break;            default:                super.onRequestPermissionsResult(requestCode, permissions, grantResults);                break;        }    }}
本文转自 bxst 51CTO博客,原文链接:http://blog.51cto.com/13013670/1943979

转载地址:http://mjjpx.baihongyu.com/

你可能感兴趣的文章
opencv计算时间
查看>>
性能瓶颈的分类
查看>>
maven scope system
查看>>
#综合实践#通过puppet管理远程docker容器——配置puppet和实现变更
查看>>
PLSQL连Oracle数据库Could not load "……\bin\oci.dll"
查看>>
centos6.4安装GitLab
查看>>
Spring(Test)
查看>>
Ruby on Rails vs. PHP vs. Python
查看>>
Android图片剪切
查看>>
如何将 rhevm 加入 AD 域
查看>>
使用putty远程连接linux防止关闭putty程序就停止
查看>>
GCC基本概念及实践(2)
查看>>
Hacker技术是怎么样学习的
查看>>
Linux Vim编辑器的使用技巧
查看>>
oracle 两表关联时,年月条件的写法引起的巨大性能的差异
查看>>
google map初次使用总结
查看>>
OSPF协议介绍及配置 (上)
查看>>
sudo
查看>>
ecshop验证码无法显示
查看>>
Exchange混合部署环境下如何手工创建迁移终结点
查看>>