diff --git a/src/org/fdroid/fdroid/AppDetails.java b/src/org/fdroid/fdroid/AppDetails.java index a6c0e7502..fbf7bcf90 100644 --- a/src/org/fdroid/fdroid/AppDetails.java +++ b/src/org/fdroid/fdroid/AppDetails.java @@ -96,7 +96,8 @@ public class AppDetails extends ListActivity { } DB.Apk apk = items.get(position); TextView version = (TextView) v.findViewById(R.id.version); - version.setText("Version " + apk.version); + boolean iscurrent = apk.vercode == app_currentvercode; + version.setText("Version " + apk.version + (iscurrent ? "*" : "")); TextView status = (TextView) v.findViewById(R.id.status); if (apk.version.equals(app.installedVersion)) status.setText(getString(R.string.inst)); @@ -132,6 +133,7 @@ public class AppDetails extends ListActivity { private DB db; private DB.App app; + private int app_currentvercode; private DB.Apk curapk; private String appid; private PackageManager mPm; @@ -168,6 +170,7 @@ public class AppDetails extends ListActivity { Log.d("FDroid", "Getting application details for " + appid); app = db.getApps(appid, null, update).get(0); + app_currentvercode = app.getCurrentVersion().vercode; // Set the icon... ImageView iv = (ImageView) findViewById(R.id.icon); @@ -431,8 +434,7 @@ public class AppDetails extends ListActivity { @Override public void handleMessage(Message msg) { pd.dismiss(); - Toast.makeText(mctx, (String)msg.obj, - Toast.LENGTH_LONG).show(); + Toast.makeText(mctx, (String) msg.obj, Toast.LENGTH_LONG).show(); } }; diff --git a/src/org/fdroid/fdroid/DB.java b/src/org/fdroid/fdroid/DB.java index 6d1c67975..81579f744 100644 --- a/src/org/fdroid/fdroid/DB.java +++ b/src/org/fdroid/fdroid/DB.java @@ -41,7 +41,7 @@ public class DB { // The TABLE_VERSION table tracks the database version. private static final String TABLE_VERSION = "fdroid_version"; private static final String CREATE_TABLE_VERSION = "create table " - + TABLE_VERSION + "( version int not null); insert into " + + TABLE_VERSION + "(version int not null); insert into " + TABLE_VERSION + "(version) values (1);"; // The TABLE_APP table stores details of all the applications we know about. @@ -81,6 +81,8 @@ public class DB { public String trackerURL; public String sourceURL; public String installedVersion; + public String marketVersion; + public int marketVercode; // True if there are new versions (apks) that the user hasn't // explicitly ignored. (We're currently not using the database @@ -98,8 +100,17 @@ public class DB { // 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... + + // Try and return the version that's in Google's market first... + if(marketVersion!=null && marketVercode>0) { + for(Apk apk : apks) { + if(apk.vercode == marketVercode) + return apk; + } + } + + // If we don't know the market version, or we don't have it, we + // return the most recent version we have... int latestcode = -1; Apk latestapk = null; for (Apk apk : apks) { @@ -160,38 +171,85 @@ public class DB { public int priority; } + // SQL to update the database to versions beyond the first. Here is + // how the database works: + // + // * The SQL to create the database tables always creates version + // 1. This SQL will never be altered. + // * In the array below there is SQL for each subsequent version + // from 2 onwards. + // * For a new install, the database is always initialised to version + // 1. + // * Then, whether it's a new install or not, all the upgrade SQL in + // the array below is executed in order to bring the database up to + // the latest version. + // * The current version is tracked by an entry in the TABLE_VERSION + // table. + // + private static final String[] DB_UPGRADES = { + + // Version 2... + "alter table " + TABLE_APK + " add marketVersion text; " + "alter table " + + TABLE_APK + " add marketVercode integer; " + + }; + public static String getIconsPath() { return "/sdcard/.fdroid/icons/"; } - + private PackageManager mPm; public DB(Context ctx) { db = ctx.openOrCreateDatabase(DATABASE_NAME, 0, null); + // Check if we already have a database and create or upgrade as + // appropriate... Cursor c = db.rawQuery( "SELECT name FROM sqlite_master WHERE type='table' AND name= '" + TABLE_VERSION + "'", null); boolean newinst = (c.getCount() == 0); c.close(); - if (newinst) - reset(); + upgrade(newinst); mPm = ctx.getPackageManager(); } - // Reset the database, i.e. (re-)create all the tables from scratch and + // Upgrade the database to the latest version. (Or, if 'reset' is true, + // completely reset it, i.e. (re-)create all the tables from scratch and // populate any initial data. - public void reset() { - db.execSQL("drop table if exists " + TABLE_VERSION); - db.execSQL("drop table if exists " + TABLE_REPO); - db.execSQL("drop table if exists " + TABLE_APP); - db.execSQL("drop table if exists " + TABLE_APK); - db.execSQL(CREATE_TABLE_VERSION); - db.execSQL(CREATE_TABLE_REPO); - db.execSQL(CREATE_TABLE_APP); - db.execSQL(CREATE_TABLE_APK); - addServer("http://f-droid.org/repo", 10); + public void upgrade(boolean reset) { + + int version; + + if (reset) { + db.execSQL("drop table if exists " + TABLE_VERSION); + db.execSQL("drop table if exists " + TABLE_REPO); + db.execSQL("drop table if exists " + TABLE_APP); + db.execSQL("drop table if exists " + TABLE_APK); + db.execSQL(CREATE_TABLE_VERSION); + db.execSQL(CREATE_TABLE_REPO); + db.execSQL(CREATE_TABLE_APP); + db.execSQL(CREATE_TABLE_APK); + addServer("http://f-droid.org/repo", 10); + version = 1; + } else { + // See what database version we have... + Cursor c = db + .rawQuery("SELECT version from " + TABLE_VERSION, null); + c.moveToFirst(); + version = c.getInt(0); + c.close(); + } + + // Run upgrade scripts if necessary... + while (version < DB_UPGRADES.length + 1) { + db.execSQL(DB_UPGRADES[version - 1]); + version++; + db.execSQL("update " + TABLE_VERSION + " set version = " + version + + ";"); + } + } public void close() { @@ -235,6 +293,10 @@ public class DB { app.sourceURL = c.getString(c.getColumnIndex("sourceURL")); app.installedVersion = c.getString(c .getColumnIndex("installedVersion")); + app.marketVersion = c2.getString(c2 + .getColumnIndex("marketVersion")); + app.marketVercode = c2.getInt(c2 + .getColumnIndex("marketVercode")); app.hasUpdates = false; c2 = db.rawQuery("select * from " + TABLE_APK + " where " @@ -429,6 +491,8 @@ public class DB { values.put("trackerURL", upapp.trackerURL); values.put("sourceURL", upapp.sourceURL); values.put("installedVersion", upapp.installedVersion); + values.put("marketVersion", upapp.marketVersion); + values.put("marketVercode", upapp.marketVercode); values.put("hasUpdates", upapp.hasUpdates ? 1 : 0); if (oldapp != null) { db.update(TABLE_APP, values, "id = '" + oldapp.id + "'", null); diff --git a/src/org/fdroid/fdroid/FDroid.java b/src/org/fdroid/fdroid/FDroid.java index 82140da8d..cb35e13e8 100644 --- a/src/org/fdroid/fdroid/FDroid.java +++ b/src/org/fdroid/fdroid/FDroid.java @@ -242,7 +242,7 @@ public class FDroid extends TabActivity implements OnItemClickListener { return true; case RESET_DB: - db.reset(); + db.upgrade(true); populateLists(true); return true; @@ -258,8 +258,7 @@ public class FDroid extends TabActivity implements OnItemClickListener { new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int whichButton) { - Uri uri = Uri - .parse("http://f-droid.org"); + Uri uri = Uri.parse("http://f-droid.org"); startActivity(new Intent(Intent.ACTION_VIEW, uri)); } }); diff --git a/src/org/fdroid/fdroid/RepoXMLHandler.java b/src/org/fdroid/fdroid/RepoXMLHandler.java index 19c115df3..b89107b8d 100644 --- a/src/org/fdroid/fdroid/RepoXMLHandler.java +++ b/src/org/fdroid/fdroid/RepoXMLHandler.java @@ -77,24 +77,33 @@ public class RepoXMLHandler extends DefaultHandler { curapk.apkName = str; } } else if (curapp != null && curel != null) { - if (curel == "id") + if (curel == "id") { curapp.id = str; - else if (curel == "name") + } else if (curel == "name") { curapp.name = str; - else if (curel == "icon") + } else if (curel == "icon") { curapp.icon = str; - else if (curel == "description") + } else if (curel == "description") { curapp.description = str; - else if (curel == "summary") + } else if (curel == "summary") { curapp.summary = str; - else if (curel == "license") + } else if (curel == "license") { curapp.license = str; - else if (curel == "source") + } else if (curel == "source") { curapp.sourceURL = str; - else if (curel == "web") + } else if (curel == "web") { curapp.webURL = str; - else if (curel == "tracker") + } else if (curel == "tracker") { curapp.trackerURL = str; + } else if (curel == "marketversion") { + curapp.marketVersion = str; + } else if (curel == "marketvercode") { + try { + curapp.marketVercode = Integer.parseInt(str); + } catch (NumberFormatException ex) { + curapp.marketVercode = 0; + } + } } }