title: How to get access to all SD-cards, using the new Lollipop API?
body: <h2>background</h2>
  
  <p>Starting with Lollipop, apps can get access to real SD-cards (after it was not accessible on Kitkat, and was not officially supported yet worked on previous versions), as I've asked about <a href="https://stackoverflow.com/q/26744842/878126">here</a>.</p>
  
  <h2>The problem</h2>
  
  <p>Because it has become quite rare to see a Lollipop device that supports SD-card and because the emulator doesn't really has the ability (or does it?) to emulate an SD-card support, it took me quite a while to test it.</p>
  
  <p>Anyway, it seems that instead of using the normal File classes to access the SD-card (once you got a permission for it), you need to use Uris for it, using DocumentFile . </p>
  
  <p>This limits the access to the normal paths, as I can't find a way to convert the Uris to paths and vice versa (plus it's quite annoying). It also means that I don't know how to check if the current SD-card/s are accessible, so I don't know when to ask the user for permission to read/write to it (or to them).</p>
  
  <h2>What I've tried</h2>
  
  <p>Currently, this is how I get the paths to all SD-cards:</p>
  
  <pre><code>  /**
     * returns a list of all available sd cards paths, or null if not found.
     *
     * @param includePrimaryExternalStorage set to true if you wish to also include the path of the primary external storage
     */
    @TargetApi(Build.VERSION_CODES.HONEYCOMB)
    public static List&lt;String&gt; getExternalStoragePaths(final Context context,final boolean includePrimaryExternalStorage)
      {
      final File primaryExternalStorageDirectory=Environment.getExternalStorageDirectory();
      final List&lt;String&gt; result=new ArrayList&lt;&gt;();
      final File[] externalCacheDirs=ContextCompat.getExternalCacheDirs(context);
      if(externalCacheDirs==null||externalCacheDirs.length==0)
        return result;
      if(externalCacheDirs.length==1)
        {
        if(externalCacheDirs[0]==null)
          return result;
        final String storageState=EnvironmentCompat.getStorageState(externalCacheDirs[0]);
        if(!Environment.MEDIA_MOUNTED.equals(storageState))
          return result;
        if(!includePrimaryExternalStorage&amp;&amp;VERSION.SDK_INT&gt;=VERSION_CODES.HONEYCOMB&amp;&amp;Environment.isExternalStorageEmulated())
          return result;
        }
      if(includePrimaryExternalStorage||externalCacheDirs.length==1)
        {
        if(primaryExternalStorageDirectory!=null)
          result.add(primaryExternalStorageDirectory.getAbsolutePath());
        else
          result.add(getRootOfInnerSdCardFolder(externalCacheDirs[0]));
        }
      for(int i=1;i&lt;externalCacheDirs.length;++i)
        {
        final File file=externalCacheDirs[i];
        if(file==null)
          continue;
        final String storageState=EnvironmentCompat.getStorageState(file);
        if(Environment.MEDIA_MOUNTED.equals(storageState))
          result.add(getRootOfInnerSdCardFolder(externalCacheDirs[i]));
        }
      return result;
      }
  
  
  private static String getRootOfInnerSdCardFolder(File file)
    {
    if(file==null)
      return null;
    final long totalSpace=file.getTotalSpace();
    while(true)
      {
      final File parentFile=file.getParentFile();
      if(parentFile==null||parentFile.getTotalSpace()!=totalSpace)
        return file.getAbsolutePath();
      file=parentFile;
      }
    }
  </code></pre>
  
  <p>This is how I check what Uris I can reach:</p>
  
  <pre><code>final List&lt;UriPermission&gt; persistedUriPermissions=getContentResolver().getPersistedUriPermissions();
  </code></pre>
  
  <p>This is how to get access to the SD cards:</p>
  
  <pre><code>startActivityForResult(new Intent(Intent.ACTION_OPEN_DOCUMENT_TREE),42);
  
  public void onActivityResult(int requestCode,int resultCode,Intent resultData)
    {
    if(resultCode!=RESULT_OK)
      return;
    Uri treeUri=resultData.getData();
    DocumentFile pickedDir=DocumentFile.fromTreeUri(this,treeUri);
    grantUriPermission(getPackageName(),treeUri,Intent.FLAG_GRANT_READ_URI_PERMISSION|Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
    getContentResolver().takePersistableUriPermission(treeUri,Intent.FLAG_GRANT_READ_URI_PERMISSION|Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
    }
  </code></pre>
  
  <h2>The questions</h2>
  
  <ol>
  <li><p>Is it possible to check if the current SD-cards are accessible, which aren't , and somehow ask the user to get permission to them?</p></li>
  <li><p>Is there an official way to convert between the DocumentFile uris and real paths? I've found <a href="https://stackoverflow.com/a/29789495/878126"><strong>this answer</strong></a>, but it crashed in my case, plus it looks hack-y.</p></li>
  <li><p>Is it possible to request permission from the user about a specific path? Maybe even show just the dialog of "do you accept yes/no ? " ?</p></li>
  <li><p>Is it possible to use the normal File API instead of the DocumentFile API once the permission was granted?</p></li>
  <li><p>Given a file/filepath, is it possible to just request a permission to access it (and check if it's given before), or its root path ? </p></li>
  <li><p>Is it possible to make the emulator have an SD-card? Currently, it has "SD-card" being mentioned, but it works as the primary external storage, and I'd like to test it using the secondary external storage, in order to try and use the new API.</p></li>
  </ol>
  
  <p>I think that for some of those questions, one helps a lot to answer the other.</p>