"Update all" and "Check for updates" buttons will now be disabled while processing

This commit is contained in:
Sergey Eremin
2017-07-29 18:09:41 +03:00
parent 41c5e3ed02
commit a2c7e291d8
11 changed files with 200 additions and 85 deletions

View File

@@ -0,0 +1,89 @@
package com.github.yeriomin.yalpstore;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.util.Log;
import com.github.yeriomin.yalpstore.model.App;
import com.github.yeriomin.yalpstore.notification.NotificationManagerWrapper;
import java.util.List;
class BackgroundUpdatableAppsTask extends UpdatableAppsTask {
@Override
protected void onPostExecute(Throwable e) {
super.onPostExecute(e);
if (null != e) {
return;
}
int updatesCount = this.updatableApps.size();
Log.i(this.getClass().getName(), "Found updates for " + updatesCount + " apps");
if (updatesCount == 0) {
return;
}
if (canUpdate()) {
process(context, updatableApps);
} else {
createNotification(context, updatesCount);
}
}
private boolean canUpdate() {
return explicitCheck ||
(PreferenceActivity.getBoolean(context, PreferenceActivity.PREFERENCE_BACKGROUND_UPDATE_DOWNLOAD)
&& (DownloadManagerFactory.get(context) instanceof DownloadManagerAdapter
|| !PreferenceActivity.getBoolean(context, PreferenceActivity.PREFERENCE_BACKGROUND_UPDATE_WIFI_ONLY)
|| NetworkState.isWifi()
)
)
;
}
private void process(Context context, List<App> apps) {
boolean canInstallInBackground = PreferenceActivity.canInstallInBackground(context);
YalpStoreApplication application = (YalpStoreApplication) context.getApplicationContext();
application.clearPendingUpdates();
for (App app: apps) {
application.addPendingUpdate(app.getPackageName());
if (!Paths.getApkPath(app.getPackageName(), app.getVersionCode()).exists()) {
download(context, app);
} else if (canInstallInBackground) {
// Not passing context because it might be an activity
// and we want it to run in background
InstallerFactory.get(context.getApplicationContext()).verifyAndInstall(app);
} else {
application.removePendingUpdate(app.getPackageName());
}
}
}
private void download(Context context, App app) {
Log.i(getClass().getName(), "Starting download of update for " + app.getPackageName());
DownloadState state = DownloadState.get(app.getPackageName());
state.setApp(app);
getPurchaseTask(context, app).execute();
}
private PurchaseTask getPurchaseTask(Context context, App app) {
PurchaseTask task = new PurchaseTask();
task.setApp(app);
task.setContext(context);
task.setTriggeredBy(context instanceof Activity
? DownloadState.TriggeredBy.UPDATE_ALL_BUTTON
: DownloadState.TriggeredBy.SCHEDULED_UPDATE
);
return task;
}
private void createNotification(Context context, int updatesCount) {
Intent i = new Intent(context, UpdatableAppsActivity.class);
i.setAction(Intent.ACTION_VIEW);
new NotificationManagerWrapper(context).show(
i,
context.getString(R.string.notification_updates_available_title),
context.getString(R.string.notification_updates_available_message, updatesCount)
);
}
}

View File

@@ -79,6 +79,7 @@ public class GlobalDownloadReceiver extends BroadcastReceiver {
installer.verifyAndInstall(app);
} else {
notifyDownloadComplete(app);
((YalpStoreApplication) context.getApplicationContext()).removePendingUpdate(app.getPackageName());
}
}

View File

