Skip to content

Commit

Permalink
Version 1.2:
Browse files Browse the repository at this point in the history
Changed application icon,
Changed Notification icon,
Added sonwload speed and time remaining to progress notification
Increased notification update rate to 0,5s (This should increase
performance)
  • Loading branch information
Fabrizio Pietrucci committed May 15, 2017
1 parent 5824f9e commit 8f23ac9
Show file tree
Hide file tree
Showing 11 changed files with 113 additions and 21 deletions.
5 changes: 2 additions & 3 deletions app/build.gradle
Expand Up @@ -7,8 +7,8 @@ android {
applicationId "chromiumupdater.bamless.com.chromiumsweupdater"
minSdkVersion 15
targetSdkVersion 25
versionCode 2
versionName "1.1"
versionCode 3
versionName "1.2"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
Expand All @@ -27,6 +27,5 @@ dependencies {
compile 'com.android.support:appcompat-v7:25.3.1'
compile 'com.android.support.constraint:constraint-layout:1.0.2'
testCompile 'junit:junit:4.12'
compile 'com.jakewharton:butterknife:8.5.1'
compile 'com.squareup.okhttp3:okhttp:3.7.0'
}
Expand Up @@ -140,8 +140,8 @@ private void updateStatusText(boolean isUpdateAvailable) {
SharedPreferences prefs = getSharedPreferences(Prefs.BUILD_PREFS, Context.MODE_PRIVATE);
BuildTime last = BuildTime.parseBuildTime(prefs.getString(Prefs.BUILD_LASTBUILDFETCHED, Constants.EPOCH));

String newBuildText = getResources().getString(R.string.newBuildText);
updateStatusText.setText(newBuildText.replace("/date/", last.dateToString()));
String newBuildText = getResources().getString(R.string.newBuildText, last.dateToString());
updateStatusText.setText(newBuildText);
updateStatusText.setTextColor(Color.BLUE);
updateStatusText.setPaintFlags(updateStatusText.getPaintFlags() | Paint.UNDERLINE_TEXT_FLAG);
//set onclick listener to start update
Expand Down
Expand Up @@ -56,7 +56,7 @@ private void showUpdateNotification() {
notBuilder.setContentTitle(getString(R.string.newUpdateNotificationText))
.setContentText(getString(R.string.newUpdateNotificationContentText))
.setSmallIcon(R.mipmap.ic_update_black)
.setLargeIcon(BitmapFactory.decodeResource(getResources(), R.drawable.chromiumswe64px))
.setLargeIcon(BitmapFactory.decodeResource(getResources(), R.drawable.chromiumsweupdater))
.setDefaults(-1 )
.setAutoCancel(true)
.setContentIntent(intent);
Expand Down
Expand Up @@ -30,14 +30,14 @@
* Class that implements logic for checking and downloading Chromium for SWE updates
*/
public class ChromiumUpdater {
public final static String TAG = "ChromiumUpdater";
private final static String TAG = "ChromiumUpdater";

/**Base address*/
public final static String REPO = "https://github.com/bamless/chromium-swe-builds/raw/master/";
private final static String REPO = "https://github.com/bamless/chromium-swe-builds/raw/master/";
/**Name of the APK*/
public final static String CHROMIUM_SWE_APK = "chromium-swe.apk";
private final static String CHROMIUM_SWE_APK = "chromium-swe.apk";
/**Name of the build file containing date and hour of last build*/
public final static String BUILD_FILE = "build";
private final static String BUILD_FILE = "build";

/**Downloading progress listener*/
private ProgressResponseBody.ProgressListener progressListener;
Expand Down Expand Up @@ -89,7 +89,7 @@ public void onResponse(Call call, Response response) throws IOException {
parseBuildTime(response.body().string().replace("\n", ""));

if(currBuild.compareTo(buildFromRepo) < 0) {
prefs.edit().putString(Prefs.BUILD_LASTBUILDFETCHED, buildFromRepo.toString()).commit();
prefs.edit().putString(Prefs.BUILD_LASTBUILDFETCHED, buildFromRepo.toString()).apply();
returnOnUIThread(returnCallback, true);
} else {
returnOnUIThread(returnCallback, false);
Expand Down Expand Up @@ -146,7 +146,7 @@ public void onResponse(Call call, Response response) throws IOException {
//update last installation time
SharedPreferences prefs = context.getSharedPreferences(Prefs.BUILD_PREFS, Context.MODE_PRIVATE);
prefs.edit().putString(Prefs.BUILD_LASTBUILDINST, prefs.
getString(Prefs.BUILD_LASTBUILDFETCHED, Constants.EPOCH)).commit();
getString(Prefs.BUILD_LASTBUILDFETCHED, Constants.EPOCH)).apply();

returnOnUIThread(returnCallback, true);
}
Expand All @@ -158,7 +158,7 @@ private void installUpdate(File downloadPath) {
File apk = new File(downloadPath, ChromiumUpdater.CHROMIUM_SWE_APK);
Intent intent = new Intent(Intent.ACTION_VIEW);

Uri uri = null;
Uri uri;
if(android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
uri = FileProvider.getUriForFile(context, context.getApplicationContext()
.getPackageName() + ".provider", apk);
Expand Down
@@ -1,5 +1,6 @@
package com.bamless.chromiumsweupdater.updater;

import android.app.Activity;
import android.app.NotificationManager;
import android.content.ComponentName;
import android.content.Context;
Expand All @@ -12,13 +13,19 @@
import com.bamless.chromiumsweupdater.R;
import com.bamless.chromiumsweupdater.http.ProgressResponseBody;

import java.text.DecimalFormat;
import java.text.DecimalFormatSymbols;
import java.util.Locale;
import java.util.concurrent.atomic.AtomicInteger;

/**
* Notification used to show download progress. To be used with an {@link okhttp3.OkHttpClient} using
* a {@link ProgressResponseBody}.
*/
public class ProgressNotification implements ProgressResponseBody.ProgressListener {
/**Update interval (in milliseconds)*/
private static final int UPDATE_INTERVAL = 500;

private Context ctx;
private ServiceConnection connection;
private NotificationManager notManager;
Expand All @@ -27,6 +34,11 @@ public class ProgressNotification implements ProgressResponseBody.ProgressListen
private String title;
private int notificationID;

/**time at notification start. Used to calculate download rate*/
private long startTime;
/**time of last notification update. Used to decide when to update notification*/
private long lastUpdate;

public ProgressNotification(Context ctx, String title) {
this.ctx = ctx;
this.title = title;
Expand All @@ -40,9 +52,10 @@ private void init() {
notBuilder.setContentTitle(this.title)
.setContentText("0%")
.setOngoing(true)
.setLargeIcon(BitmapFactory.decodeResource(ctx.getResources(), R.drawable.chromiumswe64px))
.setLargeIcon(BitmapFactory.decodeResource(ctx.getResources(), R.drawable.chromiumsweupdater64px))
.setSmallIcon(R.mipmap.ic_update_black);
notBuilder.setProgress(100, 0, false);
//init the service used to dismiss the notification upon app closure
connection = new ServiceConnection() {
public void onServiceConnected(ComponentName className, IBinder binder) {
((KillNotificationsService.KillBinder) binder).service.startService(new Intent(
Expand All @@ -56,23 +69,102 @@ public void onServiceDisconnected(ComponentName className) {
Context.BIND_AUTO_CREATE);
}

/**Resets the state of the notification and shows it*/
public void start() {
startTime = System.currentTimeMillis();
lastUpdate = 0;
update(0, 0, false);
}

/**Dismiss the notification*/
public void cancel() {
notManager.cancel(notificationID);
}

@Override
public void update(long bytesRead, long contentLength, boolean done) {
int percent = (int) (((float) bytesRead / contentLength) * 100);
notBuilder.setProgress(100, percent, false);
notBuilder.setContentText(percent + "%");
notManager.notify(notificationID, notBuilder.build());
if (done) notManager.cancel(notificationID);
long elapsedTimeMillis = System.currentTimeMillis() - startTime;
float downRate = elapsedTimeMillis == 0 ? 0 : ((float) bytesRead / (elapsedTimeMillis / 1000f));
int timeRemaining = (int) ((double) (contentLength - bytesRead) / downRate);

if(canUpdate()){
notBuilder.setProgress(100, percent, false);
notBuilder.setContentText(ctx.getString(R.string.progressNotText,
percent, formatDownloadRate(downRate), formatSeconds(timeRemaining)));
notManager.notify(notificationID, notBuilder.build());
}
if(done) notManager.cancel(notificationID);
}

/**
* Returns true if the notification should be updated. This limits the rate of update of the notification.
* This is done both to increase performance (the creation of the notification takes time) and to
* limit the updating of the text (if the text gets updated too frequently it gets difficult to read).
*/
private boolean canUpdate() {
long curr = System.currentTimeMillis();
if(curr - lastUpdate >= UPDATE_INTERVAL) {
lastUpdate = curr;
return true;
}
return false;
}

/**
* Formats the download rate.
* @param bps the download rate in bytes per second
* @return a string formatted with a different unit depending on the speed of the download rate
*/
private String formatDownloadRate(float bps) {
String rate;
DecimalFormat decimal = new DecimalFormat("0.00", DecimalFormatSymbols.getInstance(Locale.getDefault()));
DecimalFormat integer = new DecimalFormat("0");

double kbps = bps/1024.0;
double mbps = kbps/1024.0;

if(mbps > 1) {
rate = hasDecimal(mbps) ? decimal.format(mbps).concat(" MB/s") : integer.format(mbps).concat(" MB/s");
} else if(kbps > 1) {
rate = hasDecimal(kbps) ? decimal.format(kbps).concat(" KB/s") : integer.format(mbps).concat(" KB/s");
} else {
rate = integer.format(bps).concat(" B/s");
}

return rate;
}

/**
* Formats seconds
* @param seconds the number of seconds to format
* @return a string formatted with a different unit depending on the number of seconds
*/
private String formatSeconds(int seconds) {
String time;
DecimalFormat decimal = new DecimalFormat("0.0", DecimalFormatSymbols.getInstance(Locale.getDefault()));
DecimalFormat integer = new DecimalFormat("0");

float min = seconds / 60.0f;
float hour = min / 60.0f;

if(hour > 1) {
time = hasDecimal(hour) ? decimal.format(hour).concat(" h") : integer.format(hour).concat(" h");
} else if(min > 1) {
time = hasDecimal(min) ? decimal.format(min).concat(" m") : integer.format(min).concat(" m");
} else {
time = integer.format(seconds).concat(" s");
}

return time;
}

/**Returns true if the input double has decimal figures*/
private boolean hasDecimal(double num) {
return !(num % 1 == 0.0);
}

/**Unbinds the kill notification service. This method should be called in {@link Activity#onDestroy()}*/
public void destroy() {
ctx.unbindService(connection);
}
Expand Down
Binary file removed app/src/main/res/drawable/chromiumswe128px.png
Binary file not shown.
Binary file removed app/src/main/res/drawable/chromiumswe64px.png
Binary file not shown.
Binary file modified app/src/main/res/drawable/chromiumsweupdater.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
5 changes: 3 additions & 2 deletions app/src/main/res/values/strings.xml
@@ -1,11 +1,12 @@
<resources>
<string name="app_name">Chromium SWE Updater</string>
<string name="updateNotificationText">Updating Chromium SWE</string>
<string name="updateNotificationText">Updating</string>
<string name="updateFailed">Update Failed</string>
<string name="newBuildText">New build available: Build /date/\nClick here to download</string>
<string name="newBuildText">New build available: Build %1$s\nClick here to download</string>
<string name="noUpdateText">No update available</string>
<string name="titleText">Update Chromium SWE</string>
<string name="newUpdateNotificationText">Chromium SWE new update</string>
<string name="newUpdateNotificationContentText">click for download</string>
<string name="permDeniedError">You need to grant the permissions in order to download chromium</string>
<string name="progressNotText">%1$d%% %2$s, %3$s remaining</string>
</resources>
2 changes: 1 addition & 1 deletion build.gradle
Expand Up @@ -5,7 +5,7 @@ buildscript {
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:2.3.1'
classpath 'com.android.tools.build:gradle:2.3.2'

// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
Expand Down

0 comments on commit 8f23ac9

Please sign in to comment.