Last active
July 27, 2016 16:48
-
-
Save arriolac/8e98585ba3a0077a7add to your computer and use it in GitHub Desktop.
IntentService for displaying a reminder
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package chrisarriola.me.remind; | |
import android.app.IntentService; | |
import android.content.Context; | |
import android.content.Intent; | |
import android.os.Bundle; | |
import chrisarriola.me.DataPath; | |
import chrisarriola.me.remind.util.LogUtil; | |
import com.google.android.gms.common.ConnectionResult; | |
import com.google.android.gms.common.api.GoogleApiClient; | |
import com.google.android.gms.wearable.MessageApi; | |
import com.google.android.gms.wearable.Node; | |
import com.google.android.gms.wearable.NodeApi; | |
import com.google.android.gms.wearable.Wearable; | |
import java.util.Calendar; | |
import java.util.Date; | |
import java.util.List; | |
/** | |
* IntentService for displaying a reminder (https://play.google.com/store/apps/details?id=chrisarriola.me.remind). | |
* | |
* Created by chris on 7/2/14. | |
*/ | |
public class ReminderIntentService extends IntentService | |
implements GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener { | |
private static final String TAG = ReminderIntentService.class.getSimpleName(); | |
private static final String EXTRA_FORCE = "force"; | |
private static final int EARLIEST_OPERATING_HOUR = 9; | |
private static final int LATEST_OPERATING_HOUR = 21; | |
private static final int DAILY_PING_COUNT = LATEST_OPERATING_HOUR - EARLIEST_OPERATING_HOUR; | |
private GoogleApiClient mGoogleApiClient; | |
public ReminderIntentService() { | |
super(TAG); | |
} | |
@Override public void onCreate() { | |
super.onCreate(); | |
initGooglePlayServices(); | |
mGoogleApiClient.connect(); | |
LogUtil.logDebugMessage(TAG, "Creating service."); | |
} | |
@Override public void onDestroy() { | |
mGoogleApiClient.disconnect(); | |
LogUtil.logDebugMessage(TAG, "Terminating service."); | |
super.onDestroy(); | |
} | |
@Override protected void onHandleIntent(Intent intent) { | |
LogUtil.logDebugMessage(TAG, "onHandleIntent called."); | |
final boolean shouldForce = intent.getBooleanExtra(EXTRA_FORCE, false); | |
if (shouldForce) { | |
LogUtil.logDebugMessage(TAG, "Showing reminder (DEBUG)."); | |
showReminder(); | |
} else { | |
LogUtil.logDebugMessage(TAG, "Check if reminder should be shown..."); | |
checkIfReminderShouldbeShown(); | |
} | |
} | |
public static Intent createIntent(Context context) { | |
return createIntent(context, false); | |
} | |
public static Intent createIntent(Context context, boolean force) { | |
final Intent intent = new Intent(context, ReminderIntentService.class); | |
intent.putExtra(EXTRA_FORCE, force); | |
return intent; | |
} | |
//<editor-fold desc="GoogleApiClient Methods"> | |
@Override public void onConnected(Bundle bundle) { | |
LogUtil.logDebugMessage(TAG, "Google API Services connected!"); | |
} | |
@Override public void onConnectionSuspended(int i) { | |
} | |
@Override public void onConnectionFailed(ConnectionResult connectionResult) { | |
LogUtil.logDebugMessage(TAG, "Failed to connect to Google API Services."); | |
} | |
//</editor-fold> | |
//<editor-fold desc="Private Methods"> | |
private void checkIfReminderShouldbeShown() { | |
final Date currentDate = new Date(); | |
final Calendar cal = Calendar.getInstance(); | |
cal.setTime(currentDate); | |
// Don't show reminders if current time is not in (9am - 9pm) range. If outside of that range | |
// reset # of times reminder has been shown | |
final int hrOfDay = cal.get(Calendar.HOUR_OF_DAY); | |
if (hrOfDay < EARLIEST_OPERATING_HOUR || hrOfDay > LATEST_OPERATING_HOUR) { | |
LogUtil.logDebugMessage(TAG, "Outside of operating hours, resetting reminder count."); | |
Session.setRemindCount(0); | |
return; | |
} | |
// Don't show reminder if it is off. | |
if (!Session.isRemindOn()) { | |
LogUtil.logDebugMessage(TAG, "Remind is set to off by the user."); | |
return; | |
} | |
// If the number of reminders shown == selectedFrequency... don't show | |
final int selectedFrequency = Session.getFrequency(); | |
final int remindersShownCount = Session.getRemindCount(); | |
if (selectedFrequency == remindersShownCount) { | |
LogUtil.logDebugMessage(TAG, "Hit reminder limit."); | |
return; | |
} | |
// Probability based reasoning if we should show a reminder | |
final int remindFreq = DAILY_PING_COUNT / (1 + selectedFrequency); | |
final int normalizedHour = hrOfDay - EARLIEST_OPERATING_HOUR; | |
if (normalizedHour % remindFreq == 0) { | |
// Show reminder | |
showReminder(true); | |
} | |
} | |
/** | |
* Shows a reminder. NOTE: this is a blocking call. | |
* | |
* @param shouldIncrementRemindCount true if the reminder count in the session should be | |
* incremented, otherwise, false. | |
*/ | |
private void showReminder(final boolean shouldIncrementRemindCount) { | |
// Send message to wearable that it should launch MainActivity | |
final NodeApi.GetConnectedNodesResult nodesResult = | |
Wearable.NodeApi.getConnectedNodes(mGoogleApiClient).await(); | |
final List<Node> nodes = nodesResult.getNodes(); | |
for (Node node : nodes) { | |
// Try to send a message, synchronously | |
final MessageApi.SendMessageResult messageResult = Wearable.MessageApi.sendMessage( | |
mGoogleApiClient, | |
node.getId(), | |
DataPath.REMIND, | |
null).await(); | |
LogUtil.logDebugMessage(TAG, | |
"Sent to wearable: " + messageResult.getStatus().isSuccess()); | |
// Increment remind count? | |
if (shouldIncrementRemindCount) { | |
final int remindCount = Session.getRemindCount(); | |
Session.setRemindCount(remindCount + 1); | |
} | |
} | |
} | |
private void showReminder() { | |
showReminder(false); | |
} | |
private void initGooglePlayServices() { | |
mGoogleApiClient = new GoogleApiClient.Builder(this).addApi(Wearable.API) | |
.addConnectionCallbacks(this) | |
.addOnConnectionFailedListener(this) | |
.build(); | |
} | |
//</editor-fold> | |
} |
@fernandospr good point on mGoogleApiClient#blockingConnect()
. I haven't been able to get this to fail but I'm sure it will happen with the current implementation. Thanks!
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Does this work?
You are using mGoogleApiClient without knowing if it was connected or not.
You should perform your operations after it was connected.
However, because you are using an IntentService, once onHandleIntent finishes, it will call onDestroy. So if you call disconnect there it will not work.
So, I think you should use
mGoogleApiClient.blockingConnect()
and, if it was successful, perform your operations.