diff --git a/android/BOINC/src/edu/berkeley/boinc/PrefsActivity.java b/android/BOINC/src/edu/berkeley/boinc/PrefsActivity.java index 39486b5d30..a0aa56dc89 100644 --- a/android/BOINC/src/edu/berkeley/boinc/PrefsActivity.java +++ b/android/BOINC/src/edu/berkeley/boinc/PrefsActivity.java @@ -270,10 +270,8 @@ public class PrefsActivity extends FragmentActivity { break; case R.string.prefs_show_notification_header: //app pref appPrefs.setShowNotification(isSet); - try{ - if(isSet) ClientNotification.getInstance(getApplicationContext()).update(Monitor.getClientStatus()); - else ClientNotification.getInstance(getApplicationContext()).cancel(); - } catch(Exception e) {if(Logging.WARNING) Log.d(Logging.TAG, "PrefsActivity: enabling notification failed");} + if(isSet) ClientNotification.getInstance(getApplicationContext()).update(); + else ClientNotification.getInstance(getApplicationContext()).cancel(); updateBoolPref(ID, isSet); updateLayout(); break; diff --git a/android/BOINC/src/edu/berkeley/boinc/client/ClientNotification.java b/android/BOINC/src/edu/berkeley/boinc/client/ClientNotification.java index 11ec31ad7a..603c58e706 100644 --- a/android/BOINC/src/edu/berkeley/boinc/client/ClientNotification.java +++ b/android/BOINC/src/edu/berkeley/boinc/client/ClientNotification.java @@ -21,6 +21,7 @@ public class ClientNotification { private NotificationManager nm; private Integer notificationId; private PendingIntent contentIntent; + private Notification n = null; private int mOldComputingStatus = -1; private int mOldSuspendReason = -1; @@ -52,43 +53,43 @@ public class ClientNotification { /** * Updates notification with client's current status */ - public synchronized void update(ClientStatus updatedStatus) { - - // during computation, setForeground is in charge of the notification - if(foreground) return; - - // check whether notification is allowed in preferences - if (!Monitor.getAppPrefs().getShowNotification()) return; - - // update notification, only after change in status - if (clientNotification.mOldComputingStatus == -1 - || updatedStatus.computingStatus.intValue() != clientNotification.mOldComputingStatus - || (updatedStatus.computingStatus == ClientStatus.COMPUTING_STATUS_SUSPENDED - && updatedStatus.computingSuspendReason != clientNotification.mOldSuspendReason)) { + public synchronized void update() { + try { + ClientStatus updatedStatus = Monitor.getClientStatus(); - // update notification - nm.notify(notificationId, buildNotification(updatedStatus)); - - // save status for comparison next time - clientNotification.mOldComputingStatus = updatedStatus.computingStatus; - clientNotification.mOldSuspendReason = updatedStatus.computingSuspendReason; - } + // update notification, only after change in status + if (clientNotification.mOldComputingStatus == -1 + || updatedStatus.computingStatus.intValue() != clientNotification.mOldComputingStatus + || (updatedStatus.computingStatus == ClientStatus.COMPUTING_STATUS_SUSPENDED + && updatedStatus.computingSuspendReason != clientNotification.mOldSuspendReason)) { + + buildNotification(updatedStatus); + + // update notification + if(foreground || Monitor.getAppPrefs().getShowNotification()) nm.notify(notificationId, n); + + // save status for comparison next time + clientNotification.mOldComputingStatus = updatedStatus.computingStatus; + clientNotification.mOldSuspendReason = updatedStatus.computingSuspendReason; + } + } catch (Exception e) {if(Logging.WARNING) Log.d(Logging.TAG, "ClientNotification.update failed.");} } // called by Monitor to enable foreground with notification - public synchronized void setForeground(Boolean setForeground, Boolean updated, ClientStatus status, Monitor service) { - if((foreground != setForeground) || updated) { + public synchronized void setForeground(Boolean setForeground, Monitor service) { + if(foreground != setForeground) { if(setForeground) { - // cancel suspend notification - cancel(); + // check whether notification is available + if (n == null) update(); // set service foreground - service.startForeground(1337, buildNotification(status)); + service.startForeground(notificationId, n); if(Logging.DEBUG) Log.d(Logging.TAG,"ClientNotification.setForeground() start service as foreground."); foreground = true; } else { // set service background foreground = false; - service.stopForeground(true); + Boolean remove = !Monitor.getAppPrefs().getShowNotification(); + service.stopForeground(remove); if(Logging.DEBUG) Log.d(Logging.TAG,"ClientNotification.setForeground() stop service as foreground."); } } @@ -107,7 +108,7 @@ public class ClientNotification { String statusText = status.getCurrentStatusString(); // build notification - Notification n = new NotificationCompat.Builder(context) + n = new NotificationCompat.Builder(context) .setContentTitle(context.getString(R.string.app_name)) .setContentText(statusText) .setSmallIcon(getIcon(computingStatus)) diff --git a/android/BOINC/src/edu/berkeley/boinc/client/Monitor.java b/android/BOINC/src/edu/berkeley/boinc/client/Monitor.java index 5b1af48e6b..e400775040 100644 --- a/android/BOINC/src/edu/berkeley/boinc/client/Monitor.java +++ b/android/BOINC/src/edu/berkeley/boinc/client/Monitor.java @@ -356,16 +356,19 @@ public class Monitor extends Service { private void readClientStatus(Boolean forceCompleteUpdate) { try{ // read ccStatus and adjust wakelocks and service state independently of screen status + // wake locks and foreground enabled when Client is not suspended, therefore also during + // idle. CcStatus status = rpc.getCcStatus(); Boolean computing = (status.task_suspend_reason == BOINCDefs.SUSPEND_NOT_SUSPENDED); if(Logging.VERBOSE) Log.d(Logging.TAG,"readClientStatus(): computation enabled: " + computing); Monitor.getClientStatus().setWifiLock(computing); Monitor.getClientStatus().setWakeLock(computing); + ClientNotification.getInstance(getApplicationContext()).setForeground(computing, this); // complete status read, depending on screen status // screen off: only read computing status to adjust wakelock, do not send broadcast // screen on: read complete status, set ClientStatus, send broadcast - Boolean completeUpdate = false; + // forceCompleteUpdate: read complete status, independently of screen setting if(screenOn || forceCompleteUpdate) { // complete status read, with broadcast if(Logging.VERBOSE) Log.d(Logging.TAG, "readClientStatus(): screen on, get complete status"); @@ -375,8 +378,7 @@ public class Monitor extends Service { if( (status != null) && (state != null) && (state.results != null) && (state.projects != null) && (transfers != null) && (state.host_info != null)) { Monitor.getClientStatus().setClientStatus(status, state.results, state.projects, transfers, state.host_info); // Update status bar notification - ClientNotification.getInstance(getApplicationContext()).update(Monitor.getClientStatus()); - completeUpdate = true; + ClientNotification.getInstance(getApplicationContext()).update(); } else { if(Logging.ERROR) Log.e(Logging.TAG, "readClientStatus(): connection problem"); } @@ -388,9 +390,6 @@ public class Monitor extends Service { getApplicationContext().sendBroadcast(clientStatus); } } - - // set service foreground notification, after initial data retrieval in ClientStatus - ClientNotification.getInstance(getApplicationContext()).setForeground(computing, completeUpdate, Monitor.getClientStatus(), this); }catch(Exception e) { if(Logging.ERROR) Log.e(Logging.TAG, "Monitor.readClientStatus excpetion: " + e.getMessage(),e);