一.前言
安卓6.0之后有很多的改动,比如动态获取权限,特别是获取内部存储的权限只能动态获取,不能在AndroidManifest.xml写死,同时
1.动态获取内部存储访问权限
(1).在代码里面声明你的权限列表,用字符串数组存储.如下:
private static String[] PERMISSIONS_STORAGE = {
Manifest.permission.READ_EXTERNAL_STORAGE,
Manifest.permission.WRITE_EXTERNAL_STORAGE};
这里我们声明了对外部存储的读和写权限.
(2).需要在代码里面判断当前系统的版本,看是否支持动态获取,代码如下:
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.LOLLIPOP) {
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this, PERMISSIONS_STORAGE, REQUEST_PERMISSION_CODE);
}
}
如果当前系统版本大于LOLLIPOP的话,判断当前系统是否获取读写外部存储的功能,如果没有则获取权限,这个的REQUEST_PERMISSION_CODE是一个整型常量,标识请求权限吗,这里设置为1,接下来就是正式获取权限了.
(3).这里需要重写 onRequestPermissionsResult方法,该方法用于获取在PERMISSIONS_STORAGE里面获取的权限,请注意注解TargetApi,如果你要兼容android6.0以下的版本的系统的话,我这里要兼容4.4版本,因此默认是无法使用此api的,编译器会报错,该注解标识忽略兼容性问题,但是你还要处理兼容性问题,这里我在AndroidManifest.xml配置了权限以兼容4.4版本
/*
* 申请读取/写入文件的权限
* */
@Override
@TargetApi(23)
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == REQUEST_PERMISSION_CODE) {
for (int i = 0; i < permissions.length; i++) {
Log.i("MainActivity", "申请的权限为:" + permissions[i] + ",申请结果:" + grantResults[i]);
}
}
}
(4).完整的代码如下:
private static String[] PERMISSIONS_STORAGE = {
Manifest.permission.READ_EXTERNAL_STORAGE,
Manifest.permission.WRITE_EXTERNAL_STORAGE};
private static int REQUEST_PERMISSION_CODE = 1;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_splash);
String versionName = getVersionName();
//System.out.println("versionName:"+versionName);
TextView tv_version = findViewById(R.id.tv_version);
tv_version.setText("版本:"+versionName);//动态设置版本信息
mTv_progress = findViewById(R.id.tv_progress);//默认隐藏
checkVersion();
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.LOLLIPOP) {
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this, PERMISSIONS_STORAGE, REQUEST_PERMISSION_CODE);
}
}
}
/*
* 申请读取/写入文件的权限
* */
@Override
@TargetApi(23)
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == REQUEST_PERMISSION_CODE) {
for (int i = 0; i < permissions.length; i++) {
Log.i("MainActivity", "申请的权限为:" + permissions[i] + ",申请结果:" + grantResults[i]);
}
}
}
2.跳转安装页面
获取硬盘存储权限后就是下载安装文件apk,之后就是跳转到安装页面进行安装了,这里说下跳转安装页面,这里也有所改动了(android7.0的改动).
(1).在AndroidManifest.xml下面配置provider
<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="你的包名.fileProvider"
android:grantUriPermissions="true"
android:exported="false">
<meta-data android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/file_paths" />
</provider>
注意provider需要配置自己报名,provider需要配置到application里面
(2).在res文件夹里面创建xml的文件夹,在该文件夹里面创建名字为file_paths的xml文件,如下图:
(3).在file_paths.xml文件中写入如下内容:
<?xml version="1.0" encoding="utf-8"?>
<paths>
<external-path path="Android/data/你的包名/" name="files_root"/>
<external-path path="." name="external_storage_root"/>
</paths>
path标识你要获取临时访问权限的目录,"."表示所有的目录,name标识是外部或者内部存储
(4).代码里面判断当前系统版本是否大于androidN,如果是的话调用新的方法,如果不是的话调用旧的方法
//跳转到系统下载页面
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.addCategory(Intent.CATEGORY_DEFAULT);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
Uri contentUri = FileProvider.getUriForFile(SplashActivity.this, BuildConfig.APPLICATION_ID + ".fileProvider", responseInfo.result);
intent.setDataAndType(contentUri, "application/vnd.android.package-archive");
} else {
intent.setDataAndType(Uri.fromFile(responseInfo.result), "application/vnd.android.package-archive");
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
}
//startActivity(intent);
startActivityForResult(intent,0);//如果用户取消安装的话,
intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)给Uri授予临时读取权限,Uri contentUri = FileProvider.getUriForFile(SplashActivity.this, BuildConfig.APPLICATION_ID + ".fileProvider", responseInfo.result)生成了文件的uri,之前我们在files_path.xml中配置的path就是临时获取权限的目录,
3.一些需要注意的地方
在测试时需要一个问题就是在AndroidManifest.xml更改系统版本好没有效果,其实在android使用gradle来构建之后,AndroidManifest.xml的效果被削减了,其实你改版本号的话需要在build.gradle中修改才可以.
这样下载更新安装的功能就可以用了.