From 952ea803b2033bcd5c43bcae7ab95c4de44ee96e Mon Sep 17 00:00:00 2001 From: Manuel Fuhr Date: Sat, 2 Apr 2022 17:34:41 +0200 Subject: [PATCH] Use LinarProgessIndicator instead of sub-view --- .../java/btools/mapaccess/Rd5DiffTool.java | 9 +- brouter-routing-app/build.gradle | 33 ++--- .../src/main/AndroidManifest.xml | 2 +- .../btools/routingapp/BInstallerActivity.java | 58 +++++---- .../btools/routingapp/DownloadWorker.java | 116 +++++++++++------- .../main/res/layout/activity_binstaller.xml | 104 ++++++---------- .../src/main/res/values/styles.xml | 10 ++ .../java/btools/util/ProgressListener.java | 3 +- 8 files changed, 173 insertions(+), 162 deletions(-) create mode 100644 brouter-routing-app/src/main/res/values/styles.xml diff --git a/brouter-mapaccess/src/main/java/btools/mapaccess/Rd5DiffTool.java b/brouter-mapaccess/src/main/java/btools/mapaccess/Rd5DiffTool.java index e1e48c6..c5ffbf1 100644 --- a/brouter-mapaccess/src/main/java/btools/mapaccess/Rd5DiffTool.java +++ b/brouter-mapaccess/src/main/java/btools/mapaccess/Rd5DiffTool.java @@ -50,9 +50,8 @@ final public class Rd5DiffTool implements ProgressListener } @Override - public void updateProgress( String progress ) - { - System.out.println( progress ); + public void updateProgress(String task, int progress) { + System.out.println(task + ": " + progress + "%"); } @Override @@ -342,7 +341,7 @@ final public class Rd5DiffTool implements ProgressListener int pct = (int)(100. * bytesProcessed / getTileEnd( fileIndex1, 24 ) + 0.5 ); if ( pct != lastPct ) { - progress.updateProgress( "Applying delta: " + pct + "%" ); + progress.updateProgress("Applying delta", pct); lastPct = pct; } @@ -490,7 +489,7 @@ final public class Rd5DiffTool implements ProgressListener int pct = (int)( (100. * sizeRead) / (sizeTotal+1) + 0.5 ); if ( pct != lastPct ) { - progress.updateProgress( "Copying: " + pct + "%" ); + progress.updateProgress("Copying", pct); lastPct = pct; } int len = dis1.read( buf ); diff --git a/brouter-routing-app/build.gradle b/brouter-routing-app/build.gradle index ff83e75..d254021 100644 --- a/brouter-routing-app/build.gradle +++ b/brouter-routing-app/build.gradle @@ -14,16 +14,16 @@ android { versionName project.version resValue('string', 'app_version', defaultConfig.versionName) - setProperty("archivesBaseName","BRouterApp." + defaultConfig.versionName) + setProperty("archivesBaseName", "BRouterApp." + defaultConfig.versionName) minSdkVersion 14 - + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" } sourceSets.main.assets.srcDirs += new File(project.buildDir, 'assets') - if(project.hasProperty("RELEASE_STORE_FILE") && RELEASE_STORE_FILE.length() > 0) { + if (project.hasProperty("RELEASE_STORE_FILE") && RELEASE_STORE_FILE.length() > 0) { signingConfigs { // this uses a file ~/.gradle/gradle.properties // with content: @@ -33,17 +33,17 @@ android { // RELEASE_KEY_PASSWORD=***** // release { - // enable signingConfig in buildTypes to get a signed apk file - storeFile file(RELEASE_STORE_FILE) - storePassword RELEASE_STORE_PASSWORD - keyAlias RELEASE_KEY_ALIAS - keyPassword RELEASE_KEY_PASSWORD + // enable signingConfig in buildTypes to get a signed apk file + storeFile file(RELEASE_STORE_FILE) + storePassword RELEASE_STORE_PASSWORD + keyAlias RELEASE_KEY_ALIAS + keyPassword RELEASE_KEY_PASSWORD - // Optional, specify signing versions used - v1SigningEnabled true - v2SigningEnabled true + // Optional, specify signing versions used + v1SigningEnabled true + v2SigningEnabled true - } + } } } @@ -51,7 +51,7 @@ android { release { minifyEnabled false debuggable false - if(project.hasProperty("RELEASE_STORE_FILE") && RELEASE_STORE_FILE.length() > 0) { + if (project.hasProperty("RELEASE_STORE_FILE") && RELEASE_STORE_FILE.length() > 0) { signingConfig signingConfigs.release } proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' @@ -64,7 +64,8 @@ android { } lintOptions { disable 'InvalidPackage' - checkReleaseBuilds false //added this line to the build.gradle under the /android/app/build.gradle + checkReleaseBuilds false + //added this line to the build.gradle under the /android/app/build.gradle } compileOptions { @@ -96,6 +97,7 @@ dependencies { implementation 'androidx.appcompat:appcompat:1.4.1' implementation "androidx.constraintlayout:constraintlayout:2.1.3" implementation 'androidx.work:work-runtime:2.7.1' + implementation 'com.google.android.material:material:1.5.0' implementation project(':brouter-mapaccess') implementation project(':brouter-core') @@ -116,8 +118,7 @@ task generateProfiles(type: Exec) { task generateProfilesZip(type: Zip) { if (DefaultNativePlatform.getCurrentOperatingSystem().isWindows()) { logger.warn("Note: On Windows run script '../misc/scripts/generate_profile_variants.sh' manually to include all profiles") - } - else { + } else { dependsOn generateProfiles } archiveFileName = "profiles2.zip" diff --git a/brouter-routing-app/src/main/AndroidManifest.xml b/brouter-routing-app/src/main/AndroidManifest.xml index 8efa1af..76f6b51 100644 --- a/brouter-routing-app/src/main/AndroidManifest.xml +++ b/brouter-routing-app/src/main/AndroidManifest.xml @@ -18,7 +18,7 @@ android:label="@string/app_name" android:preserveLegacyExternalStorage="true" android:roundIcon="@mipmap/ic_launcher_round" - android:theme="@style/Theme.AppCompat.Light.NoActionBar"> + android:theme="@style/Theme.App"> { @@ -84,12 +82,7 @@ public class BInstallerActivity extends AppCompatActivity { } } ); - mDownloadInfo = findViewById(R.id.view_download_progress); - mDownloadInfoText = findViewById(R.id.textViewDownloadProgress); - mButtonDownloadCancel = findViewById(R.id.buttonDownloadCancel); - mButtonDownloadCancel.setOnClickListener(view -> { - cancelDownload(); - }); + mProgressIndicator = findViewById(R.id.progressDownload); mBaseDir = ConfigHelper.getBaseDir(this); scanExistingFiles(); @@ -138,21 +131,13 @@ public class BInstallerActivity extends AppCompatActivity { } } - private void cancelDownload() { - downloadCanceled = true; - mDownloadInfoText.setText(getString(R.string.download_info_cancel)); - } - public void downloadAll(ArrayList downloadList) { ArrayList urlparts = new ArrayList<>(); for (Integer i : downloadList) { urlparts.add(baseNameForTile(i)); } - mSegmentsView.setVisibility(View.GONE); - mDownloadInfo.setVisibility(View.VISIBLE); downloadCanceled = false; - mDownloadInfoText.setText(R.string.download_info_start); Data inputData = new Data.Builder() .putStringArray(DownloadWorker.KEY_INPUT_SEGMENT_NAMES, urlparts.toArray(new String[0])) @@ -171,31 +156,44 @@ public class BInstallerActivity extends AppCompatActivity { WorkManager workManager = WorkManager.getInstance(getApplicationContext()); workManager.enqueue(downloadWorkRequest); - mButtonDownloadCancel.setOnClickListener(view -> { - mDownloadInfoText.setText("Cancelling..."); - workManager.cancelWorkById(downloadWorkRequest.getId()); - }); - workManager .getWorkInfoByIdLiveData(downloadWorkRequest.getId()) .observe(this, workInfo -> { if (workInfo != null) { if (workInfo.getState() == WorkInfo.State.ENQUEUED) { - mDownloadInfoText.setText("Waiting for download to start. Check internet connection if it takes too long"); + Toast.makeText(this, "Download scheduled. Check internet connection if it doesn't start.", Toast.LENGTH_LONG).show(); + mProgressIndicator.hide(); + mProgressIndicator.setIndeterminate(true); + mProgressIndicator.show(); } if (workInfo.getState() == WorkInfo.State.RUNNING) { Data progress = workInfo.getProgress(); String segmentName = progress.getString(DownloadWorker.PROGRESS_SEGMENT_NAME); int percent = progress.getInt(DownloadWorker.PROGRESS_SEGMENT_PERCENT, 0); - if (segmentName != null) { - mDownloadInfoText.setText(String.format("Download %s - %d%%", segmentName, percent)); + if (percent > 0) { + mProgressIndicator.setIndeterminate(false); } + mProgressIndicator.setProgress(percent); } if (workInfo.getState().isFinished()) { - mSegmentsView.setVisibility(View.VISIBLE); - mDownloadInfo.setVisibility(View.GONE); + String result; + switch (workInfo.getState()) { + case FAILED: + result = "failed."; + break; + case CANCELLED: + result = "cancelled"; + break; + case SUCCEEDED: + result = "succeeded"; + break; + default: + result = ""; + } + Toast.makeText(this, "Download " + result + ".", Toast.LENGTH_SHORT).show(); + mProgressIndicator.hide(); scanExistingFiles(); } } diff --git a/brouter-routing-app/src/main/java/btools/routingapp/DownloadWorker.java b/brouter-routing-app/src/main/java/btools/routingapp/DownloadWorker.java index d675e3d..378e431 100644 --- a/brouter-routing-app/src/main/java/btools/routingapp/DownloadWorker.java +++ b/brouter-routing-app/src/main/java/btools/routingapp/DownloadWorker.java @@ -59,10 +59,59 @@ public class DownloadWorker extends Worker { notificationBuilder = createNotificationBuilder(); + downloadProgressListener = new DownloadProgressListener() { + private String currentDownloadName; + private DownloadType currentDownloadType; + private int lastProgressPercent; + + @Override + public void onDownloadStart(String downloadName, DownloadType downloadType) { + currentDownloadName = downloadName; + currentDownloadType = downloadType; + if (downloadType == DownloadType.SEGMENT) { + progressBuilder.putString(PROGRESS_SEGMENT_NAME, downloadName); + notificationBuilder.setContentText(downloadName); + } + } + + @Override + public void onDownloadInfo(String info) { + notificationBuilder.setContentText(info); + notificationManager.notify(NOTIFICATION_ID, notificationBuilder.build()); + } + + @Override + public void onDownloadProgress(int max, int progress) { + int progressPercent = (int) (progress * 100L / max); + + // Only report segments and update if it changed to avoid hammering NotificationManager + if (currentDownloadType != DownloadType.SEGMENT || progressPercent == lastProgressPercent) { + return; + } + + if (max > 0) { + notificationBuilder.setProgress(max, progress, false); + progressBuilder.putInt(PROGRESS_SEGMENT_PERCENT, progressPercent); + } else { + notificationBuilder.setProgress(0, 0, true); + progressBuilder.putInt(PROGRESS_SEGMENT_PERCENT, -1); + } + notificationManager.notify(NOTIFICATION_ID, notificationBuilder.build()); + setProgressAsync(progressBuilder.build()); + + lastProgressPercent = progressPercent; + } + + @Override + public void onDownloadFinished() { + } + }; + diffProgressListener = new ProgressListener() { @Override - public void updateProgress(String progress) { - notificationManager.notify(NOTIFICATION_ID, createNotification(progress)); + public void updateProgress(String task, int progress) { + downloadProgressListener.onDownloadInfo(task); + downloadProgressListener.onDownloadProgress(100, progress); } @Override @@ -70,32 +119,6 @@ public class DownloadWorker extends Worker { return isStopped(); } }; - - downloadProgressListener = new DownloadProgressListener() { - @Override - public void updateProgress(int max, int progress) { - if (max > 0) { - notificationBuilder.setProgress(max, progress, false); - notificationManager.notify(NOTIFICATION_ID, notificationBuilder.build()); - progressBuilder.putInt(PROGRESS_SEGMENT_PERCENT, progress * 100 / max); - setProgressAsync(progressBuilder.build()); - } else { - notificationBuilder.setProgress(0, 0, true); - notificationManager.notify(NOTIFICATION_ID, notificationBuilder.build()); - progressBuilder.putInt(PROGRESS_SEGMENT_PERCENT, -1); - setProgressAsync(progressBuilder.build()); - } - } - - @Override - public void updateProgress(String content) { - notificationBuilder.setContentText(content); - notificationManager.notify(NOTIFICATION_ID, notificationBuilder.build()); - } - }; - - progressBuilder.putInt(PROGRESS_SEGMENT_PERCENT, 0); - setProgressAsync(progressBuilder.build()); } @NonNull @@ -109,14 +132,11 @@ public class DownloadWorker extends Worker { // Mark the Worker as important setForegroundAsync(new ForegroundInfo(NOTIFICATION_ID, createNotification("Starting Download"))); try { - notificationManager.notify(NOTIFICATION_ID, createNotification("Updating profiles")); downloadLookupAndProfiles(); int segmentIndex = 1; for (String segmentName : segmentNames) { - notificationManager.notify(NOTIFICATION_ID, createNotification(String.format("%s (%d/%d)", segmentName, segmentIndex, segmentNames.length))); - progressBuilder.putString(PROGRESS_SEGMENT_NAME, segmentName); - setProgressAsync(progressBuilder.build()); + downloadProgressListener.onDownloadStart(segmentName, DownloadType.SEGMENT); downloadSegment(mServerConfig.getSegmentUrl(), segmentName + SEGMENT_SUFFIX); segmentIndex++; } @@ -135,7 +155,9 @@ public class DownloadWorker extends Worker { File lookupFile = new File(baseDir, PROFILES_DIR + fileName); String lookupLocation = mServerConfig.getLookupUrl() + fileName; URL lookupUrl = new URL(lookupLocation); + downloadProgressListener.onDownloadStart(fileName, DownloadType.LOOKUP); downloadFile(lookupUrl, lookupFile, false); + downloadProgressListener.onDownloadFinished(); } } @@ -146,7 +168,9 @@ public class DownloadWorker extends Worker { if (profileFile.exists()) { String profileLocation = mServerConfig.getProfilesUrl() + fileName; URL profileUrl = new URL(profileLocation); + downloadProgressListener.onDownloadStart(fileName, DownloadType.PROFILE); downloadFile(profileUrl, profileFile, false); + downloadProgressListener.onDownloadFinished(); } } } @@ -157,7 +181,7 @@ public class DownloadWorker extends Worker { File segmentFileTemp = new File(segmentFile.getAbsolutePath() + "_tmp"); try { if (segmentFile.exists()) { - downloadProgressListener.updateProgress("Calculating local checksum..."); + downloadProgressListener.onDownloadInfo("Calculating local checksum..."); String md5 = Rd5DiffManager.getMD5(segmentFile); String segmentDeltaLocation = segmentBaseUrl + "diff/" + segmentName.replace(SEGMENT_SUFFIX, "/" + md5 + SEGMENT_DIFF_SUFFIX); URL segmentDeltaUrl = new URL(segmentDeltaLocation); @@ -165,7 +189,7 @@ public class DownloadWorker extends Worker { File segmentDeltaFile = new File(segmentFile.getAbsolutePath() + "_diff"); try { downloadFile(segmentDeltaUrl, segmentDeltaFile, true); - downloadProgressListener.updateProgress("Applying delta..."); + downloadProgressListener.onDownloadInfo("Applying delta..."); Rd5DiffTool.recoverFromDelta(segmentFile, segmentDeltaFile, segmentFileTemp, diffProgressListener); } catch (IOException e) { throw new IOException("Failed to download & apply delta update", e); @@ -205,14 +229,10 @@ public class DownloadWorker extends Worker { } private void downloadFile(URL downloadUrl, File outputFile, boolean limitDownloadSpeed) throws IOException, InterruptedException { - // For all those small files the progress reporting is really noisy - boolean reportDownloadProgress = limitDownloadSpeed; HttpURLConnection connection = (HttpURLConnection) downloadUrl.openConnection(); connection.setConnectTimeout(5000); connection.connect(); - if (reportDownloadProgress) downloadProgressListener.updateProgress("Connecting..."); - if (connection.getResponseCode() != HttpURLConnection.HTTP_OK) { throw new IOException("HTTP Request failed"); } @@ -232,8 +252,7 @@ public class DownloadWorker extends Worker { total += count; output.write(buffer, 0, count); - // publishing the progress.... - downloadProgressListener.updateProgress(fileLength, total); + downloadProgressListener.onDownloadProgress(fileLength, total); if (limitDownloadSpeed) { // enforce < 16 Mbit/s @@ -244,8 +263,6 @@ public class DownloadWorker extends Worker { } } } - - setProgressAsync(new Data.Builder().putInt(PROGRESS_SEGMENT_PERCENT, 100).build()); } @NonNull @@ -292,8 +309,19 @@ public class DownloadWorker extends Worker { notificationManager.createNotificationChannel(channel); } + enum DownloadType { + LOOKUP, + PROFILE, + SEGMENT + } + interface DownloadProgressListener { - void updateProgress(int max, int progress); - void updateProgress(String content); + void onDownloadStart(String downloadName, DownloadType downloadType); + + void onDownloadInfo(String info); + + void onDownloadProgress(int max, int progress); + + void onDownloadFinished(); } } diff --git a/brouter-routing-app/src/main/res/layout/activity_binstaller.xml b/brouter-routing-app/src/main/res/layout/activity_binstaller.xml index 11e4a84..5f0e7c1 100644 --- a/brouter-routing-app/src/main/res/layout/activity_binstaller.xml +++ b/brouter-routing-app/src/main/res/layout/activity_binstaller.xml @@ -1,71 +1,45 @@ - + android:layout_height="match_parent"> - + +