getExternalFilesDir() 不存储文件到挂载的存储卡

getExternalFilesDir () doesnot store file to mounted memory card

我正在使用 Nougut 7.1.1 设备

当我运行下面给出的代码时,文件存储在设备或内部存储器中“emulated/0...”但我想将其存储在可移动存储卡中。

我登录了 getExternalStorageState(),它显示已安装。
我也试过使用Environment.getExternalStorageDirectory(),存储在“emulated/0...”,没有结果

我也在清单文件中使用了如下权限:

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

注意:但是,内部和外部(内存卡)存储都包含“Hello World”文件夹,如:
Android/Data/com.example.myapplication/files/Hello世界/

但存储的文件 (myData2.txt) 仅存在于内部存储的“Hello World”文件夹中

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Log.i("tag", Environment.getExternalStorageState().toString());
        Log.i("tag", getExternalFilesDir(null).toString());

        savePrivate();

    }

    public void savePrivate() {
        String info = "Written";
        File folder = getExternalFilesDir("Hello World");// Folder Name
        File myFile = new File(folder, "myData2.txt");// Filename
        writeData(myFile, info);
    }

    private void writeData(File myFile, String data) {
        FileOutputStream fileOutputStream = null;
        try {
            fileOutputStream = new FileOutputStream(myFile);
            fileOutputStream.write(data.getBytes());
            Toast.makeText(this, "Done" + myFile.getAbsolutePath(), Toast.LENGTH_SHORT).show();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (fileOutputStream != null) {
                try {
                    fileOutputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

but stored file(myData2.txt) is present only in "Hello World" folder of internal storage

它存储在 Android SDK 所指的 external storage. External storage is not removable storage, nor is it what the Android SDK refers to as internal storage 中。

When I run the below given code, file is stored in device or internal storage "emulated/0..." but I want to store it in removable memory card.

首先,您向 getExternalFilesDir() 传递了一个无效值。请按照 the documentation 并输入有效值(例如 Environment.DIRECTORY_MUSIC)或 null.

要写入可移动存储,请替换 getExternalFilesDir() with getExternalFilesDirs() 并从返回的位置数组中选择一个位置。如果该数组有 2+ 个条目,则其中 1+ 个将位于可移动存储上。

如下更改了我的 savePrivate() 方法,效果非常好!
根据@CommonsWare 的建议,使用 getExternalFilesDirs() 返回可用的位置数组,我可以从中 select 特定存储,在我的例子中,文件夹 [0] 指向 "emulated/0.." 和文件夹 [1 ] 指向可移动存储(storage/15C8-119Z/...)。

    public void savePrivate() {
    String info = "Written";
    File[] folder = getExternalFilesDirs("backup");// Folder Name
    Log.i("tag", String.valueOf(folder[1]).toString());
    File myFile = new File(folder[1], "myData2.txt");// Filename
    writeData(myFile, info);
}

Android 4.4 (API level 19) 开始,在您应用的私有外部存储目录中读取或写入文件(使用 getExternalFilesDir() 访问)不需要 READ_EXTERNAL_STORAGE 或 WRITE_EXTERNAL_STORAGE 权限。因此,如果您的应用支持 Android 4.3(API 级别 18)及更低版本,并且您只想访问私有外部存储目录,则应声明仅在较低版本的 Android 通过添加 maxSdkVersion 属性:

<manifest ...>
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"
                     android:maxSdkVersion="18" />
</manifest>

Select 多个存储位置之间

有时,分配内存分区用作外部存储的设备也会提供SD卡插槽。这意味着该设备有两个不同的外部存储目录,因此您需要 select 在将 "private" 文件写入外部存储时使用哪个目录。

从 Android 4.4(API 级别 19)开始,您可以通过调用 getExternalFilesDirs() 访问这两个位置,其中 returns 一个包含每个存储位置条目的文件数组。数组中的第一个条目被认为是主要的外部存储,您应该使用该位置,除非它已满或不可用。

如果您的应用支持 Android 4.3 及更低版本,您应该使用支持库的静态方法 ContextCompat.getExternalFilesDirs()。这总是 returns 一个文件数组,但如果设备是 运行 Android 4.3 或更低版本,那么它只包含一个用于主要外部存储的条目(如果有第二个存储位置,你无法在 Android 4.3 及更低版本上访问它。

Check official documentation详细说明。

希望对您有所帮助。

这是上下文中的一个函数,您可以在其中获取所有已安装的存储

ContextCompat.getExternalFilesDirs(context,Environment.YOUR_DIRECTORY);

因此,首先是您的主要内部存储,其次是您已安装的 SD 卡(如果已安装)。您可以使用此功能 returns 如果 sd 卡安装在 sd 卡目录,否则内部存储目录

File getDir(Context context){
 File[] mountedStorage = ContextCompat.getExternalFilesDirs(context,Environment.DIRECTORY_PICTURES);
    return mountedStorage[mountedStorage.length-1];
}

使用 Kotlin

  val dir:File = ContextCompat.getExternalFilesDirs(context,Environment.YOUR_DIRECTORY).last()