適配7.0 文件共享方式
1、首先再res目錄下創(chuàng)建xml文件夾 并且在xml文件夾創(chuàng)建fileFrovider的path文件,文件名自定義隨意取
文件內(nèi)容如下,屬性解釋:
paths :路徑根節(jié)點 所有的path都寫在里面
子節(jié)點:五項分別對應代碼中為
<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對應創(chuàng)建的文件夾保持一致-->
<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的內(nèi)部存儲上,需要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創(chuàng)建文件夾
File appCacheDir = new File(context.getExternalCacheDir(), "update");
//如果不存在就創(chuàng)建
if (!appCacheDir.exists()) {
if (appCacheDir.mkdirs()) {//創(chuàng)建成功就返回SDCard/Android/data/com.winfo.update/cache/update/
return appCacheDir;
} else {
//創(chuàng)建失敗就返回默認的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創(chuàng)建文件夾
File dir = new File(Environment.getExternalStorageDirectory(), "updateFile");
//如果不存在就創(chuàng)建
if (!dir.exists()) {
if (dir.mkdirs()) {
return dir;
} else {
//創(chuàng)建失敗就返回默認的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>