getExternalFilesDir()不会将文件存储到已安装的存储卡

时间:2018-07-04 12:48:46

标签: android android-external-storage

我正在使用Nougut 7.1.1设备

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

我记录了getExternalStorageState()并显示已安装。
我也尝试使用Environment.getExternalStorageDirectory(),存储在“仿真/ 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 World /

但存储的文件(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();
            }
        }
    }
}

}

4 个答案:

答案 0 :(得分:0)

  

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

它存储在 Android SDK 所指的external storage中。外部存储不是removable storage,也不是Android SDK所称的internal storage

  

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

首先,您要将无效值传递给getExternalFilesDir()。请遵循the documentation,并输入有效值(例如Environment.DIRECTORY_MUSIC)或null

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

答案 1 :(得分:0)

如下更改了我的savePrivate()方法,它的工作原理就像是一种魅力!
按照@CommonsWare的建议,使用getExternalFilesDirs()返回可以从中选择特定存储的位置的可用数组,在我的情况下,文件夹[0]指向“仿真/ 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);
}

答案 2 :(得分:0)

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

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

在多个存储位置之间选择

有时,分配内部存储器分区以用作外部存储器的设备还提供了SD卡插槽。这意味着该设备具有两个不同的外部存储目录,因此在将“专用”文件写入外部存储时,需要选择要使用的目录。

从Android 4.4(API级别19)开始,您可以通过调用getExternalFilesDirs()来访问两个位置,这将返回一个File数组,其中包含每个存储位置的条目。阵列中的第一个条目被视为主要外部存储,除非该位置已满或不可用,否则应使用该位置。

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

Check official documentation了解详细说明。

希望这会有所帮助。

答案 3 :(得分:0)

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

ContextCompat.getExternalFilesDirs(context,Environment.YOUR_DIRECTORY);

因此,第一个是您的主要内部存储,第二个是您安装的 SD 卡(如果已安装)。如果安装了 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()