Android 6.0的运行时权限 批量申请

Android11 授权应用获取IMEI号和ICCID 在Android11上获取IMEI号等设备信息需要权限,而这个权限又只授予系统级应用。项目中如果值小于29获取到的是null,大于28报SecurityException错误。 阅读详情

Android 6.0,代号棉花糖,自发布伊始,其主要的特征运行时权限就很受关注。因为这一特征不仅改善了用户对于应用的使用体验,还使得应用开发者在实践开发中需要做出改变。

没有深入了解运行时权限的开发者通常会有很多疑问,比如什么是运行时权限,哪些是运行时的权限,我的应用是不是会在6.0系统上各种崩溃呢,如何才能支持运行时权限机制呢。本文讲尝试回答这一些问题,希望读者阅读完成之后,都能找到较为完美的答案。

权限一刀切

在6.0以前的系统,都是权限一刀切的处理方式,只要用户安装,Manifest申请的权限都会被赋予,并且安装后权限也撤销不了。
这种情况下,当我们从Google Play安装一个应用,在安装之前会得到这样的权限提示信息。

Permission

当上述对话框弹出后,用户只有两种选择:

  • 我信任你,即使有敏感权限
  • 你一个**应用,要这个权限干嘛,我还是不安装了。

所以,这种一刀切的处理方式还是有弊端的,我们没有办法只允许某些权限或者拒绝某些权限。

棉花糖运行时权限

从棉花糖开始,Android系统引入了新的权限机制,即本文要讲的运行时权限。

何为运行时权限呢?举个栗子,以某个需要拍照的应用为例,当运行时权限生效时,其Camera权限不是在安装后赋予,而是在应用运行的时候进行请求权限(比如当用户按下”相机拍照“按钮后)看到的效果则是这样的

Requesting Camera Permission

接下来,对于Camera权限的处理完全权交给用户。是不是有点像苹果系统的处理呢,不要说这是抄袭,暂且称为师夷长技以制夷。

权限的分组

Android中有很多权限,但并非所有的权限都是敏感权限,于是6.0系统就对权限进行了分类,一般为下述几类

  • 正常(Normal Protection)权限
  • 危险(Dangerous)权限
  • 特殊(Particular)权限
  • 其他权限(一般很少用到)

正常权限

正常权限具有如下的几个特点

  • 对用户隐私没有较大影响或者不会打来安全问题。
  • 安装后就赋予这些权限,不需要显示提醒用户,用户也不能取消这些权限。

正常权限列表

