2019-07-11 09:22:54 The_Only_God 阅读数 28
  • Android 6.0运行时权限讲解

    本节课中会对Android 6.0系统中新增的运行时权限功能进行一次透彻的讲解,包含运行时权限的引入背景、基本用法、佳封装实践等,还会讲一些很多人并不知道的运行时权限微技巧。

    12890 人正在学习 去看看 CSDN讲师

文章目录

电话

//动态申请电话权限
if(ContextCompat.checkSelfPermission(LoginActivity.this, Manifest.permission.CALL_PHONE)
        != PackageManager.PERMISSION_GRANTED){
    ActivityCompat.requestPermissions(LoginActivity.this,new String[]{Manifest.permission.CALL_PHONE},1);
}
2019-06-28 14:40:58 weixin_43344890 阅读数 356
  • Android 6.0运行时权限讲解

    本节课中会对Android 6.0系统中新增的运行时权限功能进行一次透彻的讲解,包含运行时权限的引入背景、基本用法、佳封装实践等,还会讲一些很多人并不知道的运行时权限微技巧。

    12890 人正在学习 去看看 CSDN讲师

在程序运行时申请权限
自Android 6.0以后,就提供了动态申请权限功能,在Android系统中,权限分为两种,分别为普通权限和危险权限,普通权限不需要动态申请,系统会自动帮我们进行授权,而危险权限则需要动态申请。

如果你要使用某个权限,你可以去帮助文档查询一下,看你要使用的这个权限是不是危险权限,如果是,就要动态申请。

此处给出一个例子,点击按钮开始执行打电话操作,打电话是属于危险权限,所以要动态申请,当然,我们也要在AndroidManifest.xml声明一下。

在AndroidManifest.xml加入以下代码:

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

此程序包含了动态申请权限的完整流程,注释我写的很详细,代码如下:

public class MainActivity extends AppCompatActivity {

    private Button mBtn_call_phone;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mBtn_call_phone = findViewById(R.id.btn_call_phone);

        mBtn_call_phone.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                // 判断有没有开启打电话权限,如果开启好了,就打电话,如果没开启,就动态申请
                if (ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.CALL_PHONE) != PackageManager.PERMISSION_GRANTED) {
                    // 调用requestPermissions()方法之后会弹出一个权限申请的对话框
                    // 此处的 1 是请求码,可以自己设置,是int类型的,等下回调的时候要用到的
                    ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.CALL_PHONE}, 1);
                } else {
                    call();
                }

            }
        });
    }

    // 调用ActivityCompat.requestPermissions()方法使系统弹出一个权限申请的对话框
    // 在系统弹出一个权限申请的对话框之后,不管是同意还是反对,都会回调onRequestPermissionsResult()方法
    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        // 授权结果会封装在grantResults参数当中

        // 通过请求码来判断所申请的权限
        switch (requestCode) {
            case 1:
                // 判断权限有没有被授权
                if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                    call();
                } else {
                    Toast.makeText(this, "权限没有开启", Toast.LENGTH_SHORT).show();
                }
                break;
            default:
        }
    }

    // 打电话
    private void call() {
        // 此处的try catch语句可以不要
        try {
            // 此处构建了一个隐式的Intent,Intent的action指定为Intent.ACTION_CALL,这是一个此处内置的打电话动作
            Intent intent = new Intent(Intent.ACTION_CALL);
            // data部分指定了协议是tel,号码是222428
            intent.setData(Uri.parse("tel:222428"));
            startActivity(intent);
        } catch (SecurityException e) {
            e.printStackTrace();
        }
    }

}

2015-12-28 14:54:03 q4878802 阅读数 9753
  • Android 6.0运行时权限讲解

    本节课中会对Android 6.0系统中新增的运行时权限功能进行一次透彻的讲解,包含运行时权限的引入背景、基本用法、佳封装实践等,还会讲一些很多人并不知道的运行时权限微技巧。

    12890 人正在学习 去看看 CSDN讲师

Android 6.0动态获取权限

Android 6.0在我们原有的AndroidManifest.xml声明权限的基础上,又新增了运行时权限动态检测

以下权限都需要在运行时判断:

  • 身体传感器
  • 日历
  • 摄像头
  • 通讯录
  • 地理位置
  • 麦克风
  • 电话
  • 短信
  • 存储空间

效果图

  • Android 6.0添加动态获取权限
    这里写图片描述

  • Android 6.0没有动态获取权限
    这里写图片描述

动态获取权限

每次在用到摄像头等,这样需要权限的操作的时候,都要动态判断一下权限

// 扫描功能
if (ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
    //申请CAMERA权限
    ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.CAMERA}, 3);
} else {
    Intent openCameraIntent = new Intent(this, CaptureActivity.class);
    startActivityForResult(openCameraIntent, 0);
}

