Android不使用支持库请求运行时权限

本文详细介绍了如何在 Android 6.0 及以上版本中实现运行时权限请求流程,包括声明权限、检查权限状态、请求权限及处理用户授权结果等关键步骤。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Android 6.0后,用户开始在应用运行时向其授予权限,而不是在应用安装时授予。Android官网上也有相关教程:在运行时请求权限。但教程是使用支持库来举例的,用支持库的话,APK的大小也会变得很大,实际上,不使用支持库来请求权限也不难。

下面以请求写储存权限来举例。

一、声明权限

必需要在AndriodManifest.xml文件中声明权限,才能申请使用权限。

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

二、检查权限

如果您的应用需要危险权限,则每次执行需要这一权限的操作时您都必须检查自己是否具有该权限,如果用户之前有授予权限,刚会一直具有该权限,除非用户手动在设置中关闭它。这里可以直接调用context对象中的checkPermission()方法来进行是否有某一项权限的检查,如果具有该权限则返回true,因此我们可以直接调用Activity中的checkPermission()方法。具体代码如下:

private boolean doCheckPermission(String permission) {
        //检查权限
        int permissionCheck = checkPermission(permission, Process.myPid(), Process.myUid());
        if (permissionCheck == PackageManager.PERMISSION_GRANTED) {
            return true;
        }
        return false;
    }

checkPermission()方法有三个参数,参数的说明如下:

  • String permission:

    要检查的权限名称,如:Manifest.permission.WRITE_EXTERNAL_STORAGE。

  • int pid

    进程ID,可以通过Process.myPid()方法获取。

  • int uid

    用户ID,这个可以通过Process.myUid()方法获取。

三、请求权限

检查完权限后,如果具有该权限,则可以直接运行依赖该权限的代码,如果没有该权限则需要申请该权限。可以调用Activity中的requestPermissions()方法来请求权限,具体代码如下:

private final int MY_WRITE_REQUEST_CODE = 0;

private void doRequestPermission(String permission) {
    if (Build.VERSION.SDK_INT >= 23) {
        //requestPermissions()方法需要SDK23
        requestPermissions(new String[]{permission}, MY_WRITE_REQUEST_CODE);
       }
}

requestPermissions()方法有两个参数:

  • String[] permissions

    要申请的多个权限。

  • int requestCode

    请求代码,用于处理请求时,唯一识别这个请求,在下面的处理请求模块要用到。

使用requestPermissions()请求权限时,需要注意的是:这个方法的调用是异步的,它会立即返回,并且在用户响应对话框之后,系统会使用结果调用应用的回调方法。也就是说,调用这个方法后,会继续执行接下来的语句,所以不能在这个方法后马上执行依赖该权限的代码。而是要等到用户授权后,系统自动调用相应的回调方法,在回调方法(下面介绍)中处理依赖该权限的代码。

四、处理权限请求响应

我们需要重写Activity中的onRequestPermissionsResult()方法来处理请求的结果。当用户允许或者拒绝该权限时,系统会调用Activity中的onRequestPermissionsResult()方法。具体的代码处理如下:

    @Override
    public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
        switch (requestCode) {
            case MY_WRITE_REQUEST_CODE:
                // If request is cancelled, the result arrays are empty.
                if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                    Log.d(TAG, "onRequestPermissionsResult: request write permission success!");
                    //处理依赖权限的代码
                } else {
                    Log.d(TAG, "onRequestPermissionsResult: request write permission fail!");
                    //请求失败,没有权限,不能运行依赖权限的代码
                }
                break;
        }
    }

这个方法中的requestCode就是上面请求权限时的请求代码,在上面的例子中,该请求代码为MY_WRITE_REQUEST_CODE。可以看到,这里用switch语句来接收请求代码来区分不同的权限请求,然后进行相应的处理。

到这里,完整的检查权限、请求权限和处理请求的流程都介绍完了,下面是完整的Demo。

例子程序

AndriodManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.permissionnosupport">

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

    <application android:allowBackup="true" android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name" android:supportsRtl="true" android:theme="@style/AppTheme">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

MainActivity.java

package com.example.permissionnosupport;

import android.Manifest;
import android.app.Activity;
import android.content.pm.PackageManager;
import android.os.Build;
import android.os.Bundle;
import android.os.Process;
import android.util.Log;


public class MainActivity extends Activity {

    private final String TAG = "test";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        if (doCheckPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
            Log.d(TAG, "onCreate: 应用具有写外部存储的权限");
            //进行依赖权限的代码
        } else {
            Log.d(TAG, "onCreate: 应用不具有写外部存储的权限");
            doRequestPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE);
        }
    }


    private boolean doCheckPermission(String permission) {
        int permissionCheck = checkPermission(permission, Process.myPid(), Process.myUid());
        if (permissionCheck == PackageManager.PERMISSION_GRANTED) {
            return true;
        }
        return false;
    }

    private final int MY_WRITE_REQUEST_CODE = 0;

    private void doRequestPermission(String permission) {
        if (Build.VERSION.SDK_INT >= 23) {
            //requestPermissions()方法需要SDK23
            requestPermissions(new String[]{permission}, MY_WRITE_REQUEST_CODE);
        }
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
        switch (requestCode) {
            case MY_WRITE_REQUEST_CODE:
                // If request is cancelled, the result arrays are empty.
                if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                    Log.d(TAG, "onRequestPermissionsResult: request write permission success!");
                    //处理依赖权限的代码
                } else {
                    Log.d(TAG, "onRequestPermissionsResult: request write permission fail!");
                    //请求失败,没有权限,不能运行依赖权限的代码
                }
                break;
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值