<span class="line-number" style="margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-variant: inherit; font-weight: inherit; line-height: inherit; font-family: inherit; vertical-align: baseline; color: rgb(147, 161, 161) !important;">1</span>
<span class="line-number" style="margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-variant: inherit; font-weight: inherit; line-height: inherit; font-family: inherit; vertical-align: baseline; color: rgb(147, 161, 161) !important;">2</span>
<span class="line-number" style="margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-variant: inherit; font-weight: inherit; line-height: inherit; font-family: inherit; vertical-align: baseline; color: rgb(147, 161, 161) !important;">3</span>
<span class="line-number" style="margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-variant: inherit; font-weight: inherit; line-height: inherit; font-family: inherit; vertical-align: baseline; color: rgb(147, 161, 161) !important;">4</span>
<span class="line-number" style="margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-variant: inherit; font-weight: inherit; line-height: inherit; font-family: inherit; vertical-align: baseline; color: rgb(147, 161, 161) !important;">5</span>
<span class="line-number" style="margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-variant: inherit; font-weight: inherit; line-height: inherit; font-family: inherit; vertical-align: baseline; color: rgb(147, 161, 161) !important;">6</span>
<span class="line-number" style="margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-variant: inherit; font-weight: inherit; line-height: inherit; font-family: inherit; vertical-align: baseline; color: rgb(147, 161, 161) !important;">7</span>
<span class="line-number" style="margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-variant: inherit; font-weight: inherit; line-height: inherit; font-family: inherit; vertical-align: baseline; color: rgb(147, 161, 161) !important;">8</span>
<span class="line-number" style="margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-variant: inherit; font-weight: inherit; line-height: inherit; font-family: inherit; vertical-align: baseline; color: rgb(147, 161, 161) !important;">9</span>
<span class="line-number" style="margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-variant: inherit; font-weight: inherit; line-height: inherit; font-family: inherit; vertical-align: baseline; color: rgb(147, 161, 161) !important;">10</span>
<span class="line-number" style="margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-variant: inherit; font-weight: inherit; line-height: inherit; font-family: inherit; vertical-align: baseline; color: rgb(147, 161, 161) !important;">11</span>
<span class="line-number" style="margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-variant: inherit; font-weight: inherit; line-height: inherit; font-family: inherit; vertical-align: baseline; color: rgb(147, 161, 161) !important;">12</span>
<span class="line-number" style="margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-variant: inherit; font-weight: inherit; line-height: inherit; font-family: inherit; vertical-align: baseline; color: rgb(147, 161, 161) !important;">13</span>
<span class="line-number" style="margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-variant: inherit; font-weight: inherit; line-height: inherit; font-family: inherit; vertical-align: baseline; color: rgb(147, 161, 161) !important;">14</span>
<span class="line-number" style="margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-variant: inherit; font-weight: inherit; line-height: inherit; font-family: inherit; vertical-align: baseline; color: rgb(147, 161, 161) !important;">15</span>
<span class="line-number" style="margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-variant: inherit; font-weight: inherit; line-height: inherit; font-family: inherit; vertical-align: baseline; color: rgb(147, 161, 161) !important;">16</span>
<span class="line-number" style="margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-variant: inherit; font-weight: inherit; line-height: inherit; font-family: inherit; vertical-align: baseline; color: rgb(147, 161, 161) !important;">17</span>
<span class="line-number" style="margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-variant: inherit; font-weight: inherit; line-height: inherit; font-family: inherit; vertical-align: baseline; color: rgb(147, 161, 161) !important;">18</span>
<span class="line-number" style="margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-variant: inherit; font-weight: inherit; line-height: inherit; font-family: inherit; vertical-align: baseline; color: rgb(147, 161, 161) !important;">19</span>
<span class="line-number" style="margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-variant: inherit; font-weight: inherit; line-height: inherit; font-family: inherit; vertical-align: baseline; color: rgb(147, 161, 161) !important;">20</span>
<span class="line-number" style="margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-variant: inherit; font-weight: inherit; line-height: inherit; font-family: inherit; vertical-align: baseline; color: rgb(147, 161, 161) !important;">21</span>
<span class="line-number" style="margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-variant: inherit; font-weight: inherit; line-height: inherit; font-family: inherit; vertical-align: baseline; color: rgb(147, 161, 161) !important;">22</span>
<span class="line-number" style="margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-variant: inherit; font-weight: inherit; line-height: inherit; font-family: inherit; vertical-align: baseline; color: rgb(147, 161, 161) !important;">23</span>
<span class="line-number" style="margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-variant: inherit; font-weight: inherit; line-height: inherit; font-family: inherit; vertical-align: baseline; color: rgb(147, 161, 161) !important;">24</span>
<span class="line-number" style="margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-variant: inherit; font-weight: inherit; line-height: inherit; font-family: inherit; vertical-align: baseline; color: rgb(147, 161, 161) !important;">25</span>
<span class="line-number" style="margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-variant: inherit; font-weight: inherit; line-height: inherit; font-family: inherit; vertical-align: baseline; color: rgb(147, 161, 161) !important;">26</span>
<span class="line-number" style="margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-variant: inherit; font-weight: inherit; line-height: inherit; font-family: inherit; vertical-align: baseline; color: rgb(147, 161, 161) !important;">27</span>
<span class="line-number" style="margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-variant: inherit; font-weight: inherit; line-height: inherit; font-family: inherit; vertical-align: baseline; color: rgb(147, 161, 161) !important;">28</span>
<span class="line-number" style="margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-variant: inherit; font-weight: inherit; line-height: inherit; font-family: inherit; vertical-align: baseline; color: rgb(147, 161, 161) !important;">29</span>
<span class="line-number" style="margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-variant: inherit; font-weight: inherit; line-height: inherit; font-family: inherit; vertical-align: baseline; color: rgb(147, 161, 161) !important;">30</span>
<span class="line-number" style="margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-variant: inherit; font-weight: inherit; line-height: inherit; font-family: inherit; vertical-align: baseline; color: rgb(147, 161, 161) !important;">31</span>
<span class="line-number" style="margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-variant: inherit; font-weight: inherit; line-height: inherit; font-family: inherit; vertical-align: baseline; color: rgb(147, 161, 161) !important;">32</span>
<span class="line-number" style="margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-variant: inherit; font-weight: inherit; line-height: inherit; font-family: inherit; vertical-align: baseline; color: rgb(147, 161, 161) !important;">33</span>
ACCESS_LOCATION_EXTRA_COMMANDS
ACCESS_NETWORK_STATE
ACCESS_NOTIFICATION_POLICY
ACCESS_WIFI_STATE
BLUETOOTH
BLUETOOTH_ADMIN
BROADCAST_STICKY
CHANGE_NETWORK_STATE
CHANGE_WIFI_MULTICAST_STATE
CHANGE_WIFI_STATE
DISABLE_KEYGUARD
EXPAND_STATUS_BAR
GET_PACKAGE_SIZE
INTERNET
KILL_BACKGROUND_PROCESSES
MODIFY_AUDIO_SETTINGS
NFC
READ_SYNC_SETTINGS
READ_SYNC_STATS
RECEIVE_BOOT_COMPLETED
REORDER_TASKS
REQUEST_INSTALL_PACKAGES
SET_TIME_ZONE
SET_WALLPAPER
SET_WALLPAPER_HINTS
TRANSMIT_IR
USE_FINGERPRINT
VIBRATE
WAKE_LOCK
WRITE_SYNC_SETTINGS
SET_ALARM
INSTALL_SHORTCUT
UNINSTALL_SHORTCUT

上述的权限基本设计的是关于网络,蓝牙,时区,快捷方式等方面,只要在Manifest指定了这些权限,就会被授予,并且不能撤销。

特殊权限

这里讲特殊权限提前讲一下,因为这个相对来说简单一些。

特殊权限,顾名思义,就是一些特别敏感的权限,在Android系统中,主要由两个

  • SYSTEM_ALERT_WINDOW,设置悬浮窗,进行一些黑科技
  • WRITE_SETTINGS 修改系统设置

关于上面两个特殊权限的授权,做法是使用startActivityForResult启动授权界面来完成。

请求SYSTEM_ALERT_WINDOW

