0

对于我的应用程序,我有一个相当大的数据库,需要存储在用户的设备上。我计划在未来改变这一点。但是,现在,我想将其存储到用户的外部存储(如果可用),而不是填满他们的内部存储。我可以使用什么方法来获得外部存储的安全(意思是,将在大多数设备上工作)路径?

4

5 回答 5

2

您可以获得存储数据的根路径。我认为这将是最安全的情况。

String root = Environment.getExternalStorageDirectory().toString();
File dir = new File(root + "/your_folder");
dir.mkdirs();
dir.setReadOnly();
于 2013-05-19T18:21:16.480 回答
1

我有一个三星 Galaxy s3(运行 android 4.1.2),我的内部存储器名为 sdCard0,我的外部 sd 卡名为 extSdCard。

所以 Environment.getExternalStorageDirectory() 返回了 sdCard0 的路径,我的内部手机内存

在这种情况下,您可以使用以下内容获取外部存储的实际路径。但是,不建议这样做。我建议你按照文档

http://developer.android.com/guide/topics/data/data-storage.html

String externalpath = new String();
String internalpath = new String();

public  void getExternalMounts() {
Runtime runtime = Runtime.getRuntime();
try
{
Process proc = runtime.exec("mount");
InputStream is = proc.getInputStream();
InputStreamReader isr = new InputStreamReader(is);
String line;

BufferedReader br = new BufferedReader(isr);
while ((line = br.readLine()) != null) {
    if (line.contains("secure")) continue;
    if (line.contains("asec")) continue;

    if (line.contains("fat")) {//external card
        String columns[] = line.split(" ");
        if (columns != null && columns.length > 1) {
            externalpath = externalpath.concat("*" + columns[1] + "\n");
        }
} 
        else if (line.contains("fuse")) {//internal storage
        String columns[] = line.split(" ");
        if (columns != null && columns.length > 1) {
            internalpath = internalpath.concat(columns[1] + "\n");
        }
    }
}
}
catch(Exception e)
{
    e.printStackTrace();
}
System.out.println("Path  of sd card external............"+externalpath);
System.out.println("Path  of internal memory............"+internalpath);
}

以上在大多数情况下都有效

 File dir = new File(externalpath + "/MyFolder");
 if(!dir.exists)
 {
 dir.mkdirs();
 dir.setReadOnly();
 }

不要忘记在清单文件中添加权限

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

您还应该检查 sdcard 是否安装在您的设备上

  if (android.os.Environment.getExternalStorageState().equals(android.os.Environment.MEDIA_MOUNTED)
  {
       // sdcard mounted
  } 
于 2013-05-19T18:31:37.807 回答
1

我用

File rootPath = Environment.getExternalStorageDirectory();
String StorageDir = new File(rootPath.getPath()+"/"+DirectoryName);

其中 DirectoryName 是 ExternalStorage 中要使用的子目录的名称。没有人向我报告任何问题。

于 2013-05-19T18:20:37.747 回答
0

是的,KitKat 现在提供了用于与辅助外部存储设备交互的 API:

新的Context.getExternalFilesDirs()Context.getExternalCacheDirs()方法可以返回多个路径,包括主设备和辅助设备。然后,您可以遍历它们并检查Environment.getStorageState()File.getFreeSpace()确定存储文件的最佳位置。ContextCompat这些方法在 support-v4 库中也可用。

另请注意,如果您只对使用返回的目录感兴趣,则Context不再需要READ_orWRITE_EXTERNAL_STORAGE权限。展望未来,您将始终拥有对这些目录的读/写访问权限,而无需其他权限。

应用程序还可以通过终止其权限请求来继续在旧设备上工作,如下所示:

<uses-permission
    android:name="android.permission.WRITE_EXTERNAL_STORAGE"
    android:maxSdkVersion="18" />
于 2014-03-20T23:11:05.677 回答
0

我们可能要考虑获取父目录...

String myPath = Environment.getExternalStorageDirectory().getParent();
//mypath = /storage

就我而言,我有一个 GS4 和一个 Note 10.1。上面返回了一个名为“storage”的文件夹,其中包含 sdCard0(内部)和 extSdCard(存储卡)文件夹。

我正在玩一个文件浏览器类型的应用程序,但我只对显示坐骑感兴趣。在使用 .isHidden() 和 .canRead() 方法过滤掉系统文件夹后,这将在 ListView 中显示 extCard 和 sdcard0。

public class MainActivity extends Activity {

private ListView lvFiles;
private TextView label;
private List<String> item = null;
private List<String> path = null;
private String intRoot, extRoot;

/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState)
{
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    lvFiles = (ListView) findViewById(R.id.lvFiles);
    label = (TextView) findViewById(R.id.tvLabel);



    extRoot = Environment.getExternalStorageDirectory().getParent();

    label.setText(extRoot);
    displayFiles(extRoot);

}

/** Inflate menu */
@Override
public boolean onCreateOptionsMenu(Menu menu) {
    MenuInflater m = getMenuInflater();
    m.inflate(R.menu.main_menu, menu);
    return super.onCreateOptionsMenu(menu);
}

private void displayFiles(String p) {

    File f = new File(p);
    File[] files = f.listFiles();

    item = new ArrayList<String>();
    path = new ArrayList<String>();

    for (int i=0; i<files.length; i++){

        File file = files[i];
        if (!file.isHidden() && file.canRead()) {
            item.add(file.getName());
        }
    }

    ArrayAdapter<String> filelist = new ArrayAdapter<String>(this, R.layout.row, item);
    lvFiles.setAdapter(filelist);

}

当然,我还没有用非三星设备对此进行过测试。等不及 KitKat,因为它将包括开发人员轻松找到存储卡的方法。

于 2014-03-14T01:30:27.517 回答