Android动态运行时权限

news2024/11/24 19:34:28

        android 6.0(API 级别 23)开始,android引入了运行时权限,应用安装时不向其授予权限,应用运行时向其授予权限。如果在运行时该功能没有动态地申请相应的权限,就会抛出SecurityException异常。

        android的运行时权限的申请过程主要有两步:
        1、在需要申请权限的地方检查该权限是否被授权,如果已经授权就直接执行,如果未授权就动态申请权限。
        2、重写Activity或Fragment的onRequestPermissionsResult方法,根据grantResults数组判断权限是否被授权,如果授权就直接执行,如果未授权就要进行相应的提示,如果用户勾选了“don't ask again”,还要引导用户去“Settings”界面打开权限,这时还要重写onActivityResult判断权限是否被授权。

权限的分类

        android中所有的预定义权限(不包括厂商自定义的)都可以在Manifest.permission这个静态类中找到定义,android把权限分为四类:普通权限、签名权限、危险权限和特殊权限,每一种类型的权限都分配一个对应的Protection Level,分别为:normal、signature、dangerous和appop。

1、普通权限
普通权限,Protection Level为normal,不需要动态申请,只需要在AndroidManifest.xml中静态地声明,系统在应用安装时就会自动的授予该应用相应的权限。

2、签名权限
这类权限我们用得比较少,它只对拥有相同签名的应用开放,Protection Level为signature,不需要动态申请,例如应用A在AndroidManifest.xml中自定义了一个permission且在权限标签中加入android:protectionLevel=”signature”,表示应用A声明了一个签名权限,那么应用B想要访问应用A受该权限保护的数据时,必须要在AndroidManifest.xml中声明该权限,同时要用与应用A相同的签名打包,这样系统在应用B安装时才会自动地授予应用B该权限,应用B在获得授权后就可以访问该权限控制的数据,其他应用即使知道这个权限,也在AndroidManifest.xml中声明了该权限,但由于应用签名不同,安装时系统不会授予它该权限,这样其他应用就无法访问受该权限保护的数据。
还有一些签名权限不会供第三方应用程序使用,只会供系统预装应用使用,这种签名权限的Protection Level为signature和privileged。

3、危险权限
危险权限也叫运行时权限,Protection Level为dangerous,
所有的危险权限都有对应的权限组,当我们动态的申请某个危险权限时,都是按权限组申请的,当用户一旦同意授权该危险权限,那么该权限所对应的权限组中的其他在AndroidManifest.xml中注册的权限也会同时被授权,android预定义的11个权限组包含的危险权限如下:

Permission GroupDangerous Permissions
CALENDAR (日历)READ_CALENDAR
WRITE_CALENDAR
CALL_LOG (通话记录,Added in android 29)READ_CALL_LOG
WRITE_CALL_LOG
PROCESS_OUTGOING_CALLS
CAMERA (相机)CAMERA
CONTACTS (通讯录)READ_CONTACTS
WRITE_CONTACTS
GET_ACCOUNTS
LOCATION (位置信息)ACCESS_COARSE_LOCATION
ACCESS_FINE_LOCATION
ACCESS_BACKGROUND_LOCATION (Added in android 10)
MICROPHONE (麦克风)RECORD_AUDIO
PHONE (电话)READ_PHONE_NUMBERS  READ_PHONE_STATE  CALL_PHONE  ANSWER_PHONE_CALLS  ADD_VOICEMAIL  USE_SIP  ACCEPT_HANDOVER (Added in android 9)
SENSORS (身体传感器)BODY_SENSORS
SMS (短信)BODY_SENSORS
STORAGE (存储空间)READ_EXTERNAL_STORAGE
WRITE_EXTERNAL_STORAGE
ACCESS_MEDIA_LOCATION (Added in android 10)
ACTIVITY_RECOGNITION (身体活动,Added in android 10)    ACTIVITY_RECOGNITION (Added in android 10)
访问媒体文件 READ_MEDIA_IMAGES, READ_MEDIA_VIDEO, READ_MEDIA_AUDIO (Added in android 13)
通知权限POST_NOTIFICATIONS (Added in android 13)

4.特殊权限

特殊权限用于保护一些特定的应用程序操作,Protection Level为appop,使用前也需要在AndroidManifest.xml中静态地声明,也需要动态的申请,特殊权限的申请需要跳转到指定的设置界面,点击同意,截止到android 11,常用的5个特殊权限为:

1.SYSTEM_ALERT_WINDOW:允许应用在其他应用的顶部绘制悬浮窗,当你创建的悬浮窗是TYPE_APPLICATION_OVERLAY类型时需要申请这个权限;


2.WRITE_SETTINGS:允许应用修改系统设置,当你需要修改系统参数Settings.System时需要申请该权限,例如修改系统屏幕亮度等;


3.REQUEST_INSTALL_PACKAGES: 允许应用安装未知来源应用,android 8.0以后当你在应用中安装第三方应用时需要申请这个权限,否则不会跳转到安装界面;


4.PACKAGE_USAGE_STATS:允许应用收集其他应用的使用信息,当你使用UsageStatsManager相关Api获取其他应用的信息时需要申请这个权限;


5.MANAGE_EXTERNAL_STORAGE(Added in android 11):允许应用访问作用域存储(scoped storage)中的外部存储,android 11以后强制新安装的应用使用作用域存储,但是对于文件管理器这一类的应用它们需要管理整个SD卡上的文件,所以针对这些特殊应用可以申请这个权限来获得对整个SD卡的读写权限,当应用授予这个权限后,它就可以访问文件的真实路径,注意这个权限是很危险的,声明这个权限上架应用时可能需要进行审核.