<span class="line-number" style="margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-variant: inherit; font-weight: inherit; line-height: inherit; font-family: inherit; vertical-align: baseline; color: rgb(147, 161, 161) !important;">1</span>
<span class="line-number" style="margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-variant: inherit; font-weight: inherit; line-height: inherit; font-family: inherit; vertical-align: baseline; color: rgb(147, 161, 161) !important;">2</span>
<span class="line-number" style="margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-variant: inherit; font-weight: inherit; line-height: inherit; font-family: inherit; vertical-align: baseline; color: rgb(147, 161, 161) !important;">3</span>
<span class="line-number" style="margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-variant: inherit; font-weight: inherit; line-height: inherit; font-family: inherit; vertical-align: baseline; color: rgb(147, 161, 161) !important;">4</span>
<span class="line-number" style="margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-variant: inherit; font-weight: inherit; line-height: inherit; font-family: inherit; vertical-align: baseline; color: rgb(147, 161, 161) !important;">5</span>
<span class="line-number" style="margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-variant: inherit; font-weight: inherit; line-height: inherit; font-family: inherit; vertical-align: baseline; color: rgb(147, 161, 161) !important;">6</span>
<span class="line-number" style="margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-variant: inherit; font-weight: inherit; line-height: inherit; font-family: inherit; vertical-align: baseline; color: rgb(147, 161, 161) !important;">7</span>
<span class="line-number" style="margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-variant: inherit; font-weight: inherit; line-height: inherit; font-family: inherit; vertical-align: baseline; color: rgb(147, 161, 161) !important;">8</span>
<span class="line-number" style="margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-variant: inherit; font-weight: inherit; line-height: inherit; font-family: inherit; vertical-align: baseline; color: rgb(147, 161, 161) !important;">9</span>
<span class="line-number" style="margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-variant: inherit; font-weight: inherit; line-height: inherit; font-family: inherit; vertical-align: baseline; color: rgb(147, 161, 161) !important;">10</span>
<span class="line-number" style="margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-variant: inherit; font-weight: inherit; line-height: inherit; font-family: inherit; vertical-align: baseline; color: rgb(147, 161, 161) !important;">11</span>
<span class="line-number" style="margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-variant: inherit; font-weight: inherit; line-height: inherit; font-family: inherit; vertical-align: baseline; color: rgb(147, 161, 161) !important;">12</span>
<span class="line-number" style="margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-variant: inherit; font-weight: inherit; line-height: inherit; font-family: inherit; vertical-align: baseline; color: rgb(147, 161, 161) !important;">13</span>
<span class="line-number" style="margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-variant: inherit; font-weight: inherit; line-height: inherit; font-family: inherit; vertical-align: baseline; color: rgb(147, 161, 161) !important;">14</span>
<span class="line-number" style="margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-variant: inherit; font-weight: inherit; line-height: inherit; font-family: inherit; vertical-align: baseline; color: rgb(147, 161, 161) !important;">15</span>
<span class="line-number" style="margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-variant: inherit; font-weight: inherit; line-height: inherit; font-family: inherit; vertical-align: baseline; color: rgb(147, 161, 161) !important;">16</span>
private static final int REQUEST_CODE = 1;
private  void requestAlertWindowPermission() {
    Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION);
    intent.setData(Uri.parse("package:" + getPackageName()));
    startActivityForResult(intent, REQUEST_CODE);
}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if (requestCode == REQUEST_CODE) {
        if (Settings.canDrawOverlays(this)) {
          Log.i(LOGTAG, "onActivityResult granted");
        }
    }
}

上述代码需要注意的是

  • 使用Action Settings.ACTION_MANAGE_OVERLAY_PERMISSION启动隐式Intent
  • 使用"package:" + getPackageName()携带App的包名信息
  • 使用Settings.canDrawOverlays方法判断授权结果

请求

WRITE_SETTINGS

<span class="line-number" style="margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-variant: inherit; font-weight: inherit; line-height: inherit; font-family: inherit; vertical-align: baseline; color: rgb(147, 161, 161) !important;">1</span>
<span class="line-number" style="margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-variant: inherit; font-weight: inherit; line-height: inherit; font-family: inherit; vertical-align: baseline; color: rgb(147, 161, 161) !important;">2</span>
<span class="line-number" style="margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-variant: inherit; font-weight: inherit; line-height: inherit; font-family: inherit; vertical-align: baseline; color: rgb(147, 161, 161) !important;">3</span>
<span class="line-number" style="margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-variant: inherit; font-weight: inherit; line-height: inherit; font-family: inherit; vertical-align: baseline; color: rgb(147, 161, 161) !important;">4</span>
<span class="line-number" style="margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-variant: inherit; font-weight: inherit; line-height: inherit; font-family: inherit; vertical-align: baseline; color: rgb(147, 161, 161) !important;">5</span>
<span class="line-number" style="margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-variant: inherit; font-weight: inherit; line-height: inherit; font-family: inherit; vertical-align: baseline; color: rgb(147, 161, 161) !important;">6</span>
<span class="line-number" style="margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-variant: inherit; font-weight: inherit; line-height: inherit; font-family: inherit; vertical-align: baseline; color: rgb(147, 161, 161) !important;">7</span>
<span class="line-number" style="margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-variant: inherit; font-weight: inherit; line-height: inherit; font-family: inherit; vertical-align: baseline; color: rgb(147, 161, 161) !important;">8</span>
<span class="line-number" style="margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-variant: inherit; font-weight: inherit; line-height: inherit; font-family: inherit; vertical-align: baseline; color: rgb(147, 161, 161) !important;">9</span>
<span class="line-number" style="margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-variant: inherit; font-weight: inherit; line-height: inherit; font-family: inherit; vertical-align: baseline; color: rgb(147, 161, 161) !important;">10</span>
<span class="line-number" style="margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-variant: inherit; font-weight: inherit; line-height: inherit; font-family: inherit; vertical-align: baseline; color: rgb(147, 161, 161) !important;">11</span>
<span class="line-number" style="margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-variant: inherit; font-weight: inherit; line-height: inherit; font-family: inherit; vertical-align: baseline; color: rgb(147, 161, 161) !important;">12</span>
<span class="line-number" style="margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-variant: inherit; font-weight: inherit; line-height: inherit; font-family: inherit; vertical-align: baseline; color: rgb(147, 161, 161) !important;">13</span>
<span class="line-number" style="margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-variant: inherit; font-weight: inherit; line-height: inherit; font-family: inherit; vertical-align: baseline; color: rgb(147, 161, 161) !important;">14</span>
<span class="line-number" style="margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-variant: inherit; font-weight: inherit; line-height: inherit; font-family: inherit; vertical-align: baseline; color: rgb(147, 161, 161) !important;">15</span>
private static final int REQUEST_CODE_WRITE_SETTINGS = 2;
private void requestWriteSettings() {
    Intent intent = new Intent(Settings.ACTION_MANAGE_WRITE_SETTINGS);
    intent.setData(Uri.parse("package:" + getPackageName()));
    startActivityForResult(intent, REQUEST_CODE_WRITE_SETTINGS );
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if (requestCode == REQUEST_CODE_WRITE_SETTINGS) {
        if (Settings.System.canWrite(this)) {
            Log.i(LOGTAG, "onActivityResult write settings granted" );
        }
    }
}

