簡體   English   中英

使用 Android 10 (Q) 中的 SAF 文件選擇器將文件從下載文件復制到本地應用程序文件夾

[英]Using SAF File Picker in Android 10 (Q) to copy files from Downloads to local app folder

由於 Android 10 (API 29) 我需要使用存儲訪問框架的文件選擇器將 select GPX (GPS) 文件從下載文件夾復制到我的本地應用程序文件夾。 我已經實現了文件選擇器並且能夠 select GPX 文件,但是結果數據 URI 看起來與文件名不同(但唯一),我似乎無法使用它來復制文件。 代碼的 rest 與我在以前版本的 Android 中使用的“復制”代碼相同。 我做錯了什么,我應該如何最好地使用 SAF 文件選擇器來復制文件? 我無法在網上找到最近的(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());    

刪除上面的行。

FileInputStream inStream = new FileInputStream(sourceFile);

將該行替換為:

InputStream inStream = getContentResolver().openInputStream(selectedFileUri);

此外,您可以刪除

       if (!destFile.exists()) {
            destFile.createNewFile();
        }

因為文件將由new FileOutputStream();

最后:你的最后一個 Toast() 是在錯誤的地方。 它應該在try塊中。

在 catch 塊中放置一個不同的 Toast() 以通知您自己或用戶。

謝謝黑應用。 最終代碼運行良好...

    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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM