在
targetSdkVersion
23版本
以下,安装app,根据权限声明产生一个权限列表,用户只有同意全部权限后才能正常使用该app.
而在6.0以后,我们可以直接安装
而在6.0以后,我们可以直接安装,对不恰当的权限予以拒绝,
Android权限机制一般分为两种:文件权限和运行时权限
文件权限即Linux文件权限,在读写文件时进行声明,例如数据库的使用
drwxr-xr-x 2 root root 4096 11月 28 08:32 bin
drwxr-xr-x 3 root root 4096 12月 18 09:18 boot
drwxr-xr-x 2 root root 4096 3月 18 2012 cdrom
drwxr-xr-x 15 root root 4380 1月 4 19:28 dev
drwxr-xr-x 176 root root 12288 1月 4 19:01 etc
drwxr-xr-x 3 root root 4096 4月 16 2012 home
Android运行时权限
早期版本的app是可以运行在Android6.0 手机上的,如果应用的targetSdkVersion <23则仍按照以前的权限机制在安装应用时按列表给出,如果早期版本的app使用targetSdkVersion >23用户仍然有撤销,不赋予应用某个权限的权利,但这样,如果这个权限是这个应用中必要的重要权限就会报错,出现崩溃,或者部分功能无法使用.因此如果使用targetSdkVersion >23为避免该类现象的出现,我们需要在代码进行动态权限获取的处理,在程序使用某个功能时,我们先判断这个功能的权限是否得到允许,如果得到允许,则正常使用打开该功能,如果没有得到许可,则提示用户开启该权限.当然提示用户开启的权限是属于Dangerous Permissions,涉及到用户安全的一些权限,当然也有一些权限是常规权限,是不需要提示用户,系统是许可默认使用的.
As of API level 23, the following permissions are classified as PROTECTION_NORMAL:
ACCESS_LOCATION_EXTRA_COMMANDS
ACCESS_NETWORK_STATE
ACCESS_NOTIFICATION_POLICY
ACCESS_WIFI_STATE
BLUETOOTH
BLUETOOTH_ADMIN
BROADCAST_STICKY
CHANGE_NETWORK_STATE
CHANGE_WIFI_MULTICAST_STATE
CHANGE_WIFI_STATE
DISABLE_KEYGUARD
EXPAND_STATUS_BAR
FLASHLIGHT
GET_PACKAGE_SIZE
INTERNET
KILL_BACKGROUND_PROCESSES
MODIFY_AUDIO_SETTINGS
NFC
READ_SYNC_SETTINGS
READ_SYNC_STATS
RECEIVE_BOOT_COMPLETED
REORDER_TASKS
REQUEST_INSTALL_PACKAGES
SET_TIME_ZONE
SET_WALLPAPER
SET_WALLPAPER_HINTS
TRANSMIT_IR
USE_FINGERPRINT
VIBRATE
WAKE_LOCK
WRITE_SYNC_SETTINGS
SET_ALARM
INSTALL_SHORTCUT
UNINSTALL_SHORTCUT
Dangerous Permissions:
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
动态权限,提示用户获取到的权限都是一组一组的,当弹出权限对话框,得到用户许可后,该组权限就可以使用了
如何动态获取权限?
检查权限
//判断用户是否授予了所需权限 private boolean checkPermission(String permission) { //若配置了该权限,返回true if (ContextCompat.checkSelfPermission(this, permission) != PackageManager.PERMISSION_GRANTED) { // if (!ActivityCompat.shouldShowRequestPermissionRationale(this, permission)) { return false; // } } return true; }
请求权限
private void requestPermissions() { List<String> permissionsNeed = new ArrayList<>(); if (!checkPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE)) { permissionsNeed.add(Manifest.permission.WRITE_EXTERNAL_STORAGE); } if (permissionsNeed.size() > 0) { ActivityCompat.requestPermissions(this, permissionsNeed.toArray(new String[permissionsNeed.size()]), REQUEST_CODE_ASK_PERMISSIONS); } else { setCurrentFragment(mHomeTabIndexEnum); } }
权限请求回调处理
@Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { switch (requestCode) { case REQUEST_CODE_ASK_PERMISSIONS: { // If request is cancelled, the result arrays are empty. if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { // permission was granted, yay! Do the // contacts-related task you need to do. } else { // permission denied, boo! Disable the // functionality that depends on this permission. } setCurrentFragment(mHomeTabIndexEnum); return; } // other 'case' lines to check for other // permissions this app might request } }
最后附上两篇不错的博客和鸿洋封装了的权限请求