¿Cómo acceder a la carpeta de descargas en Android?

82

Soy un nuevo Android, estoy creando una aplicación en la que se pueden descargar archivos a la carpeta de descargas (usando el Administrador de descargas). Puedo ver imágenes si voy a la carpeta de descargas en el emulador. Entonces, si quiero mostrar una presentación de diapositivas de los archivos descargados, ¿cómo puedo obtener acceso a esa carpeta? En segundo lugar, cómo agregar una barra de progreso a este código: -

import java.util.Arrays;

import android.app.Activity;
import android.app.DownloadManager;
import android.app.DownloadManager.Query;
import android.app.DownloadManager.Request;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.view.View;
import android.widget.ImageView;

public class Download_managerActivity extends Activity {
     private long quueue_for_url;

     private DownloadManager dm;

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

            BroadcastReceiver receiver = new BroadcastReceiver() {
                @Override
                public void onReceive(Context context, Intent intent) {
                    String action = intent.getAction();

                    if (DownloadManager.ACTION_DOWNLOAD_COMPLETE.equals(action)) {
                        long downloadId = intent.getLongExtra(
                                DownloadManager.EXTRA_DOWNLOAD_ID, 0);
                        Query query = new Query();
                        query.setFilterById(quueue_for_url);
                        Cursor c = dm.query(query);
                        if (c.moveToFirst()) {
                            int columnIndex = c
                                    .getColumnIndex(DownloadManager.COLUMN_STATUS);
                            if (DownloadManager.STATUS_SUCCESSFUL == c
                                    .getInt(columnIndex)) {

                                ImageView view = (ImageView) findViewById(R.id.imageView1);
                                String uri_String_abcd = c
                                        .getString(c
                                                .getColumnIndex(DownloadManager.COLUMN_LOCAL_URI));
                                view.setImageURI(Uri.parse(uri_String_abcd));

                            }
                        }
                    }
                }
            };

            registerReceiver(receiver, new IntentFilter(
                    DownloadManager.ACTION_DOWNLOAD_COMPLETE));
        }

        public void onClick(View view) {
            dm = (DownloadManager) getSystemService(DOWNLOAD_SERVICE);

            Request request_for_url = new Request(
                    Uri.parse("http://fc03.deviantart.net/fs14/i/2007/086/9/1/Steve_Jobs_portrait_by_tumb.jpg"));

            Request request_for_url1 = new Request(
                    Uri.parse("http://2.bp.blogspot.com/_q7Rxg4wqDyc/S5ZRVLxVYuI/AAAAAAAAAvU/fQAUZ2XFcp8/s400/katrina-kaif.jpg"));
            Request request_for_url2 = new Request(
                    Uri.parse("http://www.buzzreactor.com/sites/default/files/Bill-Gates1.jpg"));

            quueue_for_url = dm.enqueue(request_for_url);
            quueue_for_url = dm.enqueue(request_for_url1);
            quueue_for_url = dm.enqueue(request_for_url2);

        }

        public void showDownload(View view) {
            Intent i = new Intent();
            //try more options to show downloading , retrieving and complete
            i.setAction(DownloadManager.ACTION_VIEW_DOWNLOADS);
            startActivity(i);
        }
    }

Quiero agregar un botón que realiza la función de tomar las fotos de la carpeta de descargas y luego mostrarlas como una presentación de diapositivas.

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
      package="cmpe235.lab1"
      android:versionCode="1"
      android:versionName="1.0">
    <uses-sdk android:minSdkVersion="9" />

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

    <application android:icon="@drawable/icon" android:label="@string/app_name">
        <activity android:name=".Download_managerActivity"
                  android:label="@string/app_name">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

    </application>
</manifest>

main.xml: -

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_width="fill_parent"
    android:layout_height="fill_parent">


    <Button android:text="Start Download" android:id="@+id/button1"
        android:layout_width="wrap_content" android:layout_height="wrap_content"
         android:layout_gravity="center_vertical|center_horizontal|center" android:textColor="#0000A0" 
         android:typeface="serif" android:onClick="onClick"></Button>

    <Button android:text="View Downloads" android:id="@+id/button2"
        android:layout_width="wrap_content" android:layout_height="wrap_content"
         android:layout_gravity="center_vertical|center_horizontal|center" android:textColor="#0000A0" 
         android:typeface="serif" android:onClick="showDownload"></Button>

    <ImageView android:layout_height="wrap_content" android:id="@+id/imageView1"
        android:src="@drawable/icon" android:layout_width="wrap_content"></ImageView>

</LinearLayout>
Dhruv
fuente

Respuestas:

226

Para su primera pregunta, intente

Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS); 

(disponible desde API 8)

Para acceder a archivos individuales en este directorio, use File.list () o File.listFiles () . Parece que informar el progreso de la descarga solo es posible en la notificación, consulte aquí .

slkorolev
fuente
@ slkorolev- hey gracias, ¿cómo puedo agregar una barra de progreso a este código? ¿Pueden ayudarme?
Dhruv
3
y una cosa más, que cuando tengamos acceso a externas_downloads por Environment.getExternalStoragePublicDirectory (Environment.DIRECTORY_DOWNLOADS); ¿Cómo acceder más a cada archivo en esa carpeta?
Dhruv
1
¿Escribir en DIRECTORY_DOWNLOADS requiere el permiso de WRITE_EXTERNAL_STORAGE? Si es así, ¿hay alguna alternativa?
desarrollador de Android
@androiddeveloper: sí, necesitas ese permiso. La única alternativa sería confiar en alguna otra aplicación (como un administrador de archivos) que exponga una acción de "guardar archivo" a la que podría acceder a través de una intención. Sin embargo, no hay intenciones estándar para hacer eso.
Ted Hopp
4
getExternalStoragePublicDirectoryes obsoleto. Consulte aquí
Ashish Emmanuel
26

Debe establecer este permiso en su archivo manifest.xml

android.permission.WRITE_EXTERNAL_STORAGE
Mac
fuente
7
A partir del nivel de API 23 (Marshmallow), también debe solicitar el permiso en tiempo de ejecución. Consulte Trabajar con permisos del sistema para obtener más información.
Ted Hopp
También a partir del nivel de API 19, este permiso no es necesario para leer / escribir archivos en los directorios específicos de su aplicación devueltos por Context.getExternalFilesDir (String) y Context.getExternalCacheDir (). developer.android.com/reference/android/… , developer.android.com/reference/android/… . Pero me enfrenté a java.io.FileNotFoundException (Permiso denegado) en el intento FileOutputStream (nuevo archivo (getExternalStoragePublicDirectory (DIRECTORY_DOWNLOADS), lfile))
Andrew Glukhoff
20

Actualizado

getExternalStoragePublicDirectory()está en desuso .

Para obtener la carpeta de descarga de un Fragment,

val downloadFolder = requireContext().getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS)

De una Activity,

val downloadFolder = getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS)

downloadFolder.listFiles()enumerará los Files.

downloadFolder?.path le dará la ruta de la cadena de la carpeta de descarga.

Yogesh Umesh Vaity
fuente
7
context.getExternalFilesDir (Environment.DIRECTORY_DOWNLOADS) me da el directorio /emulated/0/Android/data/{package}/files/Downloadpero quiero la carpeta de descarga pública, que es /emulated/0/Download. ¿Es posible? Gracias.
YunhaoLIU
1
@YunhaoLIU, el acceso directo del sistema de archivos al almacenamiento se ha vuelto limitado en las versiones recientes de Android. Consulte el marco de acceso al almacenamiento de la documentación de Android.
Yogesh Umesh Vaity
9

Si está usando Marshmallow, debe:

  1. Solicite permisos en tiempo de ejecución (el usuario podrá permitir o denegar la solicitud) o:
  2. El usuario debe ir a Configuración -> Aplicaciones -> {Su aplicación} -> Permisos y otorgar acceso al almacenamiento .

Esto se debe a que en Marshmallow, Google renovó por completo el funcionamiento de los permisos.

Mark Lu
fuente
1

Debe agregar el siguiente permiso:

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

Y luego aquí están los usos en el código:

val externalFilesDir = context.getExternalFilesDir(DIRECTORY_DOWNLOADS)
Yvgen
fuente
0

Si está utilizando un shell, la ruta de archivo a la carpeta Descargar (sin "s") es

/storage/emulated/0/Download
Boris
fuente
como conseguir esto
nirazverma
Abra su motor de búsqueda favorito y escriba "cómo abrir un shell de Android"
Boris