From edacd53ac24220ae9b4fdd165758085058910391 Mon Sep 17 00:00:00 2001 From: Phillip Hsu Date: Sun, 5 Jun 2016 21:21:03 -0700 Subject: [PATCH] Bug fixed --- .../clock2/ringtone/RingtoneActivity.java | 40 ++++++++++--------- .../clock2/ringtone/RingtoneService.java | 14 ++++--- 2 files changed, 31 insertions(+), 23 deletions(-) diff --git a/app/src/main/java/com/philliphsu/clock2/ringtone/RingtoneActivity.java b/app/src/main/java/com/philliphsu/clock2/ringtone/RingtoneActivity.java index 43af1e6..ee21a1f 100644 --- a/app/src/main/java/com/philliphsu/clock2/ringtone/RingtoneActivity.java +++ b/app/src/main/java/com/philliphsu/clock2/ringtone/RingtoneActivity.java @@ -33,6 +33,7 @@ public class RingtoneActivity extends AppCompatActivity implements RingtoneServi public static final String EXTRA_ITEM_ID = "com.philliphsu.clock2.ringtone.extra.ITEM_ID"; private Alarm mAlarm; + private boolean mBound = false; @Override protected void onCreate(Bundle savedInstanceState) { @@ -55,10 +56,7 @@ public class RingtoneActivity extends AppCompatActivity implements RingtoneServi // This could be the case if we're starting a new instance of this activity after leaving the first launch. AlarmUtils.removeUpcomingAlarmNotification(this, mAlarm); - // Play the ringtone - Intent intent = new Intent(this, RingtoneService.class) - .putExtra(EXTRA_ITEM_ID, mAlarm.id()); - startService(intent); + Intent intent = new Intent(this, RingtoneService.class); bindService(intent, mConnection, Context.BIND_AUTO_CREATE); Button snooze = (Button) findViewById(R.id.btn_snooze); @@ -77,18 +75,18 @@ public class RingtoneActivity extends AppCompatActivity implements RingtoneServi }); } - @Override - protected void onResume() { - super.onResume(); - } - @Override protected void onNewIntent(Intent intent) { //super.onNewIntent(intent); // Not needed since no fragments hosted? - // Calling recreate() would recreate this with its current intent, not the new intent passed in here. - mBoundService.onNewActivity(); // notify alarm missed - finish(); // destroy this, unbind from service, and stop service - startActivity(intent); + if (mBound) { + mBoundService.interrupt(); // prepare to notify the alarm was missed + // Cannot rely on finish() to call onDestroy() on time before the activity is restarted, + // so unbind from the service manually. + unbindService(); + // Calling recreate() would recreate this with its current intent, not the new intent passed in here. + finish(); + startActivity(intent); + } } @Override @@ -124,11 +122,7 @@ public class RingtoneActivity extends AppCompatActivity implements RingtoneServi @Override protected void onDestroy() { super.onDestroy(); - // According to the lifecycle diagram, you unbind from the service first and then stop the service. - unbindService(mConnection); - // TODO: Use appropriate subclass - // If service is not running, nothing happens. - stopService(new Intent(this, RingtoneService.class)); + unbindService(); } @Override @@ -148,18 +142,28 @@ public class RingtoneActivity extends AppCompatActivity implements RingtoneServi finish(); } + private void unbindService() { + if (mBound) { + unbindService(mConnection); + mBound = false; + } + } + private RingtoneService mBoundService; private ServiceConnection mConnection = new ServiceConnection() { @Override public void onServiceConnected(ComponentName name, IBinder service) { mBoundService = ((RingtoneService.RingtoneBinder) service).getService(); + mBoundService.playRingtone(mAlarm); mBoundService.setRingtoneCallback(RingtoneActivity.this); + mBound = true; } @Override public void onServiceDisconnected(ComponentName name) { mBoundService = null; + mBound = false; } }; } \ No newline at end of file diff --git a/app/src/main/java/com/philliphsu/clock2/ringtone/RingtoneService.java b/app/src/main/java/com/philliphsu/clock2/ringtone/RingtoneService.java index 1c41347..446158f 100644 --- a/app/src/main/java/com/philliphsu/clock2/ringtone/RingtoneService.java +++ b/app/src/main/java/com/philliphsu/clock2/ringtone/RingtoneService.java @@ -12,12 +12,12 @@ import android.net.Uri; import android.os.Binder; import android.os.Handler; import android.os.IBinder; +import android.support.annotation.NonNull; import android.support.v4.app.NotificationCompat; import android.util.Log; import com.philliphsu.clock2.Alarm; import com.philliphsu.clock2.R; -import com.philliphsu.clock2.model.AlarmsRepository; import static com.philliphsu.clock2.util.DateFormatUtils.formatTime; import static com.philliphsu.clock2.util.Preconditions.checkNotNull; @@ -102,9 +102,9 @@ public class RingtoneService extends Service { // TODO: abstract this, make subc return mBinder; } - public void playRingtone(long itemId) { + public void playRingtone(@NonNull Alarm alarm) { if (mAudioManager == null && mRingtone == null) { - mAlarm = checkNotNull(AlarmsRepository.getInstance(this).getItem(itemId)); + mAlarm = checkNotNull(alarm); // TODO: The below call requires a notification, and there is no way to provide one suitable // for both Alarms and Timers. Consider making this class abstract, and have subclasses // implement an abstract method that calls startForeground(). You would then call that @@ -144,9 +144,13 @@ public class RingtoneService extends Service { // TODO: abstract this, make subc mRingtoneCallback = callback; } - public void onNewActivity() { + /** + * A way for clients to interrupt the currently running instance of this service. Interrupting + * the service is akin to prematurely auto silencing the ringtone right now. Clients MUST + * unbind from this service immediately after interrupting. + */ + public void interrupt() { mAutoSilenced = true; - //stopSelf(); } // Needed so clients can get the Service instance and e.g. call setRingtoneCallback().