简体   繁体   English

通往外部存储的安全途径

[英]A Safe Path to External Storage

For my app, I have a fairly large database that needs to be stored on the user's device. 对于我的应用程序,我有一个相当大的数据库,需要将其存储在用户的设备上。 I plan to change this in the future. 我计划在将来对此进行更改。 For now, however, I'd like to store it to the user's external storage (if available) rather than fill up their internal storage. 但是,现在,我想将其存储到用户的外部存储(如果可用),而不是填充其内部存储。 What method can I use to get a safe (meaning, will work on most devices) path to the external storage? 我可以使用哪种方法来获取到外部存储的安全路径(意味着,在大多数设备上都可以使用)?

You could get the root path to store your datas. 您可以获取存储数据的根路径。 I think it will be the most secure case. 我认为这将是最安全的情况。

String root = Environment.getExternalStorageDirectory().toString();
File dir = new File(root + "/your_folder");
dir.mkdirs();
dir.setReadOnly();

I use 我用

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

where DirectoryName is the name of the subdirectory in the ExternalStorage to use. 其中DirectoryName是要使用的ExternalStorage中的子目录的名称。 No one has reported any issues to me. 没有人向我报告任何问题。

I have a samsung galaxy s3 (running android 4.1.2) and my internal memory is named sdCard0 and My external sd card named as extSdCard. 我有一个三星银河s3(运行android 4.1.2),我的内部存储器名为sdCard0,我的外部sd卡名为extSdCard。

So Environment.getExternalStorageDirectory() returned the path of sdCard0 which my internal phone memory 所以Environment.getExternalStorageDirectory()返回了sdCard0的路径,该路径是我的内部电话内存

In such cases you can use the following to get the actual path of the external storage. 在这种情况下,您可以使用以下命令获取外部存储的实际路径。 However this is not recommended. 但是,不建议这样做。 I suggest you follow the docs 我建议你按照文档

http://developer.android.com/guide/topics/data/data-storage.html 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);
}

The above works in most cases 以上情况在大多数情况下适用

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

Don't forget to add permission in manifest file 不要忘记在清单文件中添加权限

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

Also you should check if the sdcard is mounted on your device 另外,您还应该检查SD卡是否已安装在设备上

  if (android.os.Environment.getExternalStorageState().equals(android.os.Environment.MEDIA_MOUNTED)
  {
       // sdcard mounted
  } 

We may want to consider getting the parent directory instead... 我们可能要考虑获取父目录...

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

In my case, I have a GS4 and a Note 10.1. 就我而言,我有GS4和Note 10.1。 The above returned a folder called "storage" which contains the sdCard0 (internal) and extSdCard (memory card) folders. 上面的返回了一个名为“ storage”的文件夹,其中包含sdCard0(内部)和extSdCard(存储卡)文件夹。

I'm playing around with a file explorer type app, but I'm only interested in showing the mounts. 我正在玩文件浏览器类型的应用程序,但是我只对显示安装文件感兴趣。 This displays extCard and sdcard0 in the ListView after filtering out the system folders with the .isHidden() and .canRead() methods. 使用.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);

}

Of course, I haven't tested this with none-Samsung devices. 当然,我还没有使用非三星设备对此进行过测试。 Can't wait for KitKat, as it will include methods for developers to easily find the memory card. 迫不及待要使用KitKat,因为它将包含开发人员可以轻松找到存储卡的方法。

Yep, KitKat now provides APIs for interacting with secondary external storage devices: 是的,KitKat现在提供用于与辅助外部存储设备进行交互的API:

The new Context.getExternalFilesDirs() and Context.getExternalCacheDirs() methods can return multiple paths, including both primary and secondary devices. 新的Context.getExternalFilesDirs()Context.getExternalCacheDirs()方法可以返回多个路径,包括主设备和辅助设备。 You can then iterate over them and check Environment.getStorageState() and File.getFreeSpace() to determine the best place to store your files. 然后,您可以遍历它们并检查Environment.getStorageState()File.getFreeSpace()以确定存储文件的最佳位置。 These methods are also available on ContextCompat in the support-v4 library. 在support-v4库中的ContextCompat上也可以使用这些方法。

Also note that if you're only interested in using the directories returned by Context , you no longer need the READ_ or WRITE_EXTERNAL_STORAGE permissions. 还要注意,如果您仅对使用Context返回的目录感兴趣,则不再需要READ_WRITE_EXTERNAL_STORAGE权限。 Going forward, you'll always have read/write access to these directories with no additional permissions required. 展望未来,您将始终具有对这些目录的读/写访问权限,而无需其他权限。

Apps can also continue working on older devices by end-of-lifing their permission request like this: 应用也可以通过终止其许可请求来继续在旧设备上工作,如下所示:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何在android中创建外部存储目录,将外部存储路径显示为“storage / emulated / 0”? - How to create directory in external storage in android which show external storage path as “storage/emulated/0”? 如何获取外部 REMOVABLE 存储路径(micro sdcard) - How to get external REMOVABLE storage path (micro sdcard) 外部存储到内部存储 - External storage to internal storage 内部存储的安全性如何? - How safe is Internal Storage? 在Android中使用绝对路径获取内部和外部存储中所有文件(每个文件)的列表 - Get list of all files (every file) in both internal and external storage with absolute path in Android Android 5至6问题:外部存储路径File.Exists()损坏/正在寻找替代方案 - Android 5 to 6 Issue: External Storage Path File.Exists() Broken / Looking for Alternative Android 9 无法在 Android 外部公共路径中创建目录(“storage/emulated/0/MyImages”) - Android 9 can't create directory inside Android external public path("storage/emulated/0/MyImages") Firebase Java 从 firebase 存储中保存文件并知道外部 ZCD69B49357F06CD8D28D7 的保存路径 - Firebase Java Save a file from firebase storage and know the save path to external memory 写入Android 7上的外部存储 - Write to external storage on Android 7 存储在外部存储卡上 - Storing on the external storage card
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM