Home | History | Annotate | Download | only in articles
      1 page.title=Acceso a directorios determinados
      2 page.keywords=preview,sdk,scoped directory access
      3 page.tags=androidn
      4 
      5 @jd:body
      6 
      7 <div id="tb-wrapper">
      8 <div id="tb">
      9   <h2>En este documento</h2>
     10   <ol>
     11     <li><a href="#accessing">Acceder a un directorio de almacenamiento externo</a></li>
     12     <li><a href="#removable">Acceder a un directorio de un medio extrable</a></li>
     13     <li><a href="#best">Prcticas recomendadas</a></li>
     14   </ol>
     15 </div>
     16 </div>
     17 
     18 <p>Las aplicaciones como las aplicaciones de fotografa generalmente solo necesitan acceso a directorios de
     19 almacenamiento externo, como el directorio <code>Pictures</code>. Los mtodos
     20 existentes para acceder a almacenamiento externo no estn diseados para brindar un
     21 acceso fcil a determinados directorios para estos tipos de aplicaciones. Por ejemplo:</p>
     22 
     23 <ul>
     24 <li>Solicitar {@link android.Manifest.permission#READ_EXTERNAL_STORAGE}
     25 o {@link android.Manifest.permission#WRITE_EXTERNAL_STORAGE} en tu manifiesto
     26 permite el acceso a todos los directorios pblicos de un almacenamiento externo, lo cual podra ser
     27 un acceso mayor que el que necesita tu aplicacin.</li>
     28 <li>Usar el
     29 <a href="{@docRoot}guide/topics/providers/document-provider.html">framework
     30 de acceso al almacenamiento</a> generalmente implica que el usuario seleccione directorios
     31 mediante un sistema de IU, lo cual no es necesario si tu aplicacin siempre accede al mismo
     32 directorio externo.</li>
     33 </ul>
     34 
     35 <p>Android N brinda una API nueva y simplificada para acceder a
     36  directorios de almacenamiento externo comunes. </p>
     37 
     38 <h2 id="accessing">Acceder a un directorio de almacenamiento externo</h2>
     39 
     40 <p>Usa la clase <code>StorageManager</code> para obtener la instancia de
     41 <code>StorageVolume</code> correcta. Luego, crea una intent llamando al
     42  mtodo <code>StorageVolume.createAccessIntent()</code> de esa instancia.
     43 Usa esta intencin para acceder a directorios de almacenamiento externo. Para obtener una lista de
     44 todos los volmenes disponibles, incluidos los volmenes de medios extrables, usa
     45 <code>StorageManager.getVolumesList()</code>.</p>
     46 
     47 <p>Si tienes informacin sobre un archivo especfico, usa
     48 <code>StorageManager.getStorageVolume(File)</code> para obtener el
     49 <code>StorageVolume</code> que contiene el archivo. Llama a
     50 <code>createAccessIntent()</code> en este <code>StorageVolume</code> para acceder al
     51 directorio de almacenamiento externo del archivo.</p>
     52 
     53 <p>
     54 En el caso de los volmenes secundarios, como las tarjetas SD externas, pasa un valor nulo cuando llames a
     55 <code>StorageVolume.createAccessIntent()</code> para solicitar acceso al volumen
     56  completo, en lugar de un directorio especfico.
     57 <code>StorageVolume.createAccessIntent()</code> regresa un valor nulo si pasas un
     58  valor nulo para el volumen principal o si pasas un nombre de directorio no vlido.
     59 </p>
     60 
     61 <p>El siguiente fragmento de cdigo es un ejemplo de cmo abrir el
     62 directorio <code>Pictures</code> en el almacenamiento compartido principal:</p>
     63 
     64 <pre>
     65 StorageManager sm = (StorageManager)getSystemService(Context.STORAGE_SERVICE);
     66 StorageVolume volume = sm.getPrimaryVolume();
     67 Intent intent = volume.createAccessIntent(Environment.DIRECTORY_PICTURES);
     68 startActivityForResult(intent, request_code);
     69 </pre>
     70 
     71 <p>El sistema intenta otorgar acceso al directorio externo y, si
     72 es necesario, confirma el acceso con el usuario usando una IU simplificada:</p>
     73 
     74 <img src="{@docRoot}images/android-7.0/scoped-directory-access-framed.png" srcset="{@docRoot}images/android-7.0/scoped-directory-access-framed.png 1x,
     75 {@docRoot}images/android-7.0/scoped-directory-access-framed_2x.png 2x" />
     76 <p class="img-caption"><strong>Imagen 1.</strong> Una aplicacin solicitando
     77 acceso al directorio Pictures.</p>
     78 
     79 <p>Si el usuario otorga el acceso, el sistema llama a tu
     80  anulacin de <code>onActivityResult()</code> con un cdigo resultante de
     81 <code>Activity.RESULT_OK</code> y datos de intents que contienen el URI. Usa
     82 el URI brindado para acceder a la informacin del directorio. Es similar a usar URI
     83 generados por el
     84 <a href="{@docRoot}guide/topics/providers/document-provider.html">framework
     85 de acceso al almacenamiento</a>.</p>
     86 
     87 <p>Si el usuario no otorga el acceso, el sistema llama a tu
     88 anulacin de <code>onActivityResult()</code> con un cdigo resultante de
     89 <code>Activity.RESULT_CANCELED</code> y datos de intents nulos.</p>
     90 
     91 <p class="note"><b>Nota</b>: Obtener acceso a un directorio externo especfico
     92 tambin otorga el acceso a los subdirectorios de ese directorio.</p>
     93 
     94 <h2 id="removable">Acceder a un directorio de un medio extrable</h2>
     95 
     96 <p>Para usar el acceso a directorios determinados para acceder a directorios de medios extrables,
     97 primero debes agregar un {@link android.content.BroadcastReceiver} que escuche la
     98 notificacin{@link android.os.Environment#MEDIA_MOUNTED}, por ejemplo:</p>
     99 
    100 <pre>
    101 &lt;receiver
    102     android:name=".MediaMountedReceiver"
    103     android:enabled="true"
    104     android:exported="true" &gt;
    105     &lt;intent-filter&gt;
    106         &lt;action android:name="android.intent.action.MEDIA_MOUNTED" /&gt;
    107         &lt;data android:scheme="file" /&gt;
    108     &lt;/intent-filter&gt;
    109 &lt;/receiver&gt;
    110 </pre>
    111 
    112 <p>Cuando el usuario conecta un medio extrable, como una tarjeta SD, el sistema enva una
    113 notificacin{@link android.os.Environment#MEDIA_MOUNTED}. Esta notificacin
    114 brinda un objeto <code>StorageVolume</code> en los datos de intents que puedes
    115 usar para acceder a directorios del medio extrable. El siguiente ejemplo
    116 accede al directorio <code>Pictures</code> de medios extrables:</p>
    117 
    118 <pre>
    119 // BroadcastReceiver has already cached the MEDIA_MOUNTED
    120 // notification Intent in mediaMountedIntent
    121 StorageVolume volume = (StorageVolume)
    122     mediaMountedIntent.getParcelableExtra(StorageVolume.EXTRA_STORAGE_VOLUME);
    123 volume.createAccessIntent(Environment.DIRECTORY_PICTURES);
    124 startActivityForResult(intent, request_code);
    125 </pre>
    126 
    127 <h2 id="best">Prcticas recomendadas</h2>
    128 
    129 <p>Cuando sea posible, sigue usando el URI de acceso a directorios externos de modo que no tengas
    130 que solicitarle acceso al usuario continuamente. Una vez que el usuario haya otorgado el acceso, llama a
    131 <code>getContentResolver().takePersistableUriPermssion()</code> con el
    132 URI de acceso a directorios. El sistema continuar el URI, y las siguientes solicitudes
    133 de acceso generarn <code>RESULT_OK</code> y no le mostrarn una IU de confirmacin al
    134 usuario.</p>
    135 
    136 <p>Si el usuario deniega el acceso a un directorio externo, no vuelvas a solicitar el
    137 acceso inmediatamente. Hacer esto provocara una mala experiencia
    138 de usuario. Si el usuario deniega una solicitud y la aplicacin solicita acceso
    139  nuevamente, aparece la casilla de verificacin <b>Don't ask again</b> en la IU:</p>
    140 
    141 <img src="{@docRoot}images/android-7.0/scoped-directory-access-dont-ask.png" srcset="{@docRoot}images/android-7.0/scoped-directory-access-dont-ask.png 1x,
    142 {@docRoot}images/android-7.0/scoped-directory-access-dont-ask_2x.png 2x" />
    143 <p class="img-caption"><strong>Figura 1.</strong> Una aplicacin que presenta una
    144 segunda solicitud para obtener acceso a medios extrables.</p>
    145 
    146 <p>Si el usuario selecciona <b>Don't ask again</b> y deniega la solicitud, todas las
    147 solicitudes futuras que presente la aplicacin para el directorio determinado se denegarn
    148  automticamente, y el usuario no recibir ninguna IU de solicitud.</p>