Added "Installed Apps" activity to top of settings.
This is as per the mockup in issue #840, and does the following: * Adds a new `PreferencesCategory` of "My Apps" at the top of the preferences screen. * Adds a "Manage Installed Apps" preference, and moves the "Repositories" preference into this category. * Repeals an existing change which prevented "updateable" apps from appearing in the list of "installed" apps. This is because the two lists of apps are no longer displayed alongside eachother. * Enhances the `AppListItemController` to also be able to display whether or not the currently installed version is the recommended version or not. * Also adds option to display whether the user has asked to ignore any updates for any specific apps.
This commit is contained in:
parent
92943ebdf3
commit
a1a7427cd2
@ -517,6 +517,13 @@
|
||||
|
||||
<activity android:name=".views.apps.AppListActivity" />
|
||||
|
||||
<activity android:name=".views.installed.InstalledAppsActivity"
|
||||
android:parentActivityName=".views.main.MainActivity">
|
||||
<meta-data
|
||||
android:name="android.support.PARENT_ACTIVITY"
|
||||
android:value=".views.main.MainActivity" />
|
||||
</activity>
|
||||
|
||||
</application>
|
||||
|
||||
</manifest>
|
||||
|
@ -569,6 +569,10 @@ public class App extends ValueObject implements Comparable<App>, Parcelable {
|
||||
return TextUtils.isEmpty(flattrID) ? null : "https://flattr.com/thing/" + flattrID;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see App#suggestedVersionName for why this uses a getter while other member variables are
|
||||
* publicly accessible.
|
||||
*/
|
||||
public String getSuggestedVersionName() {
|
||||
return suggestedVersionName;
|
||||
}
|
||||
|
@ -199,26 +199,16 @@ public class AppProvider extends FDroidProvider {
|
||||
public AppQuerySelection add(AppQuerySelection query) {
|
||||
QuerySelection both = super.add(query);
|
||||
AppQuerySelection bothWithJoin = new AppQuerySelection(both.getSelection(), both.getArgs());
|
||||
ensureJoinsCopied(query, bothWithJoin);
|
||||
if (this.naturalJoinToInstalled() || query.naturalJoinToInstalled()) {
|
||||
bothWithJoin.requireNaturalInstalledTable();
|
||||
}
|
||||
|
||||
if (this.leftJoinToPrefs() || query.leftJoinToPrefs()) {
|
||||
bothWithJoin.requireLeftJoinPrefs();
|
||||
}
|
||||
return bothWithJoin;
|
||||
}
|
||||
|
||||
public AppQuerySelection not(AppQuerySelection query) {
|
||||
QuerySelection both = super.not(query);
|
||||
AppQuerySelection bothWithJoin = new AppQuerySelection(both.getSelection(), both.getArgs());
|
||||
ensureJoinsCopied(query, bothWithJoin);
|
||||
return bothWithJoin;
|
||||
}
|
||||
|
||||
private void ensureJoinsCopied(AppQuerySelection toAdd, AppQuerySelection newlyCreated) {
|
||||
if (this.naturalJoinToInstalled() || toAdd.naturalJoinToInstalled()) {
|
||||
newlyCreated.requireNaturalInstalledTable();
|
||||
}
|
||||
|
||||
if (this.leftJoinToPrefs() || toAdd.leftJoinToPrefs()) {
|
||||
newlyCreated.requireLeftJoinPrefs();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected class Query extends QueryBuilder {
|
||||
@ -574,8 +564,7 @@ public class AppProvider extends FDroidProvider {
|
||||
final String ignoreAll = "COALESCE(prefs." + AppPrefsTable.Cols.IGNORE_ALL_UPDATES + ", 0) != 1";
|
||||
|
||||
final String ignore = " (" + ignoreCurrent + " AND " + ignoreAll + ") ";
|
||||
final String nullChecks = app + "." + Cols.SUGGESTED_VERSION_CODE + " IS NOT NULL AND installed." + InstalledAppTable.Cols.VERSION_CODE + " IS NOT NULL ";
|
||||
final String where = nullChecks + " AND " + ignore + " AND " + app + "." + Cols.SUGGESTED_VERSION_CODE + " > installed." + InstalledAppTable.Cols.VERSION_CODE;
|
||||
final String where = ignore + " AND " + app + "." + Cols.SUGGESTED_VERSION_CODE + " > installed." + InstalledAppTable.Cols.VERSION_CODE;
|
||||
|
||||
return new AppQuerySelection(where).requireNaturalInstalledTable().requireLeftJoinPrefs();
|
||||
}
|
||||
@ -587,7 +576,7 @@ public class AppProvider extends FDroidProvider {
|
||||
}
|
||||
|
||||
private AppQuerySelection queryInstalled() {
|
||||
return new AppQuerySelection().requireNaturalInstalledTable().not(queryCanUpdate());
|
||||
return new AppQuerySelection().requireNaturalInstalledTable();
|
||||
}
|
||||
|
||||
private AppQuerySelection querySearch(String query) {
|
||||
|
@ -78,8 +78,4 @@ public class QuerySelection {
|
||||
return new QuerySelection(s, a);
|
||||
}
|
||||
|
||||
public QuerySelection not(QuerySelection querySelection) {
|
||||
String where = " NOT (" + querySelection.getSelection() + ") ";
|
||||
return add(where, querySelection.getArgs());
|
||||
}
|
||||
}
|
||||
|
@ -11,6 +11,7 @@ import android.net.Uri;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v4.app.ActivityOptionsCompat;
|
||||
import android.support.v4.content.ContextCompat;
|
||||
import android.support.v4.content.LocalBroadcastManager;
|
||||
@ -33,6 +34,7 @@ import org.fdroid.fdroid.Utils;
|
||||
import org.fdroid.fdroid.data.Apk;
|
||||
import org.fdroid.fdroid.data.ApkProvider;
|
||||
import org.fdroid.fdroid.data.App;
|
||||
import org.fdroid.fdroid.data.AppPrefs;
|
||||
import org.fdroid.fdroid.installer.ApkCache;
|
||||
import org.fdroid.fdroid.installer.InstallManagerService;
|
||||
import org.fdroid.fdroid.installer.Installer;
|
||||
@ -50,10 +52,24 @@ public class AppListItemController extends RecyclerView.ViewHolder {
|
||||
|
||||
private final Activity activity;
|
||||
|
||||
private final ImageView installButton;
|
||||
@NonNull
|
||||
private final ImageView icon;
|
||||
|
||||
@NonNull
|
||||
private final TextView name;
|
||||
|
||||
@Nullable
|
||||
private final ImageView installButton;
|
||||
|
||||
@Nullable
|
||||
private final TextView status;
|
||||
|
||||
@Nullable
|
||||
private final TextView installedVersion;
|
||||
|
||||
@Nullable
|
||||
private final TextView ignoredStatus;
|
||||
|
||||
private final DisplayImageOptions displayImageOptions;
|
||||
|
||||
private App currentApp;
|
||||
@ -65,6 +81,7 @@ public class AppListItemController extends RecyclerView.ViewHolder {
|
||||
this.activity = activity;
|
||||
|
||||
installButton = (ImageView) itemView.findViewById(R.id.install);
|
||||
if (installButton != null) {
|
||||
installButton.setOnClickListener(onInstallClicked);
|
||||
|
||||
if (Build.VERSION.SDK_INT >= 21) {
|
||||
@ -83,10 +100,13 @@ public class AppListItemController extends RecyclerView.ViewHolder {
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
icon = (ImageView) itemView.findViewById(R.id.icon);
|
||||
name = (TextView) itemView.findViewById(R.id.app_name);
|
||||
status = (TextView) itemView.findViewById(R.id.status);
|
||||
installedVersion = (TextView) itemView.findViewById(R.id.installed_version);
|
||||
ignoredStatus = (TextView) itemView.findViewById(R.id.ignored_status);
|
||||
|
||||
displayImageOptions = Utils.getImageLoadingOptions().build();
|
||||
|
||||
@ -110,6 +130,8 @@ public class AppListItemController extends RecyclerView.ViewHolder {
|
||||
broadcastManager.registerReceiver(onInstallAction, Installer.getInstallIntentFilter(Uri.parse(currentAppDownloadUrl)));
|
||||
|
||||
configureStatusText(app);
|
||||
configureInstalledVersion(app);
|
||||
configureIgnoredStatus(app);
|
||||
configureInstallButton(app);
|
||||
}
|
||||
|
||||
@ -145,6 +167,42 @@ public class AppListItemController extends RecyclerView.ViewHolder {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Shows the currently installed version name, and whether or not it is the recommended version.
|
||||
* Binds to the {@link R.id#installed_version} {@link TextView}.
|
||||
*/
|
||||
private void configureInstalledVersion(@NonNull App app) {
|
||||
if (installedVersion == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
int res = (app.suggestedVersionCode == app.installedVersionCode)
|
||||
? R.string.app_recommended_version_installed : R.string.app_version_x_installed;
|
||||
|
||||
installedVersion.setText(activity.getString(res, app.installedVersionName));
|
||||
}
|
||||
|
||||
/**
|
||||
* Shows whether the user has previously asked to ignore updates for this app entirely, or for a
|
||||
* specific version of this app. Binds to the {@link R.id#ignored_status} {@link TextView}.
|
||||
*/
|
||||
private void configureIgnoredStatus(@NonNull App app) {
|
||||
if (ignoredStatus == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
AppPrefs prefs = app.getPrefs(activity);
|
||||
if (prefs.ignoreAllUpdates) {
|
||||
ignoredStatus.setText(activity.getString(R.string.installed_app__updates_ignored));
|
||||
ignoredStatus.setVisibility(View.VISIBLE);
|
||||
} else if (prefs.ignoreThisUpdate > 0 && prefs.ignoreThisUpdate == app.suggestedVersionCode) {
|
||||
ignoredStatus.setText(activity.getString(R.string.installed_app__updates_ignored_for_suggested_version, app.getSuggestedVersionName()));
|
||||
ignoredStatus.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
ignoredStatus.setVisibility(View.GONE);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isReadyToInstall(@NonNull App app) {
|
||||
for (AppUpdateStatusManager.AppUpdateStatus appStatus : AppUpdateStatusManager.getInstance(activity).getByPackageName(app.packageName)) {
|
||||
if (appStatus.status == AppUpdateStatusManager.Status.ReadyToInstall) {
|
||||
@ -184,6 +242,7 @@ public class AppListItemController extends RecyclerView.ViewHolder {
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("FieldCanBeLocal")
|
||||
private final View.OnClickListener onAppClicked = new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
@ -206,7 +265,7 @@ public class AppListItemController extends RecyclerView.ViewHolder {
|
||||
private final BroadcastReceiver onDownloadProgress = new BroadcastReceiver() {
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
if (currentApp == null || !TextUtils.equals(currentAppDownloadUrl, intent.getDataString())) {
|
||||
if (installButton == null || currentApp == null || !TextUtils.equals(currentAppDownloadUrl, intent.getDataString())) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -226,7 +285,7 @@ public class AppListItemController extends RecyclerView.ViewHolder {
|
||||
private final BroadcastReceiver onInstallAction = new BroadcastReceiver() {
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
if (currentApp == null) {
|
||||
if (currentApp == null || installButton == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -248,6 +307,7 @@ public class AppListItemController extends RecyclerView.ViewHolder {
|
||||
}
|
||||
};
|
||||
|
||||
@SuppressWarnings("FieldCanBeLocal")
|
||||
private final View.OnClickListener onInstallClicked = new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
|
@ -0,0 +1,143 @@
|
||||
/*
|
||||
* Copyright (C) 2010-12 Ciaran Gultnieks, ciaran@ciarang.com
|
||||
* Copyright (C) 2009 Roberto Jacinto, roberto.jacinto@caixamagica.pt
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 3
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
package org.fdroid.fdroid.views.installed;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.database.Cursor;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v4.app.LoaderManager;
|
||||
import android.support.v4.content.CursorLoader;
|
||||
import android.support.v4.content.Loader;
|
||||
import android.support.v7.app.AppCompatActivity;
|
||||
import android.support.v7.widget.LinearLayoutManager;
|
||||
import android.support.v7.widget.RecyclerView;
|
||||
import android.support.v7.widget.Toolbar;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
import org.fdroid.fdroid.FDroidApp;
|
||||
import org.fdroid.fdroid.R;
|
||||
import org.fdroid.fdroid.data.App;
|
||||
import org.fdroid.fdroid.data.AppProvider;
|
||||
import org.fdroid.fdroid.data.Schema;
|
||||
import org.fdroid.fdroid.views.apps.AppListItemController;
|
||||
|
||||
public class InstalledAppsActivity extends AppCompatActivity implements LoaderManager.LoaderCallbacks<Cursor> {
|
||||
|
||||
private InstalledAppListAdapter adapter;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
|
||||
((FDroidApp) getApplication()).applyTheme(this);
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
setContentView(R.layout.installed_apps_layout);
|
||||
|
||||
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
|
||||
toolbar.setTitle(getString(R.string.installed_apps__activity_title));
|
||||
setSupportActionBar(toolbar);
|
||||
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
|
||||
|
||||
adapter = new InstalledAppListAdapter(this);
|
||||
|
||||
RecyclerView appList = (RecyclerView) findViewById(R.id.app_list);
|
||||
appList.setHasFixedSize(true);
|
||||
appList.setLayoutManager(new LinearLayoutManager(this));
|
||||
appList.setAdapter(adapter);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResume() {
|
||||
super.onResume();
|
||||
|
||||
// Starts a new or restarts an existing Loader in this manager
|
||||
getSupportLoaderManager().restartLoader(0, null, this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Loader<Cursor> onCreateLoader(int id, Bundle args) {
|
||||
return new CursorLoader(
|
||||
this,
|
||||
AppProvider.getInstalledUri(),
|
||||
Schema.AppMetadataTable.Cols.ALL,
|
||||
null, null, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoadFinished(Loader<Cursor> loader, Cursor cursor) {
|
||||
adapter.setApps(cursor);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoaderReset(Loader<Cursor> loader) {
|
||||
adapter.setApps(null);
|
||||
}
|
||||
|
||||
static class InstalledAppListAdapter extends RecyclerView.Adapter<AppListItemController> {
|
||||
|
||||
private final Activity activity;
|
||||
|
||||
@Nullable
|
||||
private Cursor cursor;
|
||||
|
||||
InstalledAppListAdapter(Activity activity) {
|
||||
this.activity = activity;
|
||||
setHasStableIds(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getItemId(int position) {
|
||||
if (cursor == null) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
cursor.moveToPosition(position);
|
||||
return cursor.getLong(cursor.getColumnIndex(Schema.AppMetadataTable.Cols.ROW_ID));
|
||||
}
|
||||
|
||||
@Override
|
||||
public AppListItemController onCreateViewHolder(ViewGroup parent, int viewType) {
|
||||
View view = activity.getLayoutInflater().inflate(R.layout.installed_app_list_item, parent, false);
|
||||
return new AppListItemController(activity, view);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(AppListItemController holder, int position) {
|
||||
if (cursor == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
cursor.moveToPosition(position);
|
||||
holder.bindModel(new App(cursor));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemCount() {
|
||||
return cursor == null ? 0 : cursor.getCount();
|
||||
}
|
||||
|
||||
public void setApps(@Nullable Cursor cursor) {
|
||||
this.cursor = cursor;
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
}
|
||||
}
|
75
app/src/main/res/layout/installed_app_list_item.xml
Normal file
75
app/src/main/res/layout/installed_app_list_item.xml
Normal file
@ -0,0 +1,75 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<android.support.constraint.ConstraintLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:padding="4dp"
|
||||
android:paddingTop="8dp"
|
||||
android:paddingBottom="8dp">
|
||||
|
||||
<!-- Ignore ContentDescription because it is kind of meaningless to have TTS read out "App icon"
|
||||
when it will inevitably read out the name of the app straight after. -->
|
||||
<ImageView
|
||||
android:id="@+id/icon"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
android:layout_width="48dp"
|
||||
android:layout_height="48dp"
|
||||
tools:src="@drawable/ic_launcher"
|
||||
android:scaleType="fitCenter"
|
||||
android:layout_marginStart="16dp"
|
||||
android:layout_marginLeft="16dp"
|
||||
android:layout_marginTop="8dp"
|
||||
tools:ignore="ContentDescription" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/app_name"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
tools:text="F-Droid Application manager with a long name that will wrap and then ellipsize"
|
||||
android:textSize="18sp"
|
||||
android:textColor="#424242"
|
||||
android:maxLines="2"
|
||||
android:ellipsize="end"
|
||||
app:layout_constraintStart_toEndOf="@+id/icon"
|
||||
app:layout_constraintTop_toTopOf="@+id/icon"
|
||||
android:layout_marginLeft="8dp"
|
||||
android:layout_marginStart="8dp"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
android:layout_marginEnd="8dp"
|
||||
android:layout_marginRight="8dp" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/installed_version"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="4dp"
|
||||
tools:text="Version 4.7.3 (recommended)"
|
||||
android:textStyle="italic"
|
||||
android:textSize="14sp"
|
||||
android:textColor="#424242"
|
||||
android:maxLines="1"
|
||||
android:ellipsize="end"
|
||||
android:fontFamily="sans-serif-light"
|
||||
app:layout_constraintTop_toBottomOf="@+id/app_name"
|
||||
app:layout_constraintStart_toEndOf="@+id/icon"
|
||||
android:layout_marginStart="8dp"
|
||||
android:layout_marginLeft="8dp" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/ignored_status"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="4dp"
|
||||
tools:text="Updates ignored"
|
||||
android:textSize="14sp"
|
||||
android:maxLines="1"
|
||||
android:ellipsize="end"
|
||||
app:layout_constraintTop_toBottomOf="@+id/installed_version"
|
||||
app:layout_constraintStart_toEndOf="@+id/icon"
|
||||
android:layout_marginStart="8dp"
|
||||
android:layout_marginLeft="8dp" />
|
||||
|
||||
</android.support.constraint.ConstraintLayout>
|
47
app/src/main/res/layout/installed_apps_layout.xml
Normal file
47
app/src/main/res/layout/installed_apps_layout.xml
Normal file
@ -0,0 +1,47 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<android.support.constraint.ConstraintLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<android.support.v7.widget.Toolbar
|
||||
android:id="@+id/toolbar"
|
||||
android:layout_width="368dp"
|
||||
android:layout_height="wrap_content"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintLeft_toLeftOf="parent"
|
||||
app:layout_constraintRight_toRightOf="parent"
|
||||
app:theme="?attr/actionBarTheme"
|
||||
app:popupTheme="?attr/actionBarPopupTheme" />
|
||||
|
||||
<android.support.v7.widget.RecyclerView
|
||||
android:id="@+id/app_list"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
tools:listitem="@layout/installed_app_list_item"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintLeft_toLeftOf="parent"
|
||||
app:layout_constraintRight_toRightOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/toolbar"
|
||||
android:scrollbars="vertical" />
|
||||
|
||||
<!--
|
||||
Commented out until the long press functionality is implemented.
|
||||
<TextView
|
||||
android:id="@+id/helpText"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintLeft_toLeftOf="parent"
|
||||
app:layout_constraintRight_toRightOf="parent"
|
||||
android:padding="16dp"
|
||||
android:textAlignment="center"
|
||||
android:textColor="#424242"
|
||||
android:textSize="14sp"
|
||||
android:text="Tap and hold on an app for more options"
|
||||
app:layout_constraintHorizontal_bias="0.0"
|
||||
android:layout_marginBottom="-1dp" />-->
|
||||
|
||||
</android.support.constraint.ConstraintLayout>
|
@ -17,7 +17,7 @@
|
||||
app:showAsAction="ifRoom|withText"
|
||||
android:id="@+id/nearby" />
|
||||
<item
|
||||
android:title="@string/main_menu__my_apps"
|
||||
android:title="@string/preference_category__my_apps"
|
||||
android:icon="@drawable/ic_my_apps"
|
||||
app:showAsAction="ifRoom|withText"
|
||||
android:id="@+id/my_apps" />
|
||||
|
@ -65,6 +65,11 @@
|
||||
<string name="app_inst_unknown_source">Installed (from unknown source)</string>
|
||||
<string name="app_version_x_available">Version %1$s available</string>
|
||||
<string name="app_version_x_installed">Version %1$s</string>
|
||||
<string name="app_recommended_version_installed">Version %1$s (Recommended)</string>
|
||||
|
||||
<string name="installed_apps__activity_title">Installed Apps</string>
|
||||
<string name="installed_app__updates_ignored">Updates ignored</string>
|
||||
<string name="installed_app__updates_ignored_for_suggested_version">Updates ignored for Version %1$s</string>
|
||||
|
||||
<string name="added_on">Added on %s</string>
|
||||
|
||||
@ -142,7 +147,9 @@
|
||||
<string name="main_menu__latest_apps">Latest</string>
|
||||
<string name="main_menu__categories">Categories</string>
|
||||
<string name="main_menu__swap_nearby">Nearby</string>
|
||||
<string name="main_menu__my_apps">My Apps</string>
|
||||
|
||||
<string name="preference_category__my_apps">My Apps</string>
|
||||
<string name="preference_manage_installed_apps">Manage Installed Apps</string>
|
||||
|
||||
|
||||
<string name="details_installed">Version %s installed</string>
|
||||
|
@ -1,6 +1,12 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<PreferenceCategory android:title="@string/updates">
|
||||
<PreferenceCategory android:title="@string/preference_category__my_apps">
|
||||
<PreferenceScreen android:title="@string/preference_manage_installed_apps">
|
||||
<intent
|
||||
android:action="android.intent.action.MAIN"
|
||||
android:targetPackage="org.fdroid.fdroid"
|
||||
android:targetClass="org.fdroid.fdroid.views.installed.InstalledAppsActivity" />
|
||||
</PreferenceScreen>
|
||||
<PreferenceScreen
|
||||
android:title="@string/menu_manage"
|
||||
android:summary="@string/repositories_summary">
|
||||
@ -9,6 +15,8 @@
|
||||
android:targetPackage="org.fdroid.fdroid"
|
||||
android:targetClass="org.fdroid.fdroid.views.ManageReposActivity" />
|
||||
</PreferenceScreen>
|
||||
</PreferenceCategory>
|
||||
<PreferenceCategory android:title="@string/updates">
|
||||
<com.geecko.QuickLyric.view.AppCompatListPreference android:title="@string/update_interval"
|
||||
android:key="updateInterval"
|
||||
android:defaultValue="24"
|
||||
|
@ -115,7 +115,7 @@ public class AppProviderTest extends FDroidProviderTest {
|
||||
assertFalse(notInstalled.canAndWantToUpdate(context));
|
||||
|
||||
assertResultCount(contentResolver, 2, AppProvider.getCanUpdateUri(), PROJ);
|
||||
assertResultCount(contentResolver, 7, AppProvider.getInstalledUri(), PROJ);
|
||||
assertResultCount(contentResolver, 9, AppProvider.getInstalledUri(), PROJ);
|
||||
|
||||
App installedOnlyOneVersionAvailable = AppProvider.Helper.findSpecificApp(r, "installed, only one version available", 1, Cols.ALL);
|
||||
App installedAlreadyLatestNoIgnore = AppProvider.Helper.findSpecificApp(r, "installed, already latest, no ignore", 1, Cols.ALL);
|
||||
|
Loading…
x
Reference in New Issue
Block a user