Android6.0仿IOS在欢迎页面统一请求权限

一. android6.0以后权限的请求改成了动态请求,不再是在安装的时候统一请求了.这样对用户来说虽然是体验好了,但是却苦了我们开发者,每个危险权限我们都得写一遍权限请求的代码,这样即麻烦,又觉得代码人冗余.我通过2个项目的实践,总结出了仿ios在欢迎页面将需要的权限统一请求了是一种不错的处理方法.先上一张效果图.
这是都允许的情况
这里写图片描述
这是拒绝的情况
这里写图片描述

二.为了方便使用,我封装了一个请求权限的库,使用非常简单, 一行调用代码即可.具体的参考一行代码请求权限的库

三.通过上面的图片应该可以看出大致的过程了,在欢迎页面我们先通过对话框将需要请求的权限都显示出来,当用户点击确定的时候就一个一个的请求权限.当用户拒绝且点击了不再提醒时,就跳出去设置界面设置权限的对话框.下面一步一步的来.

  1. 在欢迎界面发起权限请求
 if (Build.VERSION.SDK_INT < 23) {
            //6.0一下直接去主页
            UiUtils.startIntent(this, LoginActivity.class);
            finish();
        } else {
            //6.0以上请求权限
            checkPermiss();
        }
  /**
     * 请求权限
     */
    private void checkPermiss() {
        PermissionUtil.checkPermission(this,  REQUEST_PERMISSIONS, new PermissionUtil.permissionInterface() {
            @Override
            public void success() {
                //请求成功,切记不能将欢迎页面关闭,原因查看第5点
                UiUtils.startIntent(WelcomeActivity.this, LoginActivity.class);
                UiUtils.showToast(WelcomeActivity.this,"请求权限成功,去首页");
            }

            @Override
            public void fail(final List<String> permissions) {
                //请求失败 用map将对应的权限保存起来,方便显示
                if (map == null) {
                    map = new HashMap<>();
                    map.put("android.permission.CAMERA", "拍照");
                    map.put("android.permission.ACCESS_COARSE_LOCATION", "位置信息");
                    map.put("android.permission.WRITE_EXTERNAL_STORAGE", "存储空间");
                    map.put("android.permission.CALL_PHONE", "打电话");

                }
                //重新请求权限
                requestPermission(permissions.toArray(new String[permissions.size()]));


            }
        });
    }


  /**
     * 再次请求权限
     * @param permissions
     */
    private void requestPermission(final String[] permissions) {

        if (permissionDialog != null) {
            permissionDialog.dismiss();
        }
        //弹出提醒用户请求权限的对话框
        permissionDialog = new PermissionDialog(WelcomeActivity.this, new PermissionDialog.onConfirmListener() {
            @Override
            public void comfirm() {
                //点击确认按钮就请求权限
               PermissionUtil.requestContactsPermissions(WelcomeActivity.this,permissions,REQUEST_PERMISSION_CODE_TAKE_PIC);
            }

            @Override
            public void cancel() {
                //点击取消按钮就 退出程序
                WelcomeActivity.this.finish();
            }
        });

        StringBuilder sb = new StringBuilder();
        for (String permission : permissions) {
            if (map != null) {
                String s = map.get(permission);
                if (!TextUtils.isEmpty(s)) {
                    sb.append(s + " ");
                }
            }
        }

        permissionDialog.setTvcontent(sb.toString());
        permissionDialog.show();
        UiUtils.showToast(WelcomeActivity.this,"获取权限失败,开启获取权限的对话框");
    }
  1. 重写检测权限的回调方法来判断权限请求是否成功
  /**
     * 检测权限的回调
     *
     * @param requestCode
     * @param permissions
     * @param grantResults
     */
    public void onRequestPermissionsResult(int requestCode, final String[] permissions, int[] grantResults) {

        if (requestCode == REQUEST_PERMISSION_CODE_TAKE_PIC) {
            if (PermissionUtil.verifyPermissions(grantResults)) {//有权限
                //TODO 有权限
                UiUtils.startIntent(this, LoginActivity.class);

            } else {
                //没有权限
                if (!PermissionUtil.shouldShowPermissions(this, permissions)) {//这个返回false 表示勾选了不再提示

                    startToSetting();

                } else {
                    //表示没有权限 ,但是没勾选不再提示
                    for (String s : permissions) {
                        if (!ActivityCompat.shouldShowRequestPermissionRationale(WelcomeActivity.this,
                                s)) {
                            //去掉已经允许的
                            if (map != null) {
                                map.remove(s);
                            }
                        }
                    }
                    requestPermission2(permissions);
                }
            }
        } else {
            super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        }
    }

 /**
     * 请求权限2
     * @param permissions
     */
    private void requestPermission2(final String[] permissions) {
        DeleteDialog deleteDialog = new DeleteDialog(WelcomeActivity.this, new DeleteDialog.onConfirmListener() {
            @Override
            public void comfirm() {
                //去掉已经请求过的权限
                List<String> deniedPermissions = PermissionUtil.findDeniedPermissions(WelcomeActivity.this, permissions);
                //请求权限
                PermissionUtil.requestContactsPermissions(WelcomeActivity.this,deniedPermissions.toArray(new String[deniedPermissions.size()]),REQUEST_PERMISSION_CODE_TAKE_PIC);
            }

            @Override
            public void cancel() {
                WelcomeActivity.this.finish();
            }
        });

        StringBuilder sb = new StringBuilder();
        for (String permission : permissions) {
            if (map != null) {
                String s = map.get(permission);
                if (!TextUtils.isEmpty(s)) {
                    sb.append(s + " ");
                }
            }
        }
        deleteDialog.setTvcontent("请允许"+sb+"权限请求");
        deleteDialog.show();
    }

    private void startToSetting() {
        DeleteDialog deleteDialog = new DeleteDialog(WelcomeActivity.this, new DeleteDialog.onConfirmListener() {
            @Override
            public void comfirm() {
                Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
                Uri uri = Uri.fromParts("package", getPackageName(), null);
                intent.setData(uri);
                startActivityForResult(intent, REQUEST_PERMISSION_SEETING);
            }

            @Override
            public void cancel() {
                WelcomeActivity.this.finish();
            }
        });


        deleteDialog.setTvcontent("去设置界面开启权限?");
        deleteDialog.show();
    }

