[英]Using SAF File Picker in Android 10 (Q) to copy files from Downloads to local app folder
Since Android 10 (API 29) I need to use the Storage Access Framework's File Picker to select GPX (GPS) files to copy from the Downloads folder to my local app folder.由于 Android 10 (API 29) 我需要使用存储访问框架的文件选择器将 select GPX (GPS) 文件从下载文件夹复制到我的本地应用程序文件夹。 I have implemented the file picker and am able to select the GPX file, however the result data URI appears different to the filename (but unique) and I cannot seem to use it to copy the files.
我已经实现了文件选择器并且能够 select GPX 文件,但是结果数据 URI 看起来与文件名不同(但唯一),我似乎无法使用它来复制文件。 The rest of the code is the same "copy" code I used in previous versions of Android.
代码的 rest 与我在以前版本的 Android 中使用的“复制”代码相同。 What am I doing wrong and how should I best use the SAF File Picker to copy files?
我做错了什么,我应该如何最好地使用 SAF 文件选择器来复制文件? I haven't been able to find a recent (API 29) "file copy" example on the net...
我无法在网上找到最近的(API 29)“文件复制”示例......
private static final int READ_REQUEST_CODE = 42;
...
public void performFileSearch() {
Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
intent.addCategory(Intent.CATEGORY_OPENABLE);
// intent.setType("application/gpx"); // Filters GPX file but wont let me select them.
intent.setType("*/*");
startActivityForResult(intent, READ_REQUEST_CODE);
}
...
if (requestCode == READ_REQUEST_CODE && resultCode == Activity.RESULT_OK) {
Uri uri = null;
if (data != null) {
uri = data.getData();
handleDownloadedGPXFiles2(uri);
}
}
...
private void handleDownloadedGPXFiles2(Uri selectedFileUri) {
File sourceFile = new File(selectedFileUri.getPath()); // Returns a unique number or string but NOT filename string???
File destDirectory = new File(this.getExternalFilesDir(null), "Imported");
File destFile = new File(destDirectory, "test.gpx"); // Needs to be same name as original filename.
try {
if (!destFile.exists()) {
destFile.createNewFile();
}
FileInputStream inStream = new FileInputStream(sourceFile);
FileOutputStream outStream = new FileOutputStream(destFile);
FileChannel inChannel = inStream.getChannel();
FileChannel outChannel = outStream.getChannel();
inChannel.transferTo(0, inChannel.size(), outChannel);
inStream.close();
outStream.close();
} catch (IOException e) {
e.printStackTrace();
}
Toast.makeText(getApplicationContext(), "File Import Complete", Toast.LENGTH_LONG).show();
}
File sourceFile = new File(selectedFileUri.getPath());
Remove above line.删除上面的行。
FileInputStream inStream = new FileInputStream(sourceFile);
Replace that line by:将该行替换为:
InputStream inStream = getContentResolver().openInputStream(selectedFileUri);
Further you can remove此外,您可以删除
if (!destFile.exists()) {
destFile.createNewFile();
}
as the file will be created by the new FileOutputStream();
因为文件将由
new FileOutputStream();
Finally: Your last Toast() is on the wrong place.最后:你的最后一个 Toast() 是在错误的地方。 It should be in the
try
block.它应该在
try
块中。
Place a different Toast() in the catch block to inform yourself or the user.在 catch 块中放置一个不同的 Toast() 以通知您自己或用户。
Thanks blackapps.谢谢黑应用。 Final code works well...
最终代码运行良好...
private void handleDownloadedGPXFiles2(Uri selectedFileUri) {
String displayName = "imported.gpx";
String fileExtension;
ContentResolver contentResolver = getContentResolver();
Cursor cursor = contentResolver.query(selectedFileUri, null, null, null, null);
try {
if (cursor != null && cursor.moveToFirst()) {
displayName = cursor.getString(cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME));
if (displayName != null && displayName.length() >=4) {
fileExtension = displayName.substring(displayName.length() - 4);
if (!fileExtension.equals(".gpx")){
myCustomToast("Must be a .GPX file!");
return;
}
} else {
myCustomToast("Must be a .GPX file!");
return;
}
}
File destDirectory = new File(this.getExternalFilesDir(null), "Imported");
File destFile = new File(destDirectory, displayName);
FileOutputStream outStream = new FileOutputStream(destFile);
InputStream in = getContentResolver().openInputStream(selectedFileUri);
OutputStream out = outStream;
byte[] buffer = new byte[1024];
int read;
while ((read = in.read(buffer)) != -1) {
out.write(buffer, 0, read);
}
in.close();
out.flush();
out.close();
Toast.makeText(getApplicationContext(), "File Import Complete", Toast.LENGTH_LONG).show();
} catch (IOException e) {
Toast.makeText(getApplicationContext(), "File Import FAILED", Toast.LENGTH_LONG).show();
e.printStackTrace();
}
finally
{
if (cursor != null)
cursor.close();
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.