上述代码需要注意的是

  • 使用Action Settings.ACTION_MANAGE_WRITE_SETTINGS 启动隐式Intent
  • 使用"package:" + getPackageName()携带App的包名信息
  • 使用Settings.System.canWrite方法检测授权结果

注意:关于这两个特殊权限,一般不建议应用申请。

网上搜索得知当编译版本>=6.0 且运行在>=6.0的版本上 WRITE_SETTINGS权限无法获取即便运行上诉代码运行,除非将APP作为预装应用或者使用系统签名  

危险权限

危险权限实际上才是运行时权限主要处理的对象,这些权限可能引起隐私问题或者影响其他程序运行。Android中的危险权限可以归为以下几个分组:

  • CALENDAR
  • CAMERA
  • CONTACTS
  • LOCATION
  • MICROPHONE
  • PHONE
  • SENSORS
  • SMS
  • STORAGE

各个权限分组与其具体的权限,可以参考下图:

Permission Groups and detailed permissions

必须要支持运行时权限么

目前应用实际上是可以不需要支持运行时权限的,但是最终肯定还是需要支持的,只是时间问题而已。

想要不支持运行时权限机制很简单,只需要将targetSdkVersion设置低于23就可以了,意思是告诉系统,我还没有完全在API 23(6.0)上完全搞定,不要给我启动新的特性。

不支持运行时权限会崩溃么

可能会,但不是那种一上来就噼里啪啦崩溃不断的那种。

如果你的应用将targetSdkVersion设置低于23,那么在6.0的系统上不会为这个应用开启运行时权限机制,即按照以前的一刀切方式处理。

然而有点糟糕的是

6.0系统提供了一个应用权限管理界面,界面长得是这样的

既然是可以管理,用户就能取消权限,当一个不支持运行时权限的应用某项权限被取消时

系统会弹出一个对话框提醒撤销的危害,如果用户执意撤销,会带来如下的反应

  • 如果你的程序正在运行,则会被杀掉。
  • 当你的应用再次运行时,可能出现崩溃

为什么会可能崩溃的,比如下面这段代码

<span class="line-number" style="margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-variant: inherit; font-weight: inherit; line-height: inherit; font-family: inherit; vertical-align: baseline; color: rgb(147, 161, 161) !important;">1</span>
<span class="line-number" style="margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-variant: inherit; font-weight: inherit; line-height: inherit; font-family: inherit; vertical-align: baseline; color: rgb(147, 161, 161) !important;">2</span>
<span class="line-number" style="margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-variant: inherit; font-weight: inherit; line-height: inherit; font-family: inherit; vertical-align: baseline; color: rgb(147, 161, 161) !important;">3</span>
<span class="line-number" style="margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-variant: inherit; font-weight: inherit; line-height: inherit; font-family: inherit; vertical-align: baseline; color: rgb(147, 161, 161) !important;">4</span>
<span class="line-number" style="margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-variant: inherit; font-weight: inherit; line-height: inherit; font-family: inherit; vertical-align: baseline; color: rgb(147, 161, 161) !important;">5</span>
TelephonyManager telephonyManager = (TelephonyManager)getSystemService(Context.TELEPHONY_SERVICE);
String deviceId = telephonyManager.getDeviceId();
if (deviceId.equals(mLastDeviceId)) {//This may cause NPE
  //do something
}

如果用户撤消了获取DeviceId的权限,那么再次运行时,deviceId就是null,如果程序后续处理不当,就会出现崩溃。

该来的还得来

6.0的运行时权限,我们最终都是要支持的,通常我们需要使用如下的API

  • int checkSelfPermission(String permission) 用来检测应用是否已经具有权限
  • void requestPermissions(String[] permissions, int requestCode) 进行请求单个或多个权限
  • void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) 用户对请求作出响应后的回调

以一个请求Camera权限为例

