Android HttpClient – Download einer Datei mit NotificationSunday, 28 Dec 2014, 20:31
By SimonEine Sache für die ich etwas länger Suchen musste, ist das herunterladen einer Datei mit Überprüfung des Netzwerksstatus. Das sollte möglichst auch nicht auf dem Main Thread ablaufen da das Interface sonst einfriert. Um das ganze im Hintergrund ausführen zu können benötigen wir einen Thread, aber um im Interface darzustellen das der Download fertig ist (z.B. eine Notification anzeigen) muss nach dem Thread wieder Code im Main Thread ausgefürt werden. Am einfachsten erreicht man das mit der AsyncTask Klasse die in der Android Bibliothek zu Verfügung steht.
package org.graetzer;
/**
* Copyright 2011 Simon Grätzer [email protected]
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.List;
import org.apache.http.HttpEntity;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.ProgressDialog;
import android.app.AlertDialog.Builder;
import android.content.Context;
import android.content.Intent;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.AsyncTask;
import android.os.Bundle;
public class TestClass extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.layout);
LoadTask task = new LoadTask(this);
task.execute("http://google.de", "http://example.org");
}
// Ich verzichte in dieser Klasse darauf einen kontinuierlichen Fortschritt anzuzeigen, deswegen ist der zweite Parameter Void
static class LoadTask extends AsyncTask<String, Void, List<File>> {
private final Context context;
private final ConnectivityManager cmanager;
private ProgressDialog spinner;
public LoadTask (Context ctx) {
this.context = ctx;
// Netzwerke abfragen
this.cmanager = (ConnectivityManager) context.getApplicationContext().getSystemService(Context.CONNECTIVITY_SERVICE);
}
@Override
protected void onPreExecute() {
// Anzeigen dass die Anwendung noch aktiv ist
spinner = ProgressDialog.show(context, "Loading...", "Load network data", true, false);
}
@Override
protected List doInBackground(String... params) {
List result = new ArrayList();
int i = 0;
for (String url : params) {
try {
File file = cacheFile(i + "_cached");
if (download(url, file))
result.add(file);
i++;
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
return result;
}
/**
* Entferne die Aktivitätsanzeige und löse eine Notification aus
*/
protected void onPostExecute(List result) {
spinner.dismiss();
int LOAD_ID = 1;
if (result.size() > 0) {
for (File file : result) {
String ns = Context.NOTIFICATION_SERVICE;
NotificationManager mNotificationManager = (NotificationManager) getSystemService(ns);
int icon = R.drawable.appicon;
CharSequence tickerText = "Finished download";
long when = System.currentTimeMillis();
Context context = getApplicationContext();
CharSequence contentTitle = "The Download was Finished ";
CharSequence contentText = "Downloaded file was "+ file.getName();
Intent notificationIntent = new Intent(context, TestClass.class);
PendingIntent contentIntent = PendingIntent.getActivity(context, 0, notificationIntent, 0);
Notification notification = new Notification(icon, tickerText, when);
notification.setLatestEventInfo(context, contentTitle, contentText, contentIntent);
mNotificationManager.notify(LOAD_ID, notification);
LOAD_ID++;
}
} else {
// Zeige einen Fehler an
AlertDialog.Builder builder = new Builder(context).setMessage("Error while downloading");
AlertDialog alert = builder.create();
alert.show();
}
}
private File cacheFile(String name) throws IOException {
return new File(context.getCacheDir(), name);
}
private boolean download(String url, File file) {
NetworkInfo info = null;
if (cmanager != null)
info = cmanager.getActiveNetworkInfo();
if (info != null && info.isAvailable()) {
try {
HttpClient client = new DefaultHttpClient();
HttpGet get = new HttpGet(url);
HttpEntity entity = client.execute(get).getEntity();
if (entity != null) {
// Create the file or overwrite
OutputStream out = new BufferedOutputStream(
new FileOutputStream(file));
entity.writeTo(out);
entity.consumeContent();
out.close();
}
return true;
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
return false;
}
}
}