除了特殊权限,LOCATION权限组中的位置权限也有点特殊,需要注意一下,位置信息的获取不仅依赖位置权限的动态申请还依赖系统定位开关,如果你没有打开定位开关就申请了位置权限,那么就算用户同意授权位置权限,应用通过Location相关Api也无法获取到位置信息,所以申请位置权限前,最好先通过LocationManager#isProviderEnabled方法判断是否打开定位开关后再进行位置权限的申请,如果没有打开定位开关需要先跳转到设置界面打开定位开关:


    LocationManager locationManager = (LocationManager) getContext()
                    .getSystemService(Context.LOCATION_SERVICE);
            if (locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER) || locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER)) {
               //请求权限
            } else {
                    //跳转到开启定位的地方
        Toast.makeText(this, "检测到未开启定位服务,请开启", Toast.LENGTH_SHORT).show();
        Intent intent = Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
        startActivityForResult(intent, REQUEST_CODE_LOCATION_PROVIDER);
            }

 

//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//

package android;

public final class Manifest {
    public Manifest() {
        throw new RuntimeException("Stub!");
    }

    public static final class permission_group {
        public static final String ACTIVITY_RECOGNITION = "android.permission-group.ACTIVITY_RECOGNITION";
        public static final String CALENDAR = "android.permission-group.CALENDAR";
        public static final String CALL_LOG = "android.permission-group.CALL_LOG";
        public static final String CAMERA = "android.permission-group.CAMERA";
        public static final String CONTACTS = "android.permission-group.CONTACTS";
        public static final String LOCATION = "android.permission-group.LOCATION";
        public static final String MICROPHONE = "android.permission-group.MICROPHONE";
        public static final String NEARBY_DEVICES = "android.permission-group.NEARBY_DEVICES";
        public static final String PHONE = "android.permission-group.PHONE";
        public static final String SENSORS = "android.permission-group.SENSORS";
        public static final String SMS = "android.permission-group.SMS";
        public static final String STORAGE = "android.permission-group.STORAGE";

        public permission_group() {
            throw new RuntimeException("Stub!");
        }
    }

    public static final class permission {
        public static final String ACCEPT_HANDOVER = "android.permission.ACCEPT_HANDOVER";
        public static final String ACCESS_BACKGROUND_LOCATION = "android.permission.ACCESS_BACKGROUND_LOCATION";
        public static final String ACCESS_BLOBS_ACROSS_USERS = "android.permission.ACCESS_BLOBS_ACROSS_USERS";
        public static final String ACCESS_CHECKIN_PROPERTIES = "android.permission.ACCESS_CHECKIN_PROPERTIES";
        public static final String ACCESS_COARSE_LOCATION = "android.permission.ACCESS_COARSE_LOCATION";
        public static final String ACCESS_FINE_LOCATION = "android.permission.ACCESS_FINE_LOCATION";
        public static final String ACCESS_LOCATION_EXTRA_COMMANDS = "android.permission.ACCESS_LOCATION_EXTRA_COMMANDS";
        public static final String ACCESS_MEDIA_LOCATION = "android.permission.ACCESS_MEDIA_LOCATION";
        public static final String ACCESS_NETWORK_STATE = "android.permission.ACCESS_NETWORK_STATE";
        public static final String ACCESS_NOTIFICATION_POLICY = "android.permission.ACCESS_NOTIFICATION_POLICY";
        public static final String ACCESS_WIFI_STATE = "android.permission.ACCESS_WIFI_STATE";
        public static final String ACCOUNT_MANAGER = "android.permission.ACCOUNT_MANAGER";
        public static final String ACTIVITY_RECOGNITION = "android.permission.ACTIVITY_RECOGNITION";
        public static final String ADD_VOICEMAIL = "com.android.voicemail.permission.ADD_VOICEMAIL";
        public static final String ANSWER_PHONE_CALLS = "android.permission.ANSWER_PHONE_CALLS";
        public static final String BATTERY_STATS = "android.permission.BATTERY_STATS";
        public static final String BIND_ACCESSIBILITY_SERVICE = "android.permission.BIND_ACCESSIBILITY_SERVICE";
        public static final String BIND_APPWIDGET = "android.permission.BIND_APPWIDGET";
        public static final String BIND_AUTOFILL_SERVICE = "android.permission.BIND_AUTOFILL_SERVICE";
        public static final String BIND_CALL_REDIRECTION_SERVICE = "android.permission.BIND_CALL_REDIRECTION_SERVICE";
        public static final String BIND_CARRIER_MESSAGING_CLIENT_SERVICE = "android.permission.BIND_CARRIER_MESSAGING_CLIENT_SERVICE";
        /** @deprecated */
        @Deprecated
        public static final String BIND_CARRIER_MESSAGING_SERVICE = "android.permission.BIND_CARRIER_MESSAGING_SERVICE";
        public static final String BIND_CARRIER_SERVICES = "android.permission.BIND_CARRIER_SERVICES";
        /** @deprecated */
        @Deprecated
        public static final String BIND_CHOOSER_TARGET_SERVICE = "android.permission.BIND_CHOOSER_TARGET_SERVICE";
        public static final String BIND_COMPANION_DEVICE_SERVICE = "android.permission.BIND_COMPANION_DEVICE_SERVICE";
        public static final String BIND_CONDITION_PROVIDER_SERVICE = "android.permission.BIND_CONDITION_PROVIDER_SERVICE";
        public static final String BIND_CONTROLS = "android.permission.BIND_CONTROLS";
        public static final String BIND_DEVICE_ADMIN = "android.permission.BIND_DEVICE_ADMIN";
        public static final String BIND_DREAM_SERVICE = "android.permission.BIND_DREAM_SERVICE";
        public static final String BIND_INCALL_SERVICE = "android.permission.BIND_INCALL_SERVICE";
        public static final String BIND_INPUT_METHOD = "android.permission.BIND_INPUT_METHOD";
        public static final String BIND_MIDI_DEVICE_SERVICE = "android.permission.BIND_MIDI_DEVICE_SERVICE";
        public static final String BIND_NFC_SERVICE = "android.permission.BIND_NFC_SERVICE";
        public static final String BIND_NOTIFICATION_LISTENER_SERVICE = "android.permission.BIND_NOTIFICATION_LISTENER_SERVICE";
        public static final String BIND_PRINT_SERVICE = "android.permission.BIND_PRINT_SERVICE";
        public static final String BIND_QUICK_ACCESS_WALLET_SERVICE = "android.permission.BIND_QUICK_ACCESS_WALLET_SERVICE";
        public static final String BIND_QUICK_SETTINGS_TILE = "android.permission.BIND_QUICK_SETTINGS_TILE";
        public static final String BIND_REMOTEVIEWS = "android.permission.BIND_REMOTEVIEWS";
        public static final String BIND_SCREENING_SERVICE = "android.permission.BIND_SCREENING_SERVICE";
        public static final String BIND_TELECOM_CONNECTION_SERVICE = "android.permission.BIND_TELECOM_CONNECTION_SERVICE";
        public static final String BIND_TEXT_SERVICE = "android.permission.BIND_TEXT_SERVICE";
        public static final String BIND_TV_INPUT = "android.permission.BIND_TV_INPUT";
        public static final String BIND_VISUAL_VOICEMAIL_SERVICE = "android.permission.BIND_VISUAL_VOICEMAIL_SERVICE";
        public static final String BIND_VOICE_INTERACTION = "android.permission.BIND_VOICE_INTERACTION";
        public static final String BIND_VPN_SERVICE = "android.permission.BIND_VPN_SERVICE";
        public static final String BIND_VR_LISTENER_SERVICE = "android.permission.BIND_VR_LISTENER_SERVICE";
        public static final String BIND_WALLPAPER = "android.permission.BIND_WALLPAPER";
        public static final String BLUETOOTH = "android.permission.BLUETOOTH";
        public static final String BLUETOOTH_ADMIN = "android.permission.BLUETOOTH_ADMIN";
        public static final String BLUETOOTH_ADVERTISE = "android.permission.BLUETOOTH_ADVERTISE";
        public static final String BLUETOOTH_CONNECT = "android.permission.BLUETOOTH_CONNECT";
        public static final String BLUETOOTH_PRIVILEGED = "android.permission.BLUETOOTH_PRIVILEGED";
        public static final String BLUETOOTH_SCAN = "android.permission.BLUETOOTH_SCAN";
        public static final String BODY_SENSORS = "android.permission.BODY_SENSORS";
        public static final String BROADCAST_PACKAGE_REMOVED = "android.permission.BROADCAST_PACKAGE_REMOVED";
        public static final String BROADCAST_SMS = "android.permission.BROADCAST_SMS";
        public static final String BROADCAST_STICKY = "android.permission.BROADCAST_STICKY";
        public static final String BROADCAST_WAP_PUSH = "android.permission.BROADCAST_WAP_PUSH";
        public static final String CALL_COMPANION_APP = "android.permission.CALL_COMPANION_APP";
        public static final String CALL_PHONE = "android.permission.CALL_PHONE";
        public static final String CALL_PRIVILEGED = "android.permission.CALL_PRIVILEGED";
        public static final String CAMERA = "android.permission.CAMERA";
        public static final String CAPTURE_AUDIO_OUTPUT = "android.permission.CAPTURE_AUDIO_OUTPUT";
        public static final String CHANGE_COMPONENT_ENABLED_STATE = "android.permission.CHANGE_COMPONENT_ENABLED_STATE";
        public static final String CHANGE_CONFIGURATION = "android.permission.CHANGE_CONFIGURATION";
        public static final String CHANGE_NETWORK_STATE = "android.permission.CHANGE_NETWORK_STATE";
        public static final String CHANGE_WIFI_MULTICAST_STATE = "android.permission.CHANGE_WIFI_MULTICAST_STATE";
        public static final String CHANGE_WIFI_STATE = "android.permission.CHANGE_WIFI_STATE";
        public static final String CLEAR_APP_CACHE = "android.permission.CLEAR_APP_CACHE";
        public static final String CONTROL_LOCATION_UPDATES = "android.permission.CONTROL_LOCATION_UPDATES";
        public static final String DELETE_CACHE_FILES = "android.permission.DELETE_CACHE_FILES";
        public static final String DELETE_PACKAGES = "android.permission.DELETE_PACKAGES";
        public static final String DIAGNOSTIC = "android.permission.DIAGNOSTIC";
        public static final String DISABLE_KEYGUARD = "android.permission.DISABLE_KEYGUARD";
        public static final String DUMP = "android.permission.DUMP";
        public static final String EXPAND_STATUS_BAR = "android.permission.EXPAND_STATUS_BAR";
        public static final String FACTORY_TEST = "android.permission.FACTORY_TEST";
        public static final String FOREGROUND_SERVICE = "android.permission.FOREGROUND_SERVICE";
        public static final String GET_ACCOUNTS = "android.permission.GET_ACCOUNTS";
        public static final String GET_ACCOUNTS_PRIVILEGED = "android.permission.GET_ACCOUNTS_PRIVILEGED";
        public static final String GET_PACKAGE_SIZE = "android.permission.GET_PACKAGE_SIZE";
        /** @deprecated */
        @Deprecated
        public static final String GET_TASKS = "android.permission.GET_TASKS";
        public static final String GLOBAL_SEARCH = "android.permission.GLOBAL_SEARCH";
        public static final String HIDE_OVERLAY_WINDOWS = "android.permission.HIDE_OVERLAY_WINDOWS";
        public static final String HIGH_SAMPLING_RATE_SENSORS = "android.permission.HIGH_SAMPLING_RATE_SENSORS";
        public static final String INSTALL_LOCATION_PROVIDER = "android.permission.INSTALL_LOCATION_PROVIDER";
        public static final String INSTALL_PACKAGES = "android.permission.INSTALL_PACKAGES";
        public static final String INSTALL_SHORTCUT = "com.android.launcher.permission.INSTALL_SHORTCUT";
        public static final String INSTANT_APP_FOREGROUND_SERVICE = "android.permission.INSTANT_APP_FOREGROUND_SERVICE";
        public static final String INTERACT_ACROSS_PROFILES = "android.permission.INTERACT_ACROSS_PROFILES";
        public static final String INTERNET = "android.permission.INTERNET";
        public static final String KILL_BACKGROUND_PROCESSES = "android.permission.KILL_BACKGROUND_PROCESSES";
        public static final String LOADER_USAGE_STATS = "android.permission.LOADER_USAGE_STATS";
        public static final String LOCATION_HARDWARE = "android.permission.LOCATION_HARDWARE";
        public static final String MANAGE_DOCUMENTS = "android.permission.MANAGE_DOCUMENTS";
        public static final String MANAGE_EXTERNAL_STORAGE = "android.permission.MANAGE_EXTERNAL_STORAGE";
        public static final String MANAGE_MEDIA = "android.permission.MANAGE_MEDIA";
        public static final String MANAGE_ONGOING_CALLS = "android.permission.MANAGE_ONGOING_CALLS";
        public static final String MANAGE_OWN_CALLS = "android.permission.MANAGE_OWN_CALLS";
        public static final String MASTER_CLEAR = "android.permission.MASTER_CLEAR";
        public static final String MEDIA_CONTENT_CONTROL = "android.permission.MEDIA_CONTENT_CONTROL";
        public static final String MODIFY_AUDIO_SETTINGS = "android.permission.MODIFY_AUDIO_SETTINGS";
        public static final String MODIFY_PHONE_STATE = "android.permission.MODIFY_PHONE_STATE";
        public static final String MOUNT_FORMAT_FILESYSTEMS = "android.permission.MOUNT_FORMAT_FILESYSTEMS";
        public static final String MOUNT_UNMOUNT_FILESYSTEMS = "android.permission.MOUNT_UNMOUNT_FILESYSTEMS";
        public static final String NFC = "android.permission.NFC";
        public static final String NFC_PREFERRED_PAYMENT_INFO = "android.permission.NFC_PREFERRED_PAYMENT_INFO";
        public static final String NFC_TRANSACTION_EVENT = "android.permission.NFC_TRANSACTION_EVENT";
        public static final String PACKAGE_USAGE_STATS = "android.permission.PACKAGE_USAGE_STATS";
        /** @deprecated */
        @Deprecated
        public static final String PERSISTENT_ACTIVITY = "android.permission.PERSISTENT_ACTIVITY";
        /** @deprecated */
        @Deprecated
        public static final String PROCESS_OUTGOING_CALLS = "android.permission.PROCESS_OUTGOING_CALLS";
        public static final String QUERY_ALL_PACKAGES = "android.permission.QUERY_ALL_PACKAGES";
        public static final String READ_CALENDAR = "android.permission.READ_CALENDAR";
        public static final String READ_CALL_LOG = "android.permission.READ_CALL_LOG";
        public static final String READ_CONTACTS = "android.permission.READ_CONTACTS";
        public static final String READ_EXTERNAL_STORAGE = "android.permission.READ_EXTERNAL_STORAGE";
        /** @deprecated */
        @Deprecated
        public static final String READ_INPUT_STATE = "android.permission.READ_INPUT_STATE";
        public static final String READ_LOGS = "android.permission.READ_LOGS";
        public static final String READ_PHONE_NUMBERS = "android.permission.READ_PHONE_NUMBERS";
        public static final String READ_PHONE_STATE = "android.permission.READ_PHONE_STATE";
        public static final String READ_PRECISE_PHONE_STATE = "android.permission.READ_PRECISE_PHONE_STATE";
        public static final String READ_SMS = "android.permission.READ_SMS";
        public static final String READ_SYNC_SETTINGS = "android.permission.READ_SYNC_SETTINGS";
        public static final String READ_SYNC_STATS = "android.permission.READ_SYNC_STATS";
        public static final String READ_VOICEMAIL = "com.android.voicemail.permission.READ_VOICEMAIL";
        public static final String REBOOT = "android.permission.REBOOT";
        public static final String RECEIVE_BOOT_COMPLETED = "android.permission.RECEIVE_BOOT_COMPLETED";
        public static final String RECEIVE_MMS = "android.permission.RECEIVE_MMS";
        public static final String RECEIVE_SMS = "android.permission.RECEIVE_SMS";
        public static final String RECEIVE_WAP_PUSH = "android.permission.RECEIVE_WAP_PUSH";
        public static final String RECORD_AUDIO = "android.permission.RECORD_AUDIO";
        public static final String REORDER_TASKS = "android.permission.REORDER_TASKS";
        public static final String REQUEST_COMPANION_PROFILE_WATCH = "android.permission.REQUEST_COMPANION_PROFILE_WATCH";
        public static final String REQUEST_COMPANION_RUN_IN_BACKGROUND = "android.permission.REQUEST_COMPANION_RUN_IN_BACKGROUND";
        public static final String REQUEST_COMPANION_START_FOREGROUND_SERVICES_FROM_BACKGROUND = "android.permission.REQUEST_COMPANION_START_FOREGROUND_SERVICES_FROM_BACKGROUND";
        public static final String REQUEST_COMPANION_USE_DATA_IN_BACKGROUND = "android.permission.REQUEST_COMPANION_USE_DATA_IN_BACKGROUND";
        public static final String REQUEST_DELETE_PACKAGES = "android.permission.REQUEST_DELETE_PACKAGES";
        public static final String REQUEST_IGNORE_BATTERY_OPTIMIZATIONS = "android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS";
        public static final String REQUEST_INSTALL_PACKAGES = "android.permission.REQUEST_INSTALL_PACKAGES";
        public static final String REQUEST_OBSERVE_COMPANION_DEVICE_PRESENCE = "android.permission.REQUEST_OBSERVE_COMPANION_DEVICE_PRESENCE";
        public static final String REQUEST_PASSWORD_COMPLEXITY = "android.permission.REQUEST_PASSWORD_COMPLEXITY";
        /** @deprecated */
        @Deprecated
        public static final String RESTART_PACKAGES = "android.permission.RESTART_PACKAGES";
        public static final String SCHEDULE_EXACT_ALARM = "android.permission.SCHEDULE_EXACT_ALARM";
        public static final String SEND_RESPOND_VIA_MESSAGE = "android.permission.SEND_RESPOND_VIA_MESSAGE";
        public static final String SEND_SMS = "android.permission.SEND_SMS";
        public static final String SET_ALARM = "com.android.alarm.permission.SET_ALARM";
        public static final String SET_ALWAYS_FINISH = "android.permission.SET_ALWAYS_FINISH";
        public static final String SET_ANIMATION_SCALE = "android.permission.SET_ANIMATION_SCALE";
        public static final String SET_DEBUG_APP = "android.permission.SET_DEBUG_APP";
        /** @deprecated */
        @Deprecated
        public static final String SET_PREFERRED_APPLICATIONS = "android.permission.SET_PREFERRED_APPLICATIONS";
        public static final String SET_PROCESS_LIMIT = "android.permission.SET_PROCESS_LIMIT";
        public static final String SET_TIME = "android.permission.SET_TIME";
        public static final String SET_TIME_ZONE = "android.permission.SET_TIME_ZONE";
        public static final String SET_WALLPAPER = "android.permission.SET_WALLPAPER";
        public static final String SET_WALLPAPER_HINTS = "android.permission.SET_WALLPAPER_HINTS";
        public static final String SIGNAL_PERSISTENT_PROCESSES = "android.permission.SIGNAL_PERSISTENT_PROCESSES";
        /** @deprecated */
        @Deprecated
        public static final String SMS_FINANCIAL_TRANSACTIONS = "android.permission.SMS_FINANCIAL_TRANSACTIONS";
        public static final String START_FOREGROUND_SERVICES_FROM_BACKGROUND = "android.permission.START_FOREGROUND_SERVICES_FROM_BACKGROUND";
        public static final String START_VIEW_PERMISSION_USAGE = "android.permission.START_VIEW_PERMISSION_USAGE";
        public static final String STATUS_BAR = "android.permission.STATUS_BAR";
        public static final String SYSTEM_ALERT_WINDOW = "android.permission.SYSTEM_ALERT_WINDOW";
        public static final String TRANSMIT_IR = "android.permission.TRANSMIT_IR";
        public static final String UNINSTALL_SHORTCUT = "com.android.launcher.permission.UNINSTALL_SHORTCUT";
        public static final String UPDATE_DEVICE_STATS = "android.permission.UPDATE_DEVICE_STATS";
        public static final String UPDATE_PACKAGES_WITHOUT_USER_ACTION = "android.permission.UPDATE_PACKAGES_WITHOUT_USER_ACTION";
        public static final String USE_BIOMETRIC = "android.permission.USE_BIOMETRIC";
        /** @deprecated */
        @Deprecated
        public static final String USE_FINGERPRINT = "android.permission.USE_FINGERPRINT";
        public static final String USE_FULL_SCREEN_INTENT = "android.permission.USE_FULL_SCREEN_INTENT";
        public static final String USE_ICC_AUTH_WITH_DEVICE_IDENTIFIER = "android.permission.USE_ICC_AUTH_WITH_DEVICE_IDENTIFIER";
        public static final String USE_SIP = "android.permission.USE_SIP";
        public static final String UWB_RANGING = "android.permission.UWB_RANGING";
        public static final String VIBRATE = "android.permission.VIBRATE";
        public static final String WAKE_LOCK = "android.permission.WAKE_LOCK";
        public static final String WRITE_APN_SETTINGS = "android.permission.WRITE_APN_SETTINGS";
        public static final String WRITE_CALENDAR = "android.permission.WRITE_CALENDAR";
        public static final String WRITE_CALL_LOG = "android.permission.WRITE_CALL_LOG";
        public static final String WRITE_CONTACTS = "android.permission.WRITE_CONTACTS";
        public static final String WRITE_EXTERNAL_STORAGE = "android.permission.WRITE_EXTERNAL_STORAGE";
        public static final String WRITE_GSERVICES = "android.permission.WRITE_GSERVICES";
        public static final String WRITE_SECURE_SETTINGS = "android.permission.WRITE_SECURE_SETTINGS";
        public static final String WRITE_SETTINGS = "android.permission.WRITE_SETTINGS";
        public static final String WRITE_SYNC_SETTINGS = "android.permission.WRITE_SYNC_SETTINGS";
        public static final String WRITE_VOICEMAIL = "com.android.voicemail.permission.WRITE_VOICEMAIL";

        public permission() {
            throw new RuntimeException("Stub!");
        }
    }
}

动态权限申请设计 

 

 

权限申请相关变更

1.android 8.0以后并且应用的targetSdkVersion >= 28时,应用申请某个危险权限授权,用户同意后,系统不再把该危险权限对应的权限组中的其他在AndroidManifest.xml中注册的权限一并授予给应用,系统只会授予应用明确请求的权限。一旦用户应用同意授权某个危险权限,则后续对该危险权限的权限组中的其他权限请求都会被自动批准,而不会提示用户。例如某个应用在AndroidManifest.xml中注册READ_EXTERNAL_STORAGE和WRITE_EXTERNAL_STORAGE权限,应用申请READ_EXTERNAL_STORAGE权限并且用户同意,在android 8.0之前,系统在用户同意后还会一并授予WRITE_EXTERNAL_STORAGE权限,因为它和READ_EXTERNAL_STORAGE权限是同一个权限组并且也在AndroidManifest.xml中注册。但在android 8.0之后并且应用的targetSdkVersion >= 28,系统在用户同意后只会授予READ_EXTERNAL_STORAGE权限,但是如果后来应用又申请WRITE_EXTERNAL_STORAGE权限,系统会立即授予该权限,而不会提示用户,换句话说,如果只申请了外部存储空间读取权限,在低版本下(android < 8.0)对外部存储空间使用写入操作是没有问题的,但是在高版本(android >= 8.0 && targetSdkVersion >= 28)下是会出现问题的,解决方案是将两个读和写的权限一起申请。

2.android 9.0增加了CALL_LOG(通话记录)权限组,并把READ_CALL_LOG、WRITE_CALL_LOG]、PROCESS_OUTGOING_CALLS权限从PHONE(电话)权限组移动到了CALL_LOG权限组,CALL_LOG权限组使得用户能够更好地控制需要访问电话通话记录敏感信息的应用程序,例如读取通话记录和识别电话号码。

3.android 10引入了很多隐私变更,新增了ACTIVITY_RECOGNITION(身体活动)权限和权限组,允许应用检测用户的步数或分类用户的身体活动如步行、骑自行车等;同时android 10引入了作用域存储,当应用启用作用域存储时,WRITE_EXTERNAL_STORAGE权限会失效,应用对WRITE_EXTERNAL_STORAGE权限的申请不会对应用的存储访问权限产生任何影响,并且WRITE_EXTERNAL_STORAGE会在未来被废弃,因为作用域存储的目的就是不让应用随意的修改应用沙盒外的外部存储;同时新增了ACCESS_BACKGROUND_LOCATION权限,归属于LOCATION权限组,用于后台运行的应用访问用户定位时申请,与ACCESS_FINE_LOCATION和ACCESS_COARSE_LOCATION这些前台定位权限区分开,当你的应用targetSdkVersion >= 29并且运行在android 10以上时,应用在后台访问定位时需要动态的申请后台定位权限,当你把后台定位权限和前台定位权限一起申请时,弹窗授权框会有2个允许选项:始终允许和仅在应用使用过程中允许,点击始终允许表示同时授权后台定位权限和前台定位权限,点击仅在应用使用过程中允许表示仅授权前台定位权限,然后下次再次申请时只会单独申请后台定位权限,并且也会有2个允许选项,并且要点击始终允许才会让后台定位权限申请通过,当你的应用targetSdkVersion < 29运行在android 10以上时,应用在申请前台定位权限时系统会把后台定位权限一并授予给应用;android 10还新增了ACCESS_MEDIA_LOCATION权限,归属于STORAGE (存储空间) 权限组,android 10以后,因为隐私问题,默认不再提供图片的地理位置信息,要获取该信息需要向用户申请ACCESS_MEDIA_LOCATION权限,并使用MediaStore.setRequireOriginal()接口更新文件Uri。

