• 基础复习——运行时动态申请权限——重点


    App涉及到硬件设备的操作,比如拍照、录音、定位、SD卡等等,都要在AndroidManifest.xml中声明相关的权限。


    可是Android系统为了防止某些App滥用权限,又允许用户在系统设置里面对App禁用某些权限。


    但这又带来另一个问题,用户打开App之后,App可能因为权限不足导致无法正常运行,甚至直接崩溃闪退。


    有鉴于此,Android从6.0开始引入了运行时权限管理机制,允许App在运行过程中动态检查是否拥有某项权限,一旦发现缺少某种必需的权限,则系统会自动弹出小窗提示用户去开启该权限。

    (1)检查App是否开启了指定权限


    调用ContextCompat的checkSelfPermission方法。


    (2)请求系统弹窗,以便用户选择是否开启权限


    调用ActivityCompat的requestPermissions方法,即可命令系统自动弹出权限申请窗口。


    (3)判断用户的权限选择结果


    重写活动页面的权限请求回调方法onRequestPermissionsResult,在该方法内部处理用户的权限选择结果。

    权限:

        <!-- 存储卡读写 -->
        <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
        <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
        <!-- Android10新增权限MANAGE_EXTERNAL_STORAGE -->
        <uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" />
        <!-- 联系人/通讯录。包括读联系人、写联系人 -->
        <uses-permission android:name="android.permission.READ_CONTACTS" />
        <uses-permission android:name="android.permission.WRITE_CONTACTS" />
        <!-- 短信。包括发送短信、接收短信、读短信 -->
        <uses-permission android:name="android.permission.SEND_SMS" />
        <uses-permission android:name="android.permission.RECEIVE_SMS" />
        <uses-permission android:name="android.permission.READ_SMS" />
        <!-- 通话记录。包括读通话记录、写通话记录 -->
        <uses-permission android:name="android.permission.READ_CALL_LOG" />
        <uses-permission android:name="android.permission.WRITE_CALL_LOG" />
        <!-- 安装应用请求,Android8.0需要 -->
        <uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />
        <!-- 获取媒体位置(Android10新增权限) -->
        <uses-permission android:name="android.permission.ACCESS_MEDIA_LOCATION" />

    PermissionUtil
    package com.example.myapplication.util;
    
    import android.app.Activity;
    import android.content.Context;
    import android.content.Intent;
    import android.content.pm.PackageManager;
    import android.os.Build;
    import androidx.core.app.ActivityCompat;
    import androidx.core.content.ContextCompat;
    
    public class PermissionUtil
    {
        private final static String TAG = "PermissionUtil";
    
        // 检查某个权限。返回true表示已启用该权限,返回false表示未启用该权限
        public static boolean checkPermission(Activity act, String permission, int requestCode)
        {
    
            return checkPermission(act, new String[]{permission}, requestCode);
        }
    
        // 检查多个权限。返回true表示已完全启用权限,返回false表示未完全启用权限
        public static boolean checkPermission(Activity act, String[] permissions, int requestCode)
        {
            boolean result = true;
    
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M)
            {
                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);
    
                    result = false;
                }
            }
    
            return result;
    
        }
    
        // 检查权限结果数组,返回true表示都已经获得授权。返回false表示至少有一个未获得授权
        public static boolean checkGrant(int[] grantResults)
        {
            boolean result = true;
    
            if (grantResults != null)
            {
                for (int grant : grantResults)  // 遍历权限结果数组中的每条选择结果
                {
                    if (grant != PackageManager.PERMISSION_GRANTED) { // 未获得授权
                        result = false;
                    }
                }
    
            }
            else
            {
    
                result = false;
            }
    
            return result;
        }
    
    }

    权限校验:

    package com.example.myapplication;
    
    import android.Manifest;
    import android.content.Intent;
    import android.os.Bundle;
    import android.view.View;
    import android.widget.Toast;
    import androidx.appcompat.app.AppCompatActivity;
    import com.example.myapplication.util.PermissionUtil;
    
    public class MainActivity extends AppCompatActivity implements View.OnClickListener
    {
    
        @Override
        protected void onCreate(Bundle savedInstanceState)
        {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            findViewById(R.id.btn_next1).setOnClickListener(this);
            findViewById(R.id.btn_next2).setOnClickListener(this);
        }
    
        @Override
        public void onClick(View v)
        {
    
            if (PermissionUtil.checkPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE, R.id.btn_next1 % 65536))
            {
                startActivity(new Intent(this, ContentWriteActivity.class));
            }
            else
            {
                Toast.makeText(this, "需要允许存储卡权限噢", Toast.LENGTH_SHORT).show();
            }
    
            if (v.getId() == R.id.btn_next2)
            {
                startActivity(new Intent(this, ContentReadActivity.class));  //创建一个目标确定的意图
    
            }
        }
    }

    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">
    
        <ScrollView
            android:layout_width="match_parent"
            android:layout_height="wrap_content">
    
            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:paddingBottom="10dp"
                android:orientation="vertical">
    
                <TextView
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:layout_marginTop="20dp"
                    android:gravity="center"
                    android:text="7.1 在应用之间共享数据" />
    
                <LinearLayout
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:orientation="horizontal">
    
                    <Button
                        android:id="@+id/btn_content_write"
                        android:layout_width="0dp"
                        android:layout_height="wrap_content"
                        android:layout_weight="1"
                        android:text="写入共享内容" />
    
                    <Button
                        android:id="@+id/btn_content_read"
                        android:layout_width="0dp"
                        android:layout_height="wrap_content"
                        android:layout_weight="1"
                        android:text="读取共享内容" />
    
                </LinearLayout>
    
                <TextView
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:layout_marginTop="20dp"
                    android:gravity="center"
                    android:text="7.2 获取通讯信息" />
    
                <LinearLayout
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:orientation="horizontal">
    
                    <Button
                        android:id="@+id/btn_file_write"
                        android:layout_width="0dp"
                        android:layout_height="wrap_content"
                        android:layout_weight="1"
                        android:text="公共空间写入文本文件" />
    
                    <Button
                        android:id="@+id/btn_file_read"
                        android:layout_width="0dp"
                        android:layout_height="wrap_content"
                        android:layout_weight="1"
                        android:text="公共空间读取文本文件" />
                </LinearLayout>
    
                <LinearLayout
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:orientation="horizontal">
    
                    <Button
                        android:id="@+id/btn_contact_add"
                        android:layout_width="0dp"
                        android:layout_height="wrap_content"
                        android:layout_weight="1"
                        android:text="添加联系人" />
    
                    <Button
                        android:id="@+id/btn_contact_read"
                        android:layout_width="0dp"
                        android:layout_height="wrap_content"
                        android:layout_weight="1"
                        android:text="读取联系人" />
    
                    <Button
                        android:id="@+id/btn_monitor_sms"
                        android:layout_width="0dp"
                        android:layout_height="wrap_content"
                        android:layout_weight="1"
                        android:text="流量校准" />
    
                </LinearLayout>
    
                <TextView
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:layout_marginTop="20dp"
                    android:gravity="center"
                    android:text="7.3 在应用之间共享文件" />
    
                <LinearLayout
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:orientation="horizontal">
    
                    <Button
                        android:id="@+id/btn_send_mms"
                        android:layout_width="0dp"
                        android:layout_height="wrap_content"
                        android:layout_weight="1"
                        android:text="发送彩信(通过系统相册)" />
    
                    <Button
                        android:id="@+id/btn_provider_mms"
                        android:layout_width="0dp"
                        android:layout_height="wrap_content"
                        android:layout_weight="1"
                        android:text="发送彩信(Provider方式)" />
                </LinearLayout>
    
                <LinearLayout
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:orientation="horizontal">
    
                    <Button
                        android:id="@+id/btn_provider_apk"
                        android:layout_width="0dp"
                        android:layout_height="wrap_content"
                        android:layout_weight="1"
                        android:text="安装应用" />
    
                </LinearLayout>
    
            </LinearLayout>
        </ScrollView>
    
    </LinearLayout>
    package com.example.chapter07;
    
    import android.Manifest;
    import android.content.Intent;
    import android.os.Bundle;
    import android.view.View;
    import android.widget.Toast;
    
    import androidx.appcompat.app.AppCompatActivity;
    
    import com.example.chapter07.util.PermissionUtil;
    
    public class MainActivity extends AppCompatActivity implements View.OnClickListener {
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            findViewById(R.id.btn_content_write).setOnClickListener(this);
            findViewById(R.id.btn_content_read).setOnClickListener(this);
            findViewById(R.id.btn_file_write).setOnClickListener(this);
            findViewById(R.id.btn_file_read).setOnClickListener(this);
            findViewById(R.id.btn_contact_add).setOnClickListener(this);
            findViewById(R.id.btn_contact_read).setOnClickListener(this);
            findViewById(R.id.btn_monitor_sms).setOnClickListener(this);
            findViewById(R.id.btn_send_mms).setOnClickListener(this);
            findViewById(R.id.btn_provider_mms).setOnClickListener(this);
            findViewById(R.id.btn_provider_apk).setOnClickListener(this);
        }
    
        @Override
        public void onClick(View v) {
            if (v.getId() == R.id.btn_content_write) {
                Intent intent = new Intent(this, ContentWriteActivity.class);
                startActivity(intent);
            } else if (v.getId() == R.id.btn_content_read) {
                Intent intent = new Intent(this, ContentReadActivity.class);
                startActivity(intent);
            } else if (v.getId() == R.id.btn_file_write) {
                if (PermissionUtil.checkPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE, R.id.btn_file_write % 65536)) {
                    startActivity(new Intent(this, FileWriteActivity.class));
                }
            } else if (v.getId() == R.id.btn_file_read) {
                if (PermissionUtil.checkPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE, R.id.btn_file_read % 65536)) {
                    startActivity(new Intent(this, FileReadActivity.class));
                }
            } else if (v.getId() == R.id.btn_contact_add) {
                if (PermissionUtil.checkPermission(this, Manifest.permission.WRITE_CONTACTS, R.id.btn_contact_add % 65536)) {
                    startActivity(new Intent(this, ContactAddActivity.class));
                }
            } else if (v.getId() == R.id.btn_contact_read) {
                if (PermissionUtil.checkPermission(this, Manifest.permission.READ_CONTACTS, R.id.btn_contact_read % 65536)) {
                    startActivity(new Intent(this, ContactReadActivity.class));
                }
            } else if (v.getId() == R.id.btn_monitor_sms) {
                if (PermissionUtil.checkPermission(this, new String[] {Manifest.permission.SEND_SMS, Manifest.permission.READ_SMS}, R.id.btn_monitor_sms % 65536)) {
                    startActivity(new Intent(this, MonitorSmsActivity.class));
                }
            } else if (v.getId() == R.id.btn_send_mms) {
                Intent intent = new Intent(this, SendMmsActivity.class);
                startActivity(intent);
            } else if (v.getId() == R.id.btn_provider_mms) {
                if (PermissionUtil.checkPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE, R.id.btn_provider_mms % 65536)) {
                    startActivity(new Intent(this, ProviderMmsActivity.class));
                }
            } else if (v.getId() == R.id.btn_provider_apk) {
                if (PermissionUtil.checkPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE, R.id.btn_provider_apk % 65536)) {
                    startActivity(new Intent(this, ProviderApkActivity.class));
                }
            }
        }
    
        @Override
        public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
            super.onRequestPermissionsResult(requestCode, permissions, grantResults);
            // requestCode不能为负数,也不能大于2的16次方即65536
            if (requestCode == R.id.btn_file_write % 65536) {
                if (PermissionUtil.checkGrant(grantResults)) { // 用户选择了同意授权
                    startActivity(new Intent(this, FileWriteActivity.class));
                } else {
                    //ToastUtil.show(this, "需要允许存储卡权限才能写入公共空间噢");
                    Toast.makeText(this, "需要允许存储卡权限才能写入公共空间噢", Toast.LENGTH_SHORT).show();
                }
            } else if (requestCode == R.id.btn_file_read % 65536) {
                if (PermissionUtil.checkGrant(grantResults)) { // 用户选择了同意授权
                    startActivity(new Intent(this, FileReadActivity.class));
                } else {
                    Toast.makeText(this, "需要允许存储卡权限才能读取公共空间噢", Toast.LENGTH_SHORT).show();
                }
            } else if (requestCode == R.id.btn_contact_add % 65536) {
                if (PermissionUtil.checkGrant(grantResults)) { // 用户选择了同意授权
                    startActivity(new Intent(this, ContactAddActivity.class));
                } else {
                    Toast.makeText(this, "需要允许通讯录权限才能读写联系人噢", Toast.LENGTH_SHORT).show();
                }
            } else if (requestCode == R.id.btn_contact_read % 65536) {
                if (PermissionUtil.checkGrant(grantResults)) { // 用户选择了同意授权
                    startActivity(new Intent(this, ContactReadActivity.class));
                } else {
                    Toast.makeText(this, "需要允许通讯录权限才能读写联系人噢", Toast.LENGTH_SHORT).show();
                }
            } else if (requestCode == R.id.btn_monitor_sms % 65536) {
                if (PermissionUtil.checkGrant(grantResults)) { // 用户选择了同意授权
                    startActivity(new Intent(this, MonitorSmsActivity.class));
                } else {
                    Toast.makeText(this, "需要允许短信权限才能校准流量噢", Toast.LENGTH_SHORT).show();
                }
            } else if (requestCode == R.id.btn_provider_mms % 65536) {
                if (PermissionUtil.checkGrant(grantResults)) { // 用户选择了同意授权
                    startActivity(new Intent(this, ProviderMmsActivity.class));
                } else {
                    Toast.makeText(this, "需要允许存储卡权限才能发送彩信噢", Toast.LENGTH_SHORT).show();
                }
            } else if (requestCode == R.id.btn_provider_apk % 65536) {
                if (PermissionUtil.checkGrant(grantResults)) { // 用户选择了同意授权
                    startActivity(new Intent(this, ProviderApkActivity.class));
                } else {
                    Toast.makeText(this, "需要允许存储卡权限才能安装应用噢", Toast.LENGTH_SHORT).show();
                }
            }
        }
    
    }

     

     

     

     

  • 相关阅读:
    GitHub入门教程
    转:使用ActiveX插件时object显示问题,div被object标签遮挡的解决方案
    windows集成资料
    转:获取windows凭证管理器明文密码
    转: OVER() 系列函数介绍
    SQL Prompt 快捷键
    转:敏捷开发之Scrum扫盲篇
    转:修改IIS虚拟目录名称bat脚本
    转:EditPuls 5.0 注册码
    转:RowVersion 用法
  • 原文地址:https://www.cnblogs.com/xiaobaibailongma/p/16610115.html
Copyright © 2020-2023  润新知