關聯文件需要注意事項
最近爲項目進行功能擴展,需要在安卓系統中關聯文件格式,這一步需要在項目的配置文件中進行相應的配置即可,相關的代碼網上很多,不需多言,需要說明的是
<data android:scheme="file"/>
<data android:scheme="content"/>
其中第一條schema="file"一般指的是在文件管理器中點擊打開相應的文件來調起app,這種情況下一般是知道文件的真實地址的。
第二第,content類型,是在安卓7.0以上開始使用的,主要是爲了保護用戶的隱私,不同app間不能暴露文件的真實地址,所以這個時候是無法獲取文件的真實地址的。
在Activity中如何獲取文件的地址呢?
首先剛纔上文中說過了,content類型是無法獲取文件的地址的,那麼我們怎麼辦呢?這裏的主要思路是通過讀取inputstream流來將文件複製到自己定義的一個臨時文件夾中,然後對其進行相關的操作。當然這種情況只適用於小體積的文件,你要是一個文件動不動上百M我覺得這種方法也不怎麼適合。
下面直接貼代碼。
private String getFilePathFromUri(Uri uri) {
if (uri == null) {
return "";
}
switch (uri.getScheme()) {
case "content":
return getFileFromContentUri(uri);
case "file":
return uri.getPath();
default:
return "";
}
}
/**
*
* @param contentUri
* @return
*/
private String getFileFromContentUri(Uri contentUri) {
if (contentUri == null) {
return null;
}
File file = null;
String filePath = "";
String fileName;
String[] filePathColumn = {MediaStore.MediaColumns.DATA, MediaStore.MediaColumns.DISPLAY_NAME};
ContentResolver contentResolver = getContentResolver();
Cursor cursor = contentResolver.query(contentUri, filePathColumn, null,
null, null);
if (cursor != null) {
cursor.moveToFirst();
int index = cursor.getColumnIndex(filePathColumn[0]);
//這裏有可能爲空 所以要做判斷
if (index > -1) {
filePath = cursor.getString(index);
}
fileName = cursor.getString(cursor.getColumnIndex(filePathColumn[1]));
cursor.close();
if (!Check.isEmpty(filePath)) {
file = new File(filePath);
if (!file.exists() || file.length() <= 0) {
filePath = getPathFromInputStreamUri(contentUri, fileName);
}
} else {
filePath = getPathFromInputStreamUri(contentUri, fileName);
}
}
return filePath;
}
/**
* 用流拷貝文件一份到自己APP目錄下
*
* @param uri
* @param fileName
* @return
*/
public String getPathFromInputStreamUri(Uri uri, String fileName) {
InputStream inputStream = null;
String filePath = null;
if (uri.getAuthority() != null) {
try {
inputStream = getContentResolver().openInputStream(uri);
File file = FileIoTools.createTemporalFileFrom(this, inputStream, fileName);
filePath = file.getPath();
} catch (Exception e) {
Log.e(getClass().getSimpleName(), e.toString());
} finally {
try {
if (inputStream != null) {
inputStream.close();
}
} catch (Exception e) {
Log.e(getClass().getSimpleName(), e.toString());
}
}
}
return filePath;
}
/**
* 將文件通過流的方式複製到臨時文件夾
* @param context
* @param inputStream
* @param fileName
* @return
* @throws IOException
*/
public static File createTemporalFileFrom(Context context, InputStream inputStream, String fileName)
throws IOException {
File targetFile = null;
if (inputStream != null) {
int read;
byte[] buffer = new byte[8 * 1024];
//自己定義拷貝文件路徑
targetFile = new File(PATH_CACHE, fileName);
if (targetFile.exists()) {
targetFile.delete();
}
OutputStream outputStream = new FileOutputStream(targetFile);
while ((read = inputStream.read(buffer)) != -1) {
outputStream.write(buffer, 0, read);
}
outputStream.flush();
try {
outputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return targetFile;
}