Android运行时权限方案全解析

Android权限适配方案

(一) 6.0之前的版本权限处理方案

第一步: 在AndroidManifest中申明所需要的所有权限

第二步: 在用户安装App时,展示所有需要授权的程序

第三步: 用户同意授权即可安装App,反之则无法安装app

(二) 6.0版本的权限处理方案

6.0这个版本开始出现了动态申请权限这个概念

为什么会出现这个概念呢?

首先我们就必须知道权限的分类,从整体的角度可以把权限分为两大类。

一种是指普通的权限,一种是指危险权限。

那么普通权限和危险权限的本质区别是什么呢?

在我查阅相关的权限资料后,我发现普通权限与危险权限最本质的区别是是否涉及用户隐私信息的读取
危险权限主要以组的形式进行分类,以下我列出的9组都为危险权限(需要动态申请的权限),其余没有列出的就都为普通权限
身体传感器,日历,摄像头,通讯录,地理位置,麦克风,电话,短信,存储空间
这里写图片描述

不用第三方依赖的处理方式

第一步:在AndroidManifest中申明所需要的权限,这个和之前的版本处理是一致
第二步:检查权限,代码如下所示:
   if (ContextCompat.checkSelfPermission(thisActivity,Manifest.permission.READ_CONTACTS)
         != PackageManager.PERMISSION_GRANTED) {
     }else{
       }   

这里涉及到一个API,ContextCompat.checkSelfPermission,主要用于检测某个权限是否已经被授予,方法返回值为PackageManager.PERMISSION_DENIED或者PackageManager.PERMISSION_GRANTED。当返回DENIED就需要进行申请授权了。

第三步:申请授权,代码如下所示:
 ActivityCompat.requestPermissions(this,  new String[]{Manifest.permission.READ_CONTACTS}, MY_PERMISSIONS_REQUEST_READ_CONTACTS);

该方法为异步,第一个参数传入的是一个Context,第二个参数是需要申请权限的字符串数组,第三个参数为请求码,主要用于接口回调,从方法名以及第二个参数可以看出是支持一次性申请多个权限的。

第四步: 处理权限接口回调
 @Override
public void onRequestPermissionsResult(int requestCode,String permissions[], int[] grantResults) {
     switch (requestCode) {
        case MY_PERMISSIONS_REQUEST_READ_CONTACTS: {
            // I如果请求取消,则
            if (grantResults.length > 0&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
               // permission was granted
                // contacts-related task you need to do.
               } else {
                // permission denied,
                // functionality that depends on this permission.
              }
            return;
         }
       }
    }
第五步:小结

对于权限的申请结果,首先验证requestCode定位到你的申请,然后验证grantResults对应于申请的结果,这里的数组对应于申请时的第二个权限字符串数组。
如果你同时申请两个权限,那么grantResults的length就为2,分别记录你两个权限的申请结果。如果申请成功,就可以做你的事情了

第六步: 当用户在第一次授权时选择拒绝,你又需要和用户说明为什么需要这个权限时调用以下方法
if (ActivityCompat.shouldShowRequestPermissionRationale(this,Manifest.permission.READ_CONTACTS)) 
第七步:将上述步骤连接起来就是一个完整的权限处理
// Context为当前Activity
if (ContextCompat.checkSelfPermission(this,  Manifest.permission.READ_CONTACTS)
        != PackageManager.PERMISSION_GRANTED) {
    if (ActivityCompat.shouldShowRequestPermissionRationale(thisActivity,
            Manifest.permission.READ_CONTACTS)) {
        //弹出解释对话框给用户
        //等待用户响应
        // 用户看到解释再次提出请求
    } else {
        // 不需要解释对话框,直接请求权限
      ActivityCompat.requestPermissions(this,new String[]{Manifest.permission.READ_CONTACTS},
                MY_PERMISSIONS_REQUEST_READ_CONTACTS);
    }
}
第八步:范例代码
package com.example.dell.runtimerequestpermessiondemo;
import android.Manifest;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.Bundle;
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.Toast;

public class MainActivity extends AppCompatActivity {

