Issue
So I'm pretty sure this a problem with Context and I know there are a lot of related questions out there (I've read them) but nothing I could find matched my specific case so hoping someone can help. I am building against API 28, min 24, language level 7 and running on an Android 7 Samsung tablet.
Situtation
In my project I have a Service that is intended to start on device boot, and it does. In order to verify this for myself, I had the Service issue a notification. Once I got it working I cleaned up the code and moved all the titles, names, and such into string resources in the strings.xml file.
Problem
The notification no longer appears. If I use hardcoded strings, everything is fine, if I try to use string resources the notification fails. My guess is that this has something to do with the Context (from which strings are requested) and it not having access to them. However, in the hardcoded strings case an icon resource (drawable) and a color resource are both queried successfully, so I'm unclear on what the difference is with strings. I could just hardcode the strings and call it a day but I feel that goes against Android best practices. I should also note that everything is fine with the resources if I actually launch the app, this is only a problem in the "on boot" condition.
Does anyone know what I'm doing wrong?
As requested: the code
This works:
public static void notify(Context context, String text){
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
NotificationChannel channel = new NotificationChannel(
"CHANNEL",
"My App",
NotificationManager.IMPORTANCE_DEFAULT);
channel.setDescription("Service status update channel");
NotificationManager notificationManager = context.getSystemService(NotificationManager.class);
notificationManager.createNotificationChannel(channel);
}
NotificationCompat.Builder n = new NotificationCompat.Builder(context, "CHANNEL")
.setContentTitle("Status")
.setContentText(text)
.setSmallIcon(R.drawable.ic_notification)
.setPriority(NotificationCompat.PRIORITY_LOW)
.setColor(ContextCompat.getColor(context, R.color.colorPrimary))
.setOngoing(true)
.setAutoCancel(false)
.setOnlyAlertOnce(true);
NotificationManager notificationManager = context.getSystemService(NotificationManager.class);
notificationManager.notify(notification_id, n.build());
}
This does not:
public static void notify(Context context, String text){
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
NotificationChannel channel = new NotificationChannel(
context.getString(R.string.notification_channel),
context.getString(R.string.notification_channel_name),
NotificationManager.IMPORTANCE_DEFAULT);
channel.setDescription(context.getString(R.string.notification_channel_desc));
NotificationManager notificationManager = context.getSystemService(NotificationManager.class);
notificationManager.createNotificationChannel(channel);
}
NotificationCompat.Builder n = new NotificationCompat.Builder(context, context.getString(R.string.notification_channel))
.setContentTitle(context.getString(R.string.notification_title))
.setContentText(text)
.setSmallIcon(R.drawable.ic_notification)
.setPriority(NotificationCompat.PRIORITY_LOW)
.setColor(ContextCompat.getColor(context, R.color.colorPrimary))
.setOngoing(true)
.setAutoCancel(false)
.setOnlyAlertOnce(true);
NotificationManager notificationManager = context.getSystemService(NotificationManager.class);
notificationManager.notify(notification_id, n.build());
}
I call this method from the Service's onStartCommand
@Override
public int onStartCommand(Intent intent, int flags, int startId){
UIHelper.notify(getApplicationContext(), "hello");
return IntentService.START_STICKY;
}
Solution
Replace your call to getApplicationContext() with this:
UIHelper.notify(this, "hello");
Also, use context.getResources().getString() instead of just context.getString().
Unfortunately, I don't really have an explanation for why it's like this.
My thoughts are that you're making a foreground Service, so the notification for that Service should belong to the Service itself (which extends Context) and not the Application.
In theory, context.getString() is exactly the same as context.getResources().getString() (it's actually just a proxy method), although it was only introduced in Marshmallow.
Answered By - TheWanderer
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.