Android权限的存在旨在保护用户的隐私和安全,不过在Android6.0之前,权限会在安装程序前进行询问,拒绝则不能安装程序,这样就出现了一些我们离开不了的程序出现“店大欺客”的现象。为了解决这个问题,Android在6.0添加了运行时权限功能,那些涉及用户安全和隐私的权限会在程序安装后,使用这个功能时,在用户同意获取权限后,程序方可动态添加权限。
1.普通权限:不涉及用户安全和隐私的权限,只需在Manifest中添加权限语句,程序就可以自动完成权限的获取
2.特殊权限:这种权限用的很少,我就不说明了
3.危险权限:涉及用户的安全和隐私,这些权限需要运行时权限
上图就是所有的危险权限,需要注意的是,每一个权限都在一个权限组中,当一个危险权限获取了,那么这个组中的其他危险权限默认可获取了。
1.你拒绝获取时需要弹出提示,你拒绝了获取权限;
2.当点击同意获取CALL_PHONE 权限后,程序才可以拨打电话;
3.再次启用打电话功能时,不需要再次获取运行时权限;
1.在activity_main.xml中添加Button控件
2.在MainActivity中获取运行时权限
3.在AndroidManifest.xml中添加权限
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context="com.example.runtimepermissiontest.MainActivity">
<Button
android:id="@+id/main_call_btn"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="make call" />
LinearLayout>
public class MainActivity extends AppCompatActivity {
private Button callBtn;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
callBtn = findViewById(R.id.main_call_btn);
//对按钮进行监听
callBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//通过if语句判断程序是否获取了CALL_PHONE的权限
//checkSelfPermission()param1:当前环境,param2:具体要获取的权限名
//通过checkSelfPermission()的返回值与PackageManager.PERMISSION_GRANTED比较,不等就是没有获取权限呢
if (ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.CALL_PHONE) != PackageManager.PERMISSION_GRANTED) {
//调用ActivityCompat.requestPermissions()方法获取权限
//param1:当前环境 param2:通过string数组来添加我们想要获取的权限 param3:请求码
ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.CALL_PHONE}, 1);
} else {
//如果获取了权限就直接调用call()方法拨打电话
call();
}
}
});
}
private void call() {
try {
//这里使用了隐式intent方法拨打电话
Intent intent = new Intent(Intent.ACTION_CALL);
intent.setData(Uri.parse("tel:10086"));
startActivity(intent);
} catch (SecurityException e) {
e.printStackTrace();
}
}
//重写onRequestPermissionsResult()方法,接收用户的操作,同意获取或拒绝
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
//通过请求码进行筛选
switch (requestCode) {
case 1:
//条件符合说明获取运行时权限成功
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
call();
} else {
//用户拒绝获取权限,则Toast出一句话提醒用户
Toast.makeText(this, "you denied the permission", Toast.LENGTH_SHORT).show();
}
break;
default:
break;
}
}
}
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.runtimepermissiontest">
<uses-permission android:name="android.permission.CALL_PHONE" />
<application
android:allowBackup="true"
........................
印度人写的第三方插件:链接地址
你可以先看他的介绍,在继续看我的,这样会明白一点
compile 'com.master.android:permissionhelper:2.0'
public class MainActivity extends AppCompatActivity {
private Button callBtn;
//首先创建两个对象
private static final String TAG = "MainActivity";
private PermissionHelper permissionHelper;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
callBtn = findViewById(R.id.main_call_btn);
callBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//下面都是对印度大神代码的copy,只是修改了部分
//将我们要获取的曲线添加进去
permissionHelper = new PermissionHelper(MainActivity.this, new String[]{Manifest.permission.CALL_PHONE}, 100);
permissionHelper.request(new PermissionHelper.PermissionCallback() {
@Override
public void onPermissionGranted() {
//这个方法是全都授权后将要进行的操作,我们在这调用call()方法
call();
Log.d(TAG, "onPermissionGranted() called");
}
@Override
public void onIndividualPermissionGranted(String[] grantedPermission) {
//某个授权
Log.d(TAG, "onIndividualPermissionGranted() called with: grantedPermission = [" + TextUtils.join(",", grantedPermission) + "]");
}
@Override
public void onPermissionDenied() {
//某个拒绝,我们弹出提示
Toast.makeText(MainActivity.this, "you denied the permission", Toast.LENGTH_SHORT).show();
Log.d(TAG, "onPermissionDenied() called");
}
@Override
public void onPermissionDeniedBySystem() {
//用户选择了"不再询问"后,点击"拒绝按钮",执行此方法
Log.d(TAG, "onPermissionDeniedBySystem() called");
}
});
}
});
}
private void call() {
try {
//这里使用了隐式intent方法拨打电话
Intent intent = new Intent(Intent.ACTION_CALL);
intent.setData(Uri.parse("tel:10086"));
startActivity(intent);
} catch (SecurityException e) {
e.printStackTrace();
}
}
//这也是印度大神写的一部分,这里不需要进行修改
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (permissionHelper != null) {
permissionHelper.onRequestPermissionsResult(requestCode, permissions, grantResults);
}
}
}