安卓入门:获取危险权限——运行时权限处理

主题

在6.0版本以上的系统在使用危险权限时需要进行运行时权限处理

运行环境

7.0安卓手机

权限声明
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
          package="com.momingqi.runtimepermissiondemo">

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

</manifest>
执行代码:
try
                {
                    Intent intent = new Intent(Intent.ACTION_CALL);
                    intent.setData(Uri.parse("tel:10086"));
                    startActivity(intent);
                } catch (SecurityException exception)
                {
                    exception.printStackTrace();
                }
错误提示

提示没有授权这个Intent

java.lang.SecurityException:
Permission Denial: starting Intent
{ act=android.intent.action.CALL
dat=tel:xxxxx
cmp=com.android.server.telecom/.components.UserCallActivity } 
from ProcessRecord{3560ec5 2240:com.momingqi.runtimepermissiondemo/u0a72} (pid=2240, uid=10072) with revoked permission
android.permission.CALL_PHONE
修改代码

在运行时请求权限

public class MainActivity extends AppCompatActivity
{

    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        findViewById(R.id.btn_call).setOnClickListener(new View.OnClickListener()
        {
            @Override
            public void onClick(View v)
            {
                if(ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.CALL_PHONE)
                        != PackageManager.PERMISSION_GRANTED) //还没获取到拨电话权限
                {
                    ActivityCompat.requestPermissions(MainActivity.this, new String[]{ Manifest.permission.CALL_PHONE }, 1); //参数:上下文,权限列表,请求码
                }
                else //已经获取拨电话权限
                    call();
            }
        });
    }

    private void call()
    {
        try
        {
            Intent intent = new Intent(Intent.ACTION_CALL);
            intent.setData(Uri.parse("tel:10086"));
            startActivity(intent);
        } catch (SecurityException exception)
        {
            exception.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, "你拒绝了该权限请求",Toast.LENGTH_SHORT);
                }
                break;
            default:
                break;
        }
    }
}
运行结果

运行时权限1

运行时权限2

注意

ACTION.CALL与ACTION.DIAL的区别:
- ACTION_DIAL只是打开拨号界面,需要用户主动进行拨号;而ACTION_CALL会自动拨打给data中的号码
- ACTION.CALL属于危险权限,需要在manifest中声明权限并且进行运行时授权;ACTION_DIAL则不需要任何授权

获取危险权限方法过程
  1. 检查是否已经授权
if(ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.CALL_PHONE)
                        != PackageManager.PERMISSION_GRANTED)
  1. 发起权限请求
ActivityCompat.requestPermissions(MainActivity.this
, new String[]{Manifest.permission.CALL_PHONE }, 1); //参数:上下文,权限列表,请求码
  1. 重载上下文的onRequestPermissionsResult方法
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults)

通过请求码来识别这个活动在不同地方请求权限的结果,参数grantResults是对应permissions里请求的权限的返回结果合集,通过索引就能得到每一个权限请求的返回结果。

猜你喜欢

转载自blog.csdn.net/mingc0758/article/details/72470229