Je souhaite télécharger un fichier pdf à partir d'une URL . Pour visualiser le fichier pdf, j'ai utilisé le code ci-dessous.
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();
}
}
Cela fonctionne, mais comment puis-je obtenir le fichier pdf à partir d'une URL (par exemple http://.../example.pdf
). Je veux télécharger le fichier pdf à partir de cette URL. Aidez-moi, s'il vous plaît. Merci d'avance.
Le téléchargement d'un PDF fonctionne de la même manière que le téléchargement de tout autre fichier binaire.
HttpUrlConnection
getInputStream()
de la connexion pour lire le fichier.FileOutputStream
et écrivez le flux d'entrée.Vérifiez cet article par exemple le code source.
Télécharger un pdf:
startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("www.education.gov.yk.ca/pdf/pdf-test.pdf")));
Comme je viens de le découvrir, cela dépend de l'appareil.
scénarios
Il téléchargera le pdf sur votre navigateur/téléchargé/dossier
Vous avez un compte Google Documents - Il vous sera demandé de vous connecter puis de visualiser le pdf dans le navigateur.
Vous avez un lecteur de pdf installé - L'application dépendante peut attraper il ne peut pas
Dans tous les scénarios, l'utilisateur a accès au PDF avec une seule ligne de code :-)
Il existe plusieurs façons de télécharger des fichiers. Après je vais poster les moyens les plus communs; c'est à vous de décider quelle méthode convient le mieux à votre application.
AsyncTask
et affichez la progression du téléchargement dans une boîte de dialogue.Cette méthode vous permettra d'exécuter certains processus en arrière-plan et de mettre à jour l'interface utilisateur en même temps (dans ce cas, nous mettrons à jour une barre de progression).
Ceci est un exemple de code:
// 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);
}
});
La AsyncTask
ressemblera à ceci:
// 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;
}
La méthode ci-dessus (doInBackground
) est toujours exécutée sur un thread en arrière-plan. Vous ne devriez pas faire de tâches d'interface utilisateur ici. D'autre part, les onProgressUpdate
et onPreExecute
s'exécutent sur le thread d'interface utilisateur, vous pouvez donc modifier la barre de progression:
@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();
}
Pour que cela fonctionne, vous devez disposer de l'autorisation WAKE_LOCK.
<uses-permission Android:name="Android.permission.WAKE_LOCK" />
La grande question est la suivante: comment puis-je mettre à jour mon activité depuis un service?. Dans l'exemple suivant, nous allons utiliser deux classes que vous ignorez peut-être: ResultReceiver
et IntentService
. ResultReceiver
est celui qui nous permettra de mettre à jour notre thread depuis un service; IntentService
est une sous-classe de Service
qui génère un thread pour effectuer un travail en arrière-plan à partir de là (vous devez savoir qu'une Service
s'exécute réellement dans le même thread de votre application; lorsque vous étendez Service
, vous devez générer manuellement de nouveaux threads pour exécuter les opérations de blocage du processeur). .
Le service de téléchargement peut ressembler à ceci:
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);
}
}
Ajoutez le service à votre manifeste:
<service Android:name=".DownloadService"/>
Et l'activité ressemblera à ceci:
// 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);
Voici où ResultReceiver
vient jouer:
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();
}
}
}
}
Groundy est une bibliothèque qui vous aide essentiellement à exécuter des morceaux de code dans un service en arrière-plan. Elle est basée sur le concept ResultReceiver
présenté ci-dessus. Cette bibliothèque est deprecated pour le moment. Voici à quoi ressemble le code entier:
L'activité dans laquelle vous affichez le dialogue ...
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;
}
}
};
}
Une implémentation GroundyTask
utilisée par Groundy pour télécharger le fichier et afficher sa progression:
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;
}
}
}
Et ajoutez simplement ceci au manifeste:
<service Android:name="com.codeslap.groundy.GroundyService"/>
Cela ne pourrait pas être plus facile je pense. Il suffit de saisir le dernier pot de Github et vous êtes prêt à partir. N'oubliez pas que le but principal de Groundy est de faire des appels à des apis externes REST dans un service en arrière-plan et d'afficher facilement les résultats dans l'interface utilisateur. Si vous faites quelque chose comme ça dans votre application, cela pourrait être vraiment utile.
DownloadManager
(Gingerbread
et les plus récents uniquement)Gingerbread a apporté une nouvelle fonctionnalité, DownloadManager
, qui vous permet de télécharger facilement des fichiers et de déléguer le travail difficile de gestion des threads, des flux, etc. au système.
Voyons tout d'abord une méthode utilitaire:
/**
* @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;
}
Le nom de la méthode explique tout. Une fois que vous êtes sûr que DownloadManager
est disponible, vous pouvez faire quelque chose comme ceci:
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);
La progression du téléchargement sera affichée dans la barre de notification.
Les première et deuxième méthodes ne sont que la pointe de l'iceberg. Il y a beaucoup de choses que vous devez garder à l'esprit si vous voulez que votre application soit robuste. Voici une brève liste:
INTERNET
et WRITE_EXTERNAL_STORAGE
); aussi ACCESS_NETWORK_STATE
si vous voulez vérifier la disponibilité d'Internet.Sauf si vous avez besoin d'un contrôle détaillé du processus de téléchargement, envisagez d'utiliser DownloadManager
(3) car il gère déjà la plupart des éléments répertoriés ci-dessus.
Mais considérez également que vos besoins peuvent changer. Par exemple, DownloadManager
ne met pas la réponse en cache . Il téléchargera aveuglément le même gros fichier plusieurs fois. Il n'y a pas de moyen facile de régler le problème après coup. Où si vous commencez avec une HttpURLConnection
de base (1, 2), il vous suffit d’ajouter une HttpResponseCache
. L’effort initial d’apprentissage des outils de base standard peut donc être un bon investissement.
Il n'est pas nécessaire de mettre un long code pour ouvrir et télécharger le pdf dans Android. Vous pouvez simplement utiliser le code ci-dessous pour ouvrir et télécharger le pdf.
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)));
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();
}
}
Pour plus d'informations, cliquez ici http://androiddhina.blogspot.in/2015/09/how-to-download-pdf-from-url-in-Android.html