@@ -22,8 +22,10 @@ public class GlobalInstallReceiver extends BroadcastReceiver {
}
updateDetails(intent);
UpdatableAppsActivity.setNeedsUpdate(true);
String packageName = intent.getData().getSchemeSpecificPart();
((YalpStoreApplication) context.getApplicationContext()).removePendingUpdate(packageName);
if (needToRemoveApk(context) && action.equals(Intent.ACTION_PACKAGE_ADDED)) {
App app = getApp(context, intent.getData().getSchemeSpecificPart());
App app = getApp(context, packageName);
File apkPath = Paths.getApkPath(app.getPackageName(), app.getVersionCode());
boolean deleted = apkPath.delete();
Log.i(getClass().getName(), "Removed " + apkPath + " successfully: " + deleted);

View File

@@ -64,6 +64,7 @@ public abstract class InstallerAbstract {
Paths.getApkPath(app.getPackageName(), app.getVersionCode())
)) {
Log.i(getClass().getName(), "Signature mismatch for " + app.getPackageName());
((YalpStoreApplication) context.getApplicationContext()).removePendingUpdate(app.getPackageName());
if (Util.isContextUiCapable(context)) {
getSignatureMismatchDialog(app).show();
} else {

View File

@@ -22,6 +22,7 @@ abstract public class InstallerBackground extends InstallerAbstract {
}
if (background && !new PermissionsComparator(context).isSame(app)) {
Log.i(getClass().getName(), "New permissions for " + app.getPackageName());
((YalpStoreApplication) context.getApplicationContext()).removePendingUpdate(app.getPackageName());
notifyNewPermissions(app);
return false;
}

View File

@@ -23,6 +23,8 @@ public class UpdatableAppsActivity extends AppListActivity {
static private boolean needsUpdate;
private UpdateAllReceiver updateAllReceiver;
static public void setNeedsUpdate(boolean needsUpdate) {
UpdatableAppsActivity.needsUpdate = needsUpdate;
}
@@ -62,6 +64,15 @@ public class UpdatableAppsActivity extends AppListActivity {
}
});
}
updateAllReceiver = new UpdateAllReceiver(this);
}
@Override
protected void onPause() {
super.onPause();
if (null != updateAllReceiver) {
unregisterReceiver(updateAllReceiver);
}
}
@Override
@@ -85,7 +96,7 @@ public class UpdatableAppsActivity extends AppListActivity {
if (requestCode == PERMISSIONS_REQUEST_CODE
&& grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED
) {
new UpdateChecker().onReceive(this, getIntent());
launchUpdateAll();
}
}
@@ -117,13 +128,17 @@ public class UpdatableAppsActivity extends AppListActivity {
}
private void toggleUpdateAll(boolean enable) {
Button button = (Button) findViewById(R.id.update_all);
Button button = findViewById(R.id.update_all);
button.setVisibility(enable ? View.VISIBLE : View.GONE);
if (((YalpStoreApplication) getApplication()).isBackgroundUpdating()) {
button.setEnabled(false);
button.setText(R.string.list_updating);
}
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (checkPermission()) {
new UpdateChecker().onReceive(UpdatableAppsActivity.this, getIntent());
launchUpdateAll();
} else {
requestPermission();
}
@@ -131,6 +146,14 @@ public class UpdatableAppsActivity extends AppListActivity {
});
}
private void launchUpdateAll() {
((YalpStoreApplication) getApplicationContext()).setBackgroundUpdating(true);
new UpdateChecker().onReceive(UpdatableAppsActivity.this, getIntent());
Button button = findViewById(R.id.update_all);
button.setEnabled(false);
button.setText(R.string.list_updating);
}
private boolean checkPermission() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
return checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED;
@@ -172,6 +195,14 @@ public class UpdatableAppsActivity extends AppListActivity {
return result;
}
@Override
protected void onPreExecute() {
super.onPreExecute();
Button button = activity.findViewById(R.id.check_updates);
button.setEnabled(false);
button.setText(R.string.details_download_checking);
}
@Override
protected void onPostExecute(Throwable e) {
super.onPostExecute(e);
@@ -191,6 +222,9 @@ public class UpdatableAppsActivity extends AppListActivity {
}
activity.toggleUpdateAll(this.updatableApps.size() > 0);
new CategoryManager(activity).downloadCategoryNames();
Button button = activity.findViewById(R.id.check_updates);
button.setEnabled(true);
button.setText(R.string.list_check_updates);
}
}
}

View File

@@ -0,0 +1,33 @@
package com.github.yeriomin.yalpstore;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.widget.Button;
import android.widget.Toast;
public class UpdateAllReceiver extends BroadcastReceiver {
static public final String ACTION_UPDATE_COMPLETE = "ACTION_UPDATE_COMPLETE";
private Button button;
public UpdateAllReceiver(UpdatableAppsActivity activity) {
button = activity.findViewById(R.id.update_all);
IntentFilter filter = new IntentFilter();
filter.addAction(UpdateAllReceiver.ACTION_UPDATE_COMPLETE);
activity.registerReceiver(this, filter);
if (!((YalpStoreApplication) activity.getApplication()).isBackgroundUpdating()) {
onReceive(activity, new Intent());
}
}
@Override
public void onReceive(Context context, Intent intent) {
if (null != button) {
button.setEnabled(true);
button.setText(R.string.list_update_all);
}
}
}

View File

@@ -8,11 +8,6 @@ import android.content.Context;
import android.content.Intent;
import android.util.Log;
import com.github.yeriomin.yalpstore.model.App;
import com.github.yeriomin.yalpstore.notification.NotificationManagerWrapper;
import java.util.List;
public class UpdateChecker extends BroadcastReceiver {
static public void enable(Context context, int interval) {
@@ -34,83 +29,9 @@ public class UpdateChecker extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Log.i(getClass().getName(), "Started");
getTask(context).execute();
}
private UpdatableAppsTask getTask(Context context) {
UpdatableAppsTask task = new UpdatableAppsTask() {
@Override
protected void onPostExecute(Throwable e) {
super.onPostExecute(e);
if (null != e) {
return;
}
int updatesCount = this.updatableApps.size();
Log.i(this.getClass().getName(), "Found updates for " + updatesCount + " apps");
if (updatesCount == 0) {
return;
}
if (canUpdate()) {
process(context, updatableApps);
} else {
createNotification(context, updatesCount);
}
}
private boolean canUpdate() {
return explicitCheck ||
(PreferenceActivity.getBoolean(context, PreferenceActivity.PREFERENCE_BACKGROUND_UPDATE_DOWNLOAD)
&& (DownloadManagerFactory.get(context) instanceof DownloadManagerAdapter
|| !PreferenceActivity.getBoolean(context, PreferenceActivity.PREFERENCE_BACKGROUND_UPDATE_WIFI_ONLY)
|| NetworkState.isWifi()
)
)
;
}
};
UpdatableAppsTask task = new BackgroundUpdatableAppsTask();
task.setExplicitCheck(context instanceof Activity);
task.setContext(context);
return task;
}
private void process(Context context, List<App> apps) {
boolean canInstallInBackground = PreferenceActivity.canInstallInBackground(context);
for (App app: apps) {
if (!Paths.getApkPath(app.getPackageName(), app.getVersionCode()).exists()) {
download(context, app);
} else if (canInstallInBackground) {
// Not passing context because it might be an activity
// and we want it to run in background
InstallerFactory.get(context.getApplicationContext()).verifyAndInstall(app);
}
}
}
private void download(Context context, App app) {
Log.i(getClass().getName(), "Starting download of update for " + app.getPackageName());
DownloadState state = DownloadState.get(app.getPackageName());
state.setApp(app);
getPurchaseTask(context, app).execute();
}
private PurchaseTask getPurchaseTask(Context context, App app) {
PurchaseTask task = new PurchaseTask();
task.setApp(app);
task.setContext(context);
task.setTriggeredBy(context instanceof Activity
? DownloadState.TriggeredBy.UPDATE_ALL_BUTTON
: DownloadState.TriggeredBy.SCHEDULED_UPDATE
);
return task;
}
private void createNotification(Context context, int updatesCount) {
Intent i = new Intent(context, UpdatableAppsActivity.class);
i.setAction(Intent.ACTION_VIEW);
new NotificationManagerWrapper(context).show(
i,
context.getString(R.string.notification_updates_available_title),
context.getString(R.string.notification_updates_available_message, updatesCount)
);
task.execute();
}
}

View File

@@ -8,9 +8,40 @@ import android.os.Build;
import android.os.Handler;
import android.os.HandlerThread;
import android.preference.PreferenceManager;
import android.util.Log;
import java.util.ArrayList;
import java.util.List;
public class YalpStoreApplication extends Application {
private boolean isBackgroundUpdating = false;
private List<String> pendingUpdates = new ArrayList<>();
public boolean isBackgroundUpdating() {
return isBackgroundUpdating;
}
public void setBackgroundUpdating(boolean backgroundUpdating) {
isBackgroundUpdating = backgroundUpdating;
}
public void addPendingUpdate(String packageName) {
pendingUpdates.add(packageName);
}
public void removePendingUpdate(String packageName) {
pendingUpdates.remove(packageName);
if (pendingUpdates.isEmpty()) {
isBackgroundUpdating = false;
sendBroadcast(new Intent(UpdateAllReceiver.ACTION_UPDATE_COMPLETE));
}
}
public void clearPendingUpdates() {
pendingUpdates.clear();
}
@Override
public void onCreate() {
super.onCreate();

View File

@@ -17,6 +17,7 @@
<string name="list_incompatible">несовместимо</string>
<string name="list_check_updates">Проверить обновления</string>
<string name="list_update_all">Обновить всё</string>
<string name="list_updating">Обновляем…</string>
<string name="list_app_has_ads">есть реклама</string>
<string name="list_app_no_ads">нет рекламы</string>
<string name="list_app_depends_on_gsf">зависит от GSF</string>

View File

@@ -16,6 +16,7 @@
<string name="list_incompatible">incompatible</string>
<string name="list_check_updates">Check for updates</string>
<string name="list_update_all">Update all</string>
<string name="list_updating">Updating…</string>
<string name="list_app_has_ads">has ads</string>
<string name="list_app_no_ads">no ads</string>
<string name="list_app_depends_on_gsf">depends on GSF</string>