diff --git a/res/values/strings.xml b/res/values/strings.xml
index ef243d127..c670e283c 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -90,4 +90,5 @@
Version %s installed
Not installed (%d available)
Installed
+Downloaded file is corrupt
diff --git a/src/org/fdroid/fdroid/AppDetails.java b/src/org/fdroid/fdroid/AppDetails.java
index 542cccd44..a6c0e7502 100644
--- a/src/org/fdroid/fdroid/AppDetails.java
+++ b/src/org/fdroid/fdroid/AppDetails.java
@@ -103,29 +103,26 @@ public class AppDetails extends ListActivity {
else
status.setText(getString(R.string.not_inst));
TextView size = (TextView) v.findViewById(R.id.size);
- if(apk.size==0) {
+ if (apk.size == 0) {
size.setText("");
} else {
size.setText(getFriendlySize(apk.size));
- }
+ }
return v;
}
}
- private static String getFriendlySize(int size)
- {
- double s=size;
- String[] format=new String[] {"%fb","%.0fK","%.1fM","%.2fG"};
- int i=0;
- while(i=1024)
- {
- s=(100*s/1024)/100.0;
- i++;
+ private static String getFriendlySize(int size) {
+ double s = size;
+ String[] format = new String[] { "%fb", "%.0fK", "%.1fM", "%.2fG" };
+ int i = 0;
+ while (i < format.length - 1 && s >= 1024) {
+ s = (100 * s / 1024) / 100.0;
+ i++;
}
- return String.format(format[i],s);
+ return String.format(format[i], s);
}
-
-
+
private static final int INSTALL = Menu.FIRST;
private static final int UNINSTALL = Menu.FIRST + 1;
private static final int WEBSITE = Menu.FIRST + 2;
@@ -189,10 +186,12 @@ public class AppDetails extends ListActivity {
tv.setText(app.license);
tv = (TextView) findViewById(R.id.status);
int vnum = app.apks.size();
- if(app.installedVersion == null)
- tv.setText(String.format(getString(R.string.details_notinstalled),vnum));
+ if (app.installedVersion == null)
+ tv.setText(String.format(getString(R.string.details_notinstalled),
+ vnum));
else
- tv.setText(String.format(getString(R.string.details_installed), app.installedVersion));
+ tv.setText(String.format(getString(R.string.details_installed),
+ app.installedVersion));
tv = (TextView) findViewById(R.id.description);
tv.setText(app.description);
@@ -261,23 +260,6 @@ public class AppDetails extends ListActivity {
p.show();
}
- // Install the version of this app denoted by 'curapk'.
- private void install() {
- new Thread() {
- public void run() {
- String apk_file = downloadFile(app, curapk);
- if (apk_file == null) {
- Message msg = new Message();
- msg.arg1 = 1;
- download_handler.sendMessage(msg);
- download_error_handler.sendEmptyMessage(0);
- } else {
- installApk(apk_file);
- }
- }
- }.start();
- }
-
@Override
public boolean onPrepareOptionsMenu(Menu menu) {
@@ -351,61 +333,96 @@ public class AppDetails extends ListActivity {
return super.onOptionsItemSelected(item);
}
- // Download the requested apk file, given the DB.App and DB.Apk
- // that refer to it. Returns the path to the downloaded file, or
- // null if the download was not successful.
- private String downloadFile(DB.App app, DB.Apk apk) {
- try {
+ // Install the version of this app denoted by 'curapk'.
+ private void install() {
- String apkname = apk.apkName;
- String localfile = new String(LOCAL_PATH + "/" + apkname);
- String remotefile = apk.server + "/" + apkname.replace(" ", "%20");
+ pd = new ProgressDialog(this);
+ pd.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
+ pd.setMessage(getString(R.string.download_server));
- Log.d("FDroid", "Downloading apk from " + remotefile);
+ new Thread() {
+ public void run() {
- Message msg = new Message();
- msg.arg1 = 0;
- msg.obj = new String(remotefile);
- download_handler.sendMessage(msg);
+ // Download the apk file from the repository...
+ String apk_file = null;
+ try {
- BufferedInputStream getit = new BufferedInputStream(new URL(
- remotefile).openStream(), 8192);
+ String apkname = curapk.apkName;
+ String localfile = new String(LOCAL_PATH + "/" + apkname);
+ String remotefile = curapk.server + "/"
+ + apkname.replace(" ", "%20");
- FileOutputStream saveit = new FileOutputStream(localfile);
- BufferedOutputStream bout = new BufferedOutputStream(saveit, 1024);
- byte data[] = new byte[1024];
+ Log.d("FDroid", "Downloading apk from " + remotefile);
- int readed = getit.read(data, 0, 1024);
- while (readed != -1) {
- bout.write(data, 0, readed);
- readed = getit.read(data, 0, 1024);
+ Message msg = new Message();
+ msg.arg1 = 0;
+ msg.arg2 = curapk.size;
+ msg.obj = new String(remotefile);
+ download_handler.sendMessage(msg);
+
+ BufferedInputStream getit = new BufferedInputStream(
+ new URL(remotefile).openStream(), 8192);
+
+ FileOutputStream saveit = new FileOutputStream(localfile);
+ BufferedOutputStream bout = new BufferedOutputStream(
+ saveit, 1024);
+ byte data[] = new byte[1024];
+
+ int totalRead = 0;
+ int bytesRead = getit.read(data, 0, 1024);
+ while (bytesRead != -1) {
+ bout.write(data, 0, bytesRead);
+ totalRead += bytesRead;
+ msg = new Message();
+ msg.arg1 = totalRead;
+ download_handler.sendMessage(msg);
+ bytesRead = getit.read(data, 0, 1024);
+ }
+ bout.close();
+ getit.close();
+ saveit.close();
+ File f = new File(localfile);
+ Md5Handler hash = new Md5Handler();
+
+ if (curapk.hash.equalsIgnoreCase(hash.md5Calc(f))) {
+ apk_file = localfile;
+ } else {
+ msg = new Message();
+ msg.obj = getString(R.string.corrupt_download);
+ download_error_handler.sendMessage(msg);
+ }
+
+ } catch (Exception e) {
+ Log.d("FDroid", "Download failed - " + e.getMessage());
+ Message msg = new Message();
+ msg.obj = e.getMessage();
+ download_error_handler.sendMessage(msg);
+ }
+
+ if (apk_file != null) {
+ Message msg = new Message();
+ msg.obj = apk_file;
+ download_complete_handler.sendMessage(msg);
+ }
}
- bout.close();
- getit.close();
- saveit.close();
- File f = new File(localfile);
- Md5Handler hash = new Md5Handler();
+ }.start();
+
+ pd.show();
- if (apk.hash.equalsIgnoreCase(hash.md5Calc(f))) {
- return localfile;
- } else {
- return null;
- }
- } catch (Exception e) {
- Log.d("FDroid", "Download failed - " + e.getMessage());
- return null;
- }
}
+ // Handler used to update the progress dialog while downloading. The
+ // message contains the progress (bytes read) in arg1. If this is 0,
+ // the message also contains the total bytes to read in arg2, and the
+ // message in obj.
private Handler download_handler = new Handler() {
@Override
public void handleMessage(Message msg) {
+ pd.setProgress(msg.arg1);
if (msg.arg1 == 0) {
- pd = ProgressDialog.show(mctx, getString(R.string.download),
- getString(R.string.download_server) + ":\n "
- + msg.obj.toString(), true);
- } else {
- pd.dismiss();
+ pd.setMessage(getString(R.string.download_server) + ":\n "
+ + msg.obj.toString());
+ pd.setMax(msg.arg2);
}
}
};
@@ -413,11 +430,21 @@ public class AppDetails extends ListActivity {
private Handler download_error_handler = new Handler() {
@Override
public void handleMessage(Message msg) {
- Toast.makeText(mctx, getString(R.string.connection_error_msg),
+ pd.dismiss();
+ Toast.makeText(mctx, (String)msg.obj,
Toast.LENGTH_LONG).show();
}
};
+ private Handler download_complete_handler = new Handler() {
+ @Override
+ public void handleMessage(Message msg) {
+ String apk_file = (String) msg.obj;
+ installApk(apk_file);
+ pd.dismiss();
+ }
+ };
+
private void removeApk(String id) {
PackageInfo pkginfo;
try {