3.重写activity的 onActivityResult方法,用来判断从设置权限界面回来权限是否开启了

 @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);

        //如果是从设置界面返回,就继续判断权限
        if (requestCode == REQUEST_PERMISSION_SEETING) {
            checkPermiss();
        }

    }

4.需要在基类的activity的onResume()也检测一遍权限是否开启了,这样做的目的是怕程序在后台因为application被杀死了,下次回来这个界面时,已经是重新开启了一个application,这里不会进入到欢迎界面,也就不会进行权限的判断,所以需要在这里也判断一下

   //统一检查权限
        PermissionUtil.checkPermission(getmActivity(), REQUEST_PERMISSIONS,  new PermissionUtil.permissionInterface() {
            @Override
            public void success() {

            }

            @Override
            public void fail(List<String> permissions) {

                //没有权限就回到欢迎页面
                UiUtils.startIntent(getmActivity(), WelcomeActivity.class);

            }
        });

5.需要将欢迎页面的启动模式设置成singletask,并且需要在欢迎页面重写onNewintent方法.设置成singletask的目的是当从其他界面的onresume方法检测权限没开启跳到欢迎页面时,将其他的acitvity都清空,这样当弹出权限情i去的对话框请求取消时,就可以退出程序,而不是回到之前的界面. 重写onNewintent方法是因为singletask模式,当再次进入这个activity时不会走oncreate方法而是会走onNewintent方法.

  //singtask 再次进入不会进入oncreate,而是进入到这里
    @Override
    protected void onNewIntent(Intent intent) {
        super.onNewIntent(intent);
       startToHome();
    }

6.这是我的欢迎界面的完整代码

package com.betterda.shoppingsale.welcome;

import android.Manifest;
import android.content.Intent;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.provider.Settings;
import android.support.annotation.Nullable;
import android.support.v4.app.ActivityCompat;
import android.support.v7.app.AppCompatActivity;
import android.text.TextUtils;
import android.widget.ImageView;


import com.betterda.shoppingsale.R;
import com.betterda.shoppingsale.dialog.DeleteDialog;
import com.betterda.shoppingsale.dialog.PermissionDialog;
import com.betterda.shoppingsale.home.MainActivity;
import com.betterda.shoppingsale.login.LoginActivity;
import com.betterda.shoppingsale.register.RegisterActivity;
import com.betterda.shoppingsale.utils.PermissionUtil;
import com.betterda.shoppingsale.utils.RxManager;
import com.betterda.shoppingsale.utils.UiUtils;

import java.util.HashMap;
import java.util.List;

import butterknife.BindView;
import rx.functions.Action1;

/**
 * 欢迎页面
 * Created by Administrator on 2016/12/21.
 */

public class WelcomeActivity extends AppCompatActivity {