如果没有权限,会弹窗提示用户,由用户来决定,是否给予该权限

用户选择完以后,会执行下面的回调

@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
    super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    if (3 == requestCode) {
        if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
            // 授权
            Intent openCameraIntent = new Intent(this, CaptureActivity.class);
            startActivityForResult(openCameraIntent, 0);
        } else {
            // 未授权
        }
    }
}
2018-02-09 15:24:00 u013144287 阅读数 4969
  • Android 6.0运行时权限讲解

    本节课中会对Android 6.0系统中新增的运行时权限功能进行一次透彻的讲解,包含运行时权限的引入背景、基本用法、佳封装实践等,还会讲一些很多人并不知道的运行时权限微技巧。

    12890 人正在学习 去看看 CSDN讲师
android 动态权限获取

        至从android6.0之后,权限在清单文件AndroidManifest.xml里面申明都没有作用了,所以今天如果开发每一款app,都需要动态获取权限,那么我们将怎么动态获取权限呢?下面我举个列子我们需要获取的权限有存储权限、电话权限、定位权限、相机权限。获取权限代码相对固定,复制粘贴就可以。只是贴出主要代码,大家注重思路即可。权限有些是在app内部调用相关功能的时候赋予权限,而有些是在一开始初始化就处理,我这里是后者。

1、AndroidManifest.xml

<!--存储权限-->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<!--电话权限-->
<uses-permission android:name="android.permission.CALL_PHONE"/>
<!--相机权限-->
<uses-permission android:name="android.permission.CAMERA"/>
<!--定位权限-->
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />

2、MainActivity,一般权限实在引导页处理,但是因为性能问题,我就只写了一个MainActivity。但是都一样。

(1)声明权限变量,以数组形式表示

// 要申请的权限
private String[] permissions = {Manifest.permission.WRITE_EXTERNAL_STORAGE,Manifest.permission.CALL_PHONE,
                                Manifest.permission.CAMERA,Manifest.permission.ACCESS_COARSE_LOCATION};


(2)onCreate生命周期里面进行判断是否拥有权限,可以写成循环,我只有几个权限就没有写了

// 版本判断。当手机系统大于 23 时,才有必要去判断权限是否获取
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
    // 检查该权限是否已经获取
    int i = ContextCompat.checkSelfPermission(getApplicationContext(), permissions[0]);
    int l = ContextCompat.checkSelfPermission(getApplicationContext(), permissions[1]);
    int m = ContextCompat.checkSelfPermission(getApplicationContext(), permissions[2]);
    int n = ContextCompat.checkSelfPermission(getApplicationContext(), permissions[3]);
    // 权限是否已经 授权 GRANTED---授权  DINIED---拒绝
    if (i != PackageManager.PERMISSION_GRANTED || l != PackageManager.PERMISSION_GRANTED || m != PackageManager.PERMISSION_GRANTED ||
            n != PackageManager.PERMISSION_GRANTED) {
        // 如果没有授予该权限,就去提示用户请求
        
startRequestPermission();
}}

(3)(2)中的提示用户请求的startRequestPermission()方法

/**
 * 开始提交请求权限
 */
private void startRequestPermission() {
    ActivityCompat.requestPermissions(this, permissions, 321);
}

(4)执行(3)以后,会有申请权限回调方法。回调方法如下

  /**
 * 用户权限 申请 的回调方法
 * @param requestCode
 * @param permissions
 * @param grantResults
 */
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
    super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    if (requestCode == 321) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            if (grantResults[0] != PackageManager.PERMISSION_GRANTED) {
                 //如果没有获取权限,那么可以提示用户去设置界面--->应用权限开启权限
            } else {
                //获取权限成功提示,可以不要
                Toast toast = Toast.makeText(this, "获取权限成功", Toast.LENGTH_LONG);
                toast.setGravity(Gravity.CENTER, 0, 0);
                toast.show();
            }
        }
    }
}

至此,动态获取权限就已经ok了,但是如果我们要提示用户去应用设置手动开启权限的话,我再把代码补充一下,只演示一种存储权限未开启的情况

(5)那么(4)的写法应该是

  /**
 * 用户权限 申请 的回调方法
 * @param requestCode
 * @param permissions
 * @param grantResults
 */
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
    super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    if (requestCode == 321) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            if (grantResults[0] != PackageManager.PERMISSION_GRANTED) {
                   // 判断用户是否 点击了不再提醒。(检测该权限是否还可以申请)
                    boolean b = shouldShowRequestPermissionRationale(permissions[0]);
                    // 以前是!b
                    if (b) {
                    // 用户还是想用我的 APP 的
                    // 提示用户去应用设置界面手动开启权限
                        showDialogTipUserGoToAppSettting();
                    } else{
                        finish();
                    }
            } else {
                //获取权限成功提示,可以不要
                Toast toast = Toast.makeText(this, "获取权限成功", Toast.LENGTH_LONG);
                toast.setGravity(Gravity.CENTER, 0, 0);
                toast.show();
            }
        }
    }
}


(6)showDialogTipUserGoToAppSettting()

 /**
 * 提示用户去应用设置界面手动开启权限
 */
private void showDialogTipUserGoToAppSettting() {

    dialog = new AlertDialog.Builder(this)
            .setTitle("存储权限不可用")
            .setMessage("请在-应用设置-权限-中,允许应用使用存储权限来保存用户数据")
            .setPositiveButton("立即开启", new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int which) {
                    // 跳转到应用设置界面
                    goToAppSetting();
                }
            })
            .setNegativeButton("取消", new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int which) {
//                        finish();
                }
            }).setCancelable(false).show();
}


(7)goToAppSetting()

/**
     * 跳转到当前应用的设置界面
     */
    private void goToAppSetting() {
        Intent intent = new Intent();

        intent.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
        Uri uri = Uri.fromParts("package", getPackageName(), null);
        intent.setData(uri);

        startActivityForResult(intent, 123);
    }

(8)去应用设置里面的对权限设置的回调方法

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    //权限管理
    if (requestCode == 123) {
        if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            // 检查该权限是否已经获取
            int i = ContextCompat.checkSelfPermission(this, permissions[0]);
            // 权限是否已经 授权 GRANTED---授权  DINIED---拒绝
            if (i != PackageManager.PERMISSION_GRANTED) {
                // 提示用户应该去应用设置界面手动开启权限
                showDialogTipUserGoToAppSettting();
            } else {
                if (dialog != null && dialog.isShowing()) {
                    dialog.dismiss();
                }
                Toast.makeText(this, "权限获取成功", Toast.LENGTH_SHORT).show();
            }
        }
    }
}

至此提示用户去设置界面手动开启存储功能就实现了

2017-06-14 19:41:15 u010326875 阅读数 2363
  • Android 6.0运行时权限讲解

    本节课中会对Android 6.0系统中新增的运行时权限功能进行一次透彻的讲解,包含运行时权限的引入背景、基本用法、佳封装实践等,还会讲一些很多人并不知道的运行时权限微技巧。

    12890 人正在学习 去看看 CSDN讲师

做安卓其实挺费劲的,各种机型都够操心了,动态权限又恶心了一下骂人


but 项目中针对6.0以上手机,还是必要处理一下权限申请的问题!!


首先,判断是否6.0以上,判断是否申请权限,拒绝了的权限怎么办?(android机型比较多,三星手机弹出申请弹框拒绝了,第二次还是会弹出权限申请框;但是我用的小米4,拒绝了第二次就默认拒绝了不会弹框;还有一些手机低版本的会一直弹框敲打



权限工具类:

import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.Build;
import android.provider.Settings;
import android.support.annotation.NonNull;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.support.v4.content.PermissionChecker;

import com.motian.permissionrequest.ToastUtils;

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

import static android.R.attr.targetSdkVersion;

/**
 * ClassName:ParameterFactory
 * Description TODO 动态权限处理
 *      参考:http://blog.csdn.net/u011200604/article/details/52874599
 * created by BAI
 * Data 2016/12/20
 */
public class PermissionUtils {

    private static final int PERMISSION_REQUEST_CODE = 100;

    /**
     * 请求权限
     * @param mActivity
     * @param permissions
     */
    public void requestRunPermission(Activity mActivity, String[] permissions, PermissionListener mListener){
        List<String> permissionLists = new ArrayList<>();
        for(String permission : permissions){
            if( selfPermissionGranted(mActivity,permission)){
                permissionLists.add(permission);
            }
        }
        if(!permissionLists.isEmpty()){
            ActivityCompat.requestPermissions(mActivity, permissionLists.toArray(new String[permissionLists.size()]), PERMISSION_REQUEST_CODE);
        }else{
            //表示全都授权了
            mListener.onGranted();
        }
    }

    /**
     * 判断权限是否已授权
     * @param permission
     * @return
     */
    public boolean selfPermissionGranted(Activity mContext,String permission) {
        // For Android < Android M, self permissions are always granted.
        boolean result = true;
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            if (targetSdkVersion >= Build.VERSION_CODES.M) {
                // targetSdkVersion >= Android M, we can
                // use Context#checkSelfPermission
                result = ContextCompat.checkSelfPermission(mContext, permission) != PackageManager.PERMISSION_GRANTED;
            } else {
                // targetSdkVersion < Android M, we have to use PermissionChecker
                result = PermissionChecker.checkSelfPermission(mContext, permission) == PermissionChecker.PERMISSION_GRANTED;
            }
        }
        return result;
    }

    /**
     * 请求权限结果,baseActivity调用
     * @param requestCode
     * @param permissions
     * @param grantResults
     * @param mListener
     */
    public void requestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults,PermissionListener mListener) {
        switch (requestCode){
            case PERMISSION_REQUEST_CODE:
                if(grantResults.length > 0){
                    //存放没授权的权限
                    List<String> deniedPermissions = new ArrayList<>();
                    for(int i = 0; i < grantResults.length; i++){
                        int grantResult = grantResults[i];
                        String permission = permissions[i];
                        if(grantResult != PackageManager.PERMISSION_GRANTED){
                            deniedPermissions.add(permission);
                        }
                    }
                    if(deniedPermissions.isEmpty()){
                        //说明都授权了
                        mListener.onGranted();
                    }else{
                        mListener.onDenied(deniedPermissions);
                    }
                }
                break;
            default:
                break;
        }
    }

    /**
     * 打开设置权限页面
     * @param activity
     * @param message
     */
    public static void openSettingActivity(final Activity activity, String message) {
        showMessageOKCancel(activity, message, new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                Intent intent = new Intent();
                intent.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
                Uri uri = Uri.fromParts("package", activity.getPackageName(), null);
                intent.setData(uri);
                activity.startActivity(intent);
            }
        }, new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialogInterface, int which) {
                ToastUtils.showToast(activity,"请设置必要的权限!");
            }
        });
    }

    /**
     * 显示弹框
     * @param context
     * @param message
     * @param settingListener
     * @param cancelListener
     */
    private static void showMessageOKCancel(final Activity context, String message,
                                            DialogInterface.OnClickListener settingListener,
                                            DialogInterface.OnClickListener cancelListener) {
        String permissionMessage = "当前应用缺少必要权限("+message+")\n" +
                "\n 请点击“设置”-“权限”-打开所需权限。\n"+"" +
                "\n 最后点击两次后退按钮,即可返回";
        new AlertDialog.Builder(context)
                .setTitle("提示")
                .setMessage(permissionMessage)
                .setPositiveButton("设置", settingListener)
                .setNegativeButton("取消", cancelListener)
                .create()
                .show();

    }
}

