mardi 10 mars 2015

Pending Intent firing at Uneven Time

I have created three pending intents in a service class - one pending intent should fire in the morning, other one at the afternoon and the final one at the evening. When the pending intent is fired it calls the broadcast receiver where the broadcast receiver checks my sqlite database and if there are any items present in the database it will display a notification to the user to read the items in the sqlite database.


The thing is that the pending intents are been fired at unusual time rather that firing at right time. Please check the code below:


NotificationService.java



public class NotificationService extends Service {

private String TAG = getClass().getSimpleName();

@Override
public IBinder onBind(Intent intent) {
return null;
}

@Override
public int onStartCommand(Intent intent, int flags, int startId) {

Calendar cur_cal = new GregorianCalendar();
cur_cal.setTimeInMillis(System.currentTimeMillis());//set the current time and date for this calendar

Calendar calMor = new GregorianCalendar();
calMor.add(Calendar.DAY_OF_MONTH, cur_cal.get(Calendar.DAY_OF_MONTH));
calMor.set(Calendar.HOUR_OF_DAY, 06);
calMor.set(Calendar.MINUTE, 00);
calMor.set(Calendar.SECOND, 01);
calMor.set(Calendar.MILLISECOND, 00);
calMor.set(Calendar.DATE, cur_cal.get(Calendar.DATE));
calMor.set(Calendar.MONTH, cur_cal.get(Calendar.MONTH));

Calendar calNoon = new GregorianCalendar();
calNoon.add(Calendar.DAY_OF_MONTH, cur_cal.get(Calendar.DAY_OF_MONTH));
calNoon.set(Calendar.HOUR_OF_DAY, 12);
calNoon.set(Calendar.MINUTE, 00);
calNoon.set(Calendar.SECOND, 01);
calNoon.set(Calendar.MILLISECOND, 00);
calNoon.set(Calendar.DATE, cur_cal.get(Calendar.DATE));
calNoon.set(Calendar.MONTH, cur_cal.get(Calendar.MONTH));

Calendar calEven = new GregorianCalendar();
calEven.add(Calendar.DAY_OF_MONTH, cur_cal.get(Calendar.DAY_OF_MONTH));
calEven.set(Calendar.HOUR_OF_DAY, 18);
calEven.set(Calendar.MINUTE, 00);
calEven.set(Calendar.SECOND, 01);
calEven.set(Calendar.MILLISECOND, 00);
calEven.set(Calendar.DATE, cur_cal.get(Calendar.DATE));
calEven.set(Calendar.MONTH, cur_cal.get(Calendar.MONTH));

Intent inteMor = new Intent(this, NotificationPublisher.class);
AlarmManager alrmManagerMor = (AlarmManager) getSystemService(ALARM_SERVICE);
// Pending Intent for Morning
PendingIntent penIntMor = PendingIntent.getBroadcast(this, 0, inteMor, PendingIntent.FLAG_CANCEL_CURRENT);
//set from today morning
alrmManagerMor.setRepeating(AlarmManager.RTC_WAKEUP,
calMor.getTimeInMillis(), (24 * 60 * 60 + 1) * 1000,
penIntMor);

Intent inteAft= new Intent(this, NotificationPublisher.class);
AlarmManager alrmManagerAft = (AlarmManager) getSystemService(ALARM_SERVICE);
// Pending Intent for Afternoon
PendingIntent penIntNoon = PendingIntent.getBroadcast(this, 1, inteAft, PendingIntent.FLAG_CANCEL_CURRENT);
//set from today afternoon
alrmManagerAft.setRepeating(AlarmManager.RTC_WAKEUP,
calNoon.getTimeInMillis(), (24 * 60 * 60 + 1) * 1000,
penIntNoon);

Intent inteEve= new Intent(this, NotificationPublisher.class);
AlarmManager alrmManagerEve = (AlarmManager) getSystemService(ALARM_SERVICE);
// Pending Intent for Evening
PendingIntent penIntEve = PendingIntent.getBroadcast(this, 2, inteEve, PendingIntent.FLAG_CANCEL_CURRENT);
//set from today evening
alrmManagerEve.setRepeating(AlarmManager.RTC_WAKEUP,
calEven.getTimeInMillis(), (24 * 60 * 60 + 1) * 1000,
penIntEve);

System.out.println("Fired NotificationService");
return Service.START_NOT_STICKY;
}/**/

}


This is the service where pending intents are fired to call the broadcast receiver.


NotificationPublisher.java



public class NotificationPublisher extends BroadcastReceiver {

private DBAdapter dbAdapter;
private Cursor cursor;

private String TAG = getClass().getSimpleName();

@TargetApi(Build.VERSION_CODES.JELLY_BEAN)
@Override
public void onReceive(Context context, Intent intent) {


System.out.println("Received Alarm");
Log.i(TAG, "Received Alarm");

dbAdapter = new DBAdapter(context);
dbAdapter.openDatabase();
cursor = dbAdapter.getUpdatedRecords();
cursor.moveToFirst();

int records_count = cursor.getCount();

if (records_count != 0) {

int donecount = 0;
for (int i = 0; i < records_count; i++) {
cursor.moveToPosition(i);
String doneStr = cursor.getString(cursor.getColumnIndex(DBAdapter.COL_DONE));
if (doneStr.equals("false"))
donecount++;
}

if (donecount != 0) {

// code for waking up the device in sleep mode
PowerManager pm = (PowerManager) context
.getSystemService(Context.POWER_SERVICE);
PowerManager.WakeLock wl = pm.newWakeLock(
PowerManager.PARTIAL_WAKE_LOCK, "");
wl.acquire();

Intent inte = new Intent(context, NotificationDetailsActivity.class);
PendingIntent pIntent = PendingIntent.getActivity(context, 0, inte, 0);
Notification noti = new Notification.Builder(context)
.setContentTitle("ThirteenDaysReminder")
.setSmallIcon(R.drawable.ic_launcher)
.setContentIntent(pIntent).build();
NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
// hide the notification after its selected
noti.flags |= Notification.FLAG_AUTO_CANCEL;
notificationManager.notify(0, noti);

wl.release();
}

}

dbAdapter.close();
cursor.close();

}


}


This is the Broadcast receiver class where it receives the broadcast and displays the notification to the user.


AndroidManifest.xml



<manifest xmlns:android="http://ift.tt/nIICcg"
package="in.co.ybn.thirteendaysreminder" >

<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.WAKE_LOCK"/>

<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name=".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>

<activity android:name=".ItemDetailsActivity"></activity>
<activity android:name=".NotificationDetailsActivity"/>
<activity android:name=".DoneActivity"/>

<receiver android:name=".servicesreceivers.NotificationPublisher"/>
<service android:name=".servicesreceivers.NotificationService"/>

<receiver android:name=".servicesreceivers.MyStartServiceReceiver"
android:process=":remote">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
</application>

</manifest>


I want the pending intent in the service class to be fired at right time to show the notifications instead of firing it at unusual time.


Aucun commentaire:

Enregistrer un commentaire