    private String[] REQUEST_PERMISSIONS = new String[]{Manifest.permission.CAMERA, Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.WRITE_EXTERNAL_STORAGE,
            Manifest.permission.CALL_PHONE};
    private HashMap<String,String> map;//管理权限的map
    private static final int REQUEST_PERMISSION_CODE_TAKE_PIC = 9; //权限的请求码
    private static final int REQUEST_PERMISSION_SEETING = 8; //去设置界面的请求码
    protected RxManager mRxManager;
    @BindView(R.id.iv_welcome)
    ImageView mIvWelcome;
    private PermissionDialog permissionDialog;//权限请求对话框


    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_welcome);
        initRxBus();
        startToHome();

    }

    /**
     * 跳转到首页
     */
    private void startToHome() {
        if (Build.VERSION.SDK_INT < 23) {
            //6.0一下直接去主页
            UiUtils.startIntent(this, LoginActivity.class);
            finish();
        } else {
            //6.0以上请求权限
            checkPermiss();
        }
    }

    private void initRxBus() {
        mRxManager = new RxManager();
        mRxManager.on(WelcomeActivity.class.getSimpleName(), new Action1<Object>() {
            @Override
            public void call(Object o) {

                finish();
            }
        });

    }

    //singtask 再次进入不会进入oncreate,而是进入到这里
    @Override
    protected void onNewIntent(Intent intent) {
        super.onNewIntent(intent);
       startToHome();
    }

    /**
     * 请求权限
     */
    private void checkPermiss() {
        PermissionUtil.checkPermission(this,  REQUEST_PERMISSIONS, new PermissionUtil.permissionInterface() {
            @Override
            public void success() {
                //请求成功
                UiUtils.startIntent(WelcomeActivity.this, LoginActivity.class);
                UiUtils.showToast(WelcomeActivity.this,"请求权限成功,去首页");
            }

            @Override
            public void fail(final List<String> permissions) {

                if (map == null) {
                    map = new HashMap<>();
                    map.put("android.permission.CAMERA", "拍照");
                    map.put("android.permission.ACCESS_COARSE_LOCATION", "位置信息");
                    map.put("android.permission.WRITE_EXTERNAL_STORAGE", "存储空间");
                    map.put("android.permission.CALL_PHONE", "打电话");

                }

                requestPermission(permissions.toArray(new String[permissions.size()]));


            }
        });
    }

    /**
     * 请求权限
     * @param permissions
     */
    private void requestPermission(final String[] permissions) {

        if (permissionDialog != null) {
            permissionDialog.dismiss();
        }
        //请求权限
        permissionDialog = new PermissionDialog(WelcomeActivity.this, new PermissionDialog.onConfirmListener() {
            @Override
            public void comfirm() {
                //请求权限
                PermissionUtil.requestContactsPermissions(WelcomeActivity.this,permissions,REQUEST_PERMISSION_CODE_TAKE_PIC);
            }

            @Override
            public void cancel() {
                WelcomeActivity.this.finish();
            }
        });

        StringBuilder sb = new StringBuilder();
        for (String permission : permissions) {
            if (map != null) {
                String s = map.get(permission);
                if (!TextUtils.isEmpty(s)) {
                    sb.append(s + " ");
                }
            }
        }

        permissionDialog.setTvcontent(sb.toString());
        permissionDialog.show();
        UiUtils.showToast(WelcomeActivity.this,"获取权限失败,开启获取权限的对话框");
    }

    /**
     * 请求权限2
     * @param permissions
     */
    private void requestPermission2(final String[] permissions) {
        DeleteDialog deleteDialog = new DeleteDialog(WelcomeActivity.this, new DeleteDialog.onConfirmListener() {
            @Override
            public void comfirm() {
                //去掉已经请求过的权限
                List<String> deniedPermissions = PermissionUtil.findDeniedPermissions(WelcomeActivity.this, permissions);
                //请求权限
                PermissionUtil.requestContactsPermissions(WelcomeActivity.this,deniedPermissions.toArray(new String[deniedPermissions.size()]),REQUEST_PERMISSION_CODE_TAKE_PIC);
            }

            @Override
            public void cancel() {
                WelcomeActivity.this.finish();
            }
        });

        StringBuilder sb = new StringBuilder();
        for (String permission : permissions) {
            if (map != null) {
                String s = map.get(permission);
                if (!TextUtils.isEmpty(s)) {
                    sb.append(s + " ");
                }
            }
        }
        deleteDialog.setTvcontent("请允许"+sb+"权限请求");
        deleteDialog.show();
    }

    private void startToSetting() {
        DeleteDialog deleteDialog = new DeleteDialog(WelcomeActivity.this, new DeleteDialog.onConfirmListener() {
            @Override
            public void comfirm() {
                Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
                Uri uri = Uri.fromParts("package", getPackageName(), null);
                intent.setData(uri);
                startActivityForResult(intent, REQUEST_PERMISSION_SEETING);
            }

            @Override
            public void cancel() {
                WelcomeActivity.this.finish();
            }
        });


        deleteDialog.setTvcontent("去设置界面开启权限?");
        deleteDialog.show();
    }



    /**
     * 检测权限的回调
     *
     * @param requestCode
     * @param permissions
     * @param grantResults
     */
    public void onRequestPermissionsResult(int requestCode, final String[] permissions, int[] grantResults) {

        if (requestCode == REQUEST_PERMISSION_CODE_TAKE_PIC) {
            if (PermissionUtil.verifyPermissions(grantResults)) {//有权限
                //TODO 有权限
                UiUtils.startIntent(this, LoginActivity.class);

            } else {
                //没有权限
                if (!PermissionUtil.shouldShowPermissions(this, permissions)) {//这个返回false 表示勾选了不再提示

                    startToSetting();

                } else {
                    //表示没有权限 ,但是没勾选不再提示
                    for (String s : permissions) {
                        if (!ActivityCompat.shouldShowRequestPermissionRationale(WelcomeActivity.this,
                                s)) {
                            //去掉已经允许的
                            if (map != null) {
                                map.remove(s);
                            }
                        }
                    }
                    requestPermission2(permissions);
                }
            }
        } else {
            super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        }
    }



    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);

        //如果是从设置界面返回,就继续判断权限
        if (requestCode == REQUEST_PERMISSION_SEETING) {
            checkPermiss();
        }

    }

    @Override
    protected void onStop() {
        super.onStop();
        if (map != null) {
            map.clear();
            map = null;
        }

    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        mRxManager.clear();
    }
}

