web-dev-qa-db-de.com

Wie kann ich eine pdf-Datei in Android herunterladen?

Ich möchte eine PDF-Datei von einer URL herunterladen . Zum Anzeigen der PDF-Datei habe ich den folgenden Code verwendet.

File file = new File("/sdcard/example.pdf");

if (file.exists()) {
    Uri path = Uri.fromFile(file);
    Intent intent = new Intent(Intent.ACTION_VIEW);
    intent.setDataAndType(path, "application/pdf");
    intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);

    try {
        startActivity(intent);
    } 
    catch (ActivityNotFoundException e) {
        Toast.makeText(OpenPdf.this, "No Application Available to View PDF",
            Toast.LENGTH_SHORT).show();
    }
}

Es funktioniert, aber wie bekomme ich die pdf-Datei von einer URL (z. B. http://.../example.pdf). Ich möchte download die pdf-Datei von dieser URL _. Bitte hilf mir. Danke im Voraus.

18
Ramakrishna

Das Herunterladen eines PDF funktioniert genauso wie das Herunterladen anderer Binärdateien. 

  1. Öffnen Sie eine HttpUrlConnection
  2. Verwenden Sie die Methode getInputStream() der Verbindung, um die Datei zu lesen.
  3. Erstellen Sie eine FileOutputStream und schreiben Sie den Eingabestrom.

Überprüfen Sie diesen Beitrag zum Beispiel Quellcode.

8
THelper

PDF herunterladen:

 startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("www.education.gov.yk.ca/pdf/pdf-test.pdf")));

Ah, wie ich gerade herausgefunden habe, ist das Gerät abhängig.

Szenarien

  1. Es wird die PDF-Datei in Ihren Browser heruntergeladen/Ordner heruntergeladen

  2. Sie haben ein Google Docs-Konto. Sie werden aufgefordert, sich anzumelden und die PDF-Datei im Browser anzuzeigen

  3. Sie haben einen PDF-Reader installiert - Abhängig von der App kann es vorkommen, dass es nicht funktioniert

In allen Szenarien hat der Benutzer jedoch Zugriff auf PDF mit einer Codezeile :-)

20
Blundell

Es gibt viele Möglichkeiten, Dateien herunterzuladen. Im Folgenden werde ich die gebräuchlichsten Wege posten; Sie entscheiden selbst, welche Methode für Ihre App besser ist.

1. Verwenden Sie AsyncTask und zeigen Sie den Download-Fortschritt in einem Dialog an

Mit dieser Methode können Sie einige Hintergrundprozesse ausführen und gleichzeitig die Benutzeroberfläche aktualisieren (in diesem Fall aktualisieren wir eine Fortschrittsleiste).

Dies ist ein Beispielcode:

// declare the dialog as a member field of your activity
ProgressDialog mProgressDialog;

// instantiate it within the onCreate method
mProgressDialog = new ProgressDialog(YourActivity.this);
mProgressDialog.setMessage("A message");
mProgressDialog.setIndeterminate(true);
mProgressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
mProgressDialog.setCancelable(true);

// execute this when the downloader must be fired
final DownloadTask downloadTask = new DownloadTask(YourActivity.this);
downloadTask.execute("the url to the file you want to download");

mProgressDialog.setOnCancelListener(new DialogInterface.OnCancelListener() {
    @Override
    public void onCancel(DialogInterface dialog) {
        downloadTask.cancel(true);
    }
});

Das AsyncTask sieht so aus:

// usually, subclasses of AsyncTask are declared inside the activity class.
// that way, you can easily modify the UI thread from here
private class DownloadTask extends AsyncTask<String, Integer, String> {

    private Context context;
    private PowerManager.WakeLock mWakeLock;

    public DownloadTask(Context context) {
        this.context = context;
    }

