Reputation: 219
I'm currenty devepoling an Android Application that remembers the user to a daily action. The idea is, that the app gives a notification to the user if he did not already performed the action. The notification should appear every day at i.e. 3PM.
My Question is, how I can implement the check. I already found tutorials about how to use AlarmManager and NotificationManager, but these would remember the user even, if he already is finished. Is there a way to start the check instead of the Notification, and if the check says there should be a notification, it is published?
Upvotes: 1
Views: 2126
Reputation: 8371
You could save a shared preference that indicated the last time the user had completed the daily action. The when your alarm fires, you start a service that checks the status of the shared preference. If it was less than 1 day ago, then the user has done the daily action today.
Here's how you'd check:
SharedPreferences settings = getSharedPreferences(MainActivity.PREFS, MODE_PRIVATE);
if (System.currentTimeMillis() - settings.getLong("lastTimeActionDone", 0) < MILLISECS_PER_DAY) {
// Action done within last day
} else {
// Action not done within last day
}
Here's how you'd save the last time the action had been done:
SharedPreferences settings = getSharedPreferences(MainActivity.PREFS, MODE_PRIVATE);
SharedPreferences.Editor editor = null;
editor.putLong("lastTimeActionDone", System.currentTimeMillis());
editor.commit();
Here's a sample app that does most of what you want. As written, it just wakes up at the same time each day with that time being the time of day that the app was last started. So the one major piece missing is to make the alarm wake at a specific time each day. To get that part working, you'd need to a little date-time arithmetic when setting the (first) alarm time.
package com.example.dailycheck;
import android.app.Activity;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
public class MainActivity extends Activity {
private final static String TAG = "MainActivity";
public final static String PREFS = "PrefsFile";
private SharedPreferences settings = null;
private SharedPreferences.Editor editor = null;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main_activity);
// Save time of run:
settings = getSharedPreferences(PREFS, MODE_PRIVATE);
editor = settings.edit();
// First time running app?
if (!settings.contains("lastTimeActionDone"))
enableNotification(null);
Log.v(TAG, "Starting CheckRecentRun service...");
startService(new Intent(this, CheckActionDone.class));
}
public void doAction(View v) {
Log.v(TAG, "Recording time action done");
editor.putLong("lastTimeActionDone", System.currentTimeMillis());
editor.commit();
}
public void enableNotification(View v) {
editor.putBoolean("enabled", true);
editor.commit();
Log.v(TAG, "Notifications enabled");
}
public void disableNotification(View v) {
editor.putBoolean("enabled", false);
editor.commit();
Log.v(TAG, "Notifications disabled");
}
}
package com.example.dailycheck;
import android.app.AlarmManager;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.IBinder;
import android.util.Log;
public class CheckActionDone extends Service {
private final static String TAG = "CheckRecentPlay";
private static Long MILLISECS_PER_DAY = 86400000L;
private static long delay = 60000; // 1 minute (for testing)
// private static long delay = MILLISECS_PER_DAY; // 1 day
@Override
public void onCreate() {
super.onCreate();
Log.v(TAG, "Service started");
SharedPreferences settings = getSharedPreferences(MainActivity.PREFS, MODE_PRIVATE);
// Are notifications enabled?
if (settings.getBoolean("enabled", true)) {
// And was action not recently done?
Long lastTimeDone = settings.getLong("lastTimeActionDone", 0);
if ((System.currentTimeMillis() - lastTimeDone) >= delay) {
sendNotification();
} else {
Log.i(TAG, "Action recently done");
}
} else {
Log.i(TAG, "Notifications are disabled");
}
// Set an alarm for the next time this service should run:
setAlarm();
Log.v(TAG, "Service stopped");
stopSelf();
}
public void setAlarm() {
Intent serviceIntent = new Intent(this, CheckActionDone.class);
PendingIntent pi = PendingIntent.getService(this, 131313, serviceIntent,
PendingIntent.FLAG_CANCEL_CURRENT);
AlarmManager am = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
am.set(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + delay, pi);
Log.v(TAG, "Alarm set");
}
public void sendNotification() {
Intent mainIntent = new Intent(this, MainActivity.class);
@SuppressWarnings("deprecation")
Notification noti = new Notification.Builder(this)
.setAutoCancel(true)
.setContentIntent(PendingIntent.getActivity(this, 131314, mainIntent,
PendingIntent.FLAG_UPDATE_CURRENT))
.setContentTitle("Action Not Do")
.setContentText("You didn't do the daily action.")
.setDefaults(Notification.DEFAULT_ALL)
.setSmallIcon(R.drawable.ic_launcher)
.setTicker("You haven;t done the daily action; please do it now.")
.setWhen(System.currentTimeMillis())
.getNotification();
NotificationManager notificationManager
= (NotificationManager) this.getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(131315, noti);
Log.v(TAG, "Notification sent");
}
@Override
public IBinder onBind(Intent intent) {
return null;
}
}
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:onClick="doAction"
android:text="@string/do_action" />
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:onClick="enableNotification"
android:text="@string/enable" />
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:onClick="disableNotification"
android:text="@string/disable" />
</LinearLayout>
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">Come Back</string>
<string name="do_action">Do Action</string>
<string name="enable">Enable Notifications</string>
<string name="disable">Disable Notifications</string>
</resources>
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.dailycheck"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="11"
android:targetSdkVersion="19" />
<uses-permission android:name="android.permission.VIBRATE" />
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name="com.example.dailycheck.MainActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service
android:name="com.example.dailycheck.CheckActionDone" >
</service>
</application>
</manifest>
Upvotes: 2