Android6.0
The 6
Android的6.0版本,即盛传已久的Android M已经在Google 2015年的 I/O大会上被正式发布。一个在业内已经被热议的议题是:Android M“为工作升级而生”(Android for Work Update)。有业内人士解释道:“Android M将把Android的强大功能拓展至任何你所能看到的工作领域。”
根据Android系统以往的惯例,每一代新系统往往会根据其字母代号,对应一个关于零食的全名。如2014年在Google I/O大会上发布的Android L,其代号“L”一开始还只是Google为开发者称呼方便而准备的一个代号,但后来逐步演变成了“Lollipop”(棒棒糖Android 5.0)。所以,按照这种命名的传统,Android [字母]这种新模式也将意味着,一款新口味Android“零食”即将出现。
Google I/O 2015大会如约已于2015年5月28日举行。在发布会上代号为“Marshmallow(棉花糖)”的安卓6.0系统正式推出。
6.0较以往的版本(5.1之前) 有了很大的提升和变动 :
5.1之前如果需要某些权限 比如联网/获取WIFI信息/拍照/定位/打电话等 直接在Manifest.xml里面声明 <uses-permission xxx/>
就可以了
但6.0之后有了权限划分 普通和敏感权限 像联网INTERNET 之类的权限是不用去动态申请:
正常权限 不需要动态申请的:
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
GET_PACKAGE_SIZE
INSTALL_SHORTCUT
INTERNET
KILL_BACKGROUND_PROCESSES
MODIFY_AUDIO_SETTINGS
NFC
READ_SYNC_SETTINGS
READ_SYNC_STATS
RECEIVE_BOOT_COMPLETED
REORDER_TASKS
REQUEST_IGNORE_BATTERY_OPTIMIZATIONS
REQUEST_INSTALL_PACKAGES
SET_ALARM
SET_TIME_ZONE
SET_WALLPAPER
SET_WALLPAPER_HINTS
TRANSMIT_IR
UNINSTALL_SHORTCUT
USE_FINGERPRINT
VIBRATE
WAKE_LOCK
WRITE_SYNC_SETTINGS
特殊权限 需要动态申请的:
CALENDAR
CAMERA
CONTACTS
LOCATION
MICROPHONE
PHONE
SENSORS
SMS
STORAGE
检查和申请权限
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
# 检测是否已经被用户授予该权限
if (ContextCompat.checkSelfPermission(LaunchActivity.this, Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
# 没有被授予权限
# 判断如果已经被用户拒绝过一次(非永久拒绝),则显示用户此权限的一些说明,这里可以用toast,当然也可以用自定义界面来显示给用户,如果是采用自定义界面来显示给用户,在有“确定”,“取消”等按钮的情况下,下面的“请求权限”步骤要酌情调用
if (ActivityCompat.shouldShowRequestPermissionRationale(LaunchActivity.this, Manifest.permission.READ_EXTERNAL_STORAGE)) {
Toast.makeText(LaunchActivity.this, "request read external storage", Toast.LENGTH_LONG).show();
}
# 请求权限,数组传入多个值,可以一次请求多个权限
ActivityCompat.requestPermissions(LaunchActivity.this,
new String[]{Manifest.permission.READ_EXTERNAL_STORAGE},
PERMISSIONS_REQUEST_EXTERNAL_STORAGE);
}
} else {
# 6.0以下版本,直接使用权限
// 做一些权限对应的操作
}
如果是在6.0及6.0以上版本时,执行 ActivityCompat.requestPermissions()方法请求权限后,如果用户同意或者拒绝后,会回调onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults)方法,该方法的几个参数,我们做一下解释:
-
requestCode 对应的是ActivityCompat.requestPermissions请求时的requestCode,这个与Activity中常用的onActivityResult方法中的requestCode类似,用来标识某一次或者某一个请求的回调对应关系
-
permissions 对应ActivityCompat.requestPermissions()方法中请求的权限列表
-
grantResults 对应2中permissions的每个权限的用户应答结果
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
switch (requestCode) {
case PERMISSIONS_REQUEST_EXTERNAL_STORAGE: {
// 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.
}
return;
}
}
}
权限申请的状态:
PackageManager.PERMISSION_DENIED:拒绝
PackageManager.PERMISSION_GRANTED:授权
Android 7.0
The 7
Android 7.0是Google推出的智能手机操作系统,最终官方代号,定名为“Nougat”(牛轧糖)。2016年的Google I/O开发者大会在美国西部时间2016年5月18-20日召开,地点为山景城的Shoreline Ampitheatre圆形剧场。在这里,新版的Android N系统正式发布。
2016年8月22日,Google正式推送Android 7.0 Nougat正式版。
2016年12月5日,Google为Android 7.0发布了重要的维护性更新,也就是Android 7.1。 Android 7.1的一个小版本更新——安卓7.1.2已于2017年4月3日推送。
2017年5月5日,Google正式向开发者发出通知,宣布Andrdoid 7.0的Beta项目正式停止,最终版本止步在Android 7.1.2,让位于Android O。
继6.0依赖 每一年的版本对权限要求越来越严格,6.0的动态权限,7.0+又加入了临时环境缓存权限/7.0之前 比如拍照/打开文件等直接是
Intent intent = new Intent("android.intent.action.VIEW");
intent.addCategory("android.intent.category.DEFAULT");
intent.addFlags (Intent.FLAG_ACTIVITY_NEW_TASK);
Uri uri = Uri.fromFile(new File(picPath));
String type = getMIMEType(picPath);
if ((null!=type) && (!TextUtils.isEmpty(type))) {
intent.setDataAndType (uri, type);
context.startActivity(intent);
}
直接通过隐式Intent去打开
但是在7.0之后是不可以了 需要加入以下方式:
在Manifest里面加入
<!--
适配7.0+
-->
<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="apk的包名.fileprovider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/provider_paths"/>
</provider>
然后再res/下新建xml文件夹/然后新建:
然后在代码里的:
Uri uri = Uri.fromFile(new File(picPath));
更改为:
Uri uri;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M){
uri = FileProvider.getUriForFile(context, "com.luxiaofeng-你的应用包名 和mainfest声明的一致",newFile(picPath));
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
}else{
uri = Uri.fromFile(new File(picPath));
}
intent.setDataAndType (uri, type);
context.startActivity(intent);
但是这里有一个隐形的BUG/也就是阿里巴巴安卓开发规范提出的:
所以写代码得要考虑使用环境 设备的不同 版本的不同等
if (null != type && !TextUtils.isEmpty(type)) {
intent.setDataAndType(uri, type);
if (context.getPackageManager().resolveActivity(intent, PackageManager.MATCH_DEFAULT_ONLY) != null) {
context.startActivity(intent);
} else {
//没有匹配到相关组件
}
}
Android 8.0
The 8
安装apk的权限也是需要动态申请,
Manifest:
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES"/>
Code:
int permission = ActivityCompat.checkSelfPermission(activity,
Manifest.permission.REQUEST_INSTALL_PACKAGES);
if (permission != PackageManager.PERMISSION_GRANTED) {
// We don't have permission so prompt the user
ActivityCompat.requestPermissions(activity, PERMISSONS,
REQUEST_EXTERNAL_STORAGE);
}
private static String[] PERMISSONS= {
Manifest.permission.REQUEST_INSTALL_PACKAGES
};