<span class="line-number" style="margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-variant: inherit; font-weight: inherit; line-height: inherit; font-family: inherit; vertical-align: baseline; color: rgb(147, 161, 161) !important;">1</span>
<span class="line-number" style="margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-variant: inherit; font-weight: inherit; line-height: inherit; font-family: inherit; vertical-align: baseline; color: rgb(147, 161, 161) !important;">2</span>
<span class="line-number" style="margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-variant: inherit; font-weight: inherit; line-height: inherit; font-family: inherit; vertical-align: baseline; color: rgb(147, 161, 161) !important;">3</span>
<span class="line-number" style="margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-variant: inherit; font-weight: inherit; line-height: inherit; font-family: inherit; vertical-align: baseline; color: rgb(147, 161, 161) !important;">4</span>
<span class="line-number" style="margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-variant: inherit; font-weight: inherit; line-height: inherit; font-family: inherit; vertical-align: baseline; color: rgb(147, 161, 161) !important;">5</span>
<span class="line-number" style="margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-variant: inherit; font-weight: inherit; line-height: inherit; font-family: inherit; vertical-align: baseline; color: rgb(147, 161, 161) !important;">6</span>
<span class="line-number" style="margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-variant: inherit; font-weight: inherit; line-height: inherit; font-family: inherit; vertical-align: baseline; color: rgb(147, 161, 161) !important;">7</span>
<span class="line-number" style="margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-variant: inherit; font-weight: inherit; line-height: inherit; font-family: inherit; vertical-align: baseline; color: rgb(147, 161, 161) !important;">8</span>
<span class="line-number" style="margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-variant: inherit; font-weight: inherit; line-height: inherit; font-family: inherit; vertical-align: baseline; color: rgb(147, 161, 161) !important;">9</span>
<span class="line-number" style="margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-variant: inherit; font-weight: inherit; line-height: inherit; font-family: inherit; vertical-align: baseline; color: rgb(147, 161, 161) !important;">10</span>
<span class="line-number" style="margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-variant: inherit; font-weight: inherit; line-height: inherit; font-family: inherit; vertical-align: baseline; color: rgb(147, 161, 161) !important;">11</span>
<span class="line-number" style="margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-variant: inherit; font-weight: inherit; line-height: inherit; font-family: inherit; vertical-align: baseline; color: rgb(147, 161, 161) !important;">12</span>
<span class="line-number" style="margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-variant: inherit; font-weight: inherit; line-height: inherit; font-family: inherit; vertical-align: baseline; color: rgb(147, 161, 161) !important;">13</span>
<span class="line-number" style="margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-variant: inherit; font-weight: inherit; line-height: inherit; font-family: inherit; vertical-align: baseline; color: rgb(147, 161, 161) !important;">14</span>
<span class="line-number" style="margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-variant: inherit; font-weight: inherit; line-height: inherit; font-family: inherit; vertical-align: baseline; color: rgb(147, 161, 161) !important;">15</span>
<span class="line-number" style="margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-variant: inherit; font-weight: inherit; line-height: inherit; font-family: inherit; vertical-align: baseline; color: rgb(147, 161, 161) !important;">16</span>
<span class="line-number" style="margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-variant: inherit; font-weight: inherit; line-height: inherit; font-family: inherit; vertical-align: baseline; color: rgb(147, 161, 161) !important;">17</span>
<span class="line-number" style="margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-variant: inherit; font-weight: inherit; line-height: inherit; font-family: inherit; vertical-align: baseline; color: rgb(147, 161, 161) !important;">18</span>
<span class="line-number" style="margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-variant: inherit; font-weight: inherit; line-height: inherit; font-family: inherit; vertical-align: baseline; color: rgb(147, 161, 161) !important;">19</span>
<span class="line-number" style="margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-variant: inherit; font-weight: inherit; line-height: inherit; font-family: inherit; vertical-align: baseline; color: rgb(147, 161, 161) !important;">20</span>
<span class="line-number" style="margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-variant: inherit; font-weight: inherit; line-height: inherit; font-family: inherit; vertical-align: baseline; color: rgb(147, 161, 161) !important;">21</span>
@Override
public void onClick(View v) {
    if (!(checkSelfPermission(Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED)) {
        requestCameraPermission();
    }
}

private static final int REQUEST_PERMISSION_CAMERA_CODE = 1;
private void requestCameraPermission() {
    requestPermissions(new String[]{Manifest.permission.CAMERA}, REQUEST_PERMISSION_CAMERA_CODE);
}

@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
    super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    if (requestCode == REQUEST_PERMISSION_CAMERA_CODE) {
        int grantResult = grantResults[0];
        boolean granted = grantResult == PackageManager.PERMISSION_GRANTED;
        Log.i(LOGTAG, "onRequestPermissionsResult granted=" + granted);
    }
}

通常情况下,我们会得到这样的一个对话框

当用户选择允许,我们就可以在onRequestPermissionsResult方法中进行响应的处理,比如打开摄像头
当用户拒绝,你的应用可能就开始危险了

当我们再次尝试申请权限时,弹出的对话框和之前有点不一样了,主要表现为多了一个checkbox。如下图

当用户勾选了”不再询问“拒绝后,你的程序基本这个权限就Game Over了。

不过,你还有一丝希望,那就是再出现上述的对话框之前做一些说明信息,比如你使用这个权限的目的(一定要坦白)。

shouldShowRequestPermissionRationale这个API可以帮我们判断接下来的对话框是否包含”不再询问“选择框。

一个标准的流程

<span class="line-number" style="margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-variant: inherit; font-weight: inherit; line-height: inherit; font-family: inherit; vertical-align: baseline; color: rgb(147, 161, 161) !important;">1</span>
<span class="line-number" style="margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-variant: inherit; font-weight: inherit; line-height: inherit; font-family: inherit; vertical-align: baseline; color: rgb(147, 161, 161) !important;">2</span>
<span class="line-number" style="margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-variant: inherit; font-weight: inherit; line-height: inherit; font-family: inherit; vertical-align: baseline; color: rgb(147, 161, 161) !important;">3</span>
<span class="line-number" style="margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-variant: inherit; font-weight: inherit; line-height: inherit; font-family: inherit; vertical-align: baseline; color: rgb(147, 161, 161) !important;">4</span>
<span class="line-number" style="margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-variant: inherit; font-weight: inherit; line-height: inherit; font-family: inherit; vertical-align: baseline; color: rgb(147, 161, 161) !important;">5</span>
<span class="line-number" style="margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-variant: inherit; font-weight: inherit; line-height: inherit; font-family: inherit; vertical-align: baseline; color: rgb(147, 161, 161) !important;">6</span>
<span class="line-number" style="margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-variant: inherit; font-weight: inherit; line-height: inherit; font-family: inherit; vertical-align: baseline; color: rgb(147, 161, 161) !important;">7</span>
<span class="line-number" style="margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-variant: inherit; font-weight: inherit; line-height: inherit; font-family: inherit; vertical-align: baseline; color: rgb(147, 161, 161) !important;">8</span>
if (!(checkSelfPermission(Manifest.permission.READ_CONTACTS) == PackageManager.PERMISSION_GRANTED)) {
  if (shouldShowRequestPermissionRationale(Manifest.permission.READ_CONTACTS)) {
      Toast.makeText(this, "Please grant the permission this time", Toast.LENGTH_LONG).show();
    }
    requestReadContactsPermission();
} else {
  Log.i(LOGTAG, "onClick granted");
}

