Merge branch 'improvements-to-update-workflow' into 'master'
Improvements to update workflow Closes #922 See merge request !468
This commit is contained in:
commit
49f7248d45
@ -371,7 +371,7 @@ class NotificationHelper {
|
||||
|
||||
Intent intentDeleted = new Intent(BROADCAST_NOTIFICATIONS_UPDATE_CLEARED);
|
||||
intentDeleted.putExtra(EXTRA_NOTIFICATION_KEY, entry.getUniqueKey());
|
||||
PendingIntent piDeleted = PendingIntent.getBroadcast(context, 0, intentDeleted, 0);
|
||||
PendingIntent piDeleted = PendingIntent.getBroadcast(context, 0, intentDeleted, PendingIntent.FLAG_UPDATE_CURRENT);
|
||||
builder.setDeleteIntent(piDeleted);
|
||||
return builder.build();
|
||||
}
|
||||
@ -429,7 +429,7 @@ class NotificationHelper {
|
||||
}
|
||||
|
||||
Intent intentDeleted = new Intent(BROADCAST_NOTIFICATIONS_ALL_UPDATES_CLEARED);
|
||||
PendingIntent piDeleted = PendingIntent.getBroadcast(context, 0, intentDeleted, 0);
|
||||
PendingIntent piDeleted = PendingIntent.getBroadcast(context, 0, intentDeleted, PendingIntent.FLAG_UPDATE_CURRENT);
|
||||
builder.setDeleteIntent(piDeleted);
|
||||
return builder.build();
|
||||
}
|
||||
@ -456,7 +456,7 @@ class NotificationHelper {
|
||||
|
||||
Intent intentDeleted = new Intent(BROADCAST_NOTIFICATIONS_INSTALLED_CLEARED);
|
||||
intentDeleted.putExtra(EXTRA_NOTIFICATION_KEY, entry.getUniqueKey());
|
||||
PendingIntent piDeleted = PendingIntent.getBroadcast(context, 0, intentDeleted, 0);
|
||||
PendingIntent piDeleted = PendingIntent.getBroadcast(context, 0, intentDeleted, PendingIntent.FLAG_UPDATE_CURRENT);
|
||||
builder.setDeleteIntent(piDeleted);
|
||||
return builder.build();
|
||||
}
|
||||
@ -484,7 +484,7 @@ class NotificationHelper {
|
||||
|
||||
// Intent to open main app list
|
||||
Intent intentObject = new Intent(context, MainActivity.class);
|
||||
PendingIntent piAction = PendingIntent.getActivity(context, 0, intentObject, 0);
|
||||
PendingIntent piAction = PendingIntent.getActivity(context, 0, intentObject, PendingIntent.FLAG_UPDATE_CURRENT);
|
||||
|
||||
NotificationCompat.Builder builder =
|
||||
new NotificationCompat.Builder(context)
|
||||
@ -501,7 +501,7 @@ class NotificationHelper {
|
||||
.setGroupSummary(true);
|
||||
}
|
||||
Intent intentDeleted = new Intent(BROADCAST_NOTIFICATIONS_ALL_INSTALLED_CLEARED);
|
||||
PendingIntent piDeleted = PendingIntent.getBroadcast(context, 0, intentDeleted, 0);
|
||||
PendingIntent piDeleted = PendingIntent.getBroadcast(context, 0, intentDeleted, PendingIntent.FLAG_UPDATE_CURRENT);
|
||||
builder.setDeleteIntent(piDeleted);
|
||||
return builder.build();
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@ -329,9 +338,7 @@ public class AppListItemController extends RecyclerView.ViewHolder {
|
||||
}
|
||||
|
||||
if (isReadyToInstall(app)) {
|
||||
installButton.setImageDrawable(ContextCompat.getDrawable(activity, R.drawable.ic_download_complete));
|
||||
installButton.setVisibility(View.VISIBLE);
|
||||
// TODO: If in the downloading phase, then need to reflect that instead of this "download complete" icon.
|
||||
installButton.setVisibility(View.GONE);
|
||||
} else {
|
||||
boolean installable = app.canAndWantToUpdate(activity) || !app.isInstalled();
|
||||
boolean shouldAllow = app.compatible && !app.isFiltered();
|
||||
@ -386,7 +393,7 @@ public class AppListItemController extends RecyclerView.ViewHolder {
|
||||
|
||||
private void onDownloadComplete() {
|
||||
if (installButton != null) {
|
||||
installButton.setImageDrawable(ContextCompat.getDrawable(activity, R.drawable.ic_download_complete));
|
||||
installButton.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
if (progressBar != null) {
|
||||
@ -473,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)) {
|
||||
|
@ -316,7 +316,7 @@ public class UpdatesAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder
|
||||
|
||||
// After adding the new item to our list (somewhere) we can then look it back up again in
|
||||
// order to notify the recycler view and scroll to that item.
|
||||
int positionOfNewApp = 0;
|
||||
int positionOfNewApp = -1;
|
||||
for (int i = 0; i < appsToShowStatus.size(); i++) {
|
||||
if (TextUtils.equals(appsToShowStatus.get(i).status.getUniqueKey(), apkUrl)) {
|
||||
positionOfNewApp = i;
|
||||
@ -324,17 +324,19 @@ public class UpdatesAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder
|
||||
}
|
||||
}
|
||||
|
||||
notifyItemInserted(positionOfNewApp);
|
||||
if (positionOfNewApp != -1) {
|
||||
notifyItemInserted(positionOfNewApp);
|
||||
|
||||
if (recyclerView != null) {
|
||||
recyclerView.smoothScrollToPosition(positionOfNewApp);
|
||||
if (recyclerView != null) {
|
||||
recyclerView.smoothScrollToPosition(positionOfNewApp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void onAppStatusRemoved(String apkUrl) {
|
||||
// Find out where the item is in our internal data structure, so that we can remove it and
|
||||
// also notify the recycler view appropriately.
|
||||
int positionOfOldApp = 0;
|
||||
int positionOfOldApp = -1;
|
||||
for (int i = 0; i < appsToShowStatus.size(); i++) {
|
||||
if (TextUtils.equals(appsToShowStatus.get(i).status.getUniqueKey(), apkUrl)) {
|
||||
positionOfOldApp = i;
|
||||
@ -342,10 +344,12 @@ public class UpdatesAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder
|
||||
}
|
||||
}
|
||||
|
||||
appsToShowStatus.remove(positionOfOldApp);
|
||||
if (positionOfOldApp != -1) {
|
||||
appsToShowStatus.remove(positionOfOldApp);
|
||||
|
||||
populateItems();
|
||||
notifyItemRemoved(positionOfOldApp);
|
||||
populateItems();
|
||||
notifyItemRemoved(positionOfOldApp);
|
||||
}
|
||||
}
|
||||
|
||||
private final BroadcastReceiver receiverAppStatusChanges = new BroadcastReceiver() {
|
||||
|
@ -1,33 +0,0 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="90dp"
|
||||
android:height="90dp"
|
||||
android:viewportWidth="90.0"
|
||||
android:viewportHeight="90.0">
|
||||
<path
|
||||
android:pathData="m45,9.73c19.49,0 35.27,15.78 35.27,35.27 0,19.49 -15.78,35.27 -35.27,35.27 -19.49,0 -35.27,-15.78 -35.27,-35.27 0,-19.49 15.78,-35.27 35.27,-35.27z"
|
||||
android:strokeLineCap="butt"
|
||||
android:fillAlpha="1"
|
||||
android:strokeColor="#00000000"
|
||||
android:fillColor="#ffffff"
|
||||
android:strokeWidth="2"
|
||||
android:strokeLineJoin="miter"
|
||||
android:strokeAlpha="1"/>
|
||||
<path
|
||||
android:pathData="m45,7.73c-2.14,0 -4.24,0.19 -6.29,0.54l0.44,1.95c1.9,-0.32 3.86,-0.49 5.85,-0.49 19.49,0 35.27,15.78 35.27,35.27 0,19.49 -15.78,35.27 -35.27,35.27 -19.49,0 -35.27,-15.78 -35.27,-35.27 0,-1.94 0.16,-3.85 0.46,-5.7l-1.97,-0.35c-0.32,1.97 -0.5,3.99 -0.5,6.05 0,20.57 16.7,37.27 37.27,37.27 20.57,0 37.27,-16.7 37.27,-37.27 0,-20.57 -16.7,-37.27 -37.27,-37.27zM30.57,10.64c-3,1.26 -5.8,2.92 -8.34,4.88l1.26,1.53c2.41,-1.86 5.07,-3.42 7.92,-4.61l-0.85,-1.81zM16.08,21.52c-2.24,2.75 -4.09,5.82 -5.47,9.14l1.84,0.76c1.31,-3.15 3.07,-6.06 5.19,-8.67l-1.56,-1.23z"
|
||||
android:strokeLineCap="butt"
|
||||
android:fillAlpha="1"
|
||||
android:strokeColor="#00000000"
|
||||
android:fillColor="#0066cc"
|
||||
android:strokeWidth="2"
|
||||
android:strokeLineJoin="miter"
|
||||
android:strokeAlpha="1"/>
|
||||
<path
|
||||
android:pathData="m59.21,32.08a2.5,2.5 0,0 0,-1.72 0.76l-18.12,18.12 -8.09,-8.09a2.5,2.5 0,1 0,-3.54 3.54l9.85,9.86a2.5,2.5 0,0 0,3.54 0l19.89,-19.89a2.5,2.5 0,0 0,-1.82 -4.29z"
|
||||
android:strokeLineCap="round"
|
||||
android:fillAlpha="1"
|
||||
android:strokeColor="#00000000"
|
||||
android:fillColor="#0066cc"
|
||||
android:strokeWidth="5"
|
||||
android:strokeLineJoin="round"
|
||||
android:strokeAlpha="1"/>
|
||||
</vector>
|
@ -36,7 +36,7 @@
|
||||
app:layout_constraintTop_toTopOf="@+id/icon"
|
||||
android:layout_marginLeft="8dp"
|
||||
android:layout_marginStart="8dp"
|
||||
app:layout_constraintEnd_toStartOf="@+id/install"
|
||||
app:layout_constraintEnd_toStartOf="@+id/buttons"
|
||||
android:layout_marginEnd="8dp"
|
||||
android:layout_marginRight="8dp" />
|
||||
|
||||
@ -57,18 +57,34 @@
|
||||
android:layout_marginStart="8dp"
|
||||
android:layout_marginLeft="8dp" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/install"
|
||||
tools:src="@drawable/ic_download"
|
||||
android:scaleType="fitXY"
|
||||
android:contentDescription="@string/menu_install"
|
||||
android:layout_width="64dp"
|
||||
android:layout_height="64dp"
|
||||
android:elevation="2dp"
|
||||
android:padding="4dp"
|
||||
<FrameLayout
|
||||
android:id="@+id/buttons"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:layout_marginRight="16dp"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toTopOf="@+id/icon" />
|
||||
app:layout_constraintTop_toTopOf="@+id/icon">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/install"
|
||||
tools:src="@drawable/ic_download"
|
||||
android:scaleType="fitXY"
|
||||
android:contentDescription="@string/menu_install"
|
||||
android:layout_width="64dp"
|
||||
android:layout_height="64dp"
|
||||
android:elevation="2dp"
|
||||
android:padding="4dp" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/action_button"
|
||||
style="@style/DetailsPrimaryButtonStyle"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="8dp"
|
||||
android:layout_marginBottom="8dp"
|
||||
tools:text="Update" />
|
||||
|
||||
</FrameLayout>
|
||||
|
||||
</android.support.constraint.ConstraintLayout>
|
@ -55,8 +55,22 @@
|
||||
android:layout_marginRight="16dp"
|
||||
android:layout_marginTop="8dp"
|
||||
android:layout_marginBottom="8dp"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintEnd_toStartOf="@+id/action_button"
|
||||
app:layout_constraintTop_toTopOf="@+id/icon"
|
||||
app:layout_constraintBottom_toBottomOf="@+id/icon" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/action_button"
|
||||
style="@style/DetailsPrimaryButtonStyleSmall"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:layout_marginRight="16dp"
|
||||
android:layout_marginTop="8dp"
|
||||
android:layout_marginBottom="8dp"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
tools:text="Update" />
|
||||
|
||||
</android.support.constraint.ConstraintLayout>
|
Loading…
x
Reference in New Issue
Block a user