From 42965701a39c70745f405c6a5c7c41ca0bd44f08 Mon Sep 17 00:00:00 2001 From: Peter Serwylo Date: Fri, 7 Apr 2017 15:14:49 +1000 Subject: [PATCH] Show "Run" button next to a successfully installed app. There was some confusion in the user tests about how to launch an app once it was installed. Hopefully this small change goes towards fixing some of that confusion. Instead of just showing "X installed successfully" in the app list, it now shows a "Run" button next to it. --- .../views/apps/AppListItemController.java | 64 +++++++++++++++---- 1 file changed, 53 insertions(+), 11 deletions(-) diff --git a/app/src/main/java/org/fdroid/fdroid/views/apps/AppListItemController.java b/app/src/main/java/org/fdroid/fdroid/views/apps/AppListItemController.java index 92b01e730..cad2498ce 100644 --- a/app/src/main/java/org/fdroid/fdroid/views/apps/AppListItemController.java +++ b/app/src/main/java/org/fdroid/fdroid/views/apps/AppListItemController.java @@ -6,6 +6,7 @@ import android.app.PendingIntent; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; +import android.content.IntentFilter; import android.graphics.Outline; import android.net.Uri; import android.os.Build; @@ -96,7 +97,7 @@ public class AppListItemController extends RecyclerView.ViewHolder { installButton = (ImageView) itemView.findViewById(R.id.install); if (installButton != null) { - installButton.setOnClickListener(onInstallClicked); + installButton.setOnClickListener(onActionClicked); if (Build.VERSION.SDK_INT >= 21) { installButton.setOutlineProvider(new ViewOutlineProvider() { @@ -126,7 +127,7 @@ public class AppListItemController extends RecyclerView.ViewHolder { actionButton = (Button) itemView.findViewById(R.id.action_button); if (actionButton != null) { - actionButton.setOnClickListener(onInstallClicked); + actionButton.setOnClickListener(onActionClicked); } if (cancelButton != null) { @@ -149,9 +150,11 @@ public class AppListItemController extends RecyclerView.ViewHolder { final LocalBroadcastManager broadcastManager = LocalBroadcastManager.getInstance(activity.getApplicationContext()); broadcastManager.unregisterReceiver(onDownloadProgress); broadcastManager.unregisterReceiver(onInstallAction); + broadcastManager.unregisterReceiver(onStatusRemoved); broadcastManager.registerReceiver(onDownloadProgress, DownloaderService.getIntentFilter(currentAppDownloadUrl)); broadcastManager.registerReceiver(onInstallAction, Installer.getInstallIntentFilter(Uri.parse(currentAppDownloadUrl))); + broadcastManager.registerReceiver(onStatusRemoved, new IntentFilter(AppUpdateStatusManager.BROADCAST_APPSTATUS_REMOVED)); configureAppName(app); configureStatusText(app); @@ -255,14 +258,17 @@ public class AppListItemController extends RecyclerView.ViewHolder { /** * Queries the {@link AppUpdateStatusManager} and asks if the app was just successfully installed. + * For convenience, returns the {@link org.fdroid.fdroid.AppUpdateStatusManager.AppUpdateStatus} + * object if it was sucessfully installed, or null otherwise. */ - private boolean wasSuccessfullyInstalled(@NonNull App app) { + @Nullable + private AppUpdateStatusManager.AppUpdateStatus wasSuccessfullyInstalled(@NonNull App app) { for (AppUpdateStatusManager.AppUpdateStatus appStatus : AppUpdateStatusManager.getInstance(activity).getByPackageName(app.packageName)) { if (appStatus.status == AppUpdateStatusManager.Status.Installed) { - return true; + return appStatus; } } - return false; + return null; } /** @@ -288,7 +294,7 @@ public class AppListItemController extends RecyclerView.ViewHolder { } } else if (isDownloading(app)) { name.setText(activity.getString(R.string.app_list__name__downloading_in_progress, app.name)); - } else if (wasSuccessfullyInstalled(app)) { + } else if (wasSuccessfullyInstalled(app) != null) { name.setText(activity.getString(R.string.app_list__name__successfully_installed, app.name)); } else { name.setText(Utils.formatAppNameAndSummary(app.name, app.summary)); @@ -305,15 +311,18 @@ public class AppListItemController extends RecyclerView.ViewHolder { return; } - if (!isReadyToInstall(app)) { - actionButton.setVisibility(View.GONE); - } else { - actionButton.setVisibility(View.VISIBLE); + actionButton.setVisibility(View.VISIBLE); + + if (wasSuccessfullyInstalled(app) != null) { + actionButton.setText(R.string.menu_launch); + } else if (isReadyToInstall(app)) { if (app.isInstalled()) { actionButton.setText(R.string.app__install_downloaded_update); } else { actionButton.setText(R.string.menu_install); } + } else { + actionButton.setVisibility(View.GONE); } } @@ -471,14 +480,47 @@ public class AppListItemController extends RecyclerView.ViewHolder { } }; + /** + * If the app goes from "Successfully installed" to anything else, then reset the action button + * and the app label text to whatever they should be. + */ + private final BroadcastReceiver onStatusRemoved = new BroadcastReceiver() { + @Override + public void onReceive(Context context, Intent intent) { + if (currentApp == null || currentAppDownloadUrl == null) { + return; + } + + if (!TextUtils.equals(intent.getStringExtra(AppUpdateStatusManager.EXTRA_APK_URL), currentAppDownloadUrl)) { + return; + } + + configureAppName(currentApp); + configureActionButton(currentApp); + } + }; + @SuppressWarnings("FieldCanBeLocal") - private final View.OnClickListener onInstallClicked = new View.OnClickListener() { + private final View.OnClickListener onActionClicked = new View.OnClickListener() { @Override public void onClick(View v) { if (currentApp == null) { return; } + // When the button says "Run", then launch the app. + AppUpdateStatusManager.AppUpdateStatus successfullyInstalledStatus = wasSuccessfullyInstalled(currentApp); + if (successfullyInstalledStatus != null) { + Intent intent = activity.getPackageManager().getLaunchIntentForPackage(currentApp.packageName); + activity.startActivity(intent); + + // Once it is explicitly launched by the user, then we can pretty much forget about + // any sort of notification that the app was successfully installed. It should be + // apparent to the user because they just launched it. + AppUpdateStatusManager.getInstance(activity).removeApk(successfullyInstalledStatus.getUniqueKey()); + return; + } + final Apk suggestedApk = ApkProvider.Helper.findApkFromAnyRepo(activity, currentApp.packageName, currentApp.suggestedVersionCode); if (isReadyToInstall(currentApp)) {