Skip to content

Instantly share code, notes, and snippets.

@arriolac
Last active July 27, 2016 16:48
Show Gist options
  • Save arriolac/8e98585ba3a0077a7add to your computer and use it in GitHub Desktop.
Save arriolac/8e98585ba3a0077a7add to your computer and use it in GitHub Desktop.
IntentService for displaying a reminder
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
Copy link

fernandospr commented Jun 24, 2016

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.

@arriolac
Copy link
Author

@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