mirror of
https://github.com/MatomoCamp/matomocamp-companion-android.git
synced 2024-09-19 16:13:46 +02:00
Added Http cache awareness
to skip updating the database when the remote file has not changed.
This commit is contained in:
parent
6f48640a13
commit
90d73831c6
5 changed files with 85 additions and 32 deletions
|
@ -150,6 +150,9 @@ public class MainActivity extends ActionBarActivity implements ListView.OnItemCl
|
|||
case FosdemApi.RESULT_ERROR:
|
||||
message = getString(R.string.schedule_loading_error);
|
||||
break;
|
||||
case FosdemApi.RESULT_UP_TO_DATE:
|
||||
message = getString(R.string.events_download_up_to_date);
|
||||
break;
|
||||
case 0:
|
||||
message = getString(R.string.events_download_empty);
|
||||
break;
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
package be.digitalia.fosdem.api;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.util.concurrent.locks.Lock;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.support.v4.content.LocalBroadcastManager;
|
||||
|
||||
import java.util.concurrent.locks.Lock;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
|
||||
import be.digitalia.fosdem.db.DatabaseManager;
|
||||
import be.digitalia.fosdem.model.Event;
|
||||
import be.digitalia.fosdem.parsers.EventsParser;
|
||||
|
@ -27,6 +27,7 @@ public class FosdemApi {
|
|||
public static final String EXTRA_RESULT = "RESULT";
|
||||
|
||||
public static final int RESULT_ERROR = -1;
|
||||
public static final int RESULT_UP_TO_DATE = -2;
|
||||
|
||||
private static final Lock scheduleLock = new ReentrantLock();
|
||||
|
||||
|
@ -43,16 +44,29 @@ public class FosdemApi {
|
|||
|
||||
int result = RESULT_ERROR;
|
||||
try {
|
||||
InputStream is = HttpUtils.get(context, FosdemUrls.getSchedule(), ACTION_DOWNLOAD_SCHEDULE_PROGRESS, EXTRA_PROGRESS);
|
||||
DatabaseManager dbManager = DatabaseManager.getInstance();
|
||||
HttpUtils.HttpResult httpResult = HttpUtils.get(
|
||||
context,
|
||||
FosdemUrls.getSchedule(),
|
||||
dbManager.getLastModifiedTag(),
|
||||
ACTION_DOWNLOAD_SCHEDULE_PROGRESS,
|
||||
EXTRA_PROGRESS);
|
||||
if (httpResult.inputStream == null) {
|
||||
// Nothing to parse, the result is up-to-date.
|
||||
result = RESULT_UP_TO_DATE;
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
Iterable<Event> events = new EventsParser().parse(is);
|
||||
result = DatabaseManager.getInstance().storeSchedule(events);
|
||||
Iterable<Event> events = new EventsParser().parse(httpResult.inputStream);
|
||||
result = dbManager.storeSchedule(events, httpResult.lastModified);
|
||||
} finally {
|
||||
try {
|
||||
is.close();
|
||||
httpResult.inputStream.close();
|
||||
} catch (Exception ignored) {
|
||||
}
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
|
|
|
@ -50,6 +50,7 @@ public class DatabaseManager {
|
|||
|
||||
private static final String DB_PREFS_FILE = "database";
|
||||
private static final String LAST_UPDATE_TIME_PREF = "last_update_time";
|
||||
private static final String LAST_MODIFIED_TAG_PREF = "last_modified_tag";
|
||||
|
||||
private static DatabaseManager instance;
|
||||
|
||||
|
@ -117,13 +118,21 @@ public class DatabaseManager {
|
|||
return getSharedPreferences().getLong(LAST_UPDATE_TIME_PREF, -1L);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return The time identifier of the current version of the database.
|
||||
*/
|
||||
public String getLastModifiedTag() {
|
||||
return getSharedPreferences().getString(LAST_MODIFIED_TAG_PREF, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Stores the schedule to the database.
|
||||
*
|
||||
* @param events
|
||||
* @return The number of events processed.
|
||||
*/
|
||||
public int storeSchedule(Iterable<Event> events) {
|
||||
public int storeSchedule(Iterable<Event> events, String lastModifiedTag) {
|
||||
boolean isComplete = false;
|
||||
|
||||
SQLiteDatabase db = helper.getWritableDatabase();
|
||||
|
@ -260,8 +269,11 @@ public class DatabaseManager {
|
|||
// Clear cache
|
||||
cachedDays = null;
|
||||
year = -1;
|
||||
// Set last update time
|
||||
getSharedPreferences().edit().putLong(LAST_UPDATE_TIME_PREF, System.currentTimeMillis()).commit();
|
||||
// Set last update time and server's last modified tag
|
||||
getSharedPreferences().edit()
|
||||
.putLong(LAST_UPDATE_TIME_PREF, System.currentTimeMillis())
|
||||
.putString(LAST_MODIFIED_TAG_PREF, lastModifiedTag)
|
||||
.commit();
|
||||
|
||||
context.getContentResolver().notifyChange(URI_TRACKS, null);
|
||||
context.getContentResolver().notifyChange(URI_EVENTS, null);
|
||||
|
|
|
@ -22,7 +22,7 @@ import android.support.v4.content.LocalBroadcastManager;
|
|||
|
||||
/**
|
||||
* Utility class to perform HTTP requests.
|
||||
*
|
||||
*
|
||||
* @author Christophe Beyls
|
||||
*/
|
||||
public class HttpUtils {
|
||||
|
@ -43,9 +43,9 @@ public class HttpUtils {
|
|||
});
|
||||
|
||||
// Trust all HTTPS certificates
|
||||
TrustManager[] trustAllCerts = new TrustManager[] { new X509TrustManager() {
|
||||
TrustManager[] trustAllCerts = new TrustManager[]{new X509TrustManager() {
|
||||
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
|
||||
return new java.security.cert.X509Certificate[] {};
|
||||
return new java.security.cert.X509Certificate[]{};
|
||||
}
|
||||
|
||||
public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
|
||||
|
@ -53,7 +53,7 @@ public class HttpUtils {
|
|||
|
||||
public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
|
||||
}
|
||||
} };
|
||||
}};
|
||||
try {
|
||||
SSLContext sc = SSLContext.getInstance("TLS");
|
||||
sc.init(null, trustAllCerts, new java.security.SecureRandom());
|
||||
|
@ -63,44 +63,67 @@ public class HttpUtils {
|
|||
}
|
||||
}
|
||||
|
||||
public static class HttpResult {
|
||||
// Will be null when the local content is up-to-date
|
||||
public InputStream inputStream;
|
||||
public String lastModified;
|
||||
}
|
||||
|
||||
public static InputStream get(Context context, String path) throws IOException {
|
||||
return get(context, new URL(path), null, null);
|
||||
return get(context, new URL(path), null, null, null).inputStream;
|
||||
}
|
||||
|
||||
public static InputStream get(Context context, String path, String progressAction, String progressExtra) throws IOException {
|
||||
return get(context, new URL(path), progressAction, progressExtra);
|
||||
public static HttpResult get(Context context, String path, String lastModified,
|
||||
String progressAction, String progressExtra) throws IOException {
|
||||
return get(context, new URL(path), lastModified, progressAction, progressExtra);
|
||||
}
|
||||
|
||||
public static InputStream get(final Context context, URL url, final String progressAction, final String progressExtra) throws IOException {
|
||||
public static HttpResult get(final Context context, URL url, String lastModified,
|
||||
final String progressAction, final String progressExtra) throws IOException {
|
||||
HttpResult result = new HttpResult();
|
||||
|
||||
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
|
||||
connection.setReadTimeout(DEFAULT_TIMEOUT);
|
||||
connection.setConnectTimeout(DEFAULT_TIMEOUT);
|
||||
if (lastModified != null) {
|
||||
connection.addRequestProperty("If-Modified-Since", lastModified);
|
||||
}
|
||||
connection.connect();
|
||||
|
||||
if (connection.getResponseCode() != HttpURLConnection.HTTP_OK) {
|
||||
result.lastModified = connection.getHeaderField("Last-Modified");
|
||||
|
||||
int responseCode = connection.getResponseCode();
|
||||
if (responseCode != HttpURLConnection.HTTP_OK) {
|
||||
connection.disconnect();
|
||||
|
||||
throw new IOException("Server returned response code: " + connection.getResponseCode());
|
||||
if ((responseCode == HttpURLConnection.HTTP_NOT_MODIFIED) && (lastModified != null)) {
|
||||
// Cached result is still valid; return an empty response
|
||||
return result;
|
||||
}
|
||||
|
||||
throw new IOException("Server returned response code: " + responseCode);
|
||||
}
|
||||
|
||||
final int length = connection.getContentLength();
|
||||
InputStream is = new BufferedInputStream(connection.getInputStream());
|
||||
result.inputStream = new BufferedInputStream(connection.getInputStream());
|
||||
if ((progressAction == null) || (length == -1)) {
|
||||
// No progress support
|
||||
return is;
|
||||
return result;
|
||||
}
|
||||
|
||||
// Broadcast the progression in percents, with a precision of 1/10 of the total file size
|
||||
return new ByteCountInputStream(is, new ByteCountInputStream.ByteCountListener() {
|
||||
result.inputStream = new ByteCountInputStream(result.inputStream,
|
||||
new ByteCountInputStream.ByteCountListener() {
|
||||
|
||||
private LocalBroadcastManager lbm = LocalBroadcastManager.getInstance(context);
|
||||
private LocalBroadcastManager lbm = LocalBroadcastManager.getInstance(context);
|
||||
|
||||
@Override
|
||||
public void onNewCount(int byteCount) {
|
||||
// Cap percent to 100
|
||||
int percent = (byteCount >= length) ? 100 : byteCount * 100 / length;
|
||||
lbm.sendBroadcast(new Intent(progressAction).putExtra(progressExtra, percent));
|
||||
}
|
||||
}, length / 10);
|
||||
@Override
|
||||
public void onNewCount(int byteCount) {
|
||||
// Cap percent to 100
|
||||
int percent = (byteCount >= length) ? 100 : byteCount * 100 / length;
|
||||
lbm.sendBroadcast(new Intent(progressAction).putExtra(progressExtra, percent));
|
||||
}
|
||||
}, length / 10);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
<string name="download_reminder_message">This will update the schedule database to the latest version. Make sure you are connected to the internet.</string>
|
||||
<string name="never">Never</string>
|
||||
<string name="update_events_db">Update events database</string>
|
||||
<string name="events_download_up_to_date">Database is already up-to-date</string>
|
||||
<string name="events_download_empty">No new events found</string>
|
||||
|
||||
<plurals name="events_download_completed">
|
||||
|
|
Loading…
Reference in a new issue