    private static final int MY_PERMISSIONS_REQUEST_CALL_PHONE = 1;
    private Button mButton;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mButton= findViewById(R.id.btn_1);
        testCall( mButton);
    }

    public void testCall(View view) {
        if (ContextCompat.checkSelfPermission(this,  Manifest.permission.CALL_PHONE) != PackageManager.PERMISSION_GRANTED) {
            ActivityCompat.requestPermissions(this,new String[]{Manifest.permission.CALL_PHONE},
                    MY_PERMISSIONS_REQUEST_CALL_PHONE);
        } else {
            callPhone();
        }
    }

    public void callPhone() {
        Intent intent = new Intent(Intent.ACTION_CALL);
        Uri data = Uri.parse("tel:" + "10086");
        intent.setData(data);
        if (ActivityCompat.checkSelfPermission(this, Manifest.permission.CALL_PHONE) != PackageManager.PERMISSION_GRANTED) {
            // TODO: Consider calling
            //    ActivityCompat#requestPermissions
            // here to request the missing permissions, and then overriding
            //   public void onRequestPermissionsResult(int requestCode, String[] permissions,
            //                                          int[] grantResults)
            // to handle the case where the user grants the permission. See the documentation
            // for ActivityCompat#requestPermissions for more details.
            return;
        }
        startActivity(intent);
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {          if (requestCode == MY_PERMISSIONS_REQUEST_CALL_PHONE) {
            if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                callPhone();
            } else {
                // Permission Denied
                Toast.makeText(MainActivity.this, "Permission Denied", Toast.LENGTH_SHORT).show();
            }
            return;
        }
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    }
}

使用开源库

PermissionsDispatcher
具体用法可以从自行上Github上查阅相关文档

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
概述数采一期下位机是基于ART-PI开发板开发,服务器采用阿里云学生版云服务器ECS,单机器部署支持每秒采集2000台设备温度压力数据,连接对象(下称下位机)可以是设备也可以是网关(连接协议目前仅支持基于WebSocket,详情参考SocketIO),下位机采集或汇总的数据并通过 WIFI 上传云端远程实时监视,也可本地连接串口与 PC 端通讯,上位机通过自定义解析数据后展示到相关订阅端(可同时同步到多个Android手机)。对于物联网初创公司、自由开发者、学生,是一个相当实用的设计。数据流向完透明,不存在黑匣子,有助于开发者快速掌握物联网运行流程。 开发环境硬件:ART-PI RT-Thread版本:RT-Thread Nano v3.1.3 开发工具及版本:CubeMX v6.1.0、Keil v5.33、VSCode v1.51.1、Android Studio 4.1.1、HBuilder X v2.9.8.20201110、NodeJS v14.15.1、MongoDB v4.4.1(1主2副)、redis v6.0 RT-Thread使用情况概述内核部分:调度器。 软件包:CJSON v1.7.7 硬件框架ART-Pi是 RT-Thread 团队经过半年的精心准备,专门为嵌入式软件工程师、开源创客设计的一款极具扩展功能的 DIY 开源硬件。 软件框架说明本项目采用WebSocket协议进行设备与云端互联,本期目标,融合CubeMX、keil、RTT Nano的同时提供OTA功能和压力传感器(LPS22HH)的示例。本项目可分为4个部分: 第一部分 服务端 本期采用关键技术有nodejs、eggjs、socketio、mongodb等,主要为设备提供云端连接服务、可定制化协议解析、消息转发,报警等功能。 第二部分 后台管理端 本期采用关键技术有vue、element-ui、vue-router、vuex、monaco-editor等,主要提供一些权限分组管理,设备模型的定义(不同协议的解析),设备OTA测试。 第三部分 下位机 本期采用关键技术有RTT Nano、CJson、WebSocketClient等,主要实现了设备温度采集上传,模拟温度过载报警,OTA,以及C++14的示例代码。 第四部分 移动端 本期采用关键技术有uniapp、vue、echarts等,主要实现了设备数据实时上报、数据下发、模拟报警的功能。 软件模块说明sensor_thread_entry:传感器线程,采集数据并通过WebSocketClient发送给云端。 led_ thread _entry:闪灯线程,用来指示当前系统的运行状态。 wifi_ thread _entry:wifi线程,用来处理来自服务器的数据。 演示效果视频: 代码地址请下载附件获取代码。 若使用上有啥问题,请联系QQ: 296565890,微信:xiaosichuan2013 本项目遵循 Apache 许可证 2.0 版本,所包含4个端均可以免费在商业产品中使用,不需要公布应用程序源码,没有潜在商业风险。 真心希望有志同道合的朋友一期参与此开源项目 工作时间不一定及时回复,忘谅解! 比赛感悟纸上得来终觉浅,绝知此事要躬行。陆游的这首诗,完美的诠释了我在这次比赛中的收获。 物联网的时代,RTOS多线程是核心,通过综合对比,我最终选择了国产的RT-Thread。 通过本次比赛,让我深深体会到RTT Nano的小而美,尤其是在改动部分源码后,RTT Nano支持C++ 14,lambda、auto、函数重载、类模板用起来真是爽!(开启C++支持) 虽然本次比赛没有用到RT-Thread提供的软件包,但手动写一次WebSocketClient收获已经很满意了。 最后感谢主办方提供了这么好的一个平台,不仅能展示自我,也能学到很多知识,还要感谢论坛上那些解决我问题以及提供技术支持的大佬,希望有朝一日我也能给开源社区贡献一份自己力量。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值