Merge branch 'fix/count-apps-in-repo'
This commit is contained in:
commit
141f133c7a
@ -3,9 +3,3 @@ These issues are a must-fix before the next stable release:
|
|||||||
* Right after updating a repo, `Recently Updated` shows the apps correctly but
|
* Right after updating a repo, `Recently Updated` shows the apps correctly but
|
||||||
the new apks don't show up on App Details until the whole app is restarted
|
the new apks don't show up on App Details until the whole app is restarted
|
||||||
(or until the repos are wiped and re-downloaded)
|
(or until the repos are wiped and re-downloaded)
|
||||||
|
|
||||||
* `App.curVersion` is now used in some places where before we used
|
|
||||||
`App.curApk.version`, which means that e.g. app lists now show the current
|
|
||||||
version at upstream and not the latest stable version in the repository
|
|
||||||
(highly misleading to users, who might end up looking for versions not in
|
|
||||||
the repo yet)
|
|
||||||
|
@ -128,7 +128,7 @@ public class AppDetails extends ListActivity {
|
|||||||
|
|
||||||
holder.version.setText(getString(R.string.version)
|
holder.version.setText(getString(R.string.version)
|
||||||
+ " " + apk.version
|
+ " " + apk.version
|
||||||
+ (apk.vercode == app.curVercode ? " ☆" : ""));
|
+ (apk.vercode == app.suggestedVercode ? " ☆" : ""));
|
||||||
|
|
||||||
if (apk.vercode == app.getInstalledVerCode(getContext())
|
if (apk.vercode == app.getInstalledVerCode(getContext())
|
||||||
&& mInstalledSigID != null && apk.sig != null
|
&& mInstalledSigID != null && apk.sig != null
|
||||||
@ -534,7 +534,7 @@ public class AppDetails extends ListActivity {
|
|||||||
Apk curApk = null;
|
Apk curApk = null;
|
||||||
for (int i = 0; i < adapter.getCount(); i ++) {
|
for (int i = 0; i < adapter.getCount(); i ++) {
|
||||||
Apk apk = adapter.getItem(i);
|
Apk apk = adapter.getItem(i);
|
||||||
if (apk.vercode == app.curVercode) {
|
if (apk.vercode == app.suggestedVercode) {
|
||||||
curApk = apk;
|
curApk = apk;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -678,7 +678,7 @@ public class AppDetails extends ListActivity {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Check count > 0 due to incompatible apps resulting in an empty list.
|
// Check count > 0 due to incompatible apps resulting in an empty list.
|
||||||
if (app.getInstalledVersion(this) == null && app.curVercode > 0 &&
|
if (app.getInstalledVersion(this) == null && app.suggestedVercode > 0 &&
|
||||||
adapter.getCount() > 0) {
|
adapter.getCount() > 0) {
|
||||||
MenuItemCompat.setShowAsAction(menu.add(
|
MenuItemCompat.setShowAsAction(menu.add(
|
||||||
Menu.NONE, INSTALL, 1, R.string.menu_install)
|
Menu.NONE, INSTALL, 1, R.string.menu_install)
|
||||||
@ -716,7 +716,7 @@ public class AppDetails extends ListActivity {
|
|||||||
menu.add(Menu.NONE, IGNORETHIS, 2, R.string.menu_ignore_this)
|
menu.add(Menu.NONE, IGNORETHIS, 2, R.string.menu_ignore_this)
|
||||||
.setIcon(android.R.drawable.ic_menu_close_clear_cancel)
|
.setIcon(android.R.drawable.ic_menu_close_clear_cancel)
|
||||||
.setCheckable(true)
|
.setCheckable(true)
|
||||||
.setChecked(app.ignoreThisUpdate >= app.curVercode);
|
.setChecked(app.ignoreThisUpdate >= app.suggestedVercode);
|
||||||
}
|
}
|
||||||
if (app.webURL.length() > 0) {
|
if (app.webURL.length() > 0) {
|
||||||
menu.add(Menu.NONE, WEBSITE, 3, R.string.menu_website).setIcon(
|
menu.add(Menu.NONE, WEBSITE, 3, R.string.menu_website).setIcon(
|
||||||
@ -783,8 +783,8 @@ public class AppDetails extends ListActivity {
|
|||||||
|
|
||||||
case INSTALL:
|
case INSTALL:
|
||||||
// Note that this handles updating as well as installing.
|
// Note that this handles updating as well as installing.
|
||||||
if (app.curVercode > 0) {
|
if (app.suggestedVercode > 0) {
|
||||||
final Apk apkToInstall = ApkProvider.Helper.find(this, app.id, app.curVercode);
|
final Apk apkToInstall = ApkProvider.Helper.find(this, app.id, app.suggestedVercode);
|
||||||
install(apkToInstall);
|
install(apkToInstall);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
@ -799,10 +799,10 @@ public class AppDetails extends ListActivity {
|
|||||||
return true;
|
return true;
|
||||||
|
|
||||||
case IGNORETHIS:
|
case IGNORETHIS:
|
||||||
if (app.ignoreThisUpdate >= app.curVercode)
|
if (app.ignoreThisUpdate >= app.suggestedVercode)
|
||||||
app.ignoreThisUpdate = 0;
|
app.ignoreThisUpdate = 0;
|
||||||
else
|
else
|
||||||
app.ignoreThisUpdate = app.curVercode;
|
app.ignoreThisUpdate = app.suggestedVercode;
|
||||||
item.setChecked(app.ignoreThisUpdate > 0);
|
item.setChecked(app.ignoreThisUpdate > 0);
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
@ -226,12 +226,12 @@ public class RepoXMLHandler extends DefaultHandler {
|
|||||||
curapp.lastUpdated = null;
|
curapp.lastUpdated = null;
|
||||||
}
|
}
|
||||||
} else if (curel.equals("marketversion")) {
|
} else if (curel.equals("marketversion")) {
|
||||||
curapp.curVersion = str;
|
curapp.upstreamVersion = str;
|
||||||
} else if (curel.equals("marketvercode")) {
|
} else if (curel.equals("marketvercode")) {
|
||||||
try {
|
try {
|
||||||
curapp.curVercode = Integer.parseInt(str);
|
curapp.upstreamVercode = Integer.parseInt(str);
|
||||||
} catch (NumberFormatException ex) {
|
} catch (NumberFormatException ex) {
|
||||||
curapp.curVercode = -1;
|
curapp.upstreamVercode = -1;
|
||||||
}
|
}
|
||||||
} else if (curel.equals("categories")) {
|
} else if (curel.equals("categories")) {
|
||||||
curapp.categories = Utils.CommaSeparatedList.make(str);
|
curapp.categories = Utils.CommaSeparatedList.make(str);
|
||||||
|
@ -400,19 +400,19 @@ public class UpdateService extends IntentService implements ProgressListener {
|
|||||||
private static void calcCurrentApkForApp(App app, List<Apk> apksForApp) {
|
private static void calcCurrentApkForApp(App app, List<Apk> apksForApp) {
|
||||||
Apk latestApk = null;
|
Apk latestApk = null;
|
||||||
// Try and return the real current version first. It will find the
|
// Try and return the real current version first. It will find the
|
||||||
// closest version smaller than the curVercode, being the same
|
// closest version smaller than the upstreamVercode, being the same
|
||||||
// vercode if it exists.
|
// vercode if it exists.
|
||||||
if (app.curVercode > 0) {
|
if (app.upstreamVercode > 0) {
|
||||||
int latestcode = -1;
|
int latestcode = -1;
|
||||||
for (Apk apk : apksForApp) {
|
for (Apk apk : apksForApp) {
|
||||||
if ((!app.compatible || apk.compatible)
|
if ((!app.compatible || apk.compatible)
|
||||||
&& apk.vercode <= app.curVercode
|
&& apk.vercode <= app.upstreamVercode
|
||||||
&& apk.vercode > latestcode) {
|
&& apk.vercode > latestcode) {
|
||||||
latestApk = apk;
|
latestApk = apk;
|
||||||
latestcode = apk.vercode;
|
latestcode = apk.vercode;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (app.curVercode == -1) {
|
} else if (app.upstreamVercode == -1) {
|
||||||
// If the current version was not set we return the most recent apk.
|
// If the current version was not set we return the most recent apk.
|
||||||
int latestCode = -1;
|
int latestCode = -1;
|
||||||
for (Apk apk : apksForApp) {
|
for (Apk apk : apksForApp) {
|
||||||
@ -425,8 +425,7 @@ public class UpdateService extends IntentService implements ProgressListener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (latestApk != null) {
|
if (latestApk != null) {
|
||||||
app.curVercode = latestApk.vercode;
|
app.suggestedVercode = latestApk.vercode;
|
||||||
app.curVersion = latestApk.version;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -629,6 +628,7 @@ public class UpdateService extends IntentService implements ProgressListener {
|
|||||||
operations.add(updateExistingApk(apk));
|
operations.add(updateExistingApk(apk));
|
||||||
} else {
|
} else {
|
||||||
operations.add(insertNewApk(apk));
|
operations.add(insertNewApk(apk));
|
||||||
|
knownApks.add(apk); // In case another repo has the same version/id combo for this apk.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -100,6 +100,8 @@ public class ApkProvider extends FDroidProvider {
|
|||||||
|
|
||||||
public interface DataColumns extends BaseColumns {
|
public interface DataColumns extends BaseColumns {
|
||||||
|
|
||||||
|
public static String _COUNT_DISTINCT_ID = "countDistinct";
|
||||||
|
|
||||||
public static String APK_ID = "id";
|
public static String APK_ID = "id";
|
||||||
public static String VERSION = "version";
|
public static String VERSION = "version";
|
||||||
public static String REPO_ID = "repo";
|
public static String REPO_ID = "repo";
|
||||||
@ -221,15 +223,16 @@ public class ApkProvider extends FDroidProvider {
|
|||||||
return matcher;
|
return matcher;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class QueryBuilder {
|
private static class Query extends QueryBuilder {
|
||||||
|
|
||||||
private StringBuilder fields = new StringBuilder();
|
|
||||||
private StringBuilder tables = new StringBuilder(DBHelper.TABLE_APK + " AS apk");
|
|
||||||
private String selection = null;
|
|
||||||
private String orderBy = null;
|
|
||||||
|
|
||||||
private boolean repoTableRequired = false;
|
private boolean repoTableRequired = false;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected String getRequiredTables() {
|
||||||
|
return DBHelper.TABLE_APK + " AS apk";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void addField(String field) {
|
public void addField(String field) {
|
||||||
if (REPO_FIELDS.containsKey(field)) {
|
if (REPO_FIELDS.containsKey(field)) {
|
||||||
addRepoField(REPO_FIELDS.get(field), field);
|
addRepoField(REPO_FIELDS.get(field), field);
|
||||||
@ -237,68 +240,21 @@ public class ApkProvider extends FDroidProvider {
|
|||||||
appendField("rowid", "apk", "_id");
|
appendField("rowid", "apk", "_id");
|
||||||
} else if (field.equals(DataColumns._COUNT)) {
|
} else if (field.equals(DataColumns._COUNT)) {
|
||||||
appendField("COUNT(*) AS " + DataColumns._COUNT);
|
appendField("COUNT(*) AS " + DataColumns._COUNT);
|
||||||
|
} else if (field.equals(DataColumns._COUNT_DISTINCT_ID)) {
|
||||||
|
appendField("COUNT(DISTINCT apk.id) AS " + DataColumns._COUNT_DISTINCT_ID);
|
||||||
} else {
|
} else {
|
||||||
appendField(field, "apk");
|
appendField(field, "apk");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addRepoField(String field, String alias) {
|
private void addRepoField(String field, String alias) {
|
||||||
if (!repoTableRequired) {
|
if (!repoTableRequired) {
|
||||||
repoTableRequired = true;
|
repoTableRequired = true;
|
||||||
tables.append(" LEFT JOIN ");
|
leftJoin(DBHelper.TABLE_REPO, "repo", "apk.repo = repo._id");
|
||||||
tables.append(DBHelper.TABLE_REPO);
|
|
||||||
tables.append(" AS repo ON (apk.repo = repo._id) ");
|
|
||||||
}
|
}
|
||||||
appendField(field, "repo", alias);
|
appendField(field, "repo", alias);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void appendField(String field) {
|
|
||||||
appendField(field, null, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void appendField(String field, String tableAlias) {
|
|
||||||
appendField(field, tableAlias, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void appendField(String field, String tableAlias,
|
|
||||||
String fieldAlias) {
|
|
||||||
if (fields.length() != 0) {
|
|
||||||
fields.append(',');
|
|
||||||
}
|
|
||||||
|
|
||||||
if (tableAlias != null) {
|
|
||||||
fields.append(tableAlias).append('.');
|
|
||||||
}
|
|
||||||
|
|
||||||
fields.append(field);
|
|
||||||
|
|
||||||
if (fieldAlias != null) {
|
|
||||||
fields.append(" AS ").append(fieldAlias);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void addSelection(String selection) {
|
|
||||||
this.selection = selection;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void addOrderBy(String orderBy) {
|
|
||||||
this.orderBy = orderBy;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
|
|
||||||
StringBuilder suffix = new StringBuilder();
|
|
||||||
if (selection != null) {
|
|
||||||
suffix.append(" WHERE ").append(selection);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (orderBy != null) {
|
|
||||||
suffix.append(" ORDER BY ").append(orderBy);
|
|
||||||
}
|
|
||||||
|
|
||||||
return "SELECT " + fields + " FROM " + tables + suffix;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private QuerySelection queryApp(String appId) {
|
private QuerySelection queryApp(String appId) {
|
||||||
@ -377,7 +333,7 @@ public class ApkProvider extends FDroidProvider {
|
|||||||
throw new UnsupportedOperationException("Invalid URI for apk content provider: " + uri);
|
throw new UnsupportedOperationException("Invalid URI for apk content provider: " + uri);
|
||||||
}
|
}
|
||||||
|
|
||||||
QueryBuilder queryBuilder = new QueryBuilder();
|
Query queryBuilder = new Query();
|
||||||
for (String field : projection) {
|
for (String field : projection) {
|
||||||
queryBuilder.addField(field);
|
queryBuilder.addField(field);
|
||||||
}
|
}
|
||||||
|
@ -41,8 +41,18 @@ public class App extends ValueObject implements Comparable<App> {
|
|||||||
|
|
||||||
public String flattrID;
|
public String flattrID;
|
||||||
|
|
||||||
public String curVersion;
|
public String upstreamVersion;
|
||||||
public int curVercode;
|
public int upstreamVercode;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unlike other public fields, this is only accessible via a getter, to
|
||||||
|
* emphasise that setting it wont do anything. In order to change this,
|
||||||
|
* you need to change suggestedVercode to an apk which is in the apk table.
|
||||||
|
*/
|
||||||
|
private String suggestedVersion;
|
||||||
|
|
||||||
|
public int suggestedVercode;
|
||||||
|
|
||||||
public Date added;
|
public Date added;
|
||||||
public Date lastUpdated;
|
public Date lastUpdated;
|
||||||
|
|
||||||
@ -114,10 +124,14 @@ public class App extends ValueObject implements Comparable<App> {
|
|||||||
dogecoinAddr = cursor.getString(i);
|
dogecoinAddr = cursor.getString(i);
|
||||||
} else if (column.equals(AppProvider.DataColumns.FLATTR_ID)) {
|
} else if (column.equals(AppProvider.DataColumns.FLATTR_ID)) {
|
||||||
flattrID = cursor.getString(i);
|
flattrID = cursor.getString(i);
|
||||||
} else if (column.equals(AppProvider.DataColumns.CURRENT_VERSION)) {
|
} else if (column.equals(AppProvider.DataColumns.SuggestedApk.VERSION)) {
|
||||||
curVersion = cursor.getString(i);
|
suggestedVersion = cursor.getString(i);
|
||||||
} else if (column.equals(AppProvider.DataColumns.CURRENT_VERSION_CODE)) {
|
} else if (column.equals(AppProvider.DataColumns.SUGGESTED_VERSION_CODE)) {
|
||||||
curVercode = cursor.getInt(i);
|
suggestedVercode = cursor.getInt(i);
|
||||||
|
} else if (column.equals(AppProvider.DataColumns.UPSTREAM_VERSION_CODE)) {
|
||||||
|
upstreamVercode = cursor.getInt(i);
|
||||||
|
} else if (column.equals(AppProvider.DataColumns.UPSTREAM_VERSION)) {
|
||||||
|
upstreamVersion = cursor.getString(i);
|
||||||
} else if (column.equals(AppProvider.DataColumns.ADDED)) {
|
} else if (column.equals(AppProvider.DataColumns.ADDED)) {
|
||||||
added = ValueObject.toDate(cursor.getString(i));
|
added = ValueObject.toDate(cursor.getString(i));
|
||||||
} else if (column.equals(AppProvider.DataColumns.LAST_UPDATED)) {
|
} else if (column.equals(AppProvider.DataColumns.LAST_UPDATED)) {
|
||||||
@ -158,8 +172,9 @@ public class App extends ValueObject implements Comparable<App> {
|
|||||||
values.put(AppProvider.DataColumns.FLATTR_ID, flattrID);
|
values.put(AppProvider.DataColumns.FLATTR_ID, flattrID);
|
||||||
values.put(AppProvider.DataColumns.ADDED, added == null ? "" : Utils.DATE_FORMAT.format(added));
|
values.put(AppProvider.DataColumns.ADDED, added == null ? "" : Utils.DATE_FORMAT.format(added));
|
||||||
values.put(AppProvider.DataColumns.LAST_UPDATED, added == null ? "" : Utils.DATE_FORMAT.format(lastUpdated));
|
values.put(AppProvider.DataColumns.LAST_UPDATED, added == null ? "" : Utils.DATE_FORMAT.format(lastUpdated));
|
||||||
values.put(AppProvider.DataColumns.CURRENT_VERSION, curVersion);
|
values.put(AppProvider.DataColumns.SUGGESTED_VERSION_CODE, suggestedVercode);
|
||||||
values.put(AppProvider.DataColumns.CURRENT_VERSION_CODE, curVercode);
|
values.put(AppProvider.DataColumns.UPSTREAM_VERSION, upstreamVersion);
|
||||||
|
values.put(AppProvider.DataColumns.UPSTREAM_VERSION_CODE, upstreamVercode);
|
||||||
values.put(AppProvider.DataColumns.CATEGORIES, Utils.CommaSeparatedList.str(categories));
|
values.put(AppProvider.DataColumns.CATEGORIES, Utils.CommaSeparatedList.str(categories));
|
||||||
values.put(AppProvider.DataColumns.ANTI_FEATURES, Utils.CommaSeparatedList.str(antiFeatures));
|
values.put(AppProvider.DataColumns.ANTI_FEATURES, Utils.CommaSeparatedList.str(antiFeatures));
|
||||||
values.put(AppProvider.DataColumns.REQUIREMENTS, Utils.CommaSeparatedList.str(requirements));
|
values.put(AppProvider.DataColumns.REQUIREMENTS, Utils.CommaSeparatedList.str(requirements));
|
||||||
@ -207,9 +222,9 @@ public class App extends ValueObject implements Comparable<App> {
|
|||||||
*/
|
*/
|
||||||
public boolean hasUpdates(Context context) {
|
public boolean hasUpdates(Context context) {
|
||||||
boolean updates = false;
|
boolean updates = false;
|
||||||
if (curVercode > 0) {
|
if (suggestedVercode > 0) {
|
||||||
int installedVerCode = getInstalledVerCode(context);
|
int installedVerCode = getInstalledVerCode(context);
|
||||||
updates = (installedVerCode > 0 && installedVerCode < curVercode);
|
updates = (installedVerCode > 0 && installedVerCode < suggestedVercode);
|
||||||
}
|
}
|
||||||
return updates;
|
return updates;
|
||||||
}
|
}
|
||||||
@ -218,7 +233,7 @@ public class App extends ValueObject implements Comparable<App> {
|
|||||||
// to be notified about them
|
// to be notified about them
|
||||||
public boolean canAndWantToUpdate(Context context) {
|
public boolean canAndWantToUpdate(Context context) {
|
||||||
boolean canUpdate = hasUpdates(context);
|
boolean canUpdate = hasUpdates(context);
|
||||||
boolean wantsUpdate = !ignoreAllUpdates && ignoreThisUpdate < curVercode;
|
boolean wantsUpdate = !ignoreAllUpdates && ignoreThisUpdate < suggestedVercode;
|
||||||
return canUpdate && wantsUpdate && !isFiltered();
|
return canUpdate && wantsUpdate && !isFiltered();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -227,4 +242,8 @@ public class App extends ValueObject implements Comparable<App> {
|
|||||||
public boolean isFiltered() {
|
public boolean isFiltered() {
|
||||||
return new AppFilter().filter(this);
|
return new AppFilter().filter(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getSuggestedVersion() {
|
||||||
|
return suggestedVersion;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -60,7 +60,7 @@ public class AppProvider extends FDroidProvider {
|
|||||||
public static List<String> categories(Context context) {
|
public static List<String> categories(Context context) {
|
||||||
ContentResolver resolver = context.getContentResolver();
|
ContentResolver resolver = context.getContentResolver();
|
||||||
Uri uri = getContentUri();
|
Uri uri = getContentUri();
|
||||||
String[] projection = { "DISTINCT " + DataColumns.CATEGORIES };
|
String[] projection = { DataColumns.CATEGORIES };
|
||||||
Cursor cursor = resolver.query(uri, projection, null, null, null );
|
Cursor cursor = resolver.query(uri, projection, null, null, null );
|
||||||
Set<String> categorySet = new HashSet<String>();
|
Set<String> categorySet = new HashSet<String>();
|
||||||
if (cursor != null) {
|
if (cursor != null) {
|
||||||
@ -110,7 +110,7 @@ public class AppProvider extends FDroidProvider {
|
|||||||
|
|
||||||
public interface DataColumns {
|
public interface DataColumns {
|
||||||
|
|
||||||
public static final String _ID = "rowid as _id";
|
public static final String _ID = "rowid as _id"; // Required for CursorLoaders
|
||||||
public static final String _COUNT = "_count";
|
public static final String _COUNT = "_count";
|
||||||
public static final String IS_COMPATIBLE = "compatible";
|
public static final String IS_COMPATIBLE = "compatible";
|
||||||
public static final String APP_ID = "id";
|
public static final String APP_ID = "id";
|
||||||
@ -127,8 +127,9 @@ public class AppProvider extends FDroidProvider {
|
|||||||
public static final String LITECOIN_ADDR = "litecoinAddr";
|
public static final String LITECOIN_ADDR = "litecoinAddr";
|
||||||
public static final String DOGECOIN_ADDR = "dogecoinAddr";
|
public static final String DOGECOIN_ADDR = "dogecoinAddr";
|
||||||
public static final String FLATTR_ID = "flattrID";
|
public static final String FLATTR_ID = "flattrID";
|
||||||
public static final String CURRENT_VERSION = "curVersion";
|
public static final String SUGGESTED_VERSION_CODE = "suggestedVercode";
|
||||||
public static final String CURRENT_VERSION_CODE = "curVercode";
|
public static final String UPSTREAM_VERSION = "upstreamVersion";
|
||||||
|
public static final String UPSTREAM_VERSION_CODE = "upstreamVercode";
|
||||||
public static final String CURRENT_APK = null;
|
public static final String CURRENT_APK = null;
|
||||||
public static final String ADDED = "added";
|
public static final String ADDED = "added";
|
||||||
public static final String LAST_UPDATED = "lastUpdated";
|
public static final String LAST_UPDATED = "lastUpdated";
|
||||||
@ -147,16 +148,73 @@ public class AppProvider extends FDroidProvider {
|
|||||||
public static final String UPDATED = null;
|
public static final String UPDATED = null;
|
||||||
public static final String APKS = null;
|
public static final String APKS = null;
|
||||||
|
|
||||||
|
public interface SuggestedApk {
|
||||||
|
public static final String VERSION = "suggestedApkVersion";
|
||||||
|
}
|
||||||
|
|
||||||
public static String[] ALL = {
|
public static String[] ALL = {
|
||||||
IS_COMPATIBLE, APP_ID, NAME, SUMMARY, ICON, DESCRIPTION,
|
IS_COMPATIBLE, APP_ID, NAME, SUMMARY, ICON, DESCRIPTION,
|
||||||
LICENSE, WEB_URL, TRACKER_URL, SOURCE_URL, DONATE_URL,
|
LICENSE, WEB_URL, TRACKER_URL, SOURCE_URL, DONATE_URL,
|
||||||
BITCOIN_ADDR, LITECOIN_ADDR, DOGECOIN_ADDR, FLATTR_ID,
|
BITCOIN_ADDR, LITECOIN_ADDR, DOGECOIN_ADDR, FLATTR_ID,
|
||||||
CURRENT_VERSION, CURRENT_VERSION_CODE, ADDED, LAST_UPDATED,
|
UPSTREAM_VERSION, UPSTREAM_VERSION_CODE, ADDED, LAST_UPDATED,
|
||||||
CATEGORIES, ANTI_FEATURES, REQUIREMENTS, IGNORE_ALLUPDATES,
|
CATEGORIES, ANTI_FEATURES, REQUIREMENTS, IGNORE_ALLUPDATES,
|
||||||
IGNORE_THISUPDATE, ICON_URL
|
IGNORE_THISUPDATE, ICON_URL, SUGGESTED_VERSION_CODE,
|
||||||
|
SuggestedApk.VERSION
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static class Query extends QueryBuilder {
|
||||||
|
|
||||||
|
private boolean isSuggestedApkTableAdded = false;
|
||||||
|
|
||||||
|
private boolean categoryFieldAdded = false;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected String getRequiredTables() {
|
||||||
|
return DBHelper.TABLE_APP;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean isDistinct() {
|
||||||
|
return fieldCount() == 1 && categoryFieldAdded;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addField(String field) {
|
||||||
|
if (field.equals(DataColumns.SuggestedApk.VERSION)) {
|
||||||
|
addSuggestedApkVersionField();
|
||||||
|
} else if (field.equals(DataColumns._COUNT)) {
|
||||||
|
appendCountField();
|
||||||
|
} else {
|
||||||
|
if (field.equals(DataColumns.CATEGORIES)) {
|
||||||
|
categoryFieldAdded = true;
|
||||||
|
}
|
||||||
|
appendField(field, "fdroid_app");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void appendCountField() {
|
||||||
|
appendField("COUNT(*) AS " + DataColumns._COUNT);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addSuggestedApkVersionField() {
|
||||||
|
addSuggestedApkField(
|
||||||
|
ApkProvider.DataColumns.VERSION,
|
||||||
|
DataColumns.SuggestedApk.VERSION);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addSuggestedApkField(String fieldName, String alias) {
|
||||||
|
if (!isSuggestedApkTableAdded) {
|
||||||
|
isSuggestedApkTableAdded = true;
|
||||||
|
leftJoin(
|
||||||
|
DBHelper.TABLE_APK,
|
||||||
|
"suggestedApk",
|
||||||
|
"fdroid_app.suggestedVercode = suggestedApk.vercode AND fdroid_app.id = suggestedApk.id");
|
||||||
|
}
|
||||||
|
appendField(fieldName, "suggestedApk", alias);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private static final String PROVIDER_NAME = "AppProvider";
|
private static final String PROVIDER_NAME = "AppProvider";
|
||||||
|
|
||||||
private static final UriMatcher matcher = new UriMatcher(-1);
|
private static final UriMatcher matcher = new UriMatcher(-1);
|
||||||
@ -274,18 +332,18 @@ public class AppProvider extends FDroidProvider {
|
|||||||
private QuerySelection queryCanUpdate() {
|
private QuerySelection queryCanUpdate() {
|
||||||
Map<String, PackageInfo> installedApps = Utils.getInstalledApps(getContext());
|
Map<String, PackageInfo> installedApps = Utils.getInstalledApps(getContext());
|
||||||
|
|
||||||
String ignoreCurrent = " ignoreThisUpdate != curVercode ";
|
String ignoreCurrent = " fdroid_app.ignoreThisUpdate != fdroid_app.suggestedVercode ";
|
||||||
String ignoreAll = " ignoreAllUpdates != 1 ";
|
String ignoreAll = " fdroid_app.ignoreAllUpdates != 1 ";
|
||||||
String ignore = " ( " + ignoreCurrent + " AND " + ignoreAll + " ) ";
|
String ignore = " ( " + ignoreCurrent + " AND " + ignoreAll + " ) ";
|
||||||
|
|
||||||
StringBuilder where = new StringBuilder( ignore + " AND ( 0 ");
|
StringBuilder where = new StringBuilder( ignore + " AND ( 0 ");
|
||||||
String[] selectionArgs = new String[installedApps.size() * 2];
|
String[] selectionArgs = new String[installedApps.size() * 2];
|
||||||
int i = 0;
|
int i = 0;
|
||||||
for (PackageInfo info : installedApps.values() ) {
|
for (PackageInfo info : installedApps.values() ) {
|
||||||
where.append(" OR ( ")
|
where.append(" OR ( fdroid_app.")
|
||||||
.append(AppProvider.DataColumns.APP_ID)
|
.append(DataColumns.APP_ID)
|
||||||
.append(" = ? AND ")
|
.append(" = ? AND fdroid_app.")
|
||||||
.append(DataColumns.CURRENT_VERSION_CODE)
|
.append(DataColumns.SUGGESTED_VERSION_CODE)
|
||||||
.append(" > ?) ");
|
.append(" > ?) ");
|
||||||
selectionArgs[ i * 2 ] = info.packageName;
|
selectionArgs[ i * 2 ] = info.packageName;
|
||||||
selectionArgs[ i * 2 + 1 ] = Integer.toString(info.versionCode);
|
selectionArgs[ i * 2 + 1 ] = Integer.toString(info.versionCode);
|
||||||
@ -302,7 +360,7 @@ public class AppProvider extends FDroidProvider {
|
|||||||
String[] selectionArgs = new String[installedApps.size()];
|
String[] selectionArgs = new String[installedApps.size()];
|
||||||
int i = 0;
|
int i = 0;
|
||||||
for (Map.Entry<String, PackageInfo> entry : installedApps.entrySet() ) {
|
for (Map.Entry<String, PackageInfo> entry : installedApps.entrySet() ) {
|
||||||
where.append(" OR ")
|
where.append(" OR fdroid_app.")
|
||||||
.append(AppProvider.DataColumns.APP_ID)
|
.append(AppProvider.DataColumns.APP_ID)
|
||||||
.append(" = ? ");
|
.append(" = ? ");
|
||||||
selectionArgs[i] = entry.getKey();
|
selectionArgs[i] = entry.getKey();
|
||||||
@ -316,27 +374,29 @@ public class AppProvider extends FDroidProvider {
|
|||||||
private QuerySelection querySearch(String keywords) {
|
private QuerySelection querySearch(String keywords) {
|
||||||
keywords = "%" + keywords + "%";
|
keywords = "%" + keywords + "%";
|
||||||
String selection =
|
String selection =
|
||||||
"id like ? OR " +
|
"fdroid_app.id like ? OR " +
|
||||||
"name like ? OR " +
|
"fdroid_app.name like ? OR " +
|
||||||
"summary like ? OR " +
|
"fdroid_app.summary like ? OR " +
|
||||||
"description like ? ";
|
"fdroid_app.description like ? ";
|
||||||
String[] args = new String[] { keywords, keywords, keywords, keywords};
|
String[] args = new String[] { keywords, keywords, keywords, keywords};
|
||||||
return new QuerySelection(selection, args);
|
return new QuerySelection(selection, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private QuerySelection querySingle(String id) {
|
||||||
|
String selection = "fdroid_app.id = ?";
|
||||||
|
String[] args = { id };
|
||||||
|
return new QuerySelection(selection, args);
|
||||||
|
}
|
||||||
|
|
||||||
private QuerySelection queryNewlyAdded() {
|
private QuerySelection queryNewlyAdded() {
|
||||||
String selection = "added > ?";
|
String selection = "fdroid_app.added > ?";
|
||||||
String[] args = new String[] {
|
String[] args = { Utils.DATE_FORMAT.format(Preferences.get().calcMaxHistory()) };
|
||||||
Utils.DATE_FORMAT.format(Preferences.get().calcMaxHistory())
|
|
||||||
};
|
|
||||||
return new QuerySelection(selection, args);
|
return new QuerySelection(selection, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
private QuerySelection queryRecentlyUpdated() {
|
private QuerySelection queryRecentlyUpdated() {
|
||||||
String selection = "added != lastUpdated AND lastUpdated > ?";
|
String selection = "fdroid_app.added != fdroid_app.lastUpdated AND fdroid_app.lastUpdated > ?";
|
||||||
String[] args = new String[] {
|
String[] args = { Utils.DATE_FORMAT.format(Preferences.get().calcMaxHistory()) };
|
||||||
Utils.DATE_FORMAT.format(Preferences.get().calcMaxHistory())
|
|
||||||
};
|
|
||||||
return new QuerySelection(selection, args);
|
return new QuerySelection(selection, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -344,11 +404,11 @@ public class AppProvider extends FDroidProvider {
|
|||||||
// TODO: In the future, add a new table for categories,
|
// TODO: In the future, add a new table for categories,
|
||||||
// so we can join onto it.
|
// so we can join onto it.
|
||||||
String selection =
|
String selection =
|
||||||
" categories = ? OR " + // Only category e.g. "internet"
|
" fdroid_app.categories = ? OR " + // Only category e.g. "internet"
|
||||||
" categories LIKE ? OR " + // First category e.g. "internet,%"
|
" fdroid_app.categories LIKE ? OR " + // First category e.g. "internet,%"
|
||||||
" categories LIKE ? OR " + // Last category e.g. "%,internet"
|
" fdroid_app.categories LIKE ? OR " + // Last category e.g. "%,internet"
|
||||||
" categories LIKE ? "; // One of many categories e.g. "%,internet,%"
|
" fdroid_app.categories LIKE ? "; // One of many categories e.g. "%,internet,%"
|
||||||
String[] args = new String[] {
|
String[] args = {
|
||||||
category,
|
category,
|
||||||
category + ",%",
|
category + ",%",
|
||||||
"%," + category,
|
"%," + category,
|
||||||
@ -364,7 +424,7 @@ public class AppProvider extends FDroidProvider {
|
|||||||
|
|
||||||
private QuerySelection queryApps(String appIds) {
|
private QuerySelection queryApps(String appIds) {
|
||||||
String[] args = appIds.split(",");
|
String[] args = appIds.split(",");
|
||||||
String selection = "id IN (" + generateQuestionMarksForInClause(args.length) + ")";
|
String selection = "fdroid_app.id IN (" + generateQuestionMarksForInClause(args.length) + ")";
|
||||||
return new QuerySelection(selection, args);
|
return new QuerySelection(selection, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -376,9 +436,7 @@ public class AppProvider extends FDroidProvider {
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case CODE_SINGLE:
|
case CODE_SINGLE:
|
||||||
query = query.add(
|
query = query.add(querySingle(uri.getLastPathSegment()));
|
||||||
DataColumns.APP_ID + " = ?",
|
|
||||||
new String[] { uri.getLastPathSegment() } );
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CAN_UPDATE:
|
case CAN_UPDATE:
|
||||||
@ -406,12 +464,12 @@ public class AppProvider extends FDroidProvider {
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case RECENTLY_UPDATED:
|
case RECENTLY_UPDATED:
|
||||||
sortOrder = DataColumns.LAST_UPDATED + " DESC";
|
sortOrder = " fdroid_app.lastUpdated DESC";
|
||||||
query = query.add(queryRecentlyUpdated());
|
query = query.add(queryRecentlyUpdated());
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case NEWLY_ADDED:
|
case NEWLY_ADDED:
|
||||||
sortOrder = DataColumns.ADDED + " DESC";
|
sortOrder = " fdroid_app.added DESC";
|
||||||
query = query.add(queryNewlyAdded());
|
query = query.add(queryNewlyAdded());
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -421,18 +479,15 @@ public class AppProvider extends FDroidProvider {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (AppProvider.DataColumns.NAME.equals(sortOrder)) {
|
if (AppProvider.DataColumns.NAME.equals(sortOrder)) {
|
||||||
sortOrder = " lower( " + sortOrder + " ) ";
|
sortOrder = " lower( fdroid_app." + sortOrder + " ) ";
|
||||||
}
|
}
|
||||||
|
|
||||||
for (String field : projection) {
|
Query q = new Query();
|
||||||
if (field.equals(DataColumns._COUNT)) {
|
q.addFields(projection);
|
||||||
projection = new String[] { "COUNT(*) AS " + DataColumns._COUNT };
|
q.addSelection(query.getSelection());
|
||||||
break;
|
q.addOrderBy(sortOrder);
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Cursor cursor = read().query(getTableName(), projection, query.getSelection(),
|
Cursor cursor = read().rawQuery(q.toString(), query.getArgs());
|
||||||
query.getArgs(), null, null, sortOrder);
|
|
||||||
cursor.setNotificationUri(getContext().getContentResolver(), uri);
|
cursor.setNotificationUri(getContext().getContentResolver(), uri);
|
||||||
return cursor;
|
return cursor;
|
||||||
}
|
}
|
||||||
@ -472,7 +527,7 @@ public class AppProvider extends FDroidProvider {
|
|||||||
switch (matcher.match(uri)) {
|
switch (matcher.match(uri)) {
|
||||||
|
|
||||||
case CODE_SINGLE:
|
case CODE_SINGLE:
|
||||||
query = query.add(new QuerySelection("id = ?", new String[] { uri.getLastPathSegment()}));
|
query = query.add(querySingle(uri.getLastPathSegment()));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
@ -67,8 +67,9 @@ public class DBHelper extends SQLiteOpenHelper {
|
|||||||
+ "webURL text, "
|
+ "webURL text, "
|
||||||
+ "trackerURL text, "
|
+ "trackerURL text, "
|
||||||
+ "sourceURL text, "
|
+ "sourceURL text, "
|
||||||
+ "curVersion text,"
|
+ "suggestedVercode text,"
|
||||||
+ "curVercode integer,"
|
+ "upstreamVersion text,"
|
||||||
|
+ "upstreamVercode integer,"
|
||||||
+ "antiFeatures string,"
|
+ "antiFeatures string,"
|
||||||
+ "donateURL string,"
|
+ "donateURL string,"
|
||||||
+ "bitcoinAddr string,"
|
+ "bitcoinAddr string,"
|
||||||
@ -85,7 +86,7 @@ public class DBHelper extends SQLiteOpenHelper {
|
|||||||
+ "iconUrl text, "
|
+ "iconUrl text, "
|
||||||
+ "primary key(id));";
|
+ "primary key(id));";
|
||||||
|
|
||||||
private static final int DB_VERSION = 40;
|
private static final int DB_VERSION = 41;
|
||||||
|
|
||||||
private Context context;
|
private Context context;
|
||||||
|
|
||||||
|
105
src/org/fdroid/fdroid/data/QueryBuilder.java
Normal file
105
src/org/fdroid/fdroid/data/QueryBuilder.java
Normal file
@ -0,0 +1,105 @@
|
|||||||
|
package org.fdroid.fdroid.data;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
abstract class QueryBuilder {
|
||||||
|
|
||||||
|
private List<String> fields = new ArrayList<String>();
|
||||||
|
private StringBuilder tables = new StringBuilder(getRequiredTables());
|
||||||
|
private String selection = null;
|
||||||
|
private String orderBy = null;
|
||||||
|
|
||||||
|
protected abstract String getRequiredTables();
|
||||||
|
|
||||||
|
public abstract void addField(String field);
|
||||||
|
|
||||||
|
protected int fieldCount() {
|
||||||
|
return fields.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addFields(String[] fields) {
|
||||||
|
for (String field : fields) {
|
||||||
|
addField(field);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected boolean isDistinct() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void appendField(String field) {
|
||||||
|
appendField(field, null, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void appendField(String field, String tableAlias) {
|
||||||
|
appendField(field, tableAlias, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected final void appendField(String field, String tableAlias,
|
||||||
|
String fieldAlias) {
|
||||||
|
|
||||||
|
StringBuilder fieldBuilder = new StringBuilder();
|
||||||
|
|
||||||
|
if (tableAlias != null) {
|
||||||
|
fieldBuilder.append(tableAlias).append('.');
|
||||||
|
}
|
||||||
|
|
||||||
|
fieldBuilder.append(field);
|
||||||
|
|
||||||
|
if (fieldAlias != null) {
|
||||||
|
fieldBuilder.append(" AS ").append(fieldAlias);
|
||||||
|
}
|
||||||
|
|
||||||
|
fields.add(fieldBuilder.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addSelection(String selection) {
|
||||||
|
this.selection = selection;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addOrderBy(String orderBy) {
|
||||||
|
this.orderBy = orderBy;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected final void leftJoin(String table, String alias,
|
||||||
|
String condition) {
|
||||||
|
tables.append(" LEFT JOIN ");
|
||||||
|
tables.append(table);
|
||||||
|
if (alias != null) {
|
||||||
|
tables.append(" AS ");
|
||||||
|
tables.append(alias);
|
||||||
|
}
|
||||||
|
tables.append(" ON (");
|
||||||
|
tables.append(condition);
|
||||||
|
tables.append(")");
|
||||||
|
}
|
||||||
|
|
||||||
|
private String fieldsSql() {
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
for (int i = 0; i < fields.size(); i ++) {
|
||||||
|
if (i > 0) {
|
||||||
|
sb.append(',');
|
||||||
|
}
|
||||||
|
sb.append(fields.get(i));
|
||||||
|
}
|
||||||
|
return sb.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
private String whereSql() {
|
||||||
|
return selection != null ? " WHERE " + selection : "";
|
||||||
|
}
|
||||||
|
|
||||||
|
private String orderBySql() {
|
||||||
|
return orderBy != null ? " ORDER BY " + orderBy : "";
|
||||||
|
}
|
||||||
|
|
||||||
|
private String tablesSql() {
|
||||||
|
return tables.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public String toString() {
|
||||||
|
String distinct = isDistinct() ? " DISTINCT " : "";
|
||||||
|
return "SELECT " + distinct + fieldsSql() + " FROM " + tablesSql() + whereSql() + orderBySql();
|
||||||
|
}
|
||||||
|
}
|
@ -174,11 +174,9 @@ public class RepoProvider extends FDroidProvider {
|
|||||||
|
|
||||||
public static int countAppsForRepo(Context context, long repoId) {
|
public static int countAppsForRepo(Context context, long repoId) {
|
||||||
ContentResolver resolver = context.getContentResolver();
|
ContentResolver resolver = context.getContentResolver();
|
||||||
String[] projection = { "COUNT(distinct id)" };
|
String[] projection = { ApkProvider.DataColumns._COUNT_DISTINCT_ID };
|
||||||
String selection = "repo = ?";
|
Uri apkUri = ApkProvider.getRepoUri(repoId);
|
||||||
String[] args = { Long.toString(repoId) };
|
Cursor result = resolver.query(apkUri, projection, null, null, null);
|
||||||
Uri apkUri = ApkProvider.getContentUri();
|
|
||||||
Cursor result = resolver.query(apkUri, projection, selection, args, null);
|
|
||||||
if (result != null && result.getCount() > 0) {
|
if (result != null && result.getCount() > 0) {
|
||||||
result.moveToFirst();
|
result.moveToFirst();
|
||||||
return result.getInt(0);
|
return result.getInt(0);
|
||||||
@ -189,6 +187,7 @@ public class RepoProvider extends FDroidProvider {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public interface DataColumns extends BaseColumns {
|
public interface DataColumns extends BaseColumns {
|
||||||
|
|
||||||
public static String ADDRESS = "address";
|
public static String ADDRESS = "address";
|
||||||
public static String NAME = "name";
|
public static String NAME = "name";
|
||||||
public static String DESCRIPTION = "description";
|
public static String DESCRIPTION = "description";
|
||||||
|
@ -130,14 +130,14 @@ abstract public class AppListAdapter extends CursorAdapter {
|
|||||||
|
|
||||||
private String getVersionInfo(App app) {
|
private String getVersionInfo(App app) {
|
||||||
|
|
||||||
if (app.curVercode <= 0) {
|
if (app.suggestedVercode <= 0) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
PackageInfo installedInfo = app.getInstalledInfo(mContext);
|
PackageInfo installedInfo = app.getInstalledInfo(mContext);
|
||||||
|
|
||||||
if (installedInfo == null) {
|
if (installedInfo == null) {
|
||||||
return ellipsize(app.curVersion, 12);
|
return ellipsize(app.getSuggestedVersion(), 12);
|
||||||
}
|
}
|
||||||
|
|
||||||
String installedVersionString = installedInfo.versionName;
|
String installedVersionString = installedInfo.versionName;
|
||||||
@ -145,7 +145,7 @@ abstract public class AppListAdapter extends CursorAdapter {
|
|||||||
|
|
||||||
if (app.canAndWantToUpdate(mContext) && showStatusUpdate()) {
|
if (app.canAndWantToUpdate(mContext) && showStatusUpdate()) {
|
||||||
return ellipsize(installedVersionString, 8) +
|
return ellipsize(installedVersionString, 8) +
|
||||||
" → " + ellipsize(app.curVersion, 8);
|
" → " + ellipsize(app.getSuggestedVersion(), 8);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (installedVersionCode > 0 && showStatusInstalled()) {
|
if (installedVersionCode > 0 && showStatusInstalled()) {
|
||||||
|
@ -27,7 +27,7 @@ abstract public class AppListFragment extends ListFragment implements
|
|||||||
LoaderManager.LoaderCallbacks<Cursor> {
|
LoaderManager.LoaderCallbacks<Cursor> {
|
||||||
|
|
||||||
public static final String[] APP_PROJECTION = {
|
public static final String[] APP_PROJECTION = {
|
||||||
AppProvider.DataColumns._ID,
|
AppProvider.DataColumns._ID, // Required for cursor loader to work.
|
||||||
AppProvider.DataColumns.APP_ID,
|
AppProvider.DataColumns.APP_ID,
|
||||||
AppProvider.DataColumns.NAME,
|
AppProvider.DataColumns.NAME,
|
||||||
AppProvider.DataColumns.SUMMARY,
|
AppProvider.DataColumns.SUMMARY,
|
||||||
@ -35,8 +35,8 @@ abstract public class AppListFragment extends ListFragment implements
|
|||||||
AppProvider.DataColumns.LICENSE,
|
AppProvider.DataColumns.LICENSE,
|
||||||
AppProvider.DataColumns.ICON,
|
AppProvider.DataColumns.ICON,
|
||||||
AppProvider.DataColumns.ICON_URL,
|
AppProvider.DataColumns.ICON_URL,
|
||||||
AppProvider.DataColumns.CURRENT_VERSION,
|
AppProvider.DataColumns.SuggestedApk.VERSION,
|
||||||
AppProvider.DataColumns.CURRENT_VERSION_CODE,
|
AppProvider.DataColumns.SUGGESTED_VERSION_CODE,
|
||||||
AppProvider.DataColumns.REQUIREMENTS, // Needed for filtering apps that require root.
|
AppProvider.DataColumns.REQUIREMENTS, // Needed for filtering apps that require root.
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user