A Safe Path to External Storage

前端 未结 5 1620
暗喜
暗喜 2020-12-22 11:14

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

相关标签:
5条回答
  • 2020-12-22 11:57

    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.

    So Environment.getExternalStorageDirectory() returned the path of sdCard0 which my internal phone memory

    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

    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

      if (android.os.Environment.getExternalStorageState().equals(android.os.Environment.MEDIA_MOUNTED)
      {
           // sdcard mounted
      } 
    
    0 讨论(0)
  • 2020-12-22 12:00

    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();
    
    0 讨论(0)
  • 2020-12-22 12:06

    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. The above returned a folder called "storage" which contains the sdCard0 (internal) and extSdCard (memory card) folders.

    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.

    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.

    0 讨论(0)
  • 2020-12-22 12:17

    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. No one has reported any issues to me.

    0 讨论(0)
  • 2020-12-22 12:17

    Yep, KitKat now provides APIs for interacting with secondary external storage devices:

    The new Context.getExternalFilesDirs() and Context.getExternalCacheDirs() methods can return multiple paths, including both primary and secondary devices. You can then iterate over them and check Environment.getStorageState() and File.getFreeSpace() to determine the best place to store your files. These methods are also available on ContextCompat in the support-v4 library.

    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. 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" />
    
    0 讨论(0)
提交回复
热议问题