Reputation: 775
The application is pretty simple. I have a regular app with all the activities etc...
I have a service that launches the first time the application starts and/or on device reboot.
I have a BroadcastReceiver set up to handle the notification intent and it's pretty basic as well and functions perfectly.
The notification works perfect when the display on the android device is on. But when I turn the screen off, the notifications are no longer created.
I am new to notifications so it's probably something simple I've overlooked, but I can't seem to find it.
In my service I construct a worker thread which contains a Timer which fires once a minute and takes a TimerTask as part of the schedule method:
@Override
public int onStartCommand(Intent intent, int flags, int startId)
{
boolean isStopping = false;
if (intent != null) // if the system has to shut us down, go down gracefully
{
String intentAction = intent.getStringExtra(AppData.BROADCAST_ACTION);
if (intentAction != null && intentAction.equals("android.intent.action.REBOOT"))
{
boolean isRebooting = intent.getBooleanExtra(AppData.SYSTEM_ACTION, false);
if (isRebooting)
{
isStopping = true;
stopSelf();
}
}
}
if (!isStopping && !_workerThread.isRunning())
{
_workerThread.run();
}
return Service.START_STICKY;
}
_timer.schedule(_service.getWorker(), startDelay, executionDelay);
The NotificationTask (TimerTask) ultimately gets fired every minute from the Timer. It then checks some logic to see if any of the notifications need to be created, if so, it creates and sends the notifications like this:
Notification notification = new NotificationCompat.Builder(_context)
.setContentTitle(getString(R.string.notification))
.setContentText(message)
.setLargeIcon(decodeResource(_context.getResources(), iconId))
.setSmallIcon(R.drawable.logo_mark)
.setTicker(ticker)
.setAutoCancel(true)
.setSound(getRingtone(ringtoneUrl))
.setVibrate(VIBRATION_PATTERN)
.setLights(0xfff89829, 300, 5000)
.setContentIntent(intent)
.build();
_notificationManager.notify(notificationId, notification);
The notifications are unique by the types of notifications and I don't care if the user has responded to one before I overwrite with the next. My problem is I don't get the notifications if the screen is off.
Please help.
I wanted to add code in case someone gets as stuck as I did.
Let's start with the AndroidManifest. Include 2 BroadcastReceivers and your service
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
<service android:name=".services.NotificationService"/>
<receiver android:name=".receivers.BootReceiver">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED"/>
</intent-filter>
</receiver>
<receiver android:name=".receivers.NotificationReceiver" />
The boot receiver is just going to schedule your Alarm when your device gets rebooted. You set it up to call your other receiver like so:
AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, new Intent(context, NotificationReceiver.class), 0);
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, Calendar.getInstance(), 60 * 1000, pendingIntent);
The main receiver is going to launch your service - your service should extend the IntentService instead of the regular Service. Here is the main receiver:
context.startService(new Intent(context, NotificationService.class));
And the service
public class NotificationService extends IntentService
{
public NotificationService()
{
super("Notification Service");
}
@Override
public void onHandleIntent(Intent intent)
{
// this is where I created my notifications
}
}
The last little trick is to create your AlarmManager again in your application. This will replace the AlarmManager that may have been created in the Boot Receiver. Notice PendingIntent.FLAG_CANCEL_CURRENT. This is done so when the user launches your application, your AlarmManager gets registered if it wasn't already registered on a device boot.
AlarmManager alarmMgr = (AlarmManager) this.getSystemService(Context.ALARM_SERVICE);
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0, new Intent(this, NotificationReceiver.class), PendingIntent.FLAG_CANCEL_CURRENT);
alarmMgr.setRepeating(AlarmManager.RTC_WAKEUP, Utils.getNow(), 60 * 1000, pendingIntent);
Hope this helps.
Upvotes: 1
Views: 3892
Reputation: 1002
Not saying you're doing it wrong, because I don't have much experience with Timers and TimerTasks, but I thought AlarmManager was the standard way of scheduling things to run in the future, when the screen is off, etc.
Upvotes: 2