Android中的事件传递机制

今天来看一下Android中的事件分发以及动态权限

Android的权限机制从第一个版本开始就已经存在,但之前的Android权限机制在保护用户安全和隐私等方面起到的作用有限,为此,Android开发团队在6.0系统中引用了运行时权限的功能

Android6.0的动态权限

共分为 9 组,每组只要有一个权限申请成功了,就默认整组权限都可以使用了

//获取通讯录权限
group:android.permission-group.CONTACTS
        permission:android.permission.WRITE_CONTACTS
        permission:android.permission.GET_ACCOUNTS
        permission:android.permission.READ_CONTACTS
//获取拨打电话的权限     
group:android.permission-group.PHONE
        permission:android.permission.READ_CALL_LOG
        permission:android.permission.READ_PHONE_STATE
        permission:android.permission.CALL_PHONE
        permission:android.permission.WRITE_CALL_LOG
        permission:android.permission.USE_SIP
        permission:android.permission.PROCESS_OUTGOING_CALLS
        permission:com.android.voicemail.permission.ADD_VOICEMAIL
//获取日历的权限
group:android.permission-group.CALENDAR
        permission:android.permission.READ_CALENDAR
        permission:android.permission.WRITE_CALENDAR
        group:android.permission-group.CAMERA
        permission:android.permission.CAMERA
//获取传感器的权限
group:android.permission-group.SENSORS
        permission:android.permission.BODY_SENSORS
        group:android.permission-group.LOCATION
        permission:android.permission.ACCESS_FINE_LOCATION
        permission:android.permission.ACCESS_COARSE_LOCATION
//获取文件读写的权限
group:android.permission-group.STORAGE
        permission:android.permission.READ_EXTERNAL_STORAGE
        permission:android.permission.WRITE_EXTERNAL_STORAGE
//获取麦克风的权限
group:android.permission-group.MICROPHONE
        permission:android.permission.RECORD_AUDIO
//获取短信的权限
group:android.permission-group.SMS
        permission:android.permission.READ_SMS
        permission:android.permission.RECEIVE_WAP_PUSH
        permission:android.permission.RECEIVE_MMS
        permission:android.permission.RECEIVE_SMS
        permission:android.permission.SEND_SMS
        permission:android.permission.READ_CELL_BROADCASTS

只需要在manifest.xml中添加的权限

android.permission.ACCESS_LOCATION_EXTRA_COMMANDS
android.permission.ACCESS_NETWORK_STATE
android.permission.ACCESS_NOTIFICATION_POLICY
android.permission.ACCESS_WIFI_STATE
android.permission.ACCESS_WIMAX_STATE
android.permission.BLUETOOTH
android.permission.BLUETOOTH_ADMIN
android.permission.BROADCAST_STICKY
android.permission.CHANGE_NETWORK_STATE
android.permission.CHANGE_WIFI_MULTICAST_STATE
android.permission.CHANGE_WIFI_STATE
android.permission.CHANGE_WIMAX_STATE
android.permission.DISABLE_KEYGUARD
android.permission.EXPAND_STATUS_BAR
android.permission.FLASHLIGHT
android.permission.GET_ACCOUNTS
android.permission.GET_PACKAGE_SIZE
android.permission.INTERNET
android.permission.KILL_BACKGROUND_PROCESSES
android.permission.MODIFY_AUDIO_SETTINGS
android.permission.NFC
android.permission.READ_SYNC_SETTINGS
android.permission.READ_SYNC_STATS
android.permission.RECEIVE_BOOT_COMPLETED
android.permission.REORDER_TASKS
android.permission.REQUEST_INSTALL_PACKAGES
android.permission.SET_TIME_ZONE
android.permission.SET_WALLPAPER
android.permission.SET_WALLPAPER_HINTS
android.permission.SUBSCRIBED_FEEDS_READ
android.permission.TRANSMIT_IR
android.permission.USE_FINGERPRINT
android.permission.VIBRATE
android.permission.WAKE_LOCK
android.permission.WRITE_SYNC_SETTINGS
com.android.alarm.permission.SET_ALARM
com.android.launcher.permission.INSTALL_SHORTCUT
com.android.launcher.permission.UNINSTALL_SHORTCUT

动态权限申请流程

第一步需要检测是否授权

    //检测是否有写sd卡的权限
    int code = ActivityCompat.checkSelfPermission(this,Manifest.permission.WRITE_EXTERNAL_STORAGE);
    if(code == PackageManager.PERMISSION_DENIED){
        //未授权
    }

如果没有授权则申请授权

ActivityCompat.requestPermissions(this,
        new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, REQUEST_PERMISSION);

最后处理授权结果:在Activity中重写onRequestPermissionsResult

// 授权结果
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
    super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    if (requestCode == REQUEST_PERMISSION) {
        if (grantResults[0] == PackageManager.PERMISSION_DENIED) {
            // 用户拒绝
            // 检测是否有必要跟用户说明为什么要申请这个权限,如果拒绝了会有什么结果
            if (ActivityCompat.shouldShowRequestPermissionRationale(WelcomeActivity.this, permissions[0])) {
                // 解释一下
                AlertDialog.Builder b = new AlertDialog.Builder(WelcomeActivity.this);
                b.setTitle(" 警告 ")
                        .setMessage(" 不授权将影响应用的正常使用 , 是否需要重新授权 ?")
                        .setPositiveButton(" 是 ", new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialog, int which) {
                            ActivityCompat.requestPermissions(WelcomeActivity.this,
                                new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, REQUEST_PERMISSION);
                        }
                    }).setNegativeButton(" 否 ", new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int which) {
                        finish();
                }
            });
            b.show();
        }
    } else {
        toMainActivity();
        }
    }
}

