I am using the following to present notifications to users on Android which currently works fine but I am having an issue that the notification appears in the status bar but does not come up as a heads up like a Facebook or WhatsApp notification does on the device? I get the notification but have to pull down on the status bar to view it. I am wondering is there a way to make this appear on the top of the screen in bubble format or is this something that varies between phone settings?
Code is attached below:
MainActivity
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
addNotification(10,"eventname","roomname");
addNotification(25,"eventname2","roomname2");
}
public void addNotification(int test, String test2, String test3){
AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(this, AlarmReceiver.class);
intent.putExtra("test",test2);
intent.putExtra("test2",test3);
final int _id = 50;
Random random = new Random();
final int randomInt = random.nextInt();
System.out.println("random integer:" + randomInt);
PendingIntent appIntent = PendingIntent.getBroadcast(this, randomInt, intent,PendingIntent.FLAG_UPDATE_CURRENT);
Calendar cal = Calendar.getInstance();
cal.add(Calendar.SECOND, test);
alarmManager.setExact(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), appIntent);
}
}
AlarmReceiver
public class AlarmReceiver extends BroadcastReceiver{
private static final String CHANNEL_ID = "com.singhajit.notificationDemo.channelId";
#Override
public void onReceive(Context context, Intent intent) {
Intent notificationIntent = new Intent(context, NotificationActivity.class);
String passed = intent.getStringExtra("test");
String passed2 = intent.getStringExtra("test2");
TaskStackBuilder stackBuilder = TaskStackBuilder.create(context);
stackBuilder.addParentStack(NotificationActivity.class);
stackBuilder.addNextIntent(notificationIntent);
String messageBody = "Your event " + passed + " is about to start in 15 minutes, in room "+passed2;
PendingIntent pendingIntent = stackBuilder.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT);
Notification.Builder builder = new Notification.Builder(context);
builder.setStyle(new Notification.BigTextStyle(builder)
.bigText(messageBody)
.setBigContentTitle("UA Reloaded Event Starting")
.setSummaryText("Tap To View Info"))
.setContentText(messageBody)
.setSmallIcon(R.drawable.ic_launcher)
.setDefaults(Notification.DEFAULT_SOUND | Notification.DEFAULT_VIBRATE)
.setPriority(Notification.PRIORITY_MAX);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
builder.setChannelId(CHANNEL_ID);
}
NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
String name = "NotificationDemo";
String description = "NotificationDemo";
int importance = NotificationManager.IMPORTANCE_HIGH; //Important for heads-up notification
NotificationChannel channel = new NotificationChannel("1", name, importance);
channel.setDescription(description);
channel.setShowBadge(true);
channel.setLockscreenVisibility(Notification.VISIBILITY_PUBLIC);
// NotificationManager notificationManager = getSystemService(NotificationManager.class);
notificationManager.createNotificationChannel(channel);
}
notificationManager.notify(0, builder.build());
}
}
If you still need an answer or for anyone else in order to show the notification as heads-up you have to add your channel id to the Builder.
.setChannelId(CHANNEL_ID)
like so:
val notification = NotificationCompat.Builder(getContext(), CHANNEL_ID)
.setSmallIcon(...)
.setContentTitle(getContext().getString(R.string.app_name))
...
.setChannelId(CHANNEL_ID)
...
.build()
And don't forget about the NotificationChannel importance and notification priority (set them to high/max if needed)
You updated your channel importance, which is not possible as stated in the documentation (https://developer.android.com/training/notify-user/channels#CreateChannel).
So your problem should be resolved by changing the channelId to something other than "1", as the ids for Channels must be unique.
Here is my kotlin class all you need is to call notificate(title: String, text: String) method, if you want it in java you can convert it
import android.annotation.SuppressLint
import android.app.Notification
import android.app.NotificationManager
import android.content.Context
import android.support.v4.app.NotificationCompat
import beacon.geisoft.org.beacontrakerkotlin_rebuild.R
import android.os.Build
import android.support.annotation.RequiresApi
import android.support.v4.content.ContextCompat.getSystemService
import android.app.NotificationChannel
import android.app.PendingIntent
import android.content.Intent
import android.graphics.Color
import android.media.RingtoneManager
import android.support.v4.content.ContextCompat.getSystemService
import android.support.v4.app.NotificationManagerCompat
import beacon.geisoft.org.beacontrakerkotlin_rebuild.activities.MainActivity
import android.preference.PreferenceManager
import android.content.SharedPreferences
class Notifications (var context: Context){
/**
* Send notification to the client device
* #param text String
*/
#SuppressLint("PrivateResource")
private fun notificate(title: String, text: String, id: Int, notificationManager: NotificationManager) {
val intent1 = Intent(context, MainActivity::class.java)
val pendingIntent = PendingIntent.getActivity(context, 123, intent1, PendingIntent.FLAG_UPDATE_CURRENT)
val defaultSoundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O && notificationManager.getNotificationChannel("beacon.geisoft.org.beacontraker_rebuild") == null) {
val chan2 = NotificationChannel("beacon.geisoft.org.beacontraker_rebuild", "Pazienti", NotificationManager.IMPORTANCE_HIGH)
chan2.lightColor = Color.BLUE
chan2.lockscreenVisibility = Notification.VISIBILITY_PUBLIC
notificationManager.createNotificationChannel(chan2)
/*
notificationManager.createNotificationChannel(NotificationChannel("beacon.geisoft.org.beacontraker_rebuild",
"Pazienti", NotificationManager.IMPORTANCE_HIGH))*/
}
val builder = NotificationCompat.Builder(context, "beacon.geisoft.org.beacontraker_rebuild")
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
builder.setContentTitle(title) // required
.setContentText(text) // required
.setDefaults(Notification.DEFAULT_ALL)
.setAutoCancel(true)
.setContentIntent(pendingIntent)
.setSmallIcon(R.drawable.beaconicon32) // required
.setLargeIcon(BitmapFactory.decodeResource(context.getResources(), R.drawable.beaconicon64))
.setSound(defaultSoundUri)
}else {
builder.setAutoCancel(true)
.setDefaults(Notification.DEFAULT_ALL)
.setContentTitle(title)
.setContentText(text)
.setContentIntent(pendingIntent)
.setSmallIcon(R.drawable.beaconicon32) // required
.setLargeIcon(BitmapFactory.decodeResource(context.getResources(), R.drawable.beaconicon64))
.setPriority(NotificationCompat.PRIORITY_HIGH)
.setSound(defaultSoundUri)
}
notificationManager.notify(id, builder.build());
}
fun notificate(title: String, text: String, id: Int){
val notificationManager = context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager?
notificate(title, text, id, notificationManager!!)
}
fun notificate(title: String, text: String){
val notificationManager = context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager?
var num: Int
do {
num = (Math.random() * 100).toInt()
} while (notificationExist(notificationManager!!, num))
notificate(title, text, num, notificationManager)
}
fun notificationExist(notificationManager: NotificationManager, id: Int): Boolean {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
val notifications =
notificationManager.activeNotifications
for (notification in notifications) {
if (notification.getId() == id) {
return true
}
}
}
return false
}
}
Related
I have implemented a broadcast receiver to ask the user to restart the app if it is killed. I have confirmed that the broadcast receiver is being called fine, and it runs the below line but for some reason, I am not getting any notification.
Here is the code,
class ForegroundLocationServicesRestarter : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent?) {
if (intent != null) {
if (intent.action != ForegroundLocationService.ACTION_RESTART_LOCATION_UPDATES) {
return
}
}
val notificationChannelId = "restartDeliveryApp"
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
val notificationChannel = NotificationChannel(notificationChannelId, "location_notif_chan", NotificationManager.IMPORTANCE_MAX)
val manager = context.getSystemService(LifecycleService.NOTIFICATION_SERVICE) as NotificationManager
manager.createNotificationChannel(notificationChannel)
}
val fullScreenIntent = Intent(context, DeliveryManActivity::class.java)
fullScreenIntent.putExtra("RESTART_TRIGGERED", true)
val fullScreenPendingIntent = PendingIntent.getActivity(
context, 0,
fullScreenIntent, PendingIntent.FLAG_UPDATE_CURRENT
)
NotificationCompat.Builder(context, notificationChannelId)
.setSmallIcon(R.drawable.ic_truck_red)
.setContentTitle(context.getString(R.string.restarter_title))
.setContentText(context.getString(R.string.restarter_message))
.setOngoing(true)
.setPriority(NotificationCompat.PRIORITY_HIGH)
.setCategory(NotificationCompat.CATEGORY_CALL)
.setFullScreenIntent(fullScreenPendingIntent, true)
.setVisibility(NotificationCompat.VISIBILITY_PRIVATE)
.build()
}
}
The notification channel is unique, the app has notification permission and also, full intent permission in the manifest. Any help is highly appreciated.
Plus there is already one service notification, does that impact this in any way?
was not pushing notifications into the system to display! Just need to do this!
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
val notificationChannel = NotificationChannel(notificationChannelId, "location_notif_chan", NotificationManager.IMPORTANCE_MAX)
val manager = context.getSystemService(LifecycleService.NOTIFICATION_SERVICE) as NotificationManager
manager.createNotificationChannel(notificationChannel)
}
val dmIntent = Intent(context, DeliveryManActivity::class.java)
dmIntent.putExtra("RESTART_TRIGGERED", true)
val dmPendingIntent = PendingIntent.getActivity(
context, 0, dmIntent, PendingIntent.FLAG_UPDATE_CURRENT
)
// Prepare a notification with vibration, sound and lights
val builder = NotificationCompat.Builder(context, notificationChannelId)
.setAutoCancel(true)
.setSmallIcon(R.drawable.ic_truck_red)
.setContentTitle(context.getString(R.string.restarter_title))
.setContentText(context.getString(R.string.restarter_message))
.setLights(Color.RED, 1000, 1000)
.setVibrate(longArrayOf(0, 400, 250, 400))
.setSound(RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION))
.setContentIntent(dmPendingIntent)
Pushy.setNotificationChannel(builder, context)
val notificationManager = context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
notificationManager.notify(7, builder.build()) // same notification id to override
package com.test.android
import android.app.*
import android.app.Notification.*
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.graphics.BitmapFactory
import android.graphics.Color
import android.os.Build
import android.os.Bundle
import androidx.core.app.NotificationCompat
import androidx.core.content.ContextCompat.getSystemService
import kotlinx.android.synthetic.main.fragment_profile.*
class AlarmBroadcastReceiver2: BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
showNotification(context)
}
internal fun showNotification(context: Context) {
val CHANNEL_ID = "1"// The id of the channel.
val name = context.getResources().getString(R.string.app_name)// The user-visible name of the channel.
val mBuilder: NotificationCompat.Builder
val notificationIntent = Intent(context, MainActivity::class.java)
val bundle = Bundle()
notificationIntent.putExtras(bundle)
notificationIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP )
val contentIntent = PendingIntent.getActivity(
context,
1,
notificationIntent,
PendingIntent.FLAG_UPDATE_CURRENT
)
val mNotificationManager = context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
if (android.os.Build.VERSION.SDK_INT >= 26)
{
val mChannel = NotificationChannel(
CHANNEL_ID,
name,
NotificationManager.IMPORTANCE_HIGH
)
mNotificationManager.createNotificationChannel(mChannel)
mBuilder = NotificationCompat.Builder(context)
.setSmallIcon(R.mipmap.ic_launcher)
.setLights(Color.RED, 300, 300)
.setChannelId(CHANNEL_ID)
.setVisibility(NotificationCompat.VISIBILITY_PUBLIC)
.setDefaults(DEFAULT_ALL)
.setVibrate(longArrayOf(1000, 1000, 1000, 1000, 1000))
.setAutoCancel(true)
//.setContentTitle("Selamat Pagi Jangan Lupa Untuk Absensi ")
.setStyle(
NotificationCompat.BigPictureStyle()
// Provide the bitmap to be used as the payload for the BigPicture notification.
.bigPicture(
BitmapFactory.decodeResource(
context.resources,
R.drawable.absence2_2
)
)
// Override the large icon when the big notification is shown.
.bigLargeIcon(
BitmapFactory.decodeResource(
context.resources,
R.mipmap.ic_launcher_round
)
)
// Overrides ContentTitle in the big form of the template.
.setBigContentTitle("Selamat Sore Jangan Lupa Untuk Absensi ")
// Set the first line of text after the detail section in the big form of the template.
.setSummaryText("Mohon melakukan absensi sore ini,Terima kasih")
)
}
else
{
mBuilder = NotificationCompat.Builder(context)
.setSmallIcon(R.mipmap.ic_launcher_round)
//.setPriority(NotificationCompat.PRIORITY_MAX)
.setPriority(Notification.PRIORITY_HIGH)
.setContentTitle("Title")
}
mBuilder.setContentIntent(contentIntent)
.setDefaults(DEFAULT_ALL)
mBuilder.setSmallIcon(R.mipmap.ic_launcher_round)
val note = mBuilder.build()
//mBuilder.setContentText("Yth Kepada Seluruh Karyawan dimohon untuk melakukan absensi di pagi ini,Terima Kasih")
mBuilder.setAutoCancel(true)
mNotificationManager.notify(1, mBuilder.build())
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
mBuilder.setSmallIcon(R.mipmap.ic_launcher_round)
} else {
mBuilder.setSmallIcon(R.mipmap.ic_launcher_round)
}
}
}
//notif4 16.00 evening
val _intent2 = Intent(this, AlarmBroadcastReceiver2::class.java)
val pendingIntent2 = PendingIntent.getBroadcast(this, 0, _intent2, 0)
val alarmManager2 = this.getSystemService(Context.ALARM_SERVICE) as AlarmManager
alarmManager2.cancel(pendingIntent2)
val calendar2 = Calendar.getInstance()
calendar2.setTimeInMillis(System.currentTimeMillis())
calendar2.set(Calendar.HOUR_OF_DAY, 16)
calendar2.set(Calendar.MINUTE, 0)
calendar2.set(Calendar.SECOND, 0)
//alarmManager2.setRepeating(AlarmManager.RTC_WAKEUP, calendar2.getTimeInMillis() /1000, AlarmManager.INTERVAL_DAY, pendingIntent2)
//alarmManager2.setExact(AlarmManager.RTC_WAKEUP,calendar2.getTimeInMillis()/1000 , pendingIntent2)
//alarmManager2.setInexactRepeating(AlarmManager.RTC_WAKEUP,calendar2.getTimeInMillis()/1000 ,AlarmManager.INTERVAL_DAY , pendingIntent2)
alarmManager2.setInexactRepeating(AlarmManager.RTC_WAKEUP,calendar2.getTimeInMillis() ,AlarmManager.INTERVAL_DAY , pendingIntent2)
I'm new to android development... trying to build application which send notification at specific time daily.First time if I tap on notification it opens application and notification doesn't come again. But after that if I open application it shows notification again.. how to stop showing it again? but show only at particular time?
I am trying to send notification daily at 10am.
The code works fine when app is running and in background, but it does not work when the app is terminated/Killed.
Here is what I am doing,
In Manifest:
<receiver
android:name=".ReminderBroadcast"
android:exported="true"
android:enabled="true"/>
My BroadcastReceiver:
public class ReminderBroadcast extends BroadcastReceiver
{
#Override
public void onReceive(Context context, Intent intent)
{
context.startService(new Intent(context, NotifyService.class));
}
}
My Service inside onCreate:
NotificationCompat.Builder builder = new NotificationCompat.Builder(getApplicationContext(), "notifyHackhshieldPP")
.setSmallIcon(R.drawable.logopp)
.setContentTitle("Hello")
.setContentText("Notification Test")
.setPriority(NotificationCompat.PRIORITY_DEFAULT);
NotificationManagerCompat notificationManager = NotificationManagerCompat.from(getApplicationContext());
notificationManager.notify(200, builder.build());
Then calling it:
private void setnotificationSendService()
{
AlarmManager am = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
//creating a new intent specifying the broadcast receiver
Intent i = new Intent(this, ReminderBroadcast.class);
//creating a pending intent using the intent
PendingIntent pi = PendingIntent.getBroadcast(this, 0, i, 0);
//setting the repeating alarm that will be fired every day
Calendar alarmStartTime = Calendar.getInstance();
alarmStartTime.set(Calendar.HOUR_OF_DAY, 20);
alarmStartTime.set(Calendar.MINUTE, 5);
alarmStartTime.set(Calendar.SECOND, 0);
am.setRepeating(AlarmManager.RTC_WAKEUP, (alarmStartTime.getTimeInMillis()), AlarmManager.INTERVAL_DAY, pi);
}
Monday, August 30, 2021
According to official documents, you can use alarmMgr.setInexactRepeating() but due to the system being busy it does not work properly I found another way to do this work. Use alarmMgr.set() for this purpose this will Wake up the device to fire a one-time (non-repeating) alarm. But when it triggers the device give it next date and time. It works properly when the app is terminated/Killedwork I am describing both methods just follow which one you want
SourceCode
Method 1
NotificationUtils.kt
import android.app.NotificationChannel
import android.app.NotificationManager
import android.app.PendingIntent
import android.content.Context
import android.content.Intent
import android.os.Build
import androidx.core.app.NotificationCompat
import androidx.core.app.NotificationManagerCompat
class NotificationUtils(context:Context) {
private var mContext = context
private lateinit var notificationBuilder: NotificationCompat.Builder
val notificationManager = NotificationManagerCompat.from(mContext)
private val CHANNEL_ID = "My_Notification_Channel"
init {
createNotificationChannel()
initNotificationBuilder()
}
fun launchNotification(){
with(NotificationManagerCompat.from(mContext)) {
// notificationId is a unique int for each notification that you must define
notificationManager.notify(0, notificationBuilder.build())
}
}
private fun createNotificationChannel() {
// Create the NotificationChannel, but only on API 26+ because
// the NotificationChannel class is new and not in the support library
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
val name = "Channel Name"
val descriptionText = "Channel Description"
val importance = NotificationManager.IMPORTANCE_DEFAULT
val channel = NotificationChannel(CHANNEL_ID, name, importance).apply {
description = descriptionText
}
// Register the channel with the system
val notifiManager: NotificationManager =
mContext.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
notifiManager.createNotificationChannel(channel)
}
}
private fun initNotificationBuilder() {
// Create an explicit intent for an Activity in your app
val sampleIntent = Intent(mContext, MainActivity::class.java).apply {
flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
}
val pendingIntent: PendingIntent = PendingIntent.getActivity(mContext, 0, sampleIntent, 0)
/***
* Notice that the NotificationCompat.Builder constructor requires that you provide a channel ID.
* This is required for compatibility with Android 8.0 (API level 26) and higher,
* but is ignored by older versions.
*/
notificationBuilder = NotificationCompat.Builder(mContext, CHANNEL_ID)
.setSmallIcon(R.drawable.notification_icon)
.setContentTitle("Notification Title")
.setContentText("Notification Body Text, Notification Body Text")
.setPriority(NotificationCompat.PRIORITY_DEFAULT)
// Set the intent that will fire when the user taps the notification
.setContentIntent(pendingIntent)
// Automatically removes the notification when the user taps it.
.setAutoCancel(true)
}
}
AlarmUtils.kt
import android.app.AlarmManager
import android.app.PendingIntent
import android.content.Context
import android.content.Intent
import java.util.*
class AlarmUtils(context: Context) {
private var mContext = context
private var alarmMgr: AlarmManager? = null
private var alarmIntent: PendingIntent
init {
alarmMgr = mContext.getSystemService(Context.ALARM_SERVICE) as AlarmManager
alarmIntent = Intent(mContext, AlarmReceiver::class.java).let { mIntent ->
// if you want more than one notification use different requestCode
// every notification need different requestCode
PendingIntent.getBroadcast(mContext, 100, mIntent, PendingIntent.FLAG_UPDATE_CURRENT)
}
}
fun initRepeatingAlarm(){
val calendar: Calendar = Calendar.getInstance().apply {
timeInMillis = System.currentTimeMillis()
set(Calendar.HOUR_OF_DAY, 10)
set(Calendar.MINUTE, 0)
set(Calendar.SECOND, 0)
}
alarmMgr?.setInexactRepeating(
AlarmManager.RTC_WAKEUP,
calendar.timeInMillis,
AlarmManager.INTERVAL_DAY,
alarmIntent
)
}
}
AlarmReceiver.kt
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
class AlarmReceiver:BroadcastReceiver() {
override fun onReceive(context: Context?, mIntent: Intent?) {
val notificationUtils = NotificationUtils(context!!)
notificationUtils.launchNotification()
}
}
AndroidManifest.xml
<receiver android:name=".AlarmReceiver" />
MainActivity.kt
val alarmUtils = AlarmUtils(this)
alarmUtils.initRepeatingAlarm()
Method 2
NotificationUtils.kt
import android.app.NotificationChannel
import android.app.NotificationManager
import android.app.PendingIntent
import android.content.Context
import android.content.Intent
import android.os.Build
import androidx.core.app.NotificationCompat
import androidx.core.app.NotificationManagerCompat
class NotificationUtils(context:Context) {
private var mContext = context
private lateinit var notificationBuilder: NotificationCompat.Builder
val notificationManager = NotificationManagerCompat.from(mContext)
private val CHANNEL_ID = "My_Notification_Channel"
init {
createNotificationChannel()
initNotificationBuilder()
}
fun launchNotification(){
with(NotificationManagerCompat.from(mContext)) {
// notificationId is a unique int for each notification that you must define
notificationManager.notify(0, notificationBuilder.build())
}
}
private fun createNotificationChannel() {
// Create the NotificationChannel, but only on API 26+ because
// the NotificationChannel class is new and not in the support library
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
val name = "Channel Name"
val descriptionText = "Channel Description"
val importance = NotificationManager.IMPORTANCE_DEFAULT
val channel = NotificationChannel(CHANNEL_ID, name, importance).apply {
description = descriptionText
}
// Register the channel with the system
val notifiManager: NotificationManager =
mContext.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
notifiManager.createNotificationChannel(channel)
}
}
private fun initNotificationBuilder() {
// Create an explicit intent for an Activity in your app
val sampleIntent = Intent(mContext, MainActivity::class.java).apply {
flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
}
val pendingIntent: PendingIntent = PendingIntent.getActivity(mContext, 0, sampleIntent, 0)
/***
* Notice that the NotificationCompat.Builder constructor requires that you provide a channel ID.
* This is required for compatibility with Android 8.0 (API level 26) and higher,
* but is ignored by older versions.
*/
notificationBuilder = NotificationCompat.Builder(mContext, CHANNEL_ID)
.setSmallIcon(R.drawable.notification_icon)
.setContentTitle("Notification Title")
.setContentText("Notification Body Text, Notification Body Text")
.setPriority(NotificationCompat.PRIORITY_DEFAULT)
// Set the intent that will fire when the user taps the notification
.setContentIntent(pendingIntent)
// Automatically removes the notification when the user taps it.
.setAutoCancel(true)
}
}
AlarmUtils.kt
import android.app.AlarmManager
import android.app.PendingIntent
import android.content.Context
import android.content.Intent
import java.util.*
class AlarmUtils(context: Context) {
private var mContext = context
private var alarmMgr: AlarmManager? = null
private var alarmIntent: PendingIntent
init {
alarmMgr = mContext.getSystemService(Context.ALARM_SERVICE) as AlarmManager
alarmIntent = Intent(mContext, AlarmReceiver::class.java).let { mIntent ->
// if you want more than one notification use different requestCode
// every notification need different requestCode
PendingIntent.getBroadcast(mContext, 100, mIntent, PendingIntent.FLAG_UPDATE_CURRENT)
}
}
fun initRepeatingAlarm(calendar: Calendar){
calendar.apply {
set(Calendar.HOUR_OF_DAY, 10)
set(Calendar.MINUTE, 0)
set(Calendar.SECOND, 0)
}
alarmMgr?.set( AlarmManager.RTC_WAKEUP,
calendar.timeInMillis,
alarmIntent)
}
AlarmReceiver.kt
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import java.util.*
class AlarmReceiver:BroadcastReceiver() {
override fun onReceive(context: Context?, mIntent: Intent?) {
val notificationUtils = NotificationUtils(context!!)
notificationUtils.launchNotification()
val calendar = Calendar.getInstance()
calendar.add(Calendar.DAY_OF_YEAR, 1)
val daysNextCalendar = calendar
val alarmUtils = AlarmUtils(context)
alarmUtils.initRepeatingAlarm(daysNextCalendar)
}
}
AndroidManifest.xml
<receiver android:name=".AlarmReceiver" />
MainActivity.kt
val calendar = Calendar.getInstance()
val alarmUtils = AlarmUtils(this)
alarmUtils.initRepeatingAlarm(calendar)
Reboot Device
If you want the alarm should work after rebooting the device you should do the following thing.
AlarmBootReceiver.kt
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import java.util.*
class AlarmBootReceiver : BroadcastReceiver(){
override fun onReceive(context: Context, intent: Intent) {
if (intent.action == "android.intent.action.BOOT_COMPLETED") {
val calendar = Calendar.getInstance()
val alarmUtils = AlarmUtils(context)
alarmUtils.initRepeatingAlarm(calendar)
}
}
}
AndroidManifest.xml
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
<receiver android:name=".AlarmBootReceiver"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED"/>
</intent-filter>
</receiver>
I already made a notification without intent to MainActivity and it works fine, but when I add that intent to my MainActivity the notification does not show anymore. Is there anything wrong with my code or do I need to change the manifest or add some code in my MainActivity?
Here is my code. I set it into two functions - setDailyReminder and showAlarmNotification.
fun setDailyReminder(context: Context, type: String, message: String) {
val alarmManager = context.getSystemService(Context.ALARM_SERVICE) as AlarmManager
val intent = Intent(context, MainActivity::class.java)
intent.putExtra(EXTRA_MESSAGE, message)
intent.putExtra(EXTRA_TYPE, type)
val timeArray =
TIME_DAILY.split(":".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray()
val calendar = Calendar.getInstance()
calendar.set(Calendar.HOUR_OF_DAY, Integer.parseInt(timeArray[0]))
calendar.set(Calendar.MINUTE, Integer.parseInt(timeArray[1]))
calendar.set(Calendar.SECOND, 0)
val pendingIntent = PendingIntent.getBroadcast(context,
ID_DAILY, intent, 0)
alarmManager.setInexactRepeating(
AlarmManager.RTC_WAKEUP,
calendar.timeInMillis,
AlarmManager.INTERVAL_DAY,
pendingIntent
)
Toast.makeText(context, "Daily reminder set up", Toast.LENGTH_SHORT).show()
}
private fun showAlarmNotification(
context: Context,
title: String,
message: String?,
notifId: Int
) {
val CHANNEL_ID = "Github App"
val CHANNEL_NAME = "Let's find favourite user on Github"
val notificationManagerCompat =
context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
val alarmSound = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION)
val builder = NotificationCompat.Builder(context, CHANNEL_ID)
.setSmallIcon(R.drawable.ic_play_circle_filled_white_24dp)
.setContentTitle(title)
.setContentText(message)
.setSound(alarmSound)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
val channel = NotificationChannel(
CHANNEL_ID,
CHANNEL_NAME,
NotificationManager.IMPORTANCE_DEFAULT
)
builder.setChannelId(CHANNEL_ID)
notificationManagerCompat.createNotificationChannel(channel)
}
val notification = builder.build()
notification.flags = notification.flags or Notification.FLAG_AUTO_CANCEL
notificationManagerCompat.notify(notifId, notification)
}
fun showNotification(context: Context,title: String, message:String, notifId: Int){
createNotificationChannel(context)
val intent = Intent(context, MainActivity::class.java)
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
val pendingIntent = PendingIntent.getActivity(this, 0,
intent,PendingIntent.FLAG_ONE_SHOT)
var builder = NotificationCompat.Builder(context, CHANNEL_ID)
.setSmallIcon(R.drawable.ic_play_circle_filled_white_24dp)
.setContentTitle(title)
.setContentText(message)
.setAutoCancel(true)
.setColor(resources.getColor(R.color.colorAccent))
.setPriority(NotificationCompat.PRIORITY_DEFAULT)
.setContentIntent(pendingIntent)
val notificationManagerCompat = NotificationManagerCompat.from(this)
notificationManagerCompat.notify(notifId, builder.build())
}
private fun createNotificationChannel(context: Context) {
// Create the NotificationChannel, but only on API 26+ because
// the NotificationChannel class is new and not in the support library
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
val name = "Test"
val descriptionText = "FCM"
val importance = NotificationManager.IMPORTANCE_DEFAULT
val channel = NotificationChannel(CHANNEL_ID, name, importance).apply {
description = descriptionText
}
// Register the channel with the system
val notificationManager: NotificationManager =
context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
notificationManager.createNotificationChannel(channel)
}
}
I'm using Kotlin and Android Studio to try and push a Notification in a test app. I followed the instructions in the Android Developers site on How to create a Notification (https://developer.android.com/training/notify-user/build-notification) but I seem to be doing something wrong as my Notification is not showing anywhere. Here's my code:
val intent = Intent(context, Profile::class.java)
val pendingIntent = PendingIntent.getActivity(this.context, 0, intent, 0);
val builder = NotificationCompat.Builder(this.context)
.setSmallIcon(R.drawable.notification_icon)
.setContentTitle("My notification")
.setContentText("Hello World!")
.setPriority(NotificationCompat.PRIORITY_MAX)
builder.setContentIntent(pendingIntent).setAutoCancel(true)
val mNotificationManager = message.context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
with(mNotificationManager) {
notify(123, builder.build())
I really don't know what I'm missing so I would be grateful for any help.
According to your code, you are not creating a Notification channel.
Notification channel is necessary from Android Oreo and above
So if you are running the app Android O and above devices without a notification channel, your notification won't show up.
Create Notification Channel
fun createNotificationChannel() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
val channelId = "all_notifications" // You should create a String resource for this instead of storing in a variable
val mChannel = NotificationChannel(
channelId,
"General Notifications",
NotificationManager.IMPORTANCE_DEFAULT
)
mChannel.description = "This is default channel used for all other notifications"
val notificationManager =
mContext.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
notificationManager.createNotificationChannel(mChannel)
}
}
Then create a notification using the same channelId while creating a notification.
createNotificationChannel()
val channelId = "all_notifications" // Use same Channel ID
val intent = Intent(context, Profile::class.java)
val pendingIntent = PendingIntent.getActivity(this.context, 0, intent, 0);
val builder = NotificationCompat.Builder(this.context, channelId) // Create notification with channel Id
.setSmallIcon(R.drawable.notification_icon)
.setContentTitle("My notification")
.setContentText("Hello World!")
.setPriority(NotificationCompat.PRIORITY_MAX)
builder.setContentIntent(pendingIntent).setAutoCancel(true)
val mNotificationManager =
message.context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
with(mNotificationManager) {
notify(123, builder.build())
Hope it helps.
try something like
val intent = Intent(context, Profile::class.java)
val pendingIntent = PendingIntent.getActivity(this.context, 0, intent, 0)
val mNotificationManager =
message.context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
mNotificationManager
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {//Don't forget this check
val channel = NotificationChannel (
channelId,
"my_notification",
NotificationManager.IMPORTANCE_HIGH
)
channel.enableLights(true)
channel.lightColor = Color.GREEN
channel.enableVibration(false)
val builder = NotificationCompat.Builder(this.context, "channel_id")
.setSmallIcon(R.drawable.notification_icon)
.setContentTitle("My notification")
.setContentText("Hello World!")
.setPriority(NotificationCompat.PRIORITY_MAX)
builder.setContentIntent(pendingIntent).setAutoCancel(true)
mNotificationManager.createNotificationChannel(channel)//Notice this
mNotificationManager.notify(123, builder.build())
}
else {
//Create Notifcation for below Oreo
}
Does your Logcat say something like:
E/NotificationManager: notifyAsUser: tag=null, id=123, user=UserHandle{0}
Also have a look at your line:
val intent = Intent(context, Profile::class.java)
IF all else fails create a test Actvity with hello world.
And then make the line look like:
val intent = Intent(context, testActivity::class.java)
Remember to add the activity to your Manifest
The following line
val pendingIntent = PendingIntent.getActivity(this.context, 0, intent, 0);
should not have a semi colon. Kotin doesn't need this.
Is Profile your Class or System Class?
Try out this method and you can pass message and title dynamically :
private fun showNotification(title: String?, body: String?) {
val intent = Intent(this, Profile::class.java)
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
val pendingIntent = PendingIntent.getActivity(this, 0, intent,
PendingIntent.FLAG_ONE_SHOT)
val soundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION)
val notificationBuilder = NotificationCompat.Builder(this)
.setSmallIcon(R.mipmap.ic_launcher)
.setContentTitle(title)
.setContentText(body)
.setAutoCancel(true)
.setSound(soundUri)
.setContentIntent(pendingIntent)
val notificationManager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
notificationManager.notify(0, notificationBuilder.build())
}