    @Override
    protected String doInBackground(String... sUrl) {
        InputStream input = null;
        OutputStream output = null;
        HttpURLConnection connection = null;
        try {
            URL url = new URL(sUrl[0]);
            connection = (HttpURLConnection) url.openConnection();
            connection.connect();

            // expect HTTP 200 OK, so we don't mistakenly save error report
            // instead of the file
            if (connection.getResponseCode() != HttpURLConnection.HTTP_OK) {
                return "Server returned HTTP " + connection.getResponseCode()
                        + " " + connection.getResponseMessage();
            }

            // this will be useful to display download percentage
            // might be -1: server did not report the length
            int fileLength = connection.getContentLength();

            // download the file
            input = connection.getInputStream();
            output = new FileOutputStream("/sdcard/file_name.extension");

            byte data[] = new byte[4096];
            long total = 0;
            int count;
            while ((count = input.read(data)) != -1) {
                // allow canceling with back button
                if (isCancelled()) {
                    input.close();
                    return null;
                }
                total += count;
                // publishing the progress....
                if (fileLength > 0) // only if total length is known
                    publishProgress((int) (total * 100 / fileLength));
                output.write(data, 0, count);
            }
        } catch (Exception e) {
            return e.toString();
        } finally {
            try {
                if (output != null)
                    output.close();
                if (input != null)
                    input.close();
            } catch (IOException ignored) {
            }

            if (connection != null)
                connection.disconnect();
        }
        return null;
    }

Die obige Methode (doInBackground) wird immer in einem Hintergrundthread ausgeführt. Sie sollten dort keine UI-Aufgaben ausführen. Andererseits laufen onProgressUpdate und onPreExecute im UI-Thread, sodass Sie die Fortschrittsleiste ändern können:

    @Override
    protected void onPreExecute() {
        super.onPreExecute();
        // take CPU lock to prevent CPU from going off if the user 
        // presses the power button during download
        PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
        mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
             getClass().getName());
        mWakeLock.acquire();
        mProgressDialog.show();
    }

    @Override
    protected void onProgressUpdate(Integer... progress) {
        super.onProgressUpdate(progress);
        // if we get here, length is known, now set indeterminate to false
        mProgressDialog.setIndeterminate(false);
        mProgressDialog.setMax(100);
        mProgressDialog.setProgress(progress[0]);
    }

    @Override
    protected void onPostExecute(String result) {
        mWakeLock.release();
        mProgressDialog.dismiss();
        if (result != null)
            Toast.makeText(context,"Download error: "+result, Toast.LENGTH_LONG).show();
        else
            Toast.makeText(context,"File downloaded", Toast.LENGTH_SHORT).show();
    }

Dazu benötigen Sie die Berechtigung WAKE_LOCK.

<uses-permission Android:name="Android.permission.WAKE_LOCK" />

2. Herunterladen vom Dienst

Die große Frage ist hier: Wie aktualisiere ich meine Aktivität von einem Dienst?. Im nächsten Beispiel werden wir zwei Klassen verwenden, die Sie möglicherweise nicht kennen: ResultReceiver und IntentService. ResultReceiver erlaubt uns, unseren Thread von einem Dienst zu aktualisieren. IntentService ist eine Unterklasse von Service, die einen Thread erzeugt, um Hintergrundarbeit von dort aus auszuführen (Sie sollten wissen, dass ein Service tatsächlich im selben Thread Ihrer App ausgeführt wird; wenn Sie Service erweitern, müssen Sie manuell neue Threads erzeugen, um CPU-Blockierungsoperationen auszuführen) .

Der Download-Dienst kann folgendermaßen aussehen:

public class DownloadService extends IntentService {
    public static final int UPDATE_PROGRESS = 8344;
    public DownloadService() {
        super("DownloadService");
    }
    @Override
    protected void onHandleIntent(Intent intent) {
        String urlToDownload = intent.getStringExtra("url");
        ResultReceiver receiver = (ResultReceiver) intent.getParcelableExtra("receiver");
        try {
            URL url = new URL(urlToDownload);
            URLConnection connection = url.openConnection();
            connection.connect();
            // this will be useful so that you can show a typical 0-100% progress bar
            int fileLength = connection.getContentLength();

            // download the file
            InputStream input = new BufferedInputStream(connection.getInputStream());
            OutputStream output = new FileOutputStream("/sdcard/BarcodeScanner-debug.apk");

            byte data[] = new byte[1024];
            long total = 0;
            int count;
            while ((count = input.read(data)) != -1) {
                total += count;
                // publishing the progress....
                Bundle resultData = new Bundle();
                resultData.putInt("progress" ,(int) (total * 100 / fileLength));
                receiver.send(UPDATE_PROGRESS, resultData);
                output.write(data, 0, count);
            }

            output.flush();
            output.close();
            input.close();
        } catch (IOException e) {
            e.printStackTrace();
        }

        Bundle resultData = new Bundle();
        resultData.putInt("progress" ,100);
        receiver.send(UPDATE_PROGRESS, resultData);
    }
}