4.android 11也引入了很多隐私变更,android 11强制新安装的应用(targetSdkVersion >= 30)启用作用域存储,新增MANAGE_EXTERNAL_STORAGE用于代替WRITE_EXTERNAL_STORAGE权限,提供给手机管家、文件管理器这类需要管理整个SD卡上的文件的应用申请;android 11中当用户开启“安装未知来源应用”权限后返回应用,应用会被杀死重启,该行为与强制分区存储有关;从android 11后,如果应用对某个权限连续点击多次拒绝,那么下一次请求该权限时系统会直接拒绝连授权弹窗都不会弹出,该行为等同于android 11之前勾选了don‘t ask again;android 11后还新增了一次性权限(One-time permissions)和权限自动重置功能(Permissions auto-reset),这些变更只要你正确的进行运行时权限请求就不需要做额外适配;同时android 11后当targetSdkVersion < 30的应用把后台定位权限和前台定位权限一起申请时,弹窗授权框的允许选项中不再会显示始终允许选项,只有本次允许和仅在应用使用过程中允许,也就说点击允许时只会授予你前台定位权限不再默认授予你后台定位权限,而android 11后targetSdkVersion >= 30的应用的ACCESS_BACKGROUND_LOCATION权限需要独立申请,不能与前台权限一起申请,如果与前台权限一起申请,系统会直接拒绝连授权弹窗都不会弹出,系统推荐增量请求权限,这样对用户更友好,同时用户必须先同意前台权限后才能进入后台定位权限的申请。
可以看到从android 10引入ACCESS_BACKGROUND_LOCATION权限以来,后台定位权限的申请一直都非常特殊,它在android 10可以和前台定位权限一起申请,而在android 11又不可以一起申请还有先后申请顺序,针对这种特殊情况,申请后台定位权限时要做到:

1、先请求前台定位权限,再请求后台定位权限;
2、单独请求后台定位权限,不要与其他权限一同请求.

5.Android 13增加了通知权限,开发者需要在AndroidManifest.xml中声明POST_NOTIFICATIONS权限,还需要在使用通知栏推送功能时在代码中申请运行时权限:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    package="xxx.xxx.xxx.xxx">
    <uses-permission android:name="android.permission.POST_NOTIFICATIONS"/>
</manifest>
requestPermissions(new String[]{“android.permission.POST_NOTIFICATIONS”})

6.Android13对本地数据访问权限也做了进一步细化。Android13将READ_EXTERNAL_STORAGE和 WRITE_EXTERNAL_STORAGE权限细分为:READ_MEDIA_IMAGES、 READ_MEDIA_VIDEO和 READ_MEDIA_AUDIO。单独请求READ_MEDIA_IMAGES、单独请求 READ_MEDIA_VIDEO和同时请求READ_MEDIA_IMAGES& READ_MEDIA_VIDEO,系统均将只显示一个授权弹窗。 
另外,如果App(targetSdk == 33)已经申请了读的权限,那App同时也就有了写的权限,无需再额外声明 WRITE_EXTERNAL_STORAGE权限。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/141850.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

C语言画一个正方体

程序截图 操作方法 鼠标拖动。左键拖动及滚轮能看到不同角度下正方体的形状&#xff0c;右键拖动能将最近的正方体顶点挪到这个投影面的相应位置。 按键控制。wasd 控制投影面旋转&#xff0c;ws 关于 x 轴旋转&#xff0c;ad 关于 y 轴旋转。 个人思路 首先投影面的确立需…

【寒假第一天】LeetCode刷题

&#x1f308;一.选择题&#x1f47f;1.1.堆是一种有用的数据结构。下列那个关键码序列是一个堆&#xff08; &#xff09;。 A. 94,31,53,23,16,72 B. 94,53,31,72,16,23 C. 16,53,23,94,31,72 D. 16,31,23,94,53,72D堆排序有两种排序方法&#xff1a;大堆排序-----根结点要大…

【Kotlin】Kotlin 函数总结 ( 具名函数 | 匿名函数 | Lambda 表达式 | 闭包 | 内联函数 | 函数引用 )

文章目录一、函数头声明二、函数参数1、默认参数值2、具名参数三、Unit 函数四、TODO 函数抛出异常返回 Nothing 类型五、反引号函数名六、匿名函数七、匿名函数的函数类型八、匿名函数的隐式返回九、匿名函数参数十、匿名函数 it 关键字十一、匿名函数变量类型推断十二、匿名函…

JS中BOM 浏览器对象 提供的定时器

window对象提供了2个定时器方法&#xff1a; settTimeout()和setInterval() 1.setTimeout()定时器 语法&#xff1a; window.setTimeout(调用函数,[延迟的毫秒数]);延迟时间可以省略&#xff0c;省略则为0 用于设置一个定时器&#xff0c;该定时器再定时器到期后执行调用函数 …

【nodejs】npm与包

1、什么是包 Node.js中的第三方模块又叫包 2、包的来源 由第三方个人或团队开发出来的&#xff0c;免费供所有人使用 3、为什么需要包 由于Node.js的内置模块仅提供了一些底层的API&#xff0c;导致在基于内置模块进行项目开发时&#xff0c;效率很低。 包是基于内置模块封装出…

杨校老师课堂之IntellJ IDEA的使用技巧

下载地址&#xff1a; https://www.jetbrains.com.cn/idea/download/#sectionwindows 一、常规操作 1、忽略大小写&#xff0c;进行提示 2、启用Idea时&#xff0c;默认不再打开上次项目 3、设置主题 4、设置默认的字体 5、修改类头的文档注释信息 6、设置项目文件编码 7、统一…

electron与jquery起冲突,使用jquery报错解决方法

问题原因&#xff1a;Electron 为了整合 Node.js&#xff0c;会在 DOM 加入 module、exports、require 等模块和函数&#xff0c;和jQuery、RequireJS、Meteor、AngularJS 等发生冲突。 暴力解决方法&#xff1a;去除node功能加持&#xff0c;在加载browserWindow或者browserVi…

