如何移动SDCard中的文件

问题描述 投票:0回答:1

我目前正在运行一个应用程序。该应用程序并未在商店发布,而是作为 apk 分发供用户下载。 我们决定在 Google Play 商店上发布更新后的应用程序。在发布时,我们正在尝试实现一个功能,将保存在 SD 卡上的数据从旧应用程序转移到新应用程序,但我不知道该怎么做,所以我提出了一个问题。

我试图实现的功能如下。

  • 在旧应用程序中添加了数据传输按钮,单击该按钮会将数据传输到新应用程序。 ・请勿使用新应用程序执行任何迁移操作。

我们已确认在 Android7 及更高版本上可以使用存储访问框架的 DocumentsContract.moveDocument() 移动文件。但是,上述方法无法在我的Android 5设备上使用,因此我采用了不同的方式实现。但是,我被告知权限被拒绝,无法迁移数据。

下面是我实现的部分代码。

正在执行处理的方法

void forTEST() {
        File fileDir = getExternalFilesDir(null);
        File[] fileDirs = getExternalFilesDirs(null);

        File appAExternalFileDir = null;
        for (File dir : fileDirs) {
            if ( dir != null && !fileDir.equals(dir) && Environment.isExternalStorageRemovable(dir)) {
                appAExternalFileDir = dir;
            }
        }

        if (appAExternalFileDir == null) return;

        String appAExternalFileDirPath = appAExternalFileDir.getAbsolutePath();
        Log.d("testlog", "externalFileDirPath:" + appAExternalFileDir.getAbsolutePath()); // externalFileDirPath:/storage/MicroSD/Android/data/com.example.testAppA/files
        Log.d("testlog", appAExternalFileDir.canRead() ? "true" : "false"); // true
        Log.d("testlog", appAExternalFileDir.canWrite() ? "true" : "false"); // true

        String appBExternalFileDirPath = 
        String appBExternalFileDirPath = appAExternalFileDirPath.replace("com.example.testAppA", "testAppB");
        File appBExternalFileDir = new File(appBExternalFileDirPath);
        Log.d("testlog", "externalFileDirPath:" + appBExternalFileDir.getAbsolutePath());// externalFileDirPath:/storage/MicroSD/Android/data/com.example.testAppB/files
        Log.d("testlog", appBExternalFileDir.canRead() ? "true" : "false"); // true
        Log.d("testlog", appBExternalFileDir.canWrite() ? "true" : "false"); // true

        File[] appAFiles = appAExternalFileDir.listFiles();
        for(int i=0; i<appAFiles.length; i++) {
            String fileName = appAFiles[i].getName();
            File destFile = new File(appBExternalFileDir, appAFiles[i].getName());

            moveFileToDest(appAFiles[i], destFile);

// I tried renameTo() but only found true/false, so I created moveFileToDest() and executed it.
// renameTo() returned false.
//            if (appAFiles[i].renameTo(destFile)) {
//                Log.d("testLog", "success to renameTo()");
//            } else {
//                Log.d("testlog", "failure to renameTo()");
//            }
        }
    }

    void moveFileToDest(File sourceFile, File destinationFile) {
        try {
            // When I performed the move process described below without creating a new file first, a FileNotFoundException occurred, so I added createNewFile().
            if (destinationFile.createNewFile()) { // throw java.io.IOException: open failed: EACCES (Permission denied)
                Log.d("testlog", "create success!!");
            } else {
                Log.d("testlog", "create failed");
            }

            FileInputStream fis = new FileInputStream(sourceFile);
            FileOutputStream fos = new FileOutputStream(destinationFile);

            FileChannel sourceChannel = fis.getChannel();
            FileChannel destinationChannel = fos.getChannel();

            sourceChannel.transferTo(0, sourceChannel.size(), destinationChannel);

            sourceChannel.close();
            fis.close();
            destinationChannel.close();
            fos.close();

            sourceFile.delete();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

AndroidManifest.xml(摘录)

    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

appAExternalFileDir 和 appBExternalFileDir 的 canRead() 和 canWrite() 都是 true。 但是当我尝试在 appBExternalFileDir 中创建文件时,我收到 IOException 并显示权限被拒绝。

我该怎么办。 如果你能告诉我,我很高兴。 (如果有遗漏的信息,请告诉我,以便我补充)

java android storage
1个回答
0
投票

由于 Android 4 KitKat 可移动微型 SD 卡是只读的,除了其上的应用程序特定目录之外,您应该让新应用程序将文件从旧位置复制到新位置。

在 Android 5 上,应用程序可以读取卡上 Android 目录中的所有文件。但他们只能写入自己的特定文件目录。

© www.soinside.com 2019 - 2024. All rights reserved.