zoukankan      html  css  js  c++  java
  • 《第一行代码》阅读笔记(二十四)——Android动态请求权限

    首先本章就介绍了什么是危险权限,而不是危险权限的就是普通权限。那有那些危险权限呢,不用记,需要的时候直接来这个表里查。「Android中危险权限列表」同时可以访问http://developer.android.com/reference/android/Manifest.permission.html可以查看Android系统中完整的权限列表。

    Demo

    首先先创建项目,给布局设置一个按钮,就不说了。书上先做了一个错误示范,让大家看看没有权限的时候,程序会怎么报错,有兴趣的可以看看。这里就直奔主题,大家先来看看,完整的Activity。

    public class MainActivity extends AppCompatActivity {
        
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            Button btnCall = findViewById(R.id.btn_call);
            btnCall.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
    
                    if (ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.CALL_PHONE) != PackageManager.PERMISSION_GRANTED) {
                        // TODO: Consider calling
                        //    ActivityCompat#requestPermissions
                        // here to request the missing permissions, and then overriding
                        //   public void onRequestPermissionsResult(int requestCode, String[] permissions,
                        //                                          int[] grantResults)
                        // to handle the case where the user grants the permission. See the documentation
                        // for ActivityCompat#requestPermissions for more details.
                        ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.CALL_PHONE}, 1);
    
                    } else {
                        Intent intent = new Intent(Intent.ACTION_CALL);
                        intent.setData(Uri.parse("tel:10086"));
                        startActivity(intent);
    //                    call();
                    }
                }
            });
        }
    
    //    private void call() {
    //        try {
    //            Intent intent = new Intent(Intent.ACTION_CALL);
    //            intent.setData(Uri.parse("tel:10086"));
    //            startActivity(intent);
    //        } catch (Exception e) {
    //            e.printStackTrace();
    //        }
    //    }
    
        @Override
        public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
            switch (requestCode) {
                case 1:
                    if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
    //                    call();
                    } else {
                        Toast.makeText(this, "You denied the permission", Toast.LENGTH_LONG).show();
                    }
                    break;
                default:
            }
        }
    }
    

    如果按照书中的写法,封装的call方法会报错,这应该是新版本对动态获取权限的改变。所以笔者做了一些修改。

    if (ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.CALL_PHONE) != PackageManager.PERMISSION_GRANTED) {
        ...
    } else {
        ...
    }
    

    首先在点击的时候,通过ContextCompat.checkSelfPermission函数接受两个参数,一个是环境,另个一个就是具体的权限名,比如例子中的Manifest.permission.CALL_PHONE。然后用得到的返回值和PackageManager.PERMISSION_GRANTED进行判断。

    checkSelfPermission顾名思义就是检查当前环境的权限,而后面跟的参数就是需要检查的权限。而PackageManager.PERMISSION_GRANTED就是手机已经获得的权限。两者对比,就知道当前的APP是否已经获得了权限。根据不同的结果进行接下来的操作。

    例子中,如果已经获得,就进行Call的动作。如果没有,就通过ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.CALL_PHONE}, 1)来申请,三个参数分别是当前环境、权限名数组和为一个请求码,一般传入1就行。这个1会在后面的onRequestPermissionsResult函数中用到。

    requestPermissions方法调用后,系统会自动弹出一个请求,需要用户确认,无论用户是否确认,都会进入onRequestPermissionsResult函数,这是一个系统自动生成的函数,虽然没有调用,但是会将授权的结果封装在grantResults参数当中。

    @Override
        public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
            switch (requestCode) {
                case 1:
                    if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
    //                    call();
                    } else {
                        Toast.makeText(this, "You denied the permission", Toast.LENGTH_LONG).show();
                    }
                    break;
                default:
            }
        }
    

    然后进行判断,如果结果集的长度大于零,就说明有权限被申请。并取出第一位,因为我们只申请了一个权限名,所以第一个就是我们申请的值,然后和手机的权限进行比较。其实结果集是一串0和-1的集合,分别和PackageManager包中的两个参数对应。

    public static final int PERMISSION_DENIED = -1;
        public static final int PERMISSION_GRANTED = 0;
    

    如果用户同意,就进行操作就行了,如果不同意弹出一个toast提示。
    requestCode用来判断进入那个switch分支,用来后续多个权限申请的不同提示或者操作。

    注意

    Android10读写文件权限请求bug——open failed: EACCES (Permission denied)

  • 相关阅读:
    敏捷21天打卡-AARRR模型
    敏捷21天打卡-精益产品开发最佳实践 之 “AB测试"
    21天敏捷打卡-MVP
    敏捷21天打卡-精益产品开发最佳实践 之 “电梯演讲"
    敏捷21天打卡-精益画布
    敏捷21天打卡--精益产品开发
    21天敏捷打卡--敏捷方法实现
    敏捷21天打卡-在敏捷环境中交付
    敏捷21天打卡-创建敏捷环境
    敏捷21天打卡-生命周期
  • 原文地址:https://www.cnblogs.com/zllk/p/13416330.html
Copyright © 2011-2022 走看看