授权 Activity 的封装

1 、封装了授权检测
2 、授权分进入设置 –> 应用详情 –> 权限这种打开方式 以及 直接使用授权申请方法两种
3 、对结果同一处理为 RESULT_OK 就是成功 否则就是授权失败

/**
*  申请授权的 Activity ( 1 、可以进入设置打开或者关闭权限, 2 、直接使用授权申请方法来申请)
* github PermissionGrant
*/
public class PermissionActivity extends Activity {
    private static final int REQUEST_SETTINGS = 1;
    private static final int REQUEST_PERMISSION = 2;
    private String[] permissions;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Intent it = getIntent();
        if (it == null || !it.hasExtra("permissions")) {
            finish();
            return;
        }
        permissions = it.getStringArrayExtra("permissions");
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        setContentView(R.layout.activity_permission);
        findViewById(R.id.btn_setting).setOnClickListener(btnClick);
        findViewById(R.id.btn_grant).setOnClickListener(btnClick);
    }
/**
*  启动授权界面
*
* @param context
* @param requestCode
* @param permissions
*/

public static void startPermissionActivity(Activity context, int requestCode, String... permissions) {
        Intent it = new Intent(context, PermissionActivity.class);
        it.putExtra("permissions", permissions);
        context.startActivityForResult(it, requestCode);
    }
    private View.OnClickListener btnClick = new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            switch (v.getId()) {
                case R.id.btn_setting:
                // 进入设置打开权限
                Intent it = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
                // 配置跳转要查看的应用的包名 packege:com.xykj.filemanager
                it.setData(Uri.parse("package:" + getApplication().getPackageName()));
                startActivityForResult(it, REQUEST_SETTINGS);
                break;
        case R.id.btn_grant:
                // 使用申请授权方法
                ActivityCompat.requestPermissions(PermissionActivity.this, permissions, REQUEST_PERMISSION);
                break;
        }
    }
};
// 授权结果
@Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        if (requestCode == REQUEST_PERMISSION) {
            int deniedIndex = getFirstDeniedIndex(grantResults);
            if (deniedIndex != -1) {
            // 用户拒绝
            // 检测是否有必要跟用户说明为什么要申请这个权限,如果拒绝了会有什么结果
        if(ActivityCompat.shouldShowRequestPermissionRationale(PermissionActivity.this,
                    permissions[deniedIndex])) {
                // 解释一下
                AlertDialog.Builder b = new AlertDialog.Builder(PermissionActivity.this);
                b.setTitle(" 警告 ")
                        .setMessage(" 不授权将影响应用的正常使用 , 是否需要重新授权 ?")
                        .setPositiveButton(" 是 ", new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialog, int which) {
                            ActivityCompat.requestPermissions(
                            PermissionActivity.this,
                            PermissionActivity.this.permissions,
                            REQUEST_PERMISSION);
                        }
                    }).setNegativeButton(" 否 ", new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int which) {
                    finish();
                }
            });
            b.show();
        }
    } else {
        setResult(RESULT_OK);
        finish();
        }
    }
}
private int getFirstDeniedIndex(int[] grantResults) {
    int len = grantResults.length;
    for (int i = 0; i < len; i++) {
        if (grantResults[i] != PackageManager.PERMISSION_GRANTED) {
            return i;
        }
    }
    return -1;
}
/**
*  检测是否授权
*
* @param context
* @param permissions
* @return
*/
public static boolean isGrantedPermission(Context context, List<String> permissions) {
    if (Build.VERSION.SDK_INT < 23) {
        return true;
    }
    int size = permissions.size();
    for (int i = 0; i < size; i++) {
        String name = permissions.get(i);
        // 一个个的检测授权情况,如果发现了其中某一个未授权,返回 false 表示检测授权失败
        int code = ActivityCompat.checkSelfPermission(context, name);
        if (code == PackageManager.PERMISSION_DENIED) {
            return false;
        }
        String op = AppOpsManagerCompat.permissionToOp(name);
        if (TextUtils.isEmpty(op)) {
            continue;
        }
        code = AppOpsManagerCompat.noteProxyOp(context, op,                 context.getApplicationContext().getPackageName());
        if (code != AppOpsManagerCompat.MODE_ALLOWED) {
            return false;
        }
    }
    return true;
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == REQUEST_SETTINGS) {
            if (isGrantedPermission(PermissionActivity.this, permissions)) {
                setResult(RESULT_OK);
            } else {
                setResult(RESULT_CANCELED);
            }
            finish();
        }
    }
}

为了方便该授权Activity的运用,可以将其显示为Dialog

<activity android:name=".PermissionActivity"
android:theme="@android:style/Theme.Dialog"></activity>

使用:

if (!PermissionActivity.isGrantedPermission(this,Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
    // 未授权,申请授权
    PermissionActivity.startPermissionActivity(this,REQUEST_PERMISSION,Manifest.permission.WRITE_EXTERNAL_STORAGE);
} else {
        // 成功
        ...
}
结果处理
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if(resultCode == RESULT_OK){
        // 授权成功
    }else{
        // 授权失败
    }
}

这里我后续会慢慢改进

猜你喜欢

转载自blog.csdn.net/weixin_42097095/article/details/80740082