C++:闭包:闭包Closure理解

一&#xff1a;什么是闭包 闭包有很多定义&#xff0c;一种说法是&#xff1a;闭包是带有上下文的函数&#xff0c;说白了&#xff0c;就是有状态的函数&#xff0c;这其实就是一个类&#xff0c;换个名字而已。 一个函数&#xff0c;带上一个状态&#xff0c;就变成了闭包&…

共享模型之管程(四)

1.wait/notify 1.1.为什么需要wait? 小故事: ①.假设多个用户(线程)都需要进入房间使用算盘(CPU)进行计算工作,但是为了保证计算过程中的安全,老王设计了一把锁(Synchronized),每次只允许一个用户(线程)拿到钥匙进入房间(成为Owner线程); ②.小南(线程)费了九牛二虎之力,抢…

【Docker】搭建Zookeeper集群

【Docker】搭建Zookeeper集群 下载镜像 docker pull zookeeper:3.5.8wy:study wy$ docker pull zookeeper:3.5.8 3.5.8: Pulling from library/zookeeperDigest: sha256:12af523731cbe390f5332d6c1e254f1d56c734a786910d5582653445a5cee299 Status: Downloaded newer image f…

Allegro174版本新功能介绍之动态铜皮对单独层面参数设置

Allegro174版本新功能介绍之动态铜皮对单独层面参数设置 Allegro升级到了174版本的时候,可以支持动态铜皮对单独的层面进行参数设置,如下图 具体操作如下 在低版本166以及172的时候,只有Global Dynamic Shape Parameter设置,如下图,只有全局的铜皮参数设置升级到了174时候…

WMS智能仓储管理系统源码 SpringMVC物流仓库管理系统源码

淘源码&#xff1a;国内知名的源码免费下载平台 需要源码学习可私信我。 系统介绍&#xff1a; 基于SpringMVCHibernatMinidao&#xff08;类Mybatis&#xff09;Easyui&#xff08;UI库&#xff09; Jquery Boostrap Ehcache Redis Ztree等基础架构开发的物流仓库管理系…

人脸识别:我是如何工作的?

任何自动人脸识别过程都必须考虑导致其复杂性的几个因素&#xff0c;因为人脸是一个动态实体&#xff0c;在多个因素的影响下不断变化&#xff0c;例如光照、姿势、年龄……这三个参数中的任何一个的变化都会导致同一个人的两幅图像之间的误差值大于不同个体的两幅图像之间的误…

分享136个PHP源码,总有一款适合您

PHP源码 分享136个PHP源码&#xff0c;总有一款适合您 136个PHP源码下载链接&#xff1a;https://pan.baidu.com/s/1A5sR357dh_SlS7pu33lW1Q?pwdkzgn 提取码&#xff1a;kzgn import os# 查找指定文件夹下所有相同名称的文件 def search_file(dirPath, fileName):dirs os…

红中私教-文件上传漏洞DVWA靶场实战(浅析)

前言 &#x1f340;作者简介&#xff1a;被吉师散养、喜欢前端、学过后端、练过CTF、玩过DOS、不喜欢java的不知名学生。 &#x1f341;个人主页&#xff1a;红中 首先呢&#xff0c;针对于文件上传漏洞 这个漏洞为什么存在&#xff1f;目的是什么&#xff1f;我们为什幺要攻击…

开发环境和测试环境共用Eureka

问题描述 在开发过程中会遇到一种情况&#xff0c;那就是只需要修改一个服务&#xff0c;但是这个服务依赖了其他的3个服务&#xff0c;导致开发人员在本地也要启动其他的3个服务&#xff0c;还要启动一个Eureka注册中心。问题显而易见&#xff0c;在依赖过多的情况下&#xf…

一种多维数据库的数据事务专利解读

什么是事务&#xff1f; 事务是数据库系统中的核心机制。我们要理解下事务概念&#xff1a;什么是事务呢&#xff1f;事务是并发控制的单位&#xff0c;是用户定义的一个操作序列。有四个特性(ACID)&#xff1a; 原子性(Atomicity)&#xff1a; 事务是数据库的逻辑工作单位&…

使用 VSCode 开发的必备插件,你都安装了吗?

0️⃣前言 VSCode是由微软研发的一款免费、开源的跨平台代码编辑器&#xff0c;目前是前端开发使用最多的一款软件开发工具。 因为每个开发者所接触项目、所有技术不同, 用到的插件不同, 但总有几个插件基本是必备的, 以下就给出一些插件推荐&#xff0c;希望能给大家一些参考。…

腾讯会议发布录屏工具“会记”,让云端视频协作随用随录、随享随看

随着云端协同成为新常态&#xff0c;企业和组织沟通的形式也在不断丰富。1月5日&#xff0c;腾讯会议发布云端录屏工具“会记”&#xff0c; 用户在腾讯会议中就能自由使用人像、屏幕、声音、窗口等多种组合方式进行录制&#xff0c;录制完成后视频将自动上传至云端&#xff0c…

Centos7.9安装WebLogic详细步骤

目录 一、weblogic下载 二、准备环境 三、创建用户和组 四、安装jdk 安装 五、安装WebLogic 1、使用root用户创建目录/opt/weblogic并授权 2.创建 oraInst.loc 文件 3、创建wls.rsp 响应文件 4、安装weblogic 5、静默创建域 六、启动weblogic 一、weblogic下载 直…