Improved AppDetails to give access to web,issues,source, and make install simpler

This commit is contained in:
Ciaran Gultnieks 2010-10-20 22:07:40 +01:00
parent 2c39dae035
commit cbdb8078b7
7 changed files with 147 additions and 35 deletions

View File

@ -5,7 +5,7 @@
<string name="isinst">Installed: </string> <string name="isinst">Installed: </string>
<string name="instver">Installed version: </string> <string name="instver">Installed version: </string>
<string name="install">Install </string> <string name="install">Install </string>
<string name="rem">Uninstall </string> <string name="uninstall">Uninstall </string>
<string name="update">Update!</string> <string name="update">Update!</string>
<string name="update_alrt">There updates available for some installed applications.\nDo you wish to see them?</string> <string name="update_alrt">There updates available for some installed applications.\nDo you wish to see them?</string>

View File

@ -16,6 +16,12 @@
<string name="menu_install">Install</string>
<string name="menu_uninstall">Uninstall</string>
<string name="menu_website">Web Site</string>
<string name="menu_issues">Issues</string>
<string name="menu_source">Source Code</string>
<string name="menu_market">Market</string>
</resources> </resources>
<!-- <!--
* Copyright (C) 2009 Roberto Jacinto * Copyright (C) 2009 Roberto Jacinto

View File

@ -46,7 +46,7 @@
<string name="connection_error_msg">Could not connect to server!</string> <string name="connection_error_msg">Could not connect to server!</string>
<string name="download">Download</string> <string name="download">Download</string>
<string name="download_server">Getting application from</string> <string name="download_server">Getting application from</string>
<string name="apk_market_view">Market</string>
<string name="apk_version_new"> available v </string> <string name="apk_version_new"> available v </string>
<string name="settings_sort_title">Sort application list by:</string> <string name="settings_sort_title">Sort application list by:</string>
<string name="settings_sort_abc">Alphabetically</string> <string name="settings_sort_abc">Alphabetically</string>

View File

@ -48,6 +48,8 @@ import android.content.DialogInterface;
import android.content.Intent; import android.content.Intent;
import android.util.Log; import android.util.Log;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.widget.BaseAdapter; import android.widget.BaseAdapter;
@ -104,6 +106,13 @@ public class AppDetails extends ListActivity {
} }
} }
private static final int INSTALL = Menu.FIRST;
private static final int UNINSTALL = Menu.FIRST + 1;
private static final int WEBSITE = Menu.FIRST + 2;
private static final int ISSUES = Menu.FIRST + 3;
private static final int SOURCE = Menu.FIRST + 4;
private static final int MARKET = Menu.FIRST + 5;
private DB db; private DB db;
private DB.App app; private DB.App app;
private DB.Apk curapk; private DB.Apk curapk;
@ -215,6 +224,26 @@ public class AppDetails extends ListActivity {
new DialogInterface.OnClickListener() { new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) { public void onClick(DialogInterface dialog, int which) {
p.dismiss(); p.dismiss();
install();
}
});
}
else {
p.setButton2(getString(R.string.uninstall),
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
p.dismiss();
removeApk(app.id);
}
});
}
p.show();
}
// Install the version of this app denoted by 'curapk'.
private void install() {
new Thread() { new Thread() {
public void run() { public void run() {
String apk_pkg = downloadFile(app, curapk); String apk_pkg = downloadFile(app, curapk);
@ -222,35 +251,78 @@ public class AppDetails extends ListActivity {
Message msg = new Message(); Message msg = new Message();
msg.arg1 = 1; msg.arg1 = 1;
download_handler.sendMessage(msg); download_handler.sendMessage(msg);
download_error_handler download_error_handler.sendEmptyMessage(0);
.sendEmptyMessage(0);
} else { } else {
installApk(apk_pkg); installApk(apk_pkg);
} }
} }
}.start(); }.start();
} }
});
@Override
public boolean onPrepareOptionsMenu(Menu menu) {
super.onCreateOptionsMenu(menu);
menu.clear();
if (app.installedVersion == null && app.getCurrentVersion() != null) {
menu.add(Menu.NONE, INSTALL, 1, R.string.menu_install).setIcon(
android.R.drawable.ic_menu_add);
} else {
menu.add(Menu.NONE, UNINSTALL, 1, R.string.menu_uninstall).setIcon(
android.R.drawable.ic_menu_delete);
}
if (app.webURL.length() > 0) {
menu.add(Menu.NONE, WEBSITE, 2, R.string.menu_website).setIcon(
android.R.drawable.ic_menu_view);
}
if (app.trackerURL.length() > 0) {
menu.add(Menu.NONE, ISSUES, 3, R.string.menu_issues).setIcon(
android.R.drawable.ic_menu_view);
}
if (app.sourceURL.length() > 0) {
menu.add(Menu.NONE, SOURCE, 4, R.string.menu_source).setIcon(
android.R.drawable.ic_menu_view);
}
menu.add(Menu.NONE, MARKET, 5, R.string.menu_market).setIcon(
android.R.drawable.ic_menu_view);
return true;
} }
p.setButton3(getString(R.string.apk_market_view), @Override
new DialogInterface.OnClickListener() { public boolean onOptionsItemSelected(MenuItem item) {
public void onClick(DialogInterface dialog, int which) {
switch (item.getItemId()) {
case INSTALL:
curapk = app.getCurrentVersion();
install();
return true;
case UNINSTALL:
removeApk(app.id);
return true;
case WEBSITE:
startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(app.webURL)));
return true;
case ISSUES:
startActivity(new Intent(Intent.ACTION_VIEW, Uri
.parse(app.trackerURL)));
return true;
case SOURCE:
startActivity(new Intent(Intent.ACTION_VIEW, Uri
.parse(app.sourceURL)));
return true;
case MARKET:
startActivity(new Intent(Intent.ACTION_VIEW, Uri startActivity(new Intent(Intent.ACTION_VIEW, Uri
.parse("market://search?q=pname:" + app.id))); .parse("market://search?q=pname:" + app.id)));
} return true;
});
if (!caninstall) {
p.setButton2(getString(R.string.rem),
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
removeApk(app.id);
} }
}); return super.onOptionsItemSelected(item);
}
p.show();
} }
// Download the requested apk file, given the DB.App and DB.Apk // Download the requested apk file, given the DB.App and DB.Apk

