jak uzyskać dostęp do folderu pobierania w systemie Android?

82

Jestem nowym androidem, tworzę aplikację, w której można pobierać pliki do folderu pobierania (za pomocą Menedżera pobierania). Widzę zdjęcia, jeśli przejdę do folderu pobierania w emulatorze. Więc jeśli chcę pokazać pokaz slajdów z pobranych plików, jak mogę uzyskać dostęp do tego folderu? Po drugie, jak dodać pasek postępu do tego kodu: -

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);
        }
    }

Chcę dodać przycisk, który będzie pełnił funkcję robienia zdjęć z folderu pobranych plików, a następnie wyświetla je jak pokaz slajdów.

<?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
źródło

Odpowiedzi:

227

Spróbuj zadać pierwsze pytanie

Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS); 

(dostępne od API 8)

Aby uzyskać dostęp do poszczególnych plików w tym katalogu, użyj funkcji File.list () lub File.listFiles () . Wydaje się, że raportowanie postępu pobierania jest możliwe tylko w powiadomieniu, patrz tutaj .

slkorolev
źródło
@ slkorolev- hej dzięki, jak mogę dodać pasek postępu do tego kodu, czy możesz mi pomóc
Dhruv
3
i jeszcze jedno, że kiedy otrzymamy dostęp do externa_downloads przez Environment.getExternalStoragePublicDirectory (Environment.DIRECTORY_DOWNLOADS); jak dalej uzyskać dostęp do każdego pliku w tym folderze?
Dhruv
1
Czy pisanie do DIRECTORY_DOWNLOADS wymaga pozwolenia WRITE_EXTERNAL_STORAGE? Jeśli tak, czy istnieje alternatywa?
programista Androida
@androiddeveloper - Tak, potrzebujesz tego pozwolenia. Jedyną alternatywą byłoby poleganie na innej aplikacji (takiej jak menedżer plików), która ujawnia akcję „zapisz plik”, do której można uzyskać dostęp poprzez intencję. Nie ma jednak standardowych zamiarów, aby to zrobić.
Ted Hopp,
4
getExternalStoragePublicDirectoryjest przestarzałe. Zobacz tutaj
Ashish Emmanuel
26

Musisz ustawić to uprawnienie w swoim pliku manifest.xml

android.permission.WRITE_EXTERNAL_STORAGE
prochowiec
źródło
7
Od poziomu API 23 (Marshmallow) musisz również poprosić o pozwolenie w czasie wykonywania. Aby uzyskać więcej informacji, zobacz Praca z uprawnieniami systemowymi .
Ted Hopp,
Również począwszy od poziomu API 19, to uprawnienie nie jest wymagane do odczytu / zapisu plików w katalogach specyficznych dla aplikacji zwracanych przez Context.getExternalFilesDir (String) i Context.getExternalCacheDir (). developer.android.com/reference/android/… , developer.android.com/reference/android/… . Ale napotkałem java.io.FileNotFoundException (odmowa uprawnień) przy próbie FileOutputStream (new File (getExternalStoragePublicDirectory (DIRECTORY_DOWNLOADS), lfile))
Andrew Glukhoff
23

Zaktualizowano

getExternalStoragePublicDirectory()jest przestarzały .

Aby pobrać folder pobierania z Fragment,

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

Od Activity,

val downloadFolder = getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS)

downloadFolder.listFiles()wyświetli listę Files.

downloadFolder?.path poda ścieżkę ciągu do folderu pobierania.

Yogesh Umesh Vaity
źródło
7
context.getExternalFilesDir (Environment.DIRECTORY_DOWNLOADS) daje mi katalog, /emulated/0/Android/data/{package}/files/Downloadale chcę mieć publiczny folder pobierania, którym jest /emulated/0/Download. Czy to możliwe? Dzięki.
YunhaoLIU
1
@YunhaoLIU, bezpośredni dostęp systemu plików do pamięci został ograniczony w ostatnich wersjach Androida. Zajrzyj do struktury dostępu do pamięci masowej w dokumentacji systemu Android.
Yogesh Umesh Vaity,
9

Jeśli używasz Marshmallow, musisz:

  1. Poproś o uprawnienia w czasie wykonywania (użytkownik będzie mógł zezwolić lub odrzucić żądanie) lub:
  2. Użytkownik musi przejść do Ustawienia -> Aplikacje -> {Twoja aplikacja} -> Uprawnienia i przyznać dostęp do pamięci .

Dzieje się tak, ponieważ w Marshmallow Google całkowicie zmienił sposób działania uprawnień.

Mark Lu
źródło
1

Jeśli używasz powłoki, ścieżka do folderu Download (bez „s”) to

/storage/emulated/0/Download
Boris
źródło
jak to zdobyć?
nirazverma
Otwórz swoją ulubioną wyszukiwarkę i wpisz „jak otworzyć powłokę Androida”
Boris,
1

Należy dodać kolejne uprawnienia:

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

A oto zastosowania w kodzie:

val externalFilesDir = context.getExternalFilesDir(DIRECTORY_DOWNLOADS)
Yvgen
źródło