diff --git a/res/values/strings.xml b/res/values/strings.xml index b4069ef33..ac9310003 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -128,4 +128,8 @@ Database sync mode Set the value of SQLite\'s "synchronous" flag + + Application compatibility + Incompatible apps + Show apps written for newer Android versions or different hardware diff --git a/res/xml/preferences.xml b/res/xml/preferences.xml index 4a5c09be7..0a86e4bc3 100644 --- a/res/xml/preferences.xml +++ b/res/xml/preferences.xml @@ -33,6 +33,11 @@ android:defaultValue="false" android:summary="@string/antinonfreenetlong" android:key="antiNonFreeNet" /> + + + diff --git a/src/org/fdroid/fdroid/AppDetails.java b/src/org/fdroid/fdroid/AppDetails.java index 4496489aa..ecb6b6dee 100644 --- a/src/org/fdroid/fdroid/AppDetails.java +++ b/src/org/fdroid/fdroid/AppDetails.java @@ -70,10 +70,8 @@ public class AppDetails extends ListActivity { private class ApkListAdapter extends BaseAdapter { private List items = new ArrayList(); - private DB.Apk.CompatibilityChecker compatChecker; public ApkListAdapter(Context context) { - compatChecker = DB.Apk.CompatibilityChecker.getChecker(context); } public void addItem(DB.Apk apk) { @@ -160,6 +158,7 @@ public class AppDetails extends ListActivity { private String appid; private PackageManager mPm; private ProgressDialog pd; + private DB.Apk.CompatibilityChecker compatChecker; private Context mctx = this; @@ -200,6 +199,7 @@ public class AppDetails extends ListActivity { pref_cacheDownloaded = prefs.getBoolean("cacheDownloaded", true); pref_expert = prefs.getBoolean("expert", false); viewResetRequired = true; + compatChecker = DB.Apk.CompatibilityChecker.getChecker(this); } @@ -295,11 +295,14 @@ public class AppDetails extends ListActivity { @Override protected void onListItemClick(ListView l, View v, int position, long id) { + curapk = app.apks.get(position); + + // Ignore attempt to install incompatible APK + if (!compatChecker.isCompatible(curapk)) return; + // Create alert dialog... final AlertDialog p = new AlertDialog.Builder(this).create(); - curapk = app.apks.get(position); - // Set the title and icon... String icon_path = DB.getIconsPath() + app.icon; File test_icon = new File(icon_path); diff --git a/src/org/fdroid/fdroid/DB.java b/src/org/fdroid/fdroid/DB.java index 48e41873a..1d0d2d83f 100644 --- a/src/org/fdroid/fdroid/DB.java +++ b/src/org/fdroid/fdroid/DB.java @@ -217,9 +217,11 @@ public class DB { public boolean isCompatible(Apk apk) { if (apk.minSdkVersion > SDK_INT) return false; - for (String feat : apk.features) { - if (!pm.hasSystemFeature(feat)) - return false; + if (apk.features != null) { + for (String feat : apk.features) { + if (!pm.hasSystemFeature(feat)) + return false; + } } return true; } @@ -323,6 +325,7 @@ public class DB { private PackageManager mPm; private Context mContext; + private Apk.CompatibilityChecker compatChecker; public DB(Context ctx) { @@ -343,6 +346,7 @@ public class DB { sync_mode = null; if (sync_mode != null) Log.d("FDroid", "Database synchronization mode: " + sync_mode); + compatChecker = Apk.CompatibilityChecker.getChecker(ctx); } public void close() { @@ -374,8 +378,9 @@ public class DB { return count; } - // Return a list of apps matching the given criteria. Filtering is also - // done based on the user's current anti-features preferences. + // Return a list of apps matching the given criteria. Filtering is + // also done based on compatibility and anti-features according to + // the user's current preferences. // 'appid' - specific app id to retrieve, or null // 'filter' - search text to filter on, or null // 'update' - update installed version information from device, rather than @@ -388,6 +393,7 @@ public class DB { boolean pref_antiTracking = prefs.getBoolean("antiTracking", false); boolean pref_antiNonFreeAdd = prefs.getBoolean("antiNonFreeAdd", false); boolean pref_antiNonFreeNet = prefs.getBoolean("antiNonFreeNet", false); + boolean pref_showIncompat = prefs.getBoolean("showIncompatible", false); Vector result = new Vector(); Cursor c = null; @@ -453,6 +459,7 @@ public class DB { + " where id = ? order by vercode desc", new String[] { app.id }); c2.moveToFirst(); + boolean compatible = pref_showIncompat; while (!c2.isAfterLast()) { Apk apk = new Apk(); apk.id = app.id; @@ -475,11 +482,21 @@ public class DB { apk.features = decodeList(c2.getString(c2 .getColumnIndex("features"))); app.apks.add(apk); + if (!compatible && compatChecker.isCompatible(apk)) { + // At least one compatible APK. + compatible = true; + } c2.moveToNext(); } c2.close(); - result.add(app); + if (compatible) { + result.add(app); + } + else { + Log.d("FDroid", "Excluding incompatible application: " + + app.id); + } } c.moveToNext(); diff --git a/src/org/fdroid/fdroid/FDroid.java b/src/org/fdroid/fdroid/FDroid.java index 3385ce371..1f04f183e 100644 --- a/src/org/fdroid/fdroid/FDroid.java +++ b/src/org/fdroid/fdroid/FDroid.java @@ -309,6 +309,7 @@ public class FDroid extends TabActivity implements OnItemClickListener { apps_av.clear(); apps_up.clear(); + long startTime = System.currentTimeMillis(); Vector apps = db.getApps(null, null, update); if (apps.isEmpty()) { // Don't attempt this more than once - we may have invalid @@ -322,7 +323,9 @@ public class FDroid extends TabActivity implements OnItemClickListener { triedEmptyUpdate = true; return; } - Log.d("FDroid", "Updating lists - " + apps.size() + " apps in total"); + Log.d("FDroid", "Updating lists - " + apps.size() + " apps in total" + + " (update took " + (System.currentTimeMillis() - startTime) + + " ms)"); for (DB.App app : apps) { if (app.installedVersion == null) {