如何批量申请

批量申请权限很简单,只需要字符串数组放置多个权限即可。如请求代码

<span class="line-number" style="margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-variant: inherit; font-weight: inherit; line-height: inherit; font-family: inherit; vertical-align: baseline; color: rgb(147, 161, 161) !important;">1</span>
<span class="line-number" style="margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-variant: inherit; font-weight: inherit; line-height: inherit; font-family: inherit; vertical-align: baseline; color: rgb(147, 161, 161) !important;">2</span>
<span class="line-number" style="margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-variant: inherit; font-weight: inherit; line-height: inherit; font-family: inherit; vertical-align: baseline; color: rgb(147, 161, 161) !important;">3</span>
<span class="line-number" style="margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-variant: inherit; font-weight: inherit; line-height: inherit; font-family: inherit; vertical-align: baseline; color: rgb(147, 161, 161) !important;">4</span>
<span class="line-number" style="margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-variant: inherit; font-weight: inherit; line-height: inherit; font-family: inherit; vertical-align: baseline; color: rgb(147, 161, 161) !important;">5</span>
private static final int REQUEST_CODE = 1;
private void requestMultiplePermissions() {
    String[] permissions = {Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.READ_PHONE_STATE};
    requestPermissions(permissions, REQUEST_CODE);
}

对应的界面效果是 Multiple Requesting Permissions

注意:间隔较短的多个权限申请建议设置成单次多个权限申请形式,避免弹出多个对话框,造成不太好的视觉效果。

申请这么多权限岂不是很累

其实你不需要每个权限都去显式申请,举一个例子,如果你的应用授权了读取联系人的权限,那么你的应用也是被赋予了写入联系人的权限。因为读取联系人和写入联系人这两个权限都属于联系人权限分组,所以一旦组内某个权限被允许,该组的其他权限也是被允许的。

注意事项

API问题

由于checkSelfPermission和requestPermissions从API 23才加入,低于23版本,需要在运行时判断 或者使用Support Library v4中提供的方法

  • ContextCompat.checkSelfPermission
  • ActivityCompat.requestPermissions
  • ActivityCompat.shouldShowRequestPermissionRationale

多系统问题

当我们支持了6.0必须也要支持4.4,5.0这些系统,所以需要在很多情况下,需要有两套处理。比如Camera权限

<span class="line-number" style="margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-variant: inherit; font-weight: inherit; line-height: inherit; font-family: inherit; vertical-align: baseline; color: rgb(147, 161, 161) !important;">1</span>
<span class="line-number" style="margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-variant: inherit; font-weight: inherit; line-height: inherit; font-family: inherit; vertical-align: baseline; color: rgb(147, 161, 161) !important;">2</span>
<span class="line-number" style="margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-variant: inherit; font-weight: inherit; line-height: inherit; font-family: inherit; vertical-align: baseline; color: rgb(147, 161, 161) !important;">3</span>
<span class="line-number" style="margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-variant: inherit; font-weight: inherit; line-height: inherit; font-family: inherit; vertical-align: baseline; color: rgb(147, 161, 161) !important;">4</span>
<span class="line-number" style="margin: 0px; padding: 0px; border: 0px; font-style: inherit; font-variant: inherit; font-weight: inherit; line-height: inherit; font-family: inherit; vertical-align: baseline; color: rgb(147, 161, 161) !important;">5</span>
if (isMarshmallow()) {
    requestPermission();//然后在回调中处理
} else {
    useCamera();//低于6.0直接使用Camera
}

两个权限

运行时权限对于应用影响比较大的权限有两个,他们分别是

  • READ_PHONE_STATE
  • WRITE_EXTERNAL_STORAGE/READ_EXTERNAL_STORAGE

其中READ_PHONE_STATE用来获取deviceID,即IMEI号码。这是很多统计依赖计算设备唯一ID的参考。如果新的权限导致读取不到,避免导致统计的异常。建议在完全支持运行时权限之前,将对应的值写入到App本地数据中,对于新安装的,可以采取其他策略减少对统计的影响。

WRITE_EXTERNAL_STORAGE/READ_EXTERNAL_STORAGE这两个权限和外置存储(即sdcard)有关,对于下载相关的应用这一点还是比较重要的,我们应该尽可能的说明和引导用户授予该权限。

些许建议

  • 不要使用多余的权限,新增权限时要慎重
  • 使用Intent来替代某些权限,如拨打电话(和你的产品经理PK去吧)
  • 对于使用权限获取的某些值,比如deviceId,尽量本地存储,下次访问直接使用本地的数据值
  • 注意,由于用户可以撤销某些权限,所以不要使用应用本地的标志位来记录是否获取到某权限。

注意

即使支持了运行时权限,也要在Manifest声明,因为市场应用会根据这个信息和硬件设备进行匹配,决定你的应用是否在该设备上显示。

是否支持运行时权限

个人觉得Marshmallow的运行时权限对于用户来说绝对是一个好东西,但是目前想要支持需要做的事情还是比较多的。

对于一个有很多依赖的宿主应用,想要做到支持还是有一些工作量的,因为你的权限申请受制于依赖。

建议在短期内暂时可以不考虑支持该运行时权限机制,等时机成熟或者简单易用的第三方库完善之后再支持也未尝不可。


Android 11.0 根据包名授予读取IMEI权限 在11.0的产品开发中,对于读取设备的imei sn号功能也是常有的,而在10.0以后对于读取imei也是受权限要求越来越多了一般的app是读取不到这个权限了,根据产品需求需要读取这个权限,所以需要在系统中对这个app授权让它读取包名,从而实现功能。 阅读详情

