Filter incompatible applications

This commit is contained in:
Henrik Tunedal 2011-03-04 23:46:24 +01:00
parent 111a57fc47
commit 0513bb2de7
5 changed files with 43 additions and 11 deletions

View File

@ -128,4 +128,8 @@
<string name="db_sync_mode">Database sync mode</string> <string name="db_sync_mode">Database sync mode</string>
<string name="db_sync_mode_long">Set the value of SQLite\'s "synchronous" flag</string> <string name="db_sync_mode_long">Set the value of SQLite\'s "synchronous" flag</string>
<string name="appcompatibility">Application compatibility</string>
<string name="showincompat">Incompatible apps</string>
<string name="showincompat_long">Show apps written for newer Android versions or different hardware</string>
</resources> </resources>

View File

@ -33,6 +33,11 @@
android:defaultValue="false" android:summary="@string/antinonfreenetlong" android:defaultValue="false" android:summary="@string/antinonfreenetlong"
android:key="antiNonFreeNet" /> android:key="antiNonFreeNet" />
</PreferenceCategory> </PreferenceCategory>
<PreferenceCategory android:title="@string/appcompatibility">
<CheckBoxPreference android:title="@string/showincompat"
android:defaultValue="false" android:summary="@string/showincompat_long"
android:key="showIncompatible" />
</PreferenceCategory>
<PreferenceCategory android:title="@string/maintenance"> <PreferenceCategory android:title="@string/maintenance">
<Preference android:title="@string/reset" android:summary="@string/clear_all_cached_data" <Preference android:title="@string/reset" android:summary="@string/clear_all_cached_data"
android:key="reset" /> android:key="reset" />

View File