Fügen Sie den Service Ihrem Manifest hinzu:

<service Android:name=".DownloadService"/>

Und die Aktivität wird so aussehen:

// initialize the progress dialog like in the first example

// this is how you fire the downloader
mProgressDialog.show();
Intent intent = new Intent(this, DownloadService.class);
intent.putExtra("url", "url of the file to download");
intent.putExtra("receiver", new DownloadReceiver(new Handler()));
startService(intent);

Hier kommt ResultReceiver zum Spielen:

private class DownloadReceiver extends ResultReceiver{
    public DownloadReceiver(Handler handler) {
        super(handler);
    }

    @Override
    protected void onReceiveResult(int resultCode, Bundle resultData) {
        super.onReceiveResult(resultCode, resultData);
        if (resultCode == DownloadService.UPDATE_PROGRESS) {
            int progress = resultData.getInt("progress");
            mProgressDialog.setProgress(progress);
            if (progress == 100) {
                mProgressDialog.dismiss();
            }
        }
    }
}

2.1 Verwenden Sie die Groundy-Bibliothek

Groundy ist eine Bibliothek, die Sie im Grunde bei der Ausführung von Code in einem Hintergrunddienst unterstützt. Sie basiert auf dem oben gezeigten ResultReceiver-Konzept. Diese Bibliothek ist zur Zeit veraltet. So würde der ganze Code aussehen:

Die Aktivität, bei der Sie den Dialog anzeigen ...

public class MainActivity extends Activity {

    private ProgressDialog mProgressDialog;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        findViewById(R.id.btn_download).setOnClickListener(new View.OnClickListener() {
            public void onClick(View view) {
                String url = ((EditText) findViewById(R.id.edit_url)).getText().toString().trim();
                Bundle extras = new Bundler().add(DownloadTask.PARAM_URL, url).build();
                Groundy.create(DownloadExample.this, DownloadTask.class)
                        .receiver(mReceiver)
                        .params(extras)
                        .queue();

                mProgressDialog = new ProgressDialog(MainActivity.this);
                mProgressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
                mProgressDialog.setCancelable(false);
                mProgressDialog.show();
            }
        });
    }

    private ResultReceiver mReceiver = new ResultReceiver(new Handler()) {
        @Override
        protected void onReceiveResult(int resultCode, Bundle resultData) {
            super.onReceiveResult(resultCode, resultData);
            switch (resultCode) {
                case Groundy.STATUS_PROGRESS:
                    mProgressDialog.setProgress(resultData.getInt(Groundy.KEY_PROGRESS));
                    break;
                case Groundy.STATUS_FINISHED:
                    Toast.makeText(DownloadExample.this, R.string.file_downloaded, Toast.LENGTH_LONG);
                    mProgressDialog.dismiss();
                    break;
                case Groundy.STATUS_ERROR:
                    Toast.makeText(DownloadExample.this, resultData.getString(Groundy.KEY_ERROR), Toast.LENGTH_LONG).show();
                    mProgressDialog.dismiss();
                    break;
            }
        }
    };
}

Eine GroundyTask-Implementierung, die von Groundy verwendet wird, um die Datei herunterzuladen und den Fortschritt anzuzeigen:

public class DownloadTask extends GroundyTask {    
    public static final String PARAM_URL = "com.groundy.sample.param.url";

    @Override
    protected boolean doInBackground() {
        try {
            String url = getParameters().getString(PARAM_URL);
            File dest = new File(getContext().getFilesDir(), new File(url).getName());
            DownloadUtils.downloadFile(getContext(), url, dest, DownloadUtils.getDownloadListenerForTask(this));
            return true;
        } catch (Exception pokemon) {
            return false;
        }
    }
}

Und füge dies einfach zum Manifest hinzu:

<service Android:name="com.codeslap.groundy.GroundyService"/>

Es könnte nicht einfacher sein, denke ich. Nehmen Sie einfach das neueste Glas von Github und Sie können loslegen. Beachten Sie, dass der Hauptzweck von Groundy darin besteht, externe REST - Apis in einem Hintergrunddienst anzurufen und die Ergebnisse problemlos an die Benutzeroberfläche zu senden. Wenn Sie in Ihrer App so etwas tun, kann dies sehr nützlich sein.

2.2 Verwenden Sie https://github.com/koush/ion

3. Verwenden Sie die DownloadManager-Klasse (nur Gingerbread und neuer).

Gingerbread brachte die neue Funktion DownloadManager mit, mit der Sie Dateien problemlos herunterladen und die harte Arbeit beim Umgang mit Threads, Streams usw. an das System delegieren können.

Zuerst sehen wir eine Utility-Methode:

/**
 * @param context used to check the device version and DownloadManager information
 * @return true if the download manager is available
 */
public static boolean isDownloadManagerAvailable(Context context) {

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Gingerbread) {
        return true;
    }
    return false;
}

Der Name der Methode erklärt alles. Sobald Sie sicher sind, dass DownloadManager verfügbar ist, können Sie Folgendes tun:

String url = "url you want to download";
DownloadManager.Request request = new DownloadManager.Request(Uri.parse(url));
request.setDescription("Some descrition");
request.setTitle("Some title");
// in order for this if to run, you must use the Android 3.2 to compile your app
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
    request.allowScanningByMediaScanner();
    request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
}
request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, "name-of-the-file.ext");

// get download service and enqueue file
DownloadManager manager = (DownloadManager) getSystemService(Context.DOWNLOAD_SERVICE);
manager.enqueue(request);

Der Download-Fortschritt wird in der Benachrichtigungsleiste angezeigt.

Abschließende Gedanken

Erste und zweite Methode sind nur die Spitze des Eisbergs. Es gibt viele Dinge, die Sie beachten müssen, wenn Ihre App robust sein soll. Hier ist eine kurze Liste:

  • Sie müssen prüfen, ob der Benutzer über eine Internetverbindung verfügt
  • Stellen Sie sicher, dass Sie über die richtigen Berechtigungen verfügen (INTERNET und WRITE_EXTERNAL_STORAGE); auch ACCESS_NETWORK_STATE, wenn Sie die Verfügbarkeit des Internets überprüfen möchten.
  • Stellen Sie sicher, dass das Verzeichnis, in dem Sie Dateien herunterladen möchten, vorhanden ist und über Schreibberechtigungen verfügt.
  • Wenn der Download zu groß ist, möchten Sie möglicherweise den Download fortsetzen, falls vorherige Versuche fehlgeschlagen sind.
  • Die Benutzer sind dankbar, wenn Sie den Download unterbrechen lassen.

Sofern Sie keine detaillierte Kontrolle über den Download-Vorgang benötigen, sollten Sie DownloadManager (3) verwenden, da die meisten der oben aufgeführten Elemente bereits behandelt werden.

Bedenken Sie aber auch, dass sich Ihre Bedürfnisse ändern können. Beispielsweise führt DownloadManagerkeine Zwischenspeicherung von Antworten . Es wird die gleiche große Datei mehrmals blind heruntergeladen. Es gibt keine einfache Möglichkeit, das Problem zu beheben. Wenn Sie mit einem einfachen HttpURLConnection (1, 2) beginnen, müssen Sie lediglich ein HttpResponseCache hinzufügen. Daher kann der anfängliche Aufwand für das Erlernen der grundlegenden Standardwerkzeuge eine gute Investition sein.

9
Arpit Patel

Es ist nicht erforderlich, langwierigen Code zum Öffnen und Herunterladen von PDF-Dateien in Android einzugeben. Sie können den folgenden Code verwenden, um PDF-Dateien zu öffnen und herunterzuladen

String URL ="http://worldhappiness.report/wp-content/uploads/sites/2/2016/03/HR-V1_web.pdf"

 startActivity(new Intent(Intent.ACTION_VIEW,Uri.parse(URL)));
1
DEEP ADHIYA
public static class Downloader {

 public static void DownloadFile(String fileURL, File directory) {
    try {
         FileOutputStream file = new FileOutputStream(directory);
         URL url = new URL(fileURL);
        HttpURLConnection connection = (HttpURLConnection) url .openConnection();
         connection .setRequestMethod("GET");
         connection .setDoOutput(true);
         connection .connect();
         InputStream input = connection .getInputStream();
         byte[] buffer = new byte[1024];
         int len = 0;
          while ((len = input .read(buffer)) > 0) {
           file .write(buffer, 0, len );
         }
        file .close();
  } catch (Exception e) {
          e.printStackTrace();
   }
}

Für weitere Informationen klicken Sie hier http://androiddhina.blogspot.in/2015/09/how-to-download-pdf-von-url-in-Android.html

0
Dhina k