相关推荐

SAP 对接CBS(http方式)

CLEAR:lv_xml_crc32_string. CONCATENATEcrc32_passwordcrc32_keyi_stringINTOlv_xml_crc32_string. CONDENSElv_xml_crc32_string. CALLFUNCTION'SCMS_STRING_TO_XSTRING' EXPORTING text=lv_xml_crc32_string encoding='8400' "GB...

3598

聊一聊Android 6.0的运行时权限

聊一聊Android 6.0的运行时权限 JAN 17TH, 2016 Android 6.0,代号棉花糖,自发布伊始,其主要的特征运行时权限就很受关注。因为这一特征不仅改善了用户对于应用的使用体验,还使得应用开发者在实践开发中需要做出改变。 没有深入了解运行时权限的开发者通常会有很多疑问,比如什么是运行时权限,哪些是运行时的权限,我的应用是不是会在6.0系统上各种崩溃呢,如

wed110的专栏 915

用OpenCV+ROS实现焊接机器人智能纠偏:线激光视觉的算法调参全流程

本文详细介绍了基于OpenCV和ROS的焊接机器人智能纠偏系统全流程。通过线激光视觉系统实时感知焊缝,重点解析了抗干扰图像预处理、改进的Steger算法提取激光条纹中心线,以及从2D像素到机器人基坐标系的完整坐标变换。该系统为应对焊接飞溅、弧光等复杂工况,实现高精度实时路径纠偏提供了从算法优化到工程集成的完整解决方案。

vodka的博客 159

android申请权限一次性申请多个,Android 批量申请权限

Android开发时,到6.0系统上之后,有的权限就得申请才能用了。Android将权限分为正常权限 和 危险权限详细可参考: (https://www.cnblogs.com/liuzhipenglove/p/7102692.html)网上也有很多参考例子,我这里总结下我的理解和用法我们知道在Android6.0(SDK等级是23)以后有些权限是需要动态申请的然后这里主要记录下如何同时动态申请多...

weixin_42425334的博客 1816

手把手教你用Kali Linux搭建vulntarget-a靶场环境(附详细配置步骤)

本文详细介绍了如何在Kali Linux环境下搭建vulntarget漏洞靶场,包括环境规划、虚拟化平台配置、靶机系统部署及安全工具链配置等关键步骤。通过实战演练,帮助网络安全从业者和初学者掌握专业级漏洞实验平台的搭建与管理技巧,提升安全测试能力。

weixin_29279101的博客 107

Intent常用Uri,打开相应的应用

一些常用的Uri   显示网页:   1. Uri uri = Uri.parse("http://www.google.com");   2. Intent it = new Intent(Intent.ACTION_VIEW,uri);   3. startActivity(it); 显示地图: 1. Uri uri = Uri.parse("geo:38.89953

黑色的记忆 chester, come on 1618

mpv 源码深度解析:从 MPlayer 遗产到现代媒体播放器架构

做减法优于做加法:不值得维护的功能就移除(DVD 菜单、流缓存等)单线程事件驱动:核心逻辑在单线程中运行,通过 dispatch 队列处理并发分离关注点:demuxer 线程、VO 线程、脚本线程各司其职质量优先:使用 GPU 着色器而非固定功能硬件,默认软件解码(更可靠)可嵌入性:libmpv API 让 mpv 可以作为库嵌入其他应用mpv 是一个用纯 C 实现的、工程质量极高的媒体播放器。它的代码库展示了一个事实:C 语言完全可以通过良好的架构设计来实现复杂的多媒体系统。

世界那么大,我想去看看~【随心更新,看世界去了😄】 90

Android权限批量申请

Android权限批量申请指南 在Android开发中,权限是一个非常重要的概念。随着Android版本的演进,特别是Android 6.0 (API 23) 后,我们需要在运行时动态申请权限,而不是仅仅在安装时声明。本文将带你了解Android权限的批量申请过程。 权限申请流程 以下是申请权限的基本步骤: 步骤 描...

weixin_40395547的博客 474

Spring AI 实战:第七章、Spring AI Advisor机制之记忆大师

从金鱼到最强大脑通过 Spring AI 的记忆功能,我们成功让 AI:记住了用户身份实现了多用户隔离做到了持久化存储最终效果用户:“和上次一样” → AI 秒懂用户:“你知道我的名字吗?” → AI:“当然,张三!AI的进化路线🐟金鱼脑 →🧠最强大脑 →🏛️记忆宫殿管理员。

liaokailin的专栏 1516

最小二乘拟合圆:使用拉格朗日乘子法

在本文中,我们将探讨如何使用拉格朗日乘子法来进行最小二乘拟合,并将其应用于拟合一个空间圆。首先,我们需要定义问题。给定一组二维或三维数据点,我们的目标是找到一个圆,使得这些数据点到圆的距离的平方和最小。为了找到最小值,我们需要计算拉格朗日函数的偏导数,并令其等于零。通过解决优化问题,我们可以找到最佳拟合的圆,以最小化数据点到圆的距离的平方和。其中,(x, y) 是圆心的坐标,r 是圆的半径,(xi, yi) 是数据点的坐标。其中,g(x, y, r) = 0 是约束条件,C 是常数,λ 是拉格朗日乘子。

TechProX的博客 475

聊一聊 Android 6.0 的运行时权限

聊一聊 Android 6.0 的运行时权限 权限一刀切 棉花糖运行时权限 权限的分组 正常权限 正常权限列表 特殊权限 请求SYSTEM_ALERT_WINDOW 请求WRITE_SETTINGS 危险权限 必须要支持运行时权限么 不支持运行时权限会崩溃么 然而有点糟糕的是 该来的还得来 一个标准的流程 如何批量申请 申请这么多权限岂不是很累 注意事项 API问题 ...

weixin_33834628的博客 85

从入门到精通|Yalmip+Cplex在电力系统中的应用(Matlab代码实现)

​ 火电成本包括运行成本、碳捕集成本,其中火电运行成本由运行维护成 本和发电煤耗成本构成,发电煤耗与其出力关系: ,F 为机组煤耗量(kg/h),P 为机组出力/MW;运行维护成本按照 0.5 倍煤耗成本考虑,碳捕集成本取决于碳排放量及碳捕集单价,火电机组相关参数如附表 1 所示,电煤价格为 700 元/t ​

weixin_46039719的博客 1553

android 6.0权限

聊一聊 Android 6.0 的运行时权限 权限一刀切棉花糖运行时权限权限的分组正常权限 正常权限列表 特殊权限 请求SYSTEM_ALERT_WINDOW请求WRITE_SETTINGS 危险权限必须要支持运行时权限么不支持运行时权限会崩溃么 然而有点糟糕的是 该来的还得来 一个标准的流程如何批量申请申请这么多权限岂不是很累 注意事项 A

ou775968876的博客 278

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

Android动态运行时权限

android 6.0(API 级别 23)开始,android引入了运行时权限,应用安装时不向其授予权限,应用运行时向其授予权限。如果在运行时该功能没有动态地申请相应的权限,就会抛出SecurityException异常。android的运行时权限的申请过程主要有两步:1、在需要申请权限的地方检查该权限是否被授权,如果已经授权就直接执行,如果未授权就动态申请权限。

且听真言 3240

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

Android 6.0动态权限申请--事例代码

Android 6.0之后,为了保护用户隐私,将一些权限的申请放在了应用运行的时候去申请。并且,Android 6.0之后,将权限分为普通权限和特殊权限。 可以这样理解,Android 6.0之前,所有的权限都是普通权限,只要用户在安装时确认权限即可。Android 6.0之后,有部分权限变为特殊权限,需要应用运行时动态申请。 这里给出项目中写的模版代码。模版代码的目的为:动态申请多个

afunx的专栏 589

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

android 6.0 权限处理,Android 6.0 权限处理

Android 6.0 权限处理1.问题描述使用PandaAndroidLibs库时,在MainApplication初始化存储数据配置时AppDirConfiguration.configure(getApplicationContext());用到手机存储权限,如果权限未开启,则导致App崩溃。在手机上相机权限被拒绝,打开相机,出现程序崩溃的现象。2.问题原因Android M(版本号6.0 ...

weixin_39613561的博客 289

android+6.0+验证机制,android 6.0权限申请机制(简单案例)

android 6.0更新了全新的权限机制,在使用一些涉及用户隐私的权限时,会让用户做出选择是否该app可以使用此权限。在查看本文章之前,希望大家可以移步官方开发文档 使用权限。在该文章中,详细描述了新版本的权限机制的更改,声明权限未发生改变,需要详细观看在运行时请求权限,查看权限最佳做法可以避免糟糕的用户体验。在权限中,分为Normal Permissions和Dangerous Permiss...

weixin_34998865的博客 317

权限列表

android6.0以上在代码中再次申请权限 方式1: //==================app权限配置======================= //创建权限容器 public static Set<String> permissionSet = new HashSet<String>(); static { //内存读权限 permissionSet.add(Manifest.permission.READ_EX.

s337946745的博客 252

XXPermissions框架深度解析:Android权限管理的终极解决方案

在Android应用开发中,权限管理一直是开发者面临的重要挑战。随着Android系统版本的迭代,权限机制不断变化,从Android 6.0的运行时权限到Android 11的分区存储,再到Android 13的通知权限,每一次系统更新都带来了新的适配要求。XXPermissions框架作为一个全面、稳定、易用的Android权限管理库,为开发者提供了一套完整的权限适配解决方案,支持Android

gitblog_00632的博客 461

MonoGame Android权限处理终极指南:文件访问与硬件特性检测完全教程

想要在Android平台上开发出色的跨平台游戏吗?MonoGame作为强大的游戏开发框架,为Android游戏开发提供了完整的解决方案。本文将为您详细解析MonoGame在Android平台上的权限处理机制和硬件特性检测方法,帮助您轻松应对Android开发的挑战!🎮 ## 为什么Android权限管理如此重要? 在Android平台上开发游戏时,权限管理是确保用户体验和安全性的关键环节。M

gitblog_01054的博客 790

【Android】6.0运行时权限申请工具

功能: 支持获取单个权限、多个权限(List的方式传入) 当权限被拒绝时,会返回被拒绝的权限名称 使用方法: 1、需要使用的权限一定要记得先在"AndroidManifest.xml"中先声明,否则可能无法执行获取权限的动作! 2、在需要申请权限的地方new 工具对象,并将需要申请的权限用List的方式传入,然后一定要设定监听器,才会执行获取权限的动...

大东的博客 693

Android-6.0权限批量检查申请

Android-6.0权限申请 Android6.0之后需要动态进行申请权限,下面记录一下,简单的申请批量权限的方法。 在Activity中调用检查权限的方法,并重现权限申请结果回调。 @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(saved...

dream_xang的博客 406

快速申请Android6.0权限教程!

快速入门授权Android6.0权限教程! Android6.0权限申请 前言: Android6.0权限申请在网上虽然一搜一大堆,但是都写的太多太臃肿,而往往学习者都只是想快速去申请到6.0权限,而不是去了解它的由来,它的原因。今天,我就带给大家最简单的方式,简单到你只需要记住代码,复制拿来用就可以了。 1先了解一下,哪些权限在6.0以后是需要动态申请的 需要动态申

FynnJason的技术屋 1587
上一篇: com/android/build/ gradle/ Appplugin :unsupported major.minor version 52.0
下一篇: googlePlay 内购测试
cheating_man
博客等级 码龄11年 5粉丝 2原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值