AndroidUtilCode
AndroidUtilCode copied to clipboard
Uri转换
Android版本大于10时,选择文件后使用返回的Uri通过UriUtils.uri2File转为文件路径后,会丢失原文件名称和后缀,建议使用原文件名称
+1,我也遇到一样的问题,使用以下方法代替
/** * Android 10 以上适配 * @param context * @param uri * @return */ @RequiresApi(api = Build.VERSION_CODES.Q) private static String uriToFileApiQ(Context context, Uri uri) { File file = null; //android10以上转换 if (uri.getScheme().equals(ContentResolver.SCHEME_FILE)) { file = new File(uri.getPath()); } else if (uri.getScheme().equals(ContentResolver.SCHEME_CONTENT)) { //把文件复制到沙盒目录 ContentResolver contentResolver = context.getContentResolver(); Cursor cursor = contentResolver.query(uri, null, null, null, null); if (cursor.moveToFirst()) { @SuppressLint("Range") String displayName = cursor.getString(cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME)); try { InputStream is = contentResolver.openInputStream(uri); File cache = new File(context.getExternalCacheDir().getAbsolutePath(), Math.round((Math.random() + 1) * 1000) + displayName); FileOutputStream fos = new FileOutputStream(cache); android.os.FileUtils.copy(is, fos); file = cache; fos.close(); is.close(); } catch (IOException e) { e.printStackTrace(); } } } return file.getAbsolutePath(); }
也贡献点自己的力量,当我将api提到30的时候,使用系统文件夹获取文件Uri,经测试,可以直接以Uri进行上传转inputStream上传,但如果需求上传之后又需要打开文件(类似聊天im的文件上传),在不申请特殊权限的情况下,我使用的是将文件copy到沙盒的方式,下面提供下 @CrazyDoraemon 的代码改造,不需要限制andorid10以上能用,以及对方法进行简单拓展
public static File uriToFileApi(Context context, Uri uri) {
File file = null; //android10以上转换
if (uri.getScheme().equals(ContentResolver.SCHEME_FILE)) {
file = new File(uri.getPath());
} else if (uri.getScheme().equals(ContentResolver.SCHEME_CONTENT)) { //把文件复制到沙盒目录
ContentResolver contentResolver = context.getContentResolver();
Cursor cursor = contentResolver.query(uri, null, null, null, null);
if (cursor.moveToFirst()) {
@SuppressLint("Range")
String displayName = cursor.getString(cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME));
try {
InputStream is = contentResolver.openInputStream(uri);
//先判断当前文件夹是否有该文件
String dir =context.getExternalCacheDir().getAbsolutePath()+"/kyl_file_cache";
FileUtils.createOrExistsDir(dir);
File cache = new File(dir, displayName);
if(FileUtils.isFileExists(cache)){
//如果存在,说明已经写入过了,那么判断hash值是不是一样
int oldHash = Arrays.hashCode(FileUtils.getFileMD5(context, uri));
int newHash = Arrays.hashCode(FileUtils.getFileMD5(cache));
Timber.i("通过hash值判断文件是否相同:%s - %s = %s",oldHash,newHash,oldHash-newHash);
if(newHash==oldHash){
return cache;
}else {
// 时间原因,简单拓展,重复覆盖的几率较小,后续如果有必要,可以数字递增
cache=new File(context.getExternalCacheDir().getAbsolutePath(), Math.round((Math.random() + 1) * 1000) +displayName);
}
}
FileOutputStream fos = new FileOutputStream(cache);
// android.os.FileUtils.copy(is, fos);
UtilsBridge.writeFileFromIS(cache.getAbsolutePath(), is);
file = cache;
fos.close();
is.close();
} catch (IOException e) {
e.printStackTrace();
file=null;
}
}
}
return file;
}
以上部分工具都是该库的工具类,请自行查找