@ -70,10 +70,8 @@ public class AppDetails extends ListActivity {
private class ApkListAdapter extends BaseAdapter { private class ApkListAdapter extends BaseAdapter {
private List<DB.Apk> items = new ArrayList<DB.Apk>(); private List<DB.Apk> items = new ArrayList<DB.Apk>();
private DB.Apk.CompatibilityChecker compatChecker;
public ApkListAdapter(Context context) { public ApkListAdapter(Context context) {
compatChecker = DB.Apk.CompatibilityChecker.getChecker(context);
} }
public void addItem(DB.Apk apk) { public void addItem(DB.Apk apk) {
@ -160,6 +158,7 @@ public class AppDetails extends ListActivity {
private String appid; private String appid;
private PackageManager mPm; private PackageManager mPm;
private ProgressDialog pd; private ProgressDialog pd;
private DB.Apk.CompatibilityChecker compatChecker;
private Context mctx = this; private Context mctx = this;
@ -200,6 +199,7 @@ public class AppDetails extends ListActivity {
pref_cacheDownloaded = prefs.getBoolean("cacheDownloaded", true); pref_cacheDownloaded = prefs.getBoolean("cacheDownloaded", true);
pref_expert = prefs.getBoolean("expert", false); pref_expert = prefs.getBoolean("expert", false);
viewResetRequired = true; viewResetRequired = true;
compatChecker = DB.Apk.CompatibilityChecker.getChecker(this);
} }
@ -295,11 +295,14 @@ public class AppDetails extends ListActivity {
@Override @Override
protected void onListItemClick(ListView l, View v, int position, long id) { 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... // Create alert dialog...
final AlertDialog p = new AlertDialog.Builder(this).create(); final AlertDialog p = new AlertDialog.Builder(this).create();
curapk = app.apks.get(position);
// Set the title and icon... // Set the title and icon...
String icon_path = DB.getIconsPath() + app.icon; String icon_path = DB.getIconsPath() + app.icon;
File test_icon = new File(icon_path); File test_icon = new File(icon_path);

View File

@ -217,10 +217,12 @@ public class DB {
public boolean isCompatible(Apk apk) { public boolean isCompatible(Apk apk) {
if (apk.minSdkVersion > SDK_INT) if (apk.minSdkVersion > SDK_INT)
return false; return false;
if (apk.features != null) {
for (String feat : apk.features) { for (String feat : apk.features) {
if (!pm.hasSystemFeature(feat)) if (!pm.hasSystemFeature(feat))
return false; return false;
} }
}
return true; return true;
} }
} }
@ -323,6 +325,7 @@ public class DB {
private PackageManager mPm; private PackageManager mPm;
private Context mContext; private Context mContext;
private Apk.CompatibilityChecker compatChecker;
public DB(Context ctx) { public DB(Context ctx) {
@ -343,6 +346,7 @@ public class DB {
sync_mode = null; sync_mode = null;
if (sync_mode != null) if (sync_mode != null)
Log.d("FDroid", "Database synchronization mode: " + sync_mode); Log.d("FDroid", "Database synchronization mode: " + sync_mode);
compatChecker = Apk.CompatibilityChecker.getChecker(ctx);
} }
public void close() { public void close() {
@ -374,8 +378,9 @@ public class DB {
return count; return count;
} }
// Return a list of apps matching the given criteria. Filtering is also // Return a list of apps matching the given criteria. Filtering is
// done based on the user's current anti-features preferences. // also done based on compatibility and anti-features according to
// the user's current preferences.
// 'appid' - specific app id to retrieve, or null // 'appid' - specific app id to retrieve, or null
// 'filter' - search text to filter on, or null // 'filter' - search text to filter on, or null
// 'update' - update installed version information from device, rather than // '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_antiTracking = prefs.getBoolean("antiTracking", false);
boolean pref_antiNonFreeAdd = prefs.getBoolean("antiNonFreeAdd", false); boolean pref_antiNonFreeAdd = prefs.getBoolean("antiNonFreeAdd", false);
boolean pref_antiNonFreeNet = prefs.getBoolean("antiNonFreeNet", false); boolean pref_antiNonFreeNet = prefs.getBoolean("antiNonFreeNet", false);
boolean pref_showIncompat = prefs.getBoolean("showIncompatible", false);
Vector<App> result = new Vector<App>(); Vector<App> result = new Vector<App>();
Cursor c = null; Cursor c = null;
@ -453,6 +459,7 @@ public class DB {
+ " where id = ? order by vercode desc", + " where id = ? order by vercode desc",
new String[] { app.id }); new String[] { app.id });
c2.moveToFirst(); c2.moveToFirst();
boolean compatible = pref_showIncompat;
while (!c2.isAfterLast()) { while (!c2.isAfterLast()) {
Apk apk = new Apk(); Apk apk = new Apk();
apk.id = app.id; apk.id = app.id;
@ -475,12 +482,22 @@ public class DB {
apk.features = decodeList(c2.getString(c2 apk.features = decodeList(c2.getString(c2
.getColumnIndex("features"))); .getColumnIndex("features")));
app.apks.add(apk); app.apks.add(apk);
if (!compatible && compatChecker.isCompatible(apk)) {
// At least one compatible APK.
compatible = true;
}
c2.moveToNext(); c2.moveToNext();
} }
c2.close(); c2.close();
if (compatible) {
result.add(app); result.add(app);
} }
else {
Log.d("FDroid", "Excluding incompatible application: "
+ app.id);
}
}
c.moveToNext(); c.moveToNext();
} }

View File

@ -309,6 +309,7 @@ public class FDroid extends TabActivity implements OnItemClickListener {
apps_av.clear(); apps_av.clear();
apps_up.clear(); apps_up.clear();
long startTime = System.currentTimeMillis();
Vector<DB.App> apps = db.getApps(null, null, update); Vector<DB.App> apps = db.getApps(null, null, update);
if (apps.isEmpty()) { if (apps.isEmpty()) {
// Don't attempt this more than once - we may have invalid // Don't attempt this more than once - we may have invalid
@ -322,7 +323,9 @@ public class FDroid extends TabActivity implements OnItemClickListener {
triedEmptyUpdate = true; triedEmptyUpdate = true;
return; 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) { for (DB.App app : apps) {
if (app.installedVersion == null) { if (app.installedVersion == null) {