7.下面是请求权限的完整代码

package com.betterda.shoppingsale.utils;

import android.app.Activity;
import android.content.pm.PackageManager;
import android.os.Build;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;

import java.util.ArrayList;
import java.util.List;

/**
 * 6.0Dynamic authorization application
 * Created by Administrator on 2016/8/26.
 */
public class PermissionUtil {


    /**
     * Detection authority
     * @param activity
     * @param permissions  //Requested permission group
     */
    public  static void checkPermission(final Activity activity, final String[] permissions, permissionInterface permissionInterface) {
        //Less than 23 do nothing.
        if (Build.VERSION.SDK_INT < 23) {
            permissionInterface.success();
            return;
        }
        final List<String> deniedPermissions = findDeniedPermissions(activity, permissions);

        if (deniedPermissions!=null&&deniedPermissions.size()>0) {
            //Greater than 0, said there is no application for permission

            permissionInterface.fail(deniedPermissions);

        } else {
            //have authority
            permissionInterface.success();

        }



    }



    /**
     * Request permission
     */
    public static void requestContactsPermissions(final Activity activity,  final String[] permissions, final int requestCode) {
        //The default is false, but as long as the request once permission will be true, unless the point is no longer asked to be re changed to false
        if (shouldShowPermissions(activity,permissions)) {

            ActivityCompat
                    .requestPermissions(activity, permissions,
                            requestCode);
        } else {

            // No need to prompt the user interface, the direct request permissions, if the user points are no longer asked, even if the request does not have the right to request permissions dialog box
            ActivityCompat.requestPermissions(activity,
                    permissions,
                    requestCode);
        }
    }

    /**
     * To determine whether the requested permission is successful
     * @param grantResults
     * @return
     */
    public static boolean verifyPermissions(int[] grantResults) {
        // At least one result must be checked.
        if(grantResults.length < 1){
            return false;
        }

        // Verify that each required permission has been granted, otherwise return false.
        for (int result : grantResults) {
            if (result != PackageManager.PERMISSION_GRANTED) {
                return false;
            }
        }
        return true;
    }




    public interface permissionInterface{
        void success();

        void fail(List<String> permissions);
    }

    /**
     * To find no authorization
     * @param activity
     * @param permission
     * @return
     */
    public static List<String> findDeniedPermissions(Activity activity, String... permission)
    {
        //Storing permissions without authorization
        List<String> denyPermissions = new ArrayList<>();
        for (String value : permission)
        {
            if (ContextCompat.checkSelfPermission(activity,value) != PackageManager.PERMISSION_GRANTED)
            {

                //Add without permission
                denyPermissions.add(value);
            }
        }
        return denyPermissions;
    }

    /**
     * To detect if there is no authorization required for these permissions
     * @param activity
     * @param permission
     * @return
     */
    public static boolean shouldShowPermissions(Activity activity, String... permission)
    {

        for (String value : permission)
        {
            if (ActivityCompat.shouldShowRequestPermissionRationale(activity,
                    value))
            {
               return true;
            }
        }
        return false;
    }



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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值