Moved download classes to their own dir and fixed the way the dest dir is being 'build'
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/mobile/Downloader/DownloadActivity.java Thu Jul 14 15:41:26 2011 +0200
@@ -0,0 +1,141 @@
+package org.hedgewars.mobile.Downloader;
+
+import org.hedgewars.mobile.MainActivity;
+import org.hedgewars.mobile.R;
+
+import android.app.Activity;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.ServiceConnection;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.IBinder;
+import android.os.Message;
+import android.os.Messenger;
+import android.os.RemoteException;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.widget.Button;
+import android.widget.ProgressBar;
+import android.widget.TextView;
+
+public class DownloadActivity extends Activity{
+
+ private Messenger messageService;
+ private boolean boundToService = false;
+
+ private TextView progress_sub;
+ private ProgressBar progress;
+ private Button positive, negative;
+
+ public static final int MSG_START = 0;
+ public static final int MSG_UPDATE = 1;
+ public static final int MSG_DONE = 2;
+ private Handler.Callback messageCallback = new Handler.Callback() {
+
+ @Override
+ public boolean handleMessage(Message msg) {
+ switch(msg.what){
+ case MSG_START:
+ progress.setMax(msg.arg1);
+ progress_sub.setText(String.format("%dkb/%dkb\n%s", 0, msg.arg1, ""));
+ break;
+ case MSG_UPDATE:
+ progress_sub.setText(String.format("%d%% - %dkb/%dkb\n%s",(msg.arg1*100)/msg.arg2, msg.arg1, msg.arg2, msg.obj));
+ progress.setProgress(msg.arg1);
+ break;
+ case MSG_DONE:
+ progress.setProgress(progress.getMax());
+ progress_sub.setText(R.string.download_done);
+
+ positive.setText(R.string.download_back);
+ positive.setOnClickListener(doneClicker);
+ break;
+ }
+ return false;
+ }
+ };
+ private Handler messageHandler = new Handler(messageCallback);
+ private Messenger messenger = new Messenger(messageHandler);
+
+ public void onCreate(Bundle savedInstanceState){
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.download);
+
+ progress_sub = (TextView)findViewById(R.id.progressbar_sub);
+ progress = (ProgressBar)findViewById(R.id.progressbar);
+
+ positive = (Button) findViewById(R.id.background);
+ negative = (Button) findViewById(R.id.cancelDownload);
+ positive.setOnClickListener(backgroundClicker);
+ negative.setOnClickListener(cancelClicker);
+
+ }
+
+ private OnClickListener backgroundClicker = new OnClickListener(){
+ public void onClick(View v){
+ finish();
+ }
+ };
+ private OnClickListener cancelClicker = new OnClickListener(){
+ public void onClick(View v){
+ Intent i = new Intent(getApplicationContext(), DownloadService.class);
+ i.putExtra("taskID", DownloadService.TASKID_CANCEL);
+ startService(i);
+ finish();
+ }
+ };
+ private OnClickListener doneClicker = new OnClickListener(){
+ public void onClick(View v){
+ finish();
+ startActivity(new Intent(getApplicationContext(), MainActivity.class));
+ }
+ };
+
+ public void onStart(){
+ super.onStart();
+ bindToService();
+ }
+
+ public void onStop(){
+ super.onStop();
+ unBindFromService();
+ }
+
+ private ServiceConnection connection = new ServiceConnection(){
+
+ @Override
+ public void onServiceConnected(ComponentName name, IBinder service) {
+ messageService = new Messenger(service);
+
+ try{
+ Message msg = Message.obtain(null, DownloadService.MSG_REGISTER_CLIENT);
+ msg.replyTo = messenger;
+ messageService.send(msg);
+
+ }catch (RemoteException e){}
+ }
+
+ @Override
+ public void onServiceDisconnected(ComponentName name) {
+ messageService = null;
+ }
+
+ };
+
+ private void bindToService(){
+ Intent i = new Intent(getApplicationContext(), DownloadService.class);
+ i.putExtra("taskID", DownloadService.TASKID_START);
+ startService(i);
+ bindService(new Intent(getApplicationContext(), DownloadService.class), connection, Context.BIND_AUTO_CREATE);
+ boundToService = true;
+ }
+
+ private void unBindFromService(){
+ if(boundToService){
+ boundToService = false;
+ unbindService(connection);
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/mobile/Downloader/DownloadAsyncTask.java Thu Jul 14 15:41:26 2011 +0200
@@ -0,0 +1,115 @@
+package org.hedgewars.mobile.Downloader;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipInputStream;
+
+import android.os.AsyncTask;
+import android.util.Log;
+/**
+ * This is an AsyncTask which will download a zip from an URL and unzip it to a specified path
+ *
+ * a typical call to start the task would be new DownloadAsyncTask().execute(getExternalStorage(), "www.hedgewars.org/data.zip");
+ * @author Xeli
+ *
+ */
+public class DownloadAsyncTask extends AsyncTask<String, Object, Long> {
+
+ private DownloadService service;
+ private long lastUpdateMillis = 0;
+
+ public DownloadAsyncTask(DownloadService _service){
+ service = _service;
+ }
+
+ /**
+ *
+ * @param params - 2 Strings, first is the path where the unzipped files will be stored, second is the URL to download from
+ */
+ protected Long doInBackground(String... params) {
+ HttpURLConnection conn = null;
+ try {
+ String rootZipDest = params[0];
+
+ File rootDest = new File(rootZipDest);
+ rootDest.mkdir();
+
+ URL url = new URL(params[1]);
+ conn = (HttpURLConnection)url.openConnection();
+ String contentType = conn.getContentType();
+
+ if(contentType == null || contentType.contains("zip")){ //Seeing as we provide the url if the contentType is unknown lets assume zips
+ ZipInputStream input = new ZipInputStream(conn.getInputStream());
+ int bytesDecompressed = 0;
+ final int kbytesToProcess = conn.getContentLength()/1024;
+
+ service.start(kbytesToProcess);
+
+ ZipEntry entry = null;
+ while((entry = input.getNextEntry()) != null){
+ String fileName = entry.getName();
+
+ if(isCancelled()) break;
+ else if(System.currentTimeMillis() - lastUpdateMillis > 1000){
+ lastUpdateMillis = System.currentTimeMillis();
+ publishProgress(bytesDecompressed, kbytesToProcess, fileName);
+ }
+
+ Log.e("bla", fileName);
+ bytesDecompressed += entry.getCompressedSize();
+
+ File f = new File(rootZipDest + fileName);
+
+ if(entry.isDirectory()){
+ f.mkdir();
+ }else{
+ if(f.exists()){
+ f.delete();
+ }
+
+ try {
+ f.createNewFile();
+ FileOutputStream out = new FileOutputStream(f);
+
+ byte[] buffer = new byte[1024];
+ int count = 0;
+ while((count = input.read(buffer)) != -1){
+ out.write(buffer, 0, count);
+ }
+ out.flush();
+ out.close();
+ input.closeEntry();
+ } catch (FileNotFoundException e) {
+ e.printStackTrace();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+ input.close();
+ }else{
+ Log.e("bla", "contenttype = " + contentType);
+ }
+ } catch (IOException e) {
+ e.printStackTrace();
+ }finally{
+ if(conn != null) conn.disconnect();
+ }
+ return null;
+ }
+
+ //TODO propper result handling
+ protected void onPostExecute(Long result){
+ service.done(true);
+ }
+
+ protected void onProgressUpdate(Object...objects){
+ service.update((Integer)objects[0], (Integer)objects[1], (String)objects[2]);
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/mobile/Downloader/DownloadService.java Thu Jul 14 15:41:26 2011 +0200
@@ -0,0 +1,164 @@
+package org.hedgewars.mobile.Downloader;
+
+import java.util.ArrayList;
+
+import org.hedgewars.mobile.MainActivity;
+import org.hedgewars.mobile.R;
+import org.hedgewars.mobile.Utils;
+
+import android.app.Notification;
+import android.app.NotificationManager;
+import android.app.PendingIntent;
+import android.app.Service;
+import android.content.Intent;
+import android.os.Handler;
+import android.os.IBinder;
+import android.os.Message;
+import android.os.Messenger;
+import android.os.RemoteException;
+import android.util.Log;
+import android.widget.RemoteViews;
+
+public class DownloadService extends Service {
+
+ private final static String URL = "http://www.xelification.com/tmp/data.zip";
+ public static final int MSG_CANCEL = 0;
+ public static final int MSG_REGISTER_CLIENT = 1;
+ public static final int MSG_UNREGISTER_CLIENT = 2;
+
+ public static final int NOTIFICATION_PROCESSING = 0;
+ public static final int NOTIFICATION_DONE = 1;
+
+ private DownloadAsyncTask downloadTask;
+ private final Messenger messenger = new Messenger(new DownloadHandler());
+ private NotificationManager nM;
+ private RemoteViews contentView;
+ private Notification notification;
+
+ private ArrayList<Messenger> clientList = new ArrayList<Messenger>();
+ private Message onRegisterMessage = null;
+
+
+ class DownloadHandler extends Handler{
+
+ public void handleMessage(Message msg){
+ switch(msg.what){
+ case MSG_CANCEL:
+ downloadTask.cancel(false);
+ break;
+ case MSG_REGISTER_CLIENT:
+ clientList.add(msg.replyTo);
+ if(onRegisterMessage != null){
+ try {
+ msg.replyTo.send(Message.obtain(onRegisterMessage));
+ } catch (RemoteException e) {
+ e.printStackTrace();
+ }
+ }
+ break;
+ case MSG_UNREGISTER_CLIENT:
+ clientList.remove(msg.replyTo);
+ break;
+ }
+ }
+ }
+
+ public final static int TASKID_START = 0;
+ public final static int TASKID_CANCEL = 1;
+
+ public int onStartCommand(Intent intent, int flags, int startId){
+ switch(intent.getIntExtra("taskID", TASKID_START)){
+ case TASKID_START:
+ nM = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
+
+ notification = new Notification(R.drawable.statusbar, getString(R.string.notification_title), System.currentTimeMillis());
+ //notification.flags |= Notification.FLAG_ONGOING_EVENT;// | Notification.FLAG_NO_CLEAR | Notification.FLAG_FOREGROUND_SERVICE;
+ notification.flags |= Notification.FLAG_ONGOING_EVENT;
+
+ contentView = new RemoteViews(getPackageName(), R.layout.notification);
+ contentView.setProgressBar(R.id.notification_progress, 100, 34, false);
+ notification.contentView = contentView;
+
+ PendingIntent contentIntent = PendingIntent.getActivity(this, 0, new Intent(this, DownloadActivity.class), Intent.FLAG_ACTIVITY_NEW_TASK);
+ notification.contentIntent = contentIntent;
+
+ //nM.notify(NOTIFICATION_PROCESSING, notification);
+ startForeground(NOTIFICATION_PROCESSING, notification);
+
+ if(downloadTask == null){
+ downloadTask = new DownloadAsyncTask(this);
+ downloadTask.execute(Utils.getDownloadPath(this), URL);
+ }
+ break;
+ case TASKID_CANCEL:
+ downloadTask.cancel(false);
+ stopService();
+ break;
+ }
+ return 0;
+ }
+
+ public void onDestroy(){
+ Log.e("bla", "onDestroy");
+ downloadTask.cancel(false);
+ }
+
+ public IBinder onBind(Intent intent) {
+ return messenger.getBinder();
+ }
+
+ /*
+ * Thread safe method to let clients know the processing is starting and will process int max kbytes
+ *
+ */
+ public void start(int max){
+ onRegisterMessage = Message.obtain(null, DownloadActivity.MSG_START, max, -1);
+ sendMessageToClients(onRegisterMessage);
+ }
+
+ public void update(int progress, int max, String fileName){
+ progress = (progress/1024);
+ updateNotification(progress, max, fileName);
+
+ sendMessageToClients(Message.obtain(null, DownloadActivity.MSG_UPDATE, progress, max, fileName));
+ }
+ public void done(boolean succesful){
+ sendMessageToClients(Message.obtain(null, DownloadActivity.MSG_DONE));
+ stopService();//stopService clears all notifications and thus must be called before we show the ready notification
+ showDoneNotification();
+ }
+
+ private void stopService(){
+ nM.cancelAll();
+ stopForeground(true);
+ stopSelf();
+ }
+
+ private void updateNotification(int progress, int max, String fileName){
+
+ contentView.setProgressBar(R.id.notification_progress, max, progress, false);
+ contentView.setTextViewText(R.id.progressbar_sub, String.format("%dkb/%dkb (Compressed sizes)", progress, max));
+ nM.notify(NOTIFICATION_PROCESSING, notification);
+ }
+
+ private void showDoneNotification(){
+ nM.cancelAll();
+ stopForeground(true);
+
+ String title = getString(R.string.notification_title);
+
+ notification = new Notification(R.drawable.icon, title, System.currentTimeMillis());
+ notification.flags |= Notification.FLAG_AUTO_CANCEL;
+ PendingIntent contentIntent = PendingIntent.getActivity(this, 0, new Intent(this, MainActivity.class), Intent.FLAG_ACTIVITY_NEW_TASK);
+ notification.setLatestEventInfo(this, title, getString(R.string.notification_done), contentIntent);
+ nM.notify(NOTIFICATION_DONE, notification);
+ }
+ private void sendMessageToClients(Message msg){
+ for(Messenger m : clientList){
+ try {
+ m.send(Message.obtain(msg));
+ } catch (RemoteException e) {}//TODO should we catch this properly?
+ }
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/project_files/Android-build/SDL-android-project/src/org/hedgewars/mobile/Downloader/DownloadThread.java Thu Jul 14 15:41:26 2011 +0200
@@ -0,0 +1,13 @@
+package org.hedgewars.mobile.Downloader;
+
+public class DownloadThread extends Thread{
+
+ public DownloadThread(){
+
+ }
+
+ public void run(){
+
+ }
+
+}