I've been working on push notifications and I am able to implement it and display it on status bar, the problem I am facing is that I want to display it even if the phone is lock, Under the lock screen where it says ("drag to unlock"), I have seen notifications like that but cant find any example to that.
Example:
Just like when you received a missed call , it will show it under the lock button on your screen.
Code:
String ns = Context.NOTIFICATION_SERVICE;
NotificationManager mNotificationManager = (NotificationManager) getSystemService(ns);
int icon = R.drawable.icon_launcher;
CharSequence tickerText = "MyApplication";
long when = System.currentTimeMillis();
Notification notification = new Notification(icon, tickerText, when);
notification.defaults |= Notification.DEFAULT_SOUND|Notification.DEFAULT_VIBRATE|Notification.DEFAULT_LIGHTS;;
CharSequence contentTitle = this.title;
CharSequence contentText = this.message;
Intent notificationIntent = new Intent(this, MainActivity.class);
PendingIntent contentIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0);
notification.setLatestEventInfo(context, contentTitle, contentText, contentIntent);
mNotificationManager.notify(NOTICE_ID, notification);
Create Notification using NotificationCompat.Builder
NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(this)
.setSmallIcon(R.drawable.ic_launcher) // notification icon
.setContentTitle("Notification!") // title for notification
.setContentText("Hello word") // message for notification
.setAutoCancel(true); // clear notification after click
Intent intent = new Intent(this, MainActivity.class);
PendingIntent pi = PendingIntent.getActivity(this,0,intent,Intent.FLAG_ACTIVITY_NEW_TASK);
mBuilder.setContentIntent(pi);
NotificationManager mNotificationManager =
(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
mNotificationManager.notify(0, mBuilder.build());
Push Notification on locked Screen
http://www.hongkiat.com/blog/android-lock-screen-notifications/
Create Notification using NotificationCompat.Builder but make sure to put visibility to public like
NotificationCompat.Builder builder = new NotificationCompat.Builder(this);
builder
.setContentTitle("Title")
.setContentText("content")
.setSmallIcon(R.mipmap.ic_launcher)
.setVisibility(NotificationCompat.VISIBILITY_PUBLIC);//to show content in lock screen
Have you tried creating the alertdialog with a flag? The flag_show_when_locked should do the trick.
Please refer to this thread, you should find a more detailed answer here.
Android Lock Screen Widget
I fixed this by adding this line to notification builder
builder.setOngoing(true);
It will also make notification not cancelable by user, but it solves the problem.
Credits to: Marian Klühspies (link)
The notifications you have seen may actually be widgets placed on a custom widget host lockscreen.
If you look at the android platform source code for InstallWidgetReceiver as late as 4.4.3 here:
https://android.googlesource.com/platform/packages/apps/Launcher3/+/master/src/com/android/launcher3/InstallWidgetReceiver.java
You will see this note by the author:
/**
* We will likely flesh this out later, to handle allow external apps to place widgets, but for now,
* we just want to expose the action around for checking elsewhere.
*/
And you can see that InstallWidgetReceiver.java is in fact not fleshed out by google in the same way as InstallShortCutReceiver.java is. So it seems at least up to 4.4.3 you cant add widgets to the native lock screen in the same way that you can for example add a shortcut to the homescreen using InstallShortCutReceiver.
Unless you build your own lockscreen app as a widget host and the user installs in lieu of the native you may be out of luck using a widget.
Another approach however is to just us an activity that sets getWindow().addFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED);
This will display your activity whether the screen is locked or not. Dismissing this activity when the screen is locked will display the locked screen.
Related
I'm making an android application, and I want to receive notifications when the application is closed, how can I do that? I've read also other posts where people ask it but i can't understand how to make it work, could you please try to explain this better?
I've also tried to make a countdownTimer and make the application do something when the timer reaches the 0 but it didn't work, 'cause obviusly when I close the application, I close the timer too.
use this code to make in app notification
NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(this)
.setSmallIcon(R.drawable.ic_launcher) // notification icon
.setContentTitle("Notification!") // title for notification
.setContentText("Hello word") // message for notification
.setAutoCancel(true); // clear notification after click
Intent intent = new Intent(this, MainActivity.class);
PendingIntent pi = PendingIntent.getActivity(this,0,intent,Intent.FLAG_ACTIVITY_NEW_TASK);
mBuilder.setContentIntent(pi);
NotificationManager mNotificationManager =
(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
mNotificationManager.notify(0, mBuilder.build());
I would like to have an ongoing notification for my ForegroundService that requires as small place as possible. I like the "Android System - USB charging this device" style, but I cannot find any example how to achieve this.
Can anyone point me in the right direction?
Update
The style is given to the notification if the channel is assigned the importance IMPORTANCE_MIN.
It looks like there is no way to use Androids built in style for notifications of IMPORTANCE_MIN to be used with a ForegroundService.
Here is the description of IMPORTANCE_MIN:
Min notification importance: only shows in the shade, below the fold. This should not be used with Service.startForeground since a foreground service is supposed to be something the user cares about so it does not make semantic sense to mark its notification as minimum importance. If you do this as of Android version Build.VERSION_CODES.O, the system will show a higher-priority notification about your app running in the background.
To display a compact single line notification like the charging notification, you have to create a Notification Channel with priority to IMPORTANCE_MIN.
#TargetApi(Build.VERSION_CODES.O)
private static void createFgServiceChannel(Context context) {
NotificationChannel channel = new NotificationChannel("channel_id", "Channel Name", NotificationManager.IMPORTANCE_MIN);
NotificationManager mNotificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
mNotificationManager.createNotificationChannel(channel);
}
And then create an ongoing notification like that:
public static Notification getServiceNotification(Context context) {
NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(context, "channel_id");
mBuilder.setContentTitle("One line text");
mBuilder.setSmallIcon(R.drawable.ic_notification);
mBuilder.setProgress(0, 0, true);
mBuilder.setOngoing(true);
return mBuilder.build();
}
NOTE
Please note that I've tested it with an IntentService instead of a Service, and it works. Also I've just checked setting a Thread.sleep() of 15 seconds and the notification is showing perfectly until the IntentService stops itself.
There are some images (sorry some texts are in Spanish, but I think the images are still useful):
And if you drag down and opens the notification, it's shown as follows:
EXTRA
If you notice that Android System shows a notification indicating all apps which are using battery (apps with ongoing services), you can downgrade the priority of this kind of notifications and it will appear as one line notifications like the charging notification.
Take a look at this:
Just long click on this notification, and select ALL CATEGORIES:
And set the importance to LOW:
Next time, this "battery consumption" notification will be shown as the charging notification.
You need to set the Notification priority to Min, the Notification Channel importance to Min, and disable showing the Notification Channel Badge.
Here's a sample of how I do it. I've included creating the full notification as well for reference
private static final int MYAPP_NOTIFICATION_ID= -793531;
NotificationManager notificationManager = (NotificationManager) context
.getSystemService(Context.NOTIFICATION_SERVICE);
String CHANNEL_ID = "myapp_ongoing";
CharSequence name = context.getString(R.string.channel_name_ongoing);
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
NotificationChannel channel = new NotificationChannel(CHANNEL_ID, name, NotificationManager.IMPORTANCE_MIN);
channel.setShowBadge(false);
notificationManager.createNotificationChannel(channel);
}
NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(
context, CHANNEL_ID)
.setSmallIcon(R.drawable.ic_stat_notification_add_reminder)
.setContentTitle(context.getString(R.string.app_name))
.setContentText(context.getString(R.string.create_new))
.setOngoing(true).setWhen(0)
.setChannelId(CHANNEL_ID)
.setPriority(NotificationCompat.PRIORITY_MIN);
// Creates an intent for clicking on notification
Intent resultIntent = new Intent(context, MyActivity.class);
...
// The stack builder object will contain an artificial back stack
// for the
// started Activity.
// This ensures that navigating backward from the Activity leads out
// of
// your application to the Home screen.
TaskStackBuilder stackBuilder = TaskStackBuilder.create(context);
// Adds the back stack for the Intent (but not the Intent itself)
stackBuilder.addParentStack(MyActivity.class);
// Adds the Intent that starts the Activity to the top of the stack
stackBuilder.addNextIntent(resultIntent);
PendingIntent resultPendingIntent = stackBuilder.getPendingIntent(0,
PendingIntent.FLAG_UPDATE_CURRENT);
mBuilder.setContentIntent(resultPendingIntent);
notificationManager.notify(MYAPP_NOTIFICATION_ID, mBuilder.build());
To answer the original question:
There seems to be no built-in way on Android O to get a single line, ongoing notification for a ForegroundService. One could try adding a custom design, but as different phones have different designs for notification, that solution is hardly a good one.
There is hope, however :)
On Android P the notification in a NotificationChannel of IMPORTANCE_LOW with a priority of PRIORITY_LOW is compacted to a single line even for a ForegroundService. Yeah!!
I made the size of foreground service notification smaller by creating an empty custom view like this:
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
</LinearLayout>
and then creating the notification like this:
RemoteViews notifiactionCollapsed = new RemoteViews(getPackageName(),R.layout.notification_collapsed);
Notification notification = new NotificationCompat.Builder(this,CHANNEL_ID)
.setSmallIcon(R.drawable.eq_icon)
.setCustomContentView(notifiactionCollapsed)
.setStyle(new NotificationCompat.DecoratedCustomViewStyle())
.setShowWhen(false)
.setContentIntent(pendingIntent)
.setPriority(NotificationCompat.PRIORITY_LOW)
.setOngoing(true)
.setVisibility(NotificationCompat.VISIBILITY_SECRET)
.build();
startForeground(Constants.NOTIFICATION_ID.FOREGROUND_SERVICE,
notification);
This helps in reducing the height of the notification but still I am not sure about how to hide the notification icon.
I would like to have an ongoing notification for my ForegroundService that requires as small place as possible. I like the "Android System - USB charging this device" style, but I cannot find any example how to achieve this.
Can anyone point me in the right direction?
Update
The style is given to the notification if the channel is assigned the importance IMPORTANCE_MIN.
It looks like there is no way to use Androids built in style for notifications of IMPORTANCE_MIN to be used with a ForegroundService.
Here is the description of IMPORTANCE_MIN:
Min notification importance: only shows in the shade, below the fold. This should not be used with Service.startForeground since a foreground service is supposed to be something the user cares about so it does not make semantic sense to mark its notification as minimum importance. If you do this as of Android version Build.VERSION_CODES.O, the system will show a higher-priority notification about your app running in the background.
To display a compact single line notification like the charging notification, you have to create a Notification Channel with priority to IMPORTANCE_MIN.
#TargetApi(Build.VERSION_CODES.O)
private static void createFgServiceChannel(Context context) {
NotificationChannel channel = new NotificationChannel("channel_id", "Channel Name", NotificationManager.IMPORTANCE_MIN);
NotificationManager mNotificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
mNotificationManager.createNotificationChannel(channel);
}
And then create an ongoing notification like that:
public static Notification getServiceNotification(Context context) {
NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(context, "channel_id");
mBuilder.setContentTitle("One line text");
mBuilder.setSmallIcon(R.drawable.ic_notification);
mBuilder.setProgress(0, 0, true);
mBuilder.setOngoing(true);
return mBuilder.build();
}
NOTE
Please note that I've tested it with an IntentService instead of a Service, and it works. Also I've just checked setting a Thread.sleep() of 15 seconds and the notification is showing perfectly until the IntentService stops itself.
There are some images (sorry some texts are in Spanish, but I think the images are still useful):
And if you drag down and opens the notification, it's shown as follows:
EXTRA
If you notice that Android System shows a notification indicating all apps which are using battery (apps with ongoing services), you can downgrade the priority of this kind of notifications and it will appear as one line notifications like the charging notification.
Take a look at this:
Just long click on this notification, and select ALL CATEGORIES:
And set the importance to LOW:
Next time, this "battery consumption" notification will be shown as the charging notification.
You need to set the Notification priority to Min, the Notification Channel importance to Min, and disable showing the Notification Channel Badge.
Here's a sample of how I do it. I've included creating the full notification as well for reference
private static final int MYAPP_NOTIFICATION_ID= -793531;
NotificationManager notificationManager = (NotificationManager) context
.getSystemService(Context.NOTIFICATION_SERVICE);
String CHANNEL_ID = "myapp_ongoing";
CharSequence name = context.getString(R.string.channel_name_ongoing);
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
NotificationChannel channel = new NotificationChannel(CHANNEL_ID, name, NotificationManager.IMPORTANCE_MIN);
channel.setShowBadge(false);
notificationManager.createNotificationChannel(channel);
}
NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(
context, CHANNEL_ID)
.setSmallIcon(R.drawable.ic_stat_notification_add_reminder)
.setContentTitle(context.getString(R.string.app_name))
.setContentText(context.getString(R.string.create_new))
.setOngoing(true).setWhen(0)
.setChannelId(CHANNEL_ID)
.setPriority(NotificationCompat.PRIORITY_MIN);
// Creates an intent for clicking on notification
Intent resultIntent = new Intent(context, MyActivity.class);
...
// The stack builder object will contain an artificial back stack
// for the
// started Activity.
// This ensures that navigating backward from the Activity leads out
// of
// your application to the Home screen.
TaskStackBuilder stackBuilder = TaskStackBuilder.create(context);
// Adds the back stack for the Intent (but not the Intent itself)
stackBuilder.addParentStack(MyActivity.class);
// Adds the Intent that starts the Activity to the top of the stack
stackBuilder.addNextIntent(resultIntent);
PendingIntent resultPendingIntent = stackBuilder.getPendingIntent(0,
PendingIntent.FLAG_UPDATE_CURRENT);
mBuilder.setContentIntent(resultPendingIntent);
notificationManager.notify(MYAPP_NOTIFICATION_ID, mBuilder.build());
To answer the original question:
There seems to be no built-in way on Android O to get a single line, ongoing notification for a ForegroundService. One could try adding a custom design, but as different phones have different designs for notification, that solution is hardly a good one.
There is hope, however :)
On Android P the notification in a NotificationChannel of IMPORTANCE_LOW with a priority of PRIORITY_LOW is compacted to a single line even for a ForegroundService. Yeah!!
I made the size of foreground service notification smaller by creating an empty custom view like this:
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
</LinearLayout>
and then creating the notification like this:
RemoteViews notifiactionCollapsed = new RemoteViews(getPackageName(),R.layout.notification_collapsed);
Notification notification = new NotificationCompat.Builder(this,CHANNEL_ID)
.setSmallIcon(R.drawable.eq_icon)
.setCustomContentView(notifiactionCollapsed)
.setStyle(new NotificationCompat.DecoratedCustomViewStyle())
.setShowWhen(false)
.setContentIntent(pendingIntent)
.setPriority(NotificationCompat.PRIORITY_LOW)
.setOngoing(true)
.setVisibility(NotificationCompat.VISIBILITY_SECRET)
.build();
startForeground(Constants.NOTIFICATION_ID.FOREGROUND_SERVICE,
notification);
This helps in reducing the height of the notification but still I am not sure about how to hide the notification icon.
What is the difference between those two?
I want to use the startForeground method and cannot use it with NotificationManager..
Thanks
A Notification is a class that represents either a persistent icon that goes in the status bar and is accessible through the launcher, turning on or flashing LEDs on the device, or alerting the user by flashing the backlight, playing a sound, or vibrating.
The Notification Manager is the class that allows you to add notifications to the system,
startForeground is a method of the Serivce class. For example inside your Service class you can have something like this.
Intent notificationIntent = new Intent(this, ActivityMain.class);
notificationIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT);
NotificationCompat.Builder builder = new NotificationCompat.Builder(this);
builder.setContentIntent(pendingIntent)
.setSmallIcon(R.drawable.ic_stat_play)
.setLargeIcon(BitmapFactory.decodeResource(getResources(), R.drawable.ic_launcher))
.setTicker(getString(R.string.app_name))
.setWhen(System.currentTimeMillis())
.setOngoing(true)
.setContentTitle(getString(R.string.app_name))
.setContentText(someText);
Notification notification = builder.build();
startForeground(1, notification);
A Notification is a description of what you want to occur to alert the user about something -- what icon goes in the status bar, what ringtone to play, etc.
NotificationManager is a system service that can show a Notification.
I want to use the startForeground methode and cannot use it with NotificationManager
Correct. Create a Notification using Notification.Builder (or NotificationCompat.Builder). See this project for an example of using startForeground().
I've been developing for Android for awhile but this is my first shot at notifications. I've got my notification setup as described in the Android SDK tutorial, but I can't figure out how to keep the notification displayed until my app is closed. I want to disable that little minus sign at the end of the notification. I don't want my notification to disappear when a user clicks it. I would think there would be a notification flag... but I can't seem to figure this out. I'm developing on Android SDK 2.2. I know this is a simple question, and I apologize if this answer is already on here... I wasn't able to find exactly what I was looking for.
// Create notification manager
String ns = Context.NOTIFICATION_SERVICE;
NotificationManager mNotificationManager = (NotificationManager) getSystemService(ns);
Notification notification = new Notification(R.drawable.ic_launcher, "Ready", System.currentTimeMillis());
Intent notificationIntent = new Intent(this, HomeActivity.class);
PendingIntent contentIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0);
// Make a notification
notification.setLatestEventInfo(getApplicationContext(), "Ready", "Select to manage your settings", contentIntent);
mNotificationManager.notify(0, notification);
You want FLAG_ONGOING_EVENT. Also try removing FLAG_NO_CLEAR and FLAG_AUTO_CANCEL if they are part of the defaults.