如何利用无UI的Fragment实现动态权限申请

1.关于危险权限

总所周知Android6.0及以上涉及到危险权限需要动态权限申请。
那么那些权限是危险权限呢?官网给出以下权限组和权限是危险权限,官网链接
危险权限组及权限

2.权限申请

官网有给我们讲如何在在运行时请求权限,官方例子
简单说说以下四个方法:

2.1. ContextCompat.checkSelfPermission()

该方法是检查是否具有某项权限。例如,以下代码段显示了如何检查 Activity 是否具有在日历中进行写入的权限:

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

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

2.2. shouldShowRequestPermissionRationale()

如果应用之前请求过此权限但用户拒绝了请求,此方法将返回 true。注意:如果用户在过去拒绝了权限请求,并在权限请求系统对话框中选择了 Don’t ask again (不再询问)选项,此方法将返回 false。
我们一般用该方法判断用户是否勾选了 “不再询问” 选项,然后勾选我们可以跳转至应用设置页面,让用户开启权限。

2.3. requestPermissions()

申请权限方法,通过该方法申请你所需要的权限.。如:

ActivityCompat.requestPermissions(thisActivity, new String[]{Manifest.permission.READ_CONTACTS}, 
MY_PERMISSIONS_REQUEST_READ_CONTACTS);
2.4. onRequestPermissionsResult()

处理权限请求响应回调方法,在requestPermissions()中申请的权限结果会在该方法中返回。

@Override
public void onRequestPermissionsResult(int requestCode,
        String permissions[], int[] grantResults) {
    switch (requestCode) {
        case MY_PERMISSIONS_REQUEST_READ_CONTACTS: {
            // If request is cancelled, the result arrays are empty.
            if (grantResults.length > 0
                && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                // permission was granted, yay! Do the
                // contacts-related task you need to do.
            } else {
                // permission denied, boo! Disable the
                // functionality that depends on this permission.
            }
            return;
        }
        // other 'case' lines to check for other
        // permissions this app might request
    }
}

具体使用可有看官网例子,这里就不详细讲了。看来官网例子我们会发现申请权限流程很简单,就是先判断是否有该权限,没用就去申请该权限,然后在onRequestPermissionsResult()中获取用户的选择结果。但是如果我们很多页面都需要申请不同权限,那我们不就得在不同的页面都要重写onRequestPermissionsResult()方法。这样重写太麻烦了,我们总不能在第一个页面把所有要用的权限都申请一遍吧。这个时候就可以使用一个无UI的Fragment去帮我申请权限。

3.在Fragment中申请权限

其实Fragment中申请权限是和Activity中申请方法是一样的,也是通过requestPermissions()方法申请,onRequestPermissionsResult()方法接收权限申请结果(具体可以看文末Demo)。需要注意的是requestPermissions()方法在Activity中是ActivityCompat.requestPermissions(),而在Fragment中使用的是Fragment自身的requestPermissions()方法。如在android.support.v4.app.Fragment中实现:

import android.content.pm.PackageManager;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.util.Log;

import java.util.Arrays;
import java.util.Random;

/**
 * Created by wuzuchang On 2019/6/30
 * 在v4.app.Fragment中申请权限
 **/
public class PermissionV4AppFragment extends Fragment {

    private PermissionCallBack permissionCallBack;

    public PermissionV4AppFragment() {
    }

    public static PermissionV4AppFragment newInstance() {
        return new PermissionV4AppFragment();
    }

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setRetainInstance(true);
    }

    public void requestMyPermissions(@NonNull String[] permissions, PermissionCallBack callBack) {
        permissionCallBack = callBack;
        int requestCode = new Random().nextInt(0xFF);
        requestPermissions(permissions, requestCode);
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        Log.d("wzc", "requestCode = " + requestCode + "permissions = " + Arrays.toString(permissions) + "grantResults = " + Arrays.toString(grantResults));
        if (permissionCallBack == null) return;
        int length = grantResults.length;
        for (int i = 0; i < length; i++) {
            int grantResult = grantResults[i];
            if (grantResult == PackageManager.PERMISSION_GRANTED) {
                permissionCallBack.agree(permissions[i]);
            } else {
                if (!this.shouldShowRequestPermissionRationale(permissions[i])) {
                    permissionCallBack.alwaysRefusal(permissions[i]);
                } else {
                    permissionCallBack.refusal(permissions[i]);
                }
            }
        }

    }
}
 /**
     * android.support.v4.app.FragmentActivity 中申请权限
     *
     * @param mActivity   mActivity
     * @param permissions 权限
     * @param callBack    callBack
     */

    public void requestPermissions(FragmentActivity mActivity, String[] permissions, PermissionCallBack callBack) {
        if (mActivity == null) return;
        PermissionV4AppFragment fragment = (PermissionV4AppFragment) mActivity.getSupportFragmentManager().findFragmentByTag(TAG_PERMISSION);
        if (fragment == null) {
            fragment = PermissionV4AppFragment.newInstance();
            FragmentManager fragmentManager = mActivity.getSupportFragmentManager();
            fragmentManager
                    .beginTransaction()
                    .add(fragment, TAG_PERMISSION)
                    .commitAllowingStateLoss();
            fragmentManager.executePendingTransactions();
        }
        fragment.requestMyPermissions(permissions, callBack);
    }

点击跳转至Demo

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值