1
0
mirror of https://github.com/etesync/android synced 2025-01-11 00:01:12 +00:00

Notify the user on journal modification.

This Resolves #13.
This commit is contained in:
Tal Hacohen 2017-09-05 18:37:46 +03:00 committed by Tom Hacohen
parent f44558b8ab
commit f631fe4452
6 changed files with 100 additions and 6 deletions

View File

@ -30,6 +30,8 @@ public class NotificationHelper {
Intent detailsIntent; Intent detailsIntent;
int messageString; int messageString;
private Throwable throwable = null;
public NotificationHelper(Context context, String notificationTag, int notificationId) { public NotificationHelper(Context context, String notificationTag, int notificationId) {
this.notificationManager = NotificationManagerCompat.from(context); this.notificationManager = NotificationManagerCompat.from(context);
this.context = context; this.context = context;
@ -38,6 +40,7 @@ public class NotificationHelper {
} }
public void setThrowable(Throwable e) { public void setThrowable(Throwable e) {
throwable = e;
if (e instanceof Exceptions.UnauthorizedException) { if (e instanceof Exceptions.UnauthorizedException) {
App.log.log(Level.SEVERE, "Not authorized anymore", e); App.log.log(Level.SEVERE, "Not authorized anymore", e);
messageString = R.string.sync_error_unauthorized; messageString = R.string.sync_error_unauthorized;
@ -68,18 +71,39 @@ public class NotificationHelper {
public void notify(String title, String state) { public void notify(String title, String state) {
String message = context.getString(messageString, state); String message = context.getString(messageString, state);
notify(title, message, null, detailsIntent);
}
public void notify(String title, String content, String bigText, Intent intent) {
NotificationCompat.Builder builder = new NotificationCompat.Builder(context); NotificationCompat.Builder builder = new NotificationCompat.Builder(context);
builder.setSmallIcon(R.drawable.ic_error_light) int icon;
.setLargeIcon(App.getLauncherBitmap(context)) String category;
String tag;
//Check if error was configured
if (throwable == null) {
icon = R.drawable.ic_sync_dark;
category = NotificationCompat.CATEGORY_STATUS;
} else {
icon = R.drawable.ic_error_light;
category = NotificationCompat.CATEGORY_ERROR;
}
builder.setLargeIcon(App.getLauncherBitmap(context))
.setContentTitle(title) .setContentTitle(title)
.setContentIntent(PendingIntent.getActivity(context, 0, detailsIntent, PendingIntent.FLAG_CANCEL_CURRENT)) .setContentText(content)
.setCategory(NotificationCompat.CATEGORY_ERROR) .setAutoCancel(true)
.setContentText(message); .setCategory(category)
.setSmallIcon(icon)
.setContentIntent(PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT))
;
if (bigText != null) builder.setStyle(new NotificationCompat.BigTextStyle()
.bigText(bigText));
notificationManager.notify(notificationTag, notificationId, builder.build()); notificationManager.notify(notificationTag, notificationId, builder.build());
} }
public void cancel() { public void cancel() {
notificationManager.cancel(notificationTag, notificationId); notificationManager.cancel(notificationTag, notificationId);
} }

View File

@ -59,6 +59,12 @@ public class CalendarSyncManager extends SyncManager {
return context.getString(R.string.sync_error_calendar, account.name); return context.getString(R.string.sync_error_calendar, account.name);
} }
@Override
protected String getSyncSuccessfullyTitle() {
return context.getString(R.string.sync_successfully_calendar, info.displayName,
account.name);
}
@Override @Override
protected boolean prepare() throws ContactsStorageException, CalendarStorageException { protected boolean prepare() throws ContactsStorageException, CalendarStorageException {
if (!super.prepare()) if (!super.prepare())

View File

@ -82,6 +82,11 @@ public class ContactsSyncManager extends SyncManager {
return context.getString(R.string.sync_error_contacts, account.name); return context.getString(R.string.sync_error_contacts, account.name);
} }
@Override
protected String getSyncSuccessfullyTitle() {
return context.getString(R.string.sync_successfully_contacts, account.name);
}
@Override @Override
protected boolean prepare() throws ContactsStorageException, CalendarStorageException { protected boolean prepare() throws ContactsStorageException, CalendarStorageException {
if (!super.prepare()) if (!super.prepare())

View File

@ -12,6 +12,7 @@ import android.annotation.TargetApi;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.content.SyncResult; import android.content.SyncResult;
import android.content.res.Resources;
import android.os.Bundle; import android.os.Bundle;
import com.etesync.syncadapter.AccountSettings; import com.etesync.syncadapter.AccountSettings;
@ -32,6 +33,7 @@ import com.etesync.syncadapter.model.SyncEntry;
import com.etesync.syncadapter.resource.LocalCollection; import com.etesync.syncadapter.resource.LocalCollection;
import com.etesync.syncadapter.resource.LocalResource; import com.etesync.syncadapter.resource.LocalResource;
import com.etesync.syncadapter.ui.DebugInfoActivity; import com.etesync.syncadapter.ui.DebugInfoActivity;
import com.etesync.syncadapter.ui.ViewCollectionActivity;
import org.apache.commons.collections4.ListUtils; import org.apache.commons.collections4.ListUtils;
@ -51,6 +53,7 @@ import io.requery.sql.EntityDataStore;
import okhttp3.OkHttpClient; import okhttp3.OkHttpClient;
import static com.etesync.syncadapter.Constants.KEY_ACCOUNT; import static com.etesync.syncadapter.Constants.KEY_ACCOUNT;
import static com.etesync.syncadapter.model.SyncEntry.Actions.ADD;
abstract public class SyncManager { abstract public class SyncManager {
private static final int MAX_FETCH = 50; private static final int MAX_FETCH = 50;
@ -132,6 +135,8 @@ abstract public class SyncManager {
protected abstract String getSyncErrorTitle(); protected abstract String getSyncErrorTitle();
protected abstract String getSyncSuccessfullyTitle();
@TargetApi(21) @TargetApi(21)
public void performSync() { public void performSync() {
int syncPhase = R.string.sync_phase_prepare; int syncPhase = R.string.sync_phase_prepare;
@ -194,6 +199,8 @@ abstract public class SyncManager {
App.log.info("Sync phase: " + context.getString(syncPhase)); App.log.info("Sync phase: " + context.getString(syncPhase));
postProcess(); postProcess();
notifyUserOnSync();
App.log.info("Finished sync with CTag=" + remoteCTag); App.log.info("Finished sync with CTag=" + remoteCTag);
} catch (IOException e) { } catch (IOException e) {
App.log.log(Level.WARNING, "I/O exception during sync, trying again later", e); App.log.log(Level.WARNING, "I/O exception during sync, trying again later", e);
@ -230,6 +237,47 @@ abstract public class SyncManager {
} }
} }
private void notifyUserOnSync() {
if (remoteEntries.isEmpty()) {
return;
}
NotificationHelper notificationHelper = new NotificationHelper(context,
String.valueOf(System.currentTimeMillis()), notificationId());
int deleted = 0;
int added = 0;
int changed = 0;
for (JournalEntryManager.Entry entry : remoteEntries) {
SyncEntry cEntry = SyncEntry.fromJournalEntry(crypto, entry);
SyncEntry.Actions action = cEntry.getAction();
switch (action) {
case ADD:
added++;
break;
case DELETE:
deleted++;
break;
case CHANGE:
changed++;
break;
}
}
Resources resources = context.getResources();
Intent intent = ViewCollectionActivity.newIntent(context, account, info);
notificationHelper.notify(getSyncSuccessfullyTitle(),
String.format(context.getString(R.string.sync_successfully_modified),
resources.getQuantityString(R.plurals.sync_successfully,
remoteEntries.size(), remoteEntries.size())),
String.format(context.getString(R.string.sync_successfully_modified_full),
resources.getQuantityString(R.plurals.sync_successfully,
added, added),
resources.getQuantityString(R.plurals.sync_successfully,
changed, changed),
resources.getQuantityString(R.plurals.sync_successfully,
deleted, deleted)),
intent);
}
/** /**
* Prepares synchronization (for instance, allocates necessary resources). * Prepares synchronization (for instance, allocates necessary resources).
@ -386,7 +434,7 @@ abstract public class SyncManager {
for (LocalResource local : localDirty) { for (LocalResource local : localDirty) {
SyncEntry.Actions action; SyncEntry.Actions action;
if (local.isLocalOnly()) { if (local.isLocalOnly()) {
action = SyncEntry.Actions.ADD; action = ADD;
} else { } else {
action = SyncEntry.Actions.CHANGE; action = SyncEntry.Actions.CHANGE;
} }

View File

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<plurals name="sync_successfully">
<item quantity="one">%d entry</item>
<item quantity="other">%d entries</item>
</plurals>
</resources>

View File

@ -303,6 +303,10 @@
<string name="sync_phase_post_processing">post processing</string> <string name="sync_phase_post_processing">post processing</string>
<string name="sync_error_unauthorized">Authentication failed</string> <string name="sync_error_unauthorized">Authentication failed</string>
<string name="sync_error_user_inactive">User is inactive</string> <string name="sync_error_user_inactive">User is inactive</string>
<string name="sync_successfully_calendar" formatted="false">Calendar \"%s\" modified (%s)</string>
<string name="sync_successfully_contacts" formatted="false">Contacts modified (%s)</string>
<string name="sync_successfully_modified" formatted="false">%s modified.</string>
<string name="sync_successfully_modified_full" formatted="false">%s added.\n%s updated.\n%s deleted.</string>
<!-- cert4android --> <!-- cert4android -->
<string name="certificate_notification_connection_security">EteSync: Connection security</string> <string name="certificate_notification_connection_security">EteSync: Connection security</string>