权限申请依附于Activity,BaseAcivity和BaseFragment调用:


/**
 * ClassName: BaseActivity
 * Description: 基础信息
 * author 漠天
 * date 2017/6/11
 */
public abstract class BaseActivity extends AppCompatActivity{
    protected Activity mContext = this;
    /**
     * 权限监听
     */
    private PermissionListener mListener;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    }

    /**
     * 请求权限(在onResume中写会重复调用弹窗,知道允许权限)
     * @param mActivity
     * @param permissions
     */
    public void requestRunPermission(Activity mActivity, String[] permissions, PermissionListener mListener){
        this.mListener = mListener;
        new PermissionUtils().requestRunPermission(mActivity,permissions,mListener);
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        new PermissionUtils().requestPermissionsResult(requestCode, permissions, grantResults,mListener);
    }

}

/**
 * ClassName:BaseFragment
 * Description BaseFragment
 * created by BAI
 * Data 2017/6/11
 */
public abstract class BaseFragment extends Fragment{
    /**
     * Activity mContext
     */
    protected Activity mContext;

    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        mContext = getActivity();
        return null;
    }

    /**
     * 请求权限
     * @param mActivity
     * @param permissions
     */
    public void requestRunPermission(Activity mActivity, String[] permissions, PermissionListener mListener){
        ((BaseActivity)mActivity).requestRunPermission(mActivity,permissions,mListener);
    }

}


然后,MainActivity调用申请:

public class MainActivity extends BaseActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Button button = (Button)findViewById(R.id.request);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                permission();
            }
        });
        Button openPermissionActivity = (Button)findViewById(R.id.openPermissionActivity);
        openPermissionActivity.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Intent intent = new Intent();
                intent.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
                Uri uri = Uri.fromParts("package", mContext.getPackageName(), null);
                intent.setData(uri);
                mContext.startActivity(intent);
            }
        });

        permission();
    }

    /**
     * 判断权限
     */
    private void permission(){
        requestRunPermission(mContext,new String[]{Manifest.permission.CAMERA, Manifest.permission.CALL_PHONE,Manifest.permission.READ_EXTERNAL_STORAGE},new PermissionListener() {
            @Override
            public void onGranted() {
                //表示所有权限都授权了
                ToastUtils.showToast(mContext,"已经全部接受,可以处理其他事儿了^_^");
            }

            @Override
            public void onDenied(List<String> deniedPermission) {
                PermissionUtils.openSettingActivity(mContext,ToastUtils.getPermissionText(mContext,deniedPermission));
            }
        });
    }

}

效果图:





demo代码结构:





demo PermissionRequest






没有更多推荐了,返回首页