package com.realtrackandroid.reminderalarms;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.app.TaskStackBuilder;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.IBinder;
import android.os.PowerManager;
import android.support.v4.app.NotificationCompat;
import com.realtrackandroid.R;
import com.realtrackandroid.backend.activities.ActivitiesDAO;
import com.realtrackandroid.backend.activities.ParticipationDAO;
import com.realtrackandroid.backend.reminders.RemindersDAO;
import com.realtrackandroid.models.activities.Participation;
import com.realtrackandroid.views.participationsactive.RecordOrEditParticipationActivity;
/*
* Source: http://it-ride.blogspot.com/2010/10/android-implementing-notification.html
*/
public class NotificationService extends Service {
private PowerManager.WakeLock mWakeLock;
private int reminderid;
private static ArrayList<Participation> participation_data;
private Participation p;
/**
* This is deprecated, but you have to implement it if you're planning on supporting devices with
* an API level lower than 5 (Android 2.0).
*/
@Override
public void onStart(Intent intent, int startId) {
handleIntent(intent);
}
/**
* This is called on 2.0+ (API level 5 or higher). Returning START_NOT_STICKY tells the system to
* not restart the service if it is killed because of poor resource (memory/cpu) conditions.
*/
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
handleIntent(intent);
return START_NOT_STICKY;
}
/**
* In onDestroy() we release our wake lock. This ensures that whenever the Service stops (killed
* for resources, stopSelf() called, etc.), the wake lock will be released.
*/
public void onDestroy() {
super.onDestroy();
mWakeLock.release();
}
/**
* Simply return null, since our Service will not be communicating with any other components. It
* just does its work silently.
*/
@Override
public IBinder onBind(Intent intent) {
return null;
}
/**
* This is where we initialize. We call this when onStart/onStartCommand is called by the system.
* We won't do anything with the intent here, and you probably won't, either.
*/
private void handleIntent(Intent intent) {
// obtain the wake lock
PowerManager pm = (PowerManager) getSystemService(POWER_SERVICE);
mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "");
mWakeLock.acquire();
reminderid = intent.getExtras().getInt("reminderid");
// do the actual work, in a separate thread
new DisplayNotificationAsyncTask().execute();
}
private class DisplayNotificationAsyncTask extends AsyncTask<Void, Void, Void> {
@Override
protected Void doInBackground(Void... params) {
ParticipationDAO pDao = new ParticipationDAO(getApplicationContext());
// create a new participation event for the current time
p = new Participation();
p.setReminderid(reminderid);
p.setActivityid((new RemindersDAO(getApplicationContext()).getReminderWithId(reminderid))
.getActivityid());
p.setMen09(0);
p.setWomen09(0);
p.setDate(Calendar.getInstance().getTimeInMillis());
p.setServiced(false); // every new participation is un-serviced, by default
pDao.addParticipation(p);
NotificationReceiver.scheduleAlarm(getApplicationContext());
// show all unserviced participations for this reminder
participation_data = pDao.getAllUnservicedParticipationsForReminderId(reminderid);
for (Participation p : participation_data) {
int participationid = p.getId();
Calendar c = Calendar.getInstance();
DateFormat parser = new SimpleDateFormat("MM/dd/yyyy, EEEE, hh:mm aaa"); // example:
// 07/04/2013,
// Thursday, 6:13
// PM
c.setTimeInMillis(p.getDate());
// build a string to show the reminder date and time on the notification
// participation -> activity -> activity's title
String remindersText = new ActivitiesDAO(getApplicationContext()).getActivityWithId(
p.getActivityid()).getTitle()
+ ", ";
String dateTime = parser.format(p.getDate());
remindersText += dateTime;
// clicking on the notification must take the user to the record participation activity
Intent notifIntent = new Intent(getApplicationContext(),
RecordOrEditParticipationActivity.class);
notifIntent.putExtra("participationid", participationid);
notifIntent.putExtra("datetime", p.getDate());
PendingIntent pendingIntent = TaskStackBuilder
.create(getApplicationContext())
// add all of RecordOrEditParticipationActivity's parents to the stack,
// followed by RecordOrEditParticipationActivity itself
// this works in conjunction with parentActivityName in AndroidManifest.xml
.addNextIntentWithParentStack(notifIntent)
.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT);
// PendingIntent pendingIntent = PendingIntent.getActivity(getApplicationContext(),
// participationid, notifIntent, Intent.FLAG_ACTIVITY_NEW_TASK);
// build notification
Notification notificationBuilder = new NotificationCompat.Builder(getApplicationContext())
.setSmallIcon(R.drawable.icon).setContentTitle("Record Attendance")
.setContentText(remindersText).setContentIntent(pendingIntent).build();
// Hide the notification after it is clicked
notificationBuilder.flags |= Notification.FLAG_AUTO_CANCEL;
// display notification
NotificationManager notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
notificationManager.notify(participationid, notificationBuilder);
}
return null;
}
/**
* In here you should interpret whatever you fetched in doInBackground and push any
* notifications you need to the status bar, using the NotificationManager. I will not cover
* this here, go check the docs on NotificationManager.
* <p/>
* What you HAVE to do is call stopSelf() after you've pushed your notification(s). This will:
* 1) Kill the service so it doesn't waste precious resources 2) Call onDestroy() which will
* release the wake lock, so the device can go to sleep again and save precious battery.
*/
@Override
protected void onPostExecute(Void result) {
// handle your data
stopSelf();
}
}
}