适配7.0 文件共享方式
1、首先再res目录下创建xml文件夹 并且在xml文件夹创建fileFrovider的path文件,文件名自定义随意取
文件内容如下,属性解释:
paths :路径根节点 所有的path都写在里面
子节点:五项分别对应代码中为
<files-path> 代表 context.getFileDir()
<cache-path> 代表 context.getCacheDir()
<external-path> 代表 Environment.getExternalStorageDirectory()
<external-files-path> 代表 context.getExternalFilesDir()
<external-cache-path> 代表 getExternalCacheDir()
name:名字随意取,获取uri是会被转换成cotent的uri 把这里的name值作为uri的一部分,我们用不到,所以不需要太多关注,主要是path属性
path:是文件的路径 .是根路径 字符串则是代表文件夹 譬如:path=“aaa” 那么就代表的是该路径下的aaa文件夹
<?xml version="1.0" encoding="utf-8"?>
<paths>
<!--
代表 context.getFileDir()
文件保存路径为:/data/应用包名/files/
Uri:content://com.winfo.update.provider/fileDir/weixin667android1320.apk
-->
<files-path
name="fileDir"
path="."/>
<!--
代表 context.getExternalFilesDir()
文件保存路径为:/storage/emulated/0/Android/data/应用包名/files/
Uri:content://com.winfo.update.provider/filePath/weixin667android1320.apk
-->
<external-files-path
name="filePath"
path="."
/>
<!--
代表 context.getCacheDir()
文件保存路径为:/data/应用包名/cache/
Uri:content://com.winfo.update.provider/cache-path/weixin667android1320.apk
-->
<!--name自定义 .为根路径-->
<cache-path name="cache-path" path="." />
<!--
代表 getExternalCacheDir()
文件保存路径为:/storage/emulated/0/Android/data/应用包名/cache/
Uri:content://com.winfo.update.provider/external-cache-path/weixin667android1320.apk
-->
<!--name自定义 .为SDCard/Android/data/应用包名/cache/-->
<external-cache-path name="external-cache-path" path="." />
<!--
自定义getExternalCacheDir()
文件保存路径为:/storage/emulated/0/Android/data/应用包名/cache/update/weixin667android1320.apk
Uri:content://com.winfo.update.provider/external-cache-custom-path/weixin667android1320.apk
-->
<!--name自定义 update_file为SDCard/Android/data/应用包名/cache/update/和gettExternalCacheDirectory对应创建的文件夹保持一致-->
<external-cache-path name="external-cache-custom-path" path="update" />
<!--
代表 Environment.getExternalStorageDirectory()
文件保存路径为:/storage/emulated/0/updateFile/
Uri为:content://com.winfo.update.provider/sdcard_root_externalStorageDirectory/weixin667android1320.apk
-->
<external-path
name="sdcard_root_externalStorageDirectory"
path="updateFile"/><!--path要和代码中Environment.getExternalStorageDirectory(), "update" 保持一致否则异常
java.lang.IllegalArgumentException: Failed to find configured root that contains /storage/emulated/0/update/weixin667android1320.apk-->
<!--
<files-path> 代表 context.getFileDir()
<cache-path> 代表 context.getCacheDir()
<external-path> 代表 Environment.getExternalStorageDirectory()
<external-files-path> 代表 context.getExternalFilesDir()
<external-cache-path> 代表 getExternalCacheDir()
-->
</paths>
对应的java代码
public class StorageUtils {
/*
* context.getCacheDir()和context.getExternalCacheDir()
* 目录的路径不同。
* 前者的目录存在外部SD卡上的。在手机里可以直接看到
* 后者的目录存在app的内部存储上,需要root以后,用Root Explorer 文件管理器才能看到
*/
/**
* <files-path
* name="fileDir"
* path="."/>
*/
public static File getFileDir(Context context) {
File appCacheDir = context.getFilesDir();
if (appCacheDir == null) {
Log.w("StorageUtils", "Can't define system cache directory! The app should be re-installed.");
}
return appCacheDir;
}
/**
* <external-files-path
* name="filePath"
* path="."
* />
*/
public static File getExternalFilesDir(Context context) {
File appCacheDir = context.getExternalFilesDir(null);
if (appCacheDir == null) {
Log.w("StorageUtils", "Can't define system cache directory! The app should be re-installed.");
}
return appCacheDir;
}
/**
* <cache-path
* name="cache-path"
* path="." />
* 获取应用的缓存目录
* 路径需要root以后,用Root Explorer 文件管理器才能看到
*/
public static File getCacheDirectory(Context context) {
File appCacheDir = context.getCacheDir();
if (appCacheDir == null) {
Log.w("StorageUtils", "Can't define system cache directory! The app should be re-installed.");
}
return appCacheDir;
}
/**
* <external-cache-path
* name="external-cache-path"
* path="." />
* 获取应用的缓存目录 路径在手机里可以直接看到
* apk下载路径为:SDCard/Android/data/com.winfo.update/cache/
*/
public static File getExternalCacheDirectory(Context context) {
File appCacheDir = context.getExternalCacheDir();
if (appCacheDir == null) {
Log.w("StorageUtils", "Can't define system cache directory! The app should be re-installed.");
}
return appCacheDir;
}
/**
* <external-cache-path
* name="external-cache-path"
* path="." />
* 在cache下新增自定义缓存路径
* apk下载路径为:SDCard/Android/data/com.winfo.update/cache/update/
*/
public static File getExternalCacheCustomDirectory(Context context) {
//在SDCard/Android/data/com.winfo.update/cache/update创建文件夹
File appCacheDir = new File(context.getExternalCacheDir(), "update");
//如果不存在就创建
if (!appCacheDir.exists()) {
if (appCacheDir.mkdirs()) {//创建成功就返回SDCard/Android/data/com.winfo.update/cache/update/
return appCacheDir;
} else {
//创建失败就返回默认的SDCard/Android/data/com.winfo.update/cache/
return context.getExternalCacheDir();
}
} else {
//存在直接返回
return appCacheDir;
}
}
/**
* <external-path
* name="sdcard_root_externalStorageDirectory"
* path="updateFile"/>
* 在cache下新增自定义缓存路径
* apk下载路径为:/storage/emulated/0/updateFile/weixin667android1320.apk
*/
public static File getExternalCustomDirectory() {
//在SDCard/Android/data/com.winfo.update/cache/update创建文件夹
File dir = new File(Environment.getExternalStorageDirectory(), "updateFile");
//如果不存在就创建
if (!dir.exists()) {
if (dir.mkdirs()) {
return dir;
} else {
//创建失败就返回默认的SDCard/Android/data/com.winfo.update/cache/
return Environment.getExternalStorageDirectory();
}
} else {
//存在直接返回
return dir;
}
}
}
示例:安装APK
/**
* 获取安装文件意图
* @param context context
* @param apkFile 安装文件
* @return 安装意图
*/
private static Intent getApkInStallIntent(Context context, File apkFile) {
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.N) {
Uri uri = FileProvider.getUriForFile(context, "com.winfo.update.provider", apkFile);
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
intent.setDataAndType(uri, "application/vnd.android.package-archive");
} else {
Uri uri = getApkUri(apkFile);
intent.setDataAndType(uri, "application/vnd.android.package-archive");
}
return intent;
}
manifest注册
<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="com.winfo.update.provider" 自定义名称会作为uri的一部分
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/update_apk_paths" /> xml文件夹下的paths文件
</provider>