View File

@ -56,6 +56,10 @@ public class DB {
summary = "Unknown application"; summary = "Unknown application";
icon = "noicon.png"; icon = "noicon.png";
id = "unknown"; id = "unknown";
license = "Unknown";
trackerURL = "";
sourceURL = "";
webURL = "";
hasUpdates = false; hasUpdates = false;
updated = false; updated = false;
apks = new Vector<Apk>(); apks = new Vector<Apk>();
@ -80,6 +84,26 @@ public class DB {
public boolean updated; public boolean updated;
public Vector<Apk> apks; public Vector<Apk> apks;
// Get the current version - this will be one of the Apks from 'apks'.
// Can return null if there are no available versions.
// This should be the 'current' version, as in the most recent stable
// one, that most users would want by default. It might not be the
// most recent, if for example there are betas etc.
public Apk getCurrentVersion() {
// But, notwithstanding the above comment, FOR NOW, it's the
// most recent...
int latestcode = -1;
Apk latestapk = null;
for (Apk apk : apks) {
if (apk.vercode > latestcode) {
latestapk = apk;
latestcode = apk.vercode;
}
}
return latestapk;
}
} }
// The TABLE_APK table stores details of all the application versions we // The TABLE_APK table stores details of all the application versions we
@ -90,7 +114,8 @@ public class DB {
private static final String CREATE_TABLE_APK = "create table " + TABLE_APK private static final String CREATE_TABLE_APK = "create table " + TABLE_APK
+ "( " + "id text not null, " + "version text not null, " + "( " + "id text not null, " + "version text not null, "
+ "server text not null, " + "hash text not null, " + "server text not null, " + "hash text not null, "
+ "apkName text not null, " + "primary key(id,version));"; + "vercode int not null," + "apkName text not null, "
+ "primary key(id,version));";
public static class Apk { public static class Apk {
@ -100,6 +125,7 @@ public class DB {
public String id; public String id;
public String version; public String version;
public int vercode;
public String server; public String server;
public String hash; public String hash;
public String apkName; public String apkName;
@ -135,7 +161,7 @@ public class DB {
+ TABLE_REPO + "'", null); + TABLE_REPO + "'", null);
boolean newinst = (c.getCount() == 0); boolean newinst = (c.getCount() == 0);
c.close(); c.close();
if(newinst) if (newinst)
reset(); reset();
mPm = ctx.getPackageManager(); mPm = ctx.getPackageManager();
@ -197,12 +223,13 @@ public class DB {
app.hasUpdates = c.getInt(c.getColumnIndex("hasUpdates")) == 1; app.hasUpdates = c.getInt(c.getColumnIndex("hasUpdates")) == 1;
c2 = db.rawQuery("select * from " + TABLE_APK + " where " c2 = db.rawQuery("select * from " + TABLE_APK + " where "
+ "id = '" + app.id + "'", null); + "id = '" + app.id + "' order by vercode desc", null);
c2.moveToFirst(); c2.moveToFirst();
while (!c2.isAfterLast()) { while (!c2.isAfterLast()) {
Apk apk = new Apk(); Apk apk = new Apk();
apk.id = app.id; apk.id = app.id;
apk.version = c2.getString(c2.getColumnIndex("version")); apk.version = c2.getString(c2.getColumnIndex("version"));
apk.vercode = c2.getInt(c2.getColumnIndex("vercode"));
apk.server = c2.getString(c2.getColumnIndex("server")); apk.server = c2.getString(c2.getColumnIndex("server"));
apk.hash = c2.getString(c2.getColumnIndex("hash")); apk.hash = c2.getString(c2.getColumnIndex("hash"));
apk.apkName = c2.getString(c2.getColumnIndex("apkName")); apk.apkName = c2.getString(c2.getColumnIndex("apkName"));
@ -394,6 +421,7 @@ public class DB {
ContentValues values = new ContentValues(); ContentValues values = new ContentValues();
values.put("id", upapk.id); values.put("id", upapk.id);
values.put("version", upapk.version); values.put("version", upapk.version);
values.put("vercode", upapk.vercode);
values.put("server", upapk.server); values.put("server", upapk.server);
values.put("hash", upapk.hash); values.put("hash", upapk.hash);
values.put("apkName", upapk.apkName); values.put("apkName", upapk.apkName);

View File

@ -222,9 +222,9 @@ public class FDroid extends TabActivity implements OnItemClickListener {
android.R.drawable.ic_menu_rotate); android.R.drawable.ic_menu_rotate);
menu.add(Menu.NONE, MANAGE_REPO, 2, R.string.menu_manage).setIcon( menu.add(Menu.NONE, MANAGE_REPO, 2, R.string.menu_manage).setIcon(
android.R.drawable.ic_menu_agenda); android.R.drawable.ic_menu_agenda);
menu.add(Menu.NONE, RESET_DB, 4, "Reset DB").setIcon( menu.add(Menu.NONE, RESET_DB, 3, "Reset DB").setIcon(
android.R.drawable.ic_menu_revert); android.R.drawable.ic_menu_revert);
menu.add(Menu.NONE, ABOUT, 5, R.string.menu_about).setIcon( menu.add(Menu.NONE, ABOUT, 4, R.string.menu_about).setIcon(
android.R.drawable.ic_menu_help); android.R.drawable.ic_menu_help);
return true; return true;
} }

View File

@ -45,7 +45,7 @@ public class RepoXMLHandler extends DefaultHandler {
private DB.Apk curapk = null; private DB.Apk curapk = null;
private String curel = null; private String curel = null;
public RepoXMLHandler(Context ctx, String srv,DB db) { public RepoXMLHandler(Context ctx, String srv, DB db) {
mctx = ctx; mctx = ctx;
mserver = srv; mserver = srv;
this.db = db; this.db = db;
@ -61,7 +61,13 @@ public class RepoXMLHandler extends DefaultHandler {
if (curapk != null && curel != null) { if (curapk != null && curel != null) {
if (curel == "version") if (curel == "version")
curapk.version = str; curapk.version = str;
else if (curel == "hash") if (curel == "vercode") {
try {
curapk.vercode = Integer.parseInt(str);
} catch (NumberFormatException ex) {
curapk.vercode = 0;
}
} else if (curel == "hash")
curapk.hash = str; curapk.hash = str;
else if (curel == "apkname") else if (curel == "apkname")
curapk.apkName = str; curapk.apkName = str;