diff --git a/app/src/main/java/info/nightscout/android/medtronic/MainActivity.java b/app/src/main/java/info/nightscout/android/medtronic/MainActivity.java index 718bfe7fd9319f9f8f82441c79658419baf3f536..c07d4c9acea57965743cf7bca2c941ee179dbe9f 100644 --- a/app/src/main/java/info/nightscout/android/medtronic/MainActivity.java +++ b/app/src/main/java/info/nightscout/android/medtronic/MainActivity.java @@ -83,6 +83,8 @@ public class MainActivity extends AppCompatActivity implements OnSharedPreferenc private Handler mUiRefreshHandler = new Handler(); private Runnable mUiRefreshRunnable = new RefreshDisplayRunnable(); private Realm mRealm; + private StatusMessageReceiver statusMessageReceiver = new StatusMessageReceiver(); + private MedtronicCnlAlarmReceiver medtronicCnlAlarmReceiver = new MedtronicCnlAlarmReceiver(); public static void setActivePumpMac(long pumpMac) { activePumpMac = pumpMac; @@ -106,7 +108,7 @@ public class MainActivity extends AppCompatActivity implements OnSharedPreferenc } LocalBroadcastManager.getInstance(this).registerReceiver( - new StatusMessageReceiver(), + statusMessageReceiver, new IntentFilter(MedtronicCnlIntentService.Constants.ACTION_STATUS_MESSAGE)); LocalBroadcastManager.getInstance(this).registerReceiver( new RefreshDataReceiver(), @@ -217,6 +219,9 @@ public class MainActivity extends AppCompatActivity implements OnSharedPreferenc @Override protected void attachBaseContext(Context newBase) { super.attachBaseContext(CalligraphyContextWrapper.wrap(newBase)); + + // setup self handling alarm receiver + medtronicCnlAlarmReceiver.setContext(getBaseContext()); } @Override @@ -287,7 +292,8 @@ public class MainActivity extends AppCompatActivity implements OnSharedPreferenc } private void clearLogText() { - mTextViewLog.setText("", BufferType.EDITABLE); + statusMessageReceiver.clearMessages(); + //mTextViewLog.setText("", BufferType.EDITABLE); } private void startDisplayRefreshLoop() { @@ -299,7 +305,7 @@ public class MainActivity extends AppCompatActivity implements OnSharedPreferenc } private void startCgmService() { - startCgmService(0L); + startCgmService(System.currentTimeMillis()); } private void startCgmService(long initialPoll) { @@ -309,32 +315,16 @@ public class MainActivity extends AppCompatActivity implements OnSharedPreferenc return; } - if (initialPoll == 0) { - initialPoll = SystemClock.currentThreadTimeMillis(); - } - - Log.d(TAG, "startCgmService set to fire at " + new Date(initialPoll)); - clearLogText(); + //clearLogText(); // Cancel any existing polling. stopCgmService(); - - AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE); - Intent receiverIntent = new Intent(this, MedtronicCnlAlarmReceiver.class); - PendingIntent pending = PendingIntent.getBroadcast(this, 0, receiverIntent, 0); - - alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, - initialPoll, MedtronicCnlIntentService.POLL_PERIOD_MS, pending); + medtronicCnlAlarmReceiver.setAlarm(initialPoll); } private void stopCgmService() { Log.i(TAG, "stopCgmService called"); - - AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE); - Intent receiverIntent = new Intent(this, MedtronicCnlAlarmReceiver.class); - PendingIntent pending = PendingIntent.getBroadcast(this, 0, receiverIntent, 0); - - alarmManager.cancel(pending); + medtronicCnlAlarmReceiver.cancelAlarm(); } private void showDisconnectionNotification(String title, String message) { @@ -490,7 +480,7 @@ public class MainActivity extends AppCompatActivity implements OnSharedPreferenc } public String toString() { - return DateFormat.getTimeInstance(DateFormat.SHORT).format(timestamp) + ": " + message; + return DateFormat.getTimeInstance(DateFormat.MEDIUM).format(timestamp) + ": " + message; } } @@ -501,7 +491,7 @@ public class MainActivity extends AppCompatActivity implements OnSharedPreferenc String message = intent.getStringExtra(MedtronicCnlIntentService.Constants.EXTENDED_DATA); Log.i(TAG, "Message Receiver: " + message); - synchronized (this) { + synchronized (messages) { while (messages.size() > 8) { messages.poll(); } @@ -517,11 +507,21 @@ public class MainActivity extends AppCompatActivity implements OnSharedPreferenc mTextViewLog.setText(sb.toString(), BufferType.EDITABLE); } + + public void clearMessages() { + synchronized (messages) { + messages.clear(); + } + + mTextViewLog.setText("", BufferType.EDITABLE); + } } private class RefreshDisplayRunnable implements Runnable { @Override public void run() { + Log.d(TAG, "NOW " + new Date(System.currentTimeMillis()).toString()); + // UI elements - TODO do these need to be members? TextView textViewBg = (TextView) findViewById(R.id.textview_bg); TextView textViewBgTime = (TextView) findViewById(R.id.textview_bg_time); @@ -628,6 +628,8 @@ public class MainActivity extends AppCompatActivity implements OnSharedPreferenc long nextPoll = pumpStatusData.getEventDate().getTime() + MedtronicCnlIntentService.POLL_GRACE_PERIOD_MS + MedtronicCnlIntentService.POLL_PERIOD_MS; startCgmService(nextPoll); + Log.d(TAG, "Lokal time " + new Date()); + Log.d(TAG, "Last event was " + new Date(pumpStatusData.getEventDate().getTime())); Log.d(TAG, "Next Poll at " + new Date(nextPoll).toString()); // Delete invalid or old records from Realm diff --git a/app/src/main/java/info/nightscout/android/medtronic/service/MedtronicCnlAlarmReceiver.java b/app/src/main/java/info/nightscout/android/medtronic/service/MedtronicCnlAlarmReceiver.java index d0d4a41c68b561a7961e63637379f42c567257c9..b878eac22927edd633c6777c494a932376b6ac36 100644 --- a/app/src/main/java/info/nightscout/android/medtronic/service/MedtronicCnlAlarmReceiver.java +++ b/app/src/main/java/info/nightscout/android/medtronic/service/MedtronicCnlAlarmReceiver.java @@ -1,21 +1,66 @@ package info.nightscout.android.medtronic.service; +import android.app.AlarmManager; +import android.app.PendingIntent; import android.content.Context; import android.content.Intent; +import android.os.SystemClock; import android.support.v4.content.WakefulBroadcastReceiver; import android.util.Log; +import java.util.Date; + /** * Created by lgoedhart on 14/07/2016. */ public class MedtronicCnlAlarmReceiver extends WakefulBroadcastReceiver { private static final String TAG = MedtronicCnlAlarmReceiver.class.getSimpleName(); + private static final int ALARM_ID = 102; // Alarm id + + private static PendingIntent pi = null; + private static AlarmManager am = null; @Override public void onReceive(final Context context, Intent intent) { // Start the IntentService - Log.d(TAG, "Received broadcast message"); + Log.d(TAG, "Received broadcast message at " + new Date(System.currentTimeMillis())); Intent service = new Intent(context, MedtronicCnlIntentService.class); startWakefulService(context, service); + restartAlarm(); + } + + public void setContext(Context context) { + if (am != null && pi != null) { + // here is an old alarm. So we cancel it before + cancelAlarm(); + } + am = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE); + Intent intent = new Intent(context, MedtronicCnlAlarmReceiver.class); + pi = PendingIntent.getBroadcast(context, ALARM_ID, intent, PendingIntent.FLAG_UPDATE_CURRENT); } + + // Setting the alarm to call onRecieve every _REFRESH_INTERVAL seconds + public void setAlarm() { + setAlarm(System.currentTimeMillis()); + } + + // Setting the alarm to call onRecieve + public void setAlarm(long millis) { + try { + am.cancel(pi); + } catch (Exception ignored) {} + Log.d(TAG, "AlarmManager set to fire at " + new Date(millis)); + am.setExact(AlarmManager.RTC_WAKEUP, millis, pi); + } + + // restarting the alarm after MedtronicCnlIntentService.POLL_PERIOD_MS from now + public void restartAlarm() { + setAlarm(System.currentTimeMillis() + MedtronicCnlIntentService.POLL_PERIOD_MS); + } + + // Cancel the alarm. + public void cancelAlarm() { + am.cancel(pi); + } + } diff --git a/app/src/main/java/info/nightscout/android/medtronic/service/MedtronicCnlIntentService.java b/app/src/main/java/info/nightscout/android/medtronic/service/MedtronicCnlIntentService.java index e73e6fa342ea6d7694c3fea3ef080b82dd8a8176..99336f3dfbfe5b67ad4a4a64e810d9e1f854f980 100644 --- a/app/src/main/java/info/nightscout/android/medtronic/service/MedtronicCnlIntentService.java +++ b/app/src/main/java/info/nightscout/android/medtronic/service/MedtronicCnlIntentService.java @@ -103,6 +103,9 @@ public class MedtronicCnlIntentService extends IntentService { if (cnlStick == null) { sendStatus("USB connection error. Is the Bayer Contour Next Link plugged in?"); Log.w(TAG, "USB connection error. Is the CNL plugged in?"); + + // TODO - set status if offline or Nightscout not reachable + uploadToNightscout(); MedtronicCnlAlarmReceiver.completeWakefulIntent(intent); // TODO - throw, don't return return; @@ -279,8 +282,9 @@ public class MedtronicCnlIntentService extends IntentService { private void uploadToNightscout() { AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE); Intent receiverIntent = new Intent(this, NightscoutUploadReceiver.class); - PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0, receiverIntent, 0); - alarmManager.set(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + 1000L, pendingIntent); + final long timestamp = System.currentTimeMillis() + 1000L; + PendingIntent pendingIntent = PendingIntent.getBroadcast(this, (int)timestamp, receiverIntent, PendingIntent.FLAG_ONE_SHOT); + alarmManager.set(AlarmManager.RTC_WAKEUP, timestamp, pendingIntent); } private boolean hasUsbHostFeature() {