问题描述
我正在尝试更新我的应用以使用 Android 10 及更高版本中的 android 新范围存储规则,但我遇到了最困难的时间。我知道我需要用新版本的 java 重建我的应用程序,但我只想在我学习和学习足够的时间时让它工作。简而言之,我真的需要帮助。我已经阅读了许多使作用域存储工作的不同方法,但似乎每个人的做法都不一样。
只是为了澄清,我试图对 uri 做的是在图像视图中显示,然后上传到数据库。
此代码用于在 android 9 中拍照并选择图像和视频,但在 android 10 中,它仅在相机组件捕获图片或视频时有效。当用户从文件中选择图像或视频时,它返回空指针异常。因为我很确定错误在于我如何处理不同的选择器意图,所以我首先显示了结果代码。
我一直无法找到有关如何在 android 10 中检索可用图像或视频 uri 的清晰示例。如果有人可以提供帮助,我将不胜感激。我知道我有很多东西要学。
if ((new java.io.File(_filePath)).exists()){
} else {
_filePath = vidfile.getAbsolutePath();
if ((new java.io.File(_filePath)).exists()){
} else {
ArrayList<String> _filePath_1 = new ArrayList<>();
if (_data != null) {
if (_data.getClipData() != null) {
for (int _index = 0; _index < _data.getClipData().getItemCount(); _index++) {
ClipData.Item _item = _data.getClipData().getItemAt(_index);
_filePath_1.add(FileUtil.convertUriToFilePath(getApplicationContext(),_item.getUri()));
}
}
else {
_filePath_1.add(FileUtil.convertUriToFilePath(getApplicationContext(),_data.getData()));
}
}
_filePath = _filePath_1.get((int)0);
}
}
以防万一我错了,这里是点击事件启动选择器的代码...
SimpleDateFormat date1 = new SimpleDateFormat("yyyyMMdd_HHmmss");
String fileName1 = date1.format(new Date()) + ".jpg";
picfile = new
File(getApplicationContext().getExternalFilesDir(Environment.DIRECTORY_DCIM).getAbsolutePath() +
File.separator + fileName1);
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
Uri _uri_camr1 = null;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
_uri_camr1 = FileProvider.getUriForFile(getApplicationContext(),getApplicationContext().getPackageName() + ".provider",picfile);
}
else {
_uri_camr1 = Uri.fromFile(picfile);
}
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT,_uri_camr1);
takePictureIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
SimpleDateFormat date2 = new SimpleDateFormat("yyyyMMdd_HHmmss");
String fileName2 = date2.format(new Date()) + ".mp4";
vidfile = new
File(getApplicationContext().getExternalFilesDir(Environment.DIRECTORY_DCIM).getAbsolutePath() +
File.separator + fileName2);
Intent takeVideoIntent = new Intent(MediaStore.ACTION_VIDEO_CAPTURE);
Uri _uri_camr2 = null;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
_uri_camr2 = FileProvider.getUriForFile(getApplicationContext(),vidfile);
}
else {
_uri_camr2 = Uri.fromFile(vidfile);
}
takeVideoIntent.putExtra(MediaStore.EXTRA_OUTPUT,_uri_camr2);
takeVideoIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
Intent chooserIntent = new Intent(Intent.ACTION_CHOOSER);
Intent contentSelectionIntent = new Intent(Intent.ACTION_GET_CONTENT);
contentSelectionIntent.addCategory(Intent.CATEGORY_OPENABLE);
contentSelectionIntent.setType("*/*");
contentSelectionIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
Intent[] intentArray = new Intent[]{ takePictureIntent,takeVideoIntent};
chooserIntent.putExtra(Intent.EXTRA_INTENT,contentSelectionIntent);
chooserIntent.putExtra(Intent.EXTRA_TITLE,"Choose an action");
chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS,intentArray);
startActivityForResult(chooserIntent,REQ_CD_CAMR);
解决方法
试试这个代码。它将选定的文件复制到范围存储,并为您提供范围存储的最终路径,您可以从那里访问它。尝试一下,如果您遇到任何问题,请告诉我。
android.net.Uri sharedFileUri = android.net.Uri.fromFile(new java.io.File(_filepath));
java.io.FileInputStream input = null;
java.io.FileOutputStream output = null;
try {
String filePath = new java.io.File(getCacheDir(),"tmp").getAbsolutePath();
android.os.ParcelFileDescriptor pfd = getContentResolver().openFileDescriptor(sharedFileUri,"rw");
if (pfd != null) {
java.io.FileDescriptor fd = pfd.getFileDescriptor();
input = new java.io.FileInputStream (fd);
output = new java.io.FileOutputStream (filePath);
int read;
byte[] bytes = new byte[4096];
while ((read = input.read(bytes)) != -1) {
output.write(bytes,read);
}
java.io.File sharedFile = new java.io.File(filePath);
String finalPath = sharedFile.getPath(); // this will provide you path to scoped storage. use this final path to access the selected file from scoped storage.
}
}catch(Exception ex) {
android.widget.Toast.makeText(this,ex.toString(),android.widget.Toast.LENGTH_SHORT).show();
} finally {
try {
input.close();
output.close();
} catch (Exception ignored) {
}
}