Android は動的にアクセス許可を取得します
概要
Android6.0未満のバージョンの場合は、マニフェストで対応する権限を宣言するだけで済みます。ただし、これによりシステムのセキュリティが大幅に低下します。したがって、android6.0 以降では、アプリはユーザーからのフィードバックを取得して権限を取得する必要があります。
権限への動的アクセス
権限への動的アクセスは 2 つの状況に分類できます。状況 1.アプリの特定の機能を操作するときに、特定の権限が動的に取得されるこの状況を「怠け者」取得と呼びます。状況 2 : 初期状況 (onCreate で取得) では、必要なすべてのアクセス許可が直接取得されます。これは、「ハングリー スタイル」です。
実装
たとえば、アプリを使用する場合、アドレス帳の読み取りおよび書き込み権限と、 SMSの読み取りおよび送信権限を取得する必要があります。
注: アドレス帳の読み取りは許可であり、アドレス帳の書き込みは許可です。これらは 2 つの権限です。
テキスト メッセージの読み取りは権限であり、テキスト メッセージの送信もテキスト メッセージを操作する権限です。
レイアウト レイアウトコード
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:gravity="center_horizontal"
>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/btn_contact"
android:text="获取通讯录的读写权限"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/btn_sms"
android:text="获取短信的查看发送权限"/>
</LinearLayout>
アドレス帳の読み取りおよび書き込み権限を取得するボタンの ID : btn_contact
SMS の表示および送信権限を取得するボタンの ID : btn_sms
コールバック関数 onRequestPermissionsResult
このコールバック関数は、ユーザーがポップアップ ウィンドウをクリックして権限を動的に取得した後に実行されます。動的に権限を取得する画面が表示されるので、その画面で「許可」または「許可しない」を選択し、選択完了後、コールバック関数で許可の有無を判定します。許可。
関数は MainActivity クラスにあります
//点击申请权限弹框后的回调函数
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
}
許可判定ツールクラス
public class PermissionUtil {
//检查某个功能的多个权限,返回true表示已完全启用权限,返回false表示未完全启用权限
//比如通讯录这个功能,需要获取它有的多个权限[读权限,写权限]
//act:当前的Activity
//permissions:某个功能的权限集合,如通讯录的[读,写]
//requestCode:标识一下“某个功能”
public static boolean checkPermission(Activity act, String[] permissions, int requestCode){
//判断android的版本
//Build.VERSION.SDK_INT:当前android的版本
//Build.VERSION_CODES.M:android6.0
if (Build.VERSION.SDK_INT>=Build.VERSION_CODES.M){
//安卓版本在6.0及以后才需要判断 M就是6.0
//check的含义:权限是否开启
//这里给了默认值PackageManager.PERMISSION_GRANTED,意思是开启权限
int check = PackageManager.PERMISSION_GRANTED;//默认授权的值
for (String permission:permissions){
//返回结果为是否授权
check = ContextCompat.checkSelfPermission(act, permission);
//如果没有授权,则退出
if (check!=PackageManager.PERMISSION_GRANTED){
break;
}
}
//未开启该权限,则请求系统弹窗,好让用户选择是否立即开启权限
if (check!=PackageManager.PERMISSION_GRANTED){
//弹窗,用户操作
ActivityCompat.requestPermissions(act,permissions,requestCode);
return false;
}
}
return true;
}
//grantResults:是用户点“授权”完弹窗后的授权结果数组
//检查权限结果数组,返回true表示都已经获得授权。返回false表示至少有一个未获得授权
public static boolean checkGrant(int[] grantResults) {
if (grantResults!=null){
//遍历权限结果数组中的每条选择结果
for (int grant:grantResults){
//未获得授权
if (grant!=PackageManager.PERMISSION_GRANTED){
return false;
}
}
return true;
}
return false;
}
}
マニフェストファイル
権限の宣言 権限 (宣言する必要があります)
<!-- 声明读写通讯录权限-->
<uses-permission android:name="android.permission.READ_CONTACTS"/>
<uses-permission android:name="android.permission.WRITE_CONTACTS"/>
<!--声明读发短信权限-->
<uses-permission android:name="android.permission.READ_SMS"/>
<uses-permission android:name="android.permission.SEND_SMS"/>
方法 1: 怠惰なスタイル
前述したように、遅延スタイルは、アプリが特定の機能を実行したときに、対応する権限を取得することですが、ここでの「特定の機能」とは、ボタンがクリックされたときに動的に権限を取得することです。
権限の配列を定義する
//通信录的读写权限
private static final String[] PERMISSIONS_CONTACTS=new String[]{
Manifest.permission.READ_CONTACTS,//读通讯录
Manifest.permission.WRITE_CONTACTS//写通讯录
};
//短信的发送、读取权限
private static final String[] PERMISSIONS_SMS=new String[]{
Manifest.permission.SEND_SMS,//发送短信
Manifest.permission.READ_SMS//读取短信
};
認証コード
//标识通讯录
private static final int REQUEST_CODE_CONTACTS=1;
//标识短信
private static final int REQUEST_CODE_SMS=2;
クリックイベント監視
View.OnClickListenerの実装とonClickメソッドの実装
@Override
public void onClick(View view) {
switch (view.getId()){
case R.id.btn_contact:
PermissionUtil.checkPermission(this,PERMISSIONS_CONTACTS,REQUEST_CODE_CONTACTS);
break;
case R.id.btn_sms:
PermissionUtil.checkPermission(this,PERMISSIONS_CONTACTS,REQUEST_CODE_SMS);
break;
}
}
権限がない場合、ツール クラス PermissionUtil の次のステートメントが実行されることがわかります。
ActivityCompat.requestPermissions(act,permissions,requestCode);
すべての権限を取得するかどうかをユーザーが選択するポップアップウィンドウが表示され、
選択後アクティビティ内でコールバックされるため、この関数内で権限を取得するかどうかを判断できます。
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
}
MainActivity の完全なコード
package com.example.demo8;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import android.Manifest;
import android.os.Bundle;
import android.view.View;
import android.widget.Toast;
import com.example.demo8.util.PermissionUtil;
public class MainActivity extends AppCompatActivity implements View.OnClickListener{
//通信录的读写权限
private static final String[] PERMISSIONS_CONTACTS=new String[]{
Manifest.permission.READ_CONTACTS,
Manifest.permission.WRITE_CONTACTS
};
//短信的发送、读取权限
private static final String[] PERMISSIONS_SMS=new String[]{
Manifest.permission.SEND_SMS,
Manifest.permission.READ_SMS
};
//标识通讯录
private static final int REQUEST_CODE_CONTACTS=1;
//标识短信
private static final int REQUEST_CODE_SMS=2;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//设置监听事件
findViewById(R.id.btn_contact).setOnClickListener(this);
findViewById(R.id.btn_sms).setOnClickListener(this);
}
@Override
public void onClick(View view) {
switch (view.getId()){
case R.id.btn_contact:
//上下文、权限数组、标识
PermissionUtil.checkPermission(this,PERMISSIONS_CONTACTS,REQUEST_CODE_CONTACTS);
break;
case R.id.btn_sms:
PermissionUtil.checkPermission(this,PERMISSIONS_SMS,REQUEST_CODE_SMS);
break;
}
}
//点击申请权限弹框后的回调函数
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
switch (requestCode){
case REQUEST_CODE_CONTACTS:
if (PermissionUtil.checkGrant(grantResults)){
Toast.makeText(this, "通讯录权限获取成功", Toast.LENGTH_SHORT).show();
}else{
Toast.makeText(this, "获取通讯录读写权限获取失败", Toast.LENGTH_SHORT).show();
}
break;
case REQUEST_CODE_SMS:
if (PermissionUtil.checkGrant(grantResults)){
Toast.makeText(this, "收发短信权限获取成功", Toast.LENGTH_SHORT).show();
}else{
Toast.makeText(this, "收发短信权限获取失败", Toast.LENGTH_SHORT).show();
}
break;
}
}
}
方法2: お腹を空かせた中華風
「onCreate」時に許可を申請するのがハングリー中華流で、一度に設定されます。
適用する必要があるすべての権限を配列に入れます
//将权限放到一个数组中
private static final String[] PERMISSIONS=new String[]{
//通信录的读写权限
Manifest.permission.READ_CONTACTS,
Manifest.permission.WRITE_CONTACTS,
//短信的发送、读取权限
Manifest.permission.SEND_SMS,
Manifest.permission.READ_SMS
};
oncreate でのアクセス許可の適用
残りの原則は遅延スタイルと同じですが、アクセス許可を適用する時間が異なります。
連絡先
SMS
MainActivity コード
public class MainActivity extends AppCompatActivity implements View.OnClickListener{
//将权限放到一个数组中
private static final String[] PERMISSIONS=new String[]{
//通信录的读写权限
Manifest.permission.READ_CONTACTS,
Manifest.permission.WRITE_CONTACTS,
//短信的发送、读取权限
Manifest.permission.SEND_SMS,
Manifest.permission.READ_SMS
};
private static final int REQUEST_CODE=1;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
/初始获取权限
PermissionUtil.checkPermission(this,PERMISSIONS,REQUEST_CODE);
//设置监听事件
findViewById(R.id.btn_contact).setOnClickListener(this);
findViewById(R.id.btn_sms).setOnClickListener(this);
}
//饿汉式这里无用
@Override
public void onClick(View view) {
switch (view.getId()){
case R.id.btn_contact:
break;
case R.id.btn_sms:
break;
}
}
//点击申请权限弹框后的回调函数
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
switch (requestCode){
case REQUEST_CODE:
if (PermissionUtil.checkGrant(grantResults)){
Toast.makeText(this, "权限获取成功", Toast.LENGTH_SHORT).show();
}else{
Toast.makeText(this, "权限获取失败", Toast.LENGTH_SHORT).show();
}
break;
}
}
}