I'm developing my custom calling app, like skype and I need to show "incoming call" screen to user, when I receive fcm message. I use full screen intent notification for this purpose. My code now is like this:
val intent = Intent(Intent.ACTION_MAIN, null)
val fakeIntent = Intent()
intent.flags = Intent.FLAG_ACTIVITY_NO_USER_ACTION or Intent.FLAG_ACTIVITY_NEW_TASK
intent.setClass(ctx, IncomingCallActivity::class.java!!)
val pendingIntent = PendingIntent.getActivity(ctx, 1, intent, 0)
val pendingIntent2 = PendingIntent.getActivity(ctx, 1, fakeIntent, PendingIntent.FLAG_ONE_SHOT)
val builder = Notification.Builder(ctx)
builder.setOngoing(true)
builder.setPriority(Notification.PRIORITY_HIGH)
// Set notification content intent to take user to fullscreen UI if user taps on the
// notification body.
builder.setContentIntent(pendingIntent)
// Set full screen intent to trigger display of the fullscreen UI when the notification
// manager deems it appropriate.
builder.setFullScreenIntent(pendingIntent, true)
// Setup notification content.
builder.setSmallIcon(R.mipmap.ic_launcher)
builder.setContentTitle("Call from Vitalii")
builder.setContentText("Your notification content.")
builder.setAutoCancel(true)
// Use builder.addAction(..) to add buttons to answer or reject the call.
val acceptAction = Notification.Action.Builder(Icon.createWithResource(ctx, R.drawable.ic_launch), "Accept", pendingIntent).build()
val declineAction = Notification.Action.Builder(Icon.createWithResource(ctx, R.drawable.ic_launch), "Decline", pendingIntent2).build()
builder.addAction(acceptAction)
builder.addAction(declineAction)
val notificationManager = ctx.getSystemService(
NotificationManager::class.java)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
val channel = NotificationChannel("callnotification", "Incoming Calls", NotificationManager.IMPORTANCE_MAX)
val ringtoneUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_RINGTONE);
channel.setSound(ringtoneUri, AudioAttributes.Builder()
.setUsage(AudioAttributes.USAGE_NOTIFICATION_RINGTONE)
.setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION)
.build())
notificationManager.createNotificationChannel(channel)
builder.setChannelId("callnotification")
}
val notification = builder.build()
notification.flags = Notification.FLAG_INSISTENT
currentNotificationId = Random().nextInt(500)
intent.putExtra("notifid", currentNotificationId)
notificationManager.notify("callnotification", currentNotificationId, notification)
And when screen is unlocked I receive calling notification with buttons to accept the call and decline. But when screen is locked I receive only sound and vibration, but not the custom screen with buttons like in telegram, whatsup and viber. How can I show such custom screen when device is locked?
Add following code in your CallActivity:
getWindow().addFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED| WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON|WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
Related
I have 3 samsung S10 devices, on two of which this problem occurs:
If there is a notification present in the system tray that belongs to the app, it takes the phone about 5 seconds to turn on the screen when clicking the power button.
If there is no notification in the system tray, the screen turns on immediately.
If you manually remove the notification from the system tray, without opening the app, it fixes the issue with the delay in turning on the screen.
What could be causing this problem?
There could only be 1 notification, each new notification replaces the old one.
All the notification does is open the app.
The problem is apparent without opening the app, just having the notification in the tray and the app is not in the background is enough to cause the problem.
The problem is not apparent on any other device that I have.
This is the code that loads the notification into the system tray once it arrives via firebase messaging
private fun sendNotification(message: RemoteMessage) {
val intent = this.packageManager.getLaunchIntentForPackage(this.packageName)
intent?.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
val pendingIntent =
PendingIntent.getActivity(applicationContext, Random().nextInt(), intent, PendingIntent.FLAG_UPDATE_CURRENT)
val gson = Gson()
val jsonData = gson.toJson(message.data)
val data = gson.fromJson(jsonData, NotificationPayload::class.java)
if (data.isEmpty()) {
Timber.i("Was supposed to display notification, but there was no data to display")
return
}
val defaultSoundUri: Uri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION)
val notificationBuilder = NotificationCompat.Builder(this, context.getString(R.string.app_name))
.setSmallIcon(R.drawable.ic_notification) //
.setContentTitle(data.title) //
.setContentText(data.body) //
.setColor(ContextCompat.getColor(context, R.color.very_dark_blue)).setAutoCancel(true) //
.setSound(defaultSoundUri) //
.setOnlyAlertOnce(true) //
.setContentIntent(pendingIntent) as NotificationCompat.Builder
val notificationManager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
val importance = when(ApplicationForegroundListener.isApplicationForeground()) {
true -> NotificationManager.IMPORTANCE_DEFAULT
else -> NotificationManager.IMPORTANCE_HIGH
}
notificationBuilder.priority = importance
notificationBuilder.setVibrate(LongArray(0))
// Since android Oreo notification channel is needed.
val channel = NotificationChannel(context.getString(R.string.app_name),
context.getString(R.string.app_name),
importance)
notificationManager.createNotificationChannel(channel)
notificationManager.notify(0 /* ID of notification */, notificationBuilder.build())
}
The issue was the size of the notification icon in dp.
I needed to scale it down to 48x48 to fix it.
I am sending a notification to an Android device with my Java backend.
The Android device receives the notification and when I click on it, it simply opens my app.
So far so good, but what I would like to achieve is to be able to read the data from the Firebase message in the onCreate() method of the MainActivity class. How would that be possible?
private fun sendNotification(messageBody: String) {
val intent = Intent(this, MainActivity::class.java)
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
val pendingIntent = PendingIntent.getActivity(this, 0 /* Request code */, intent,
PendingIntent.FLAG_ONE_SHOT)
val channelId = "" // TODO CHANNEL ID NEEDED
val defaultSoundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION)
val notificationBuilder = NotificationCompat.Builder(this, channelId)
.setContentText(messageBody)
.setAutoCancel(true)
.setSound(defaultSoundUri)
.setContentIntent(pendingIntent)
val notificationManager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
// Since android Oreo notification channel is needed.
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
val channel = NotificationChannel(channelId,
"Channel human readable title",
NotificationManager.IMPORTANCE_DEFAULT)
notificationManager.createNotificationChannel(channel)
}
notificationManager.notify(0 /* ID of notification */, notificationBuilder.build())
}
This doesn't log anything for me (in onCreate()):
if (getIntent() != null) {
val dataBundle = getIntent().extras
Log.d("data bundle", dataBundle.toString())
}
At first, check the 2 different types of notifications that you can send. link
Depending on each type and the state of your app (background or Foreground) you cannot always take the data from a Notification, check this for more link2.
When your application gets a notification there is a service with a method you can override to get the data. The method is called OnMessageReceived(RemoteMessage), you can find more info about the service at link2.
That's the way to get the data of a notification. If you want the data on your Activity there are some ways you could achieve that. You could try to save them at a Database(persistent) or at SharedPreferences and access them when your Activity starts or you could pass the data through the bundle to the activity you are about to open(Deeplinks), check this stackoverflow answer.
I am building a Voip app in android. Everything is working fine but I am not able to figure out how to accept and reject calls.
I use TelephoneManager#addNewIncomingCall to report new calls to the system. After that, I created a Connection object in ConnectionService#onCreateIncomingConnection and returned it. The onShowIncomingCallUi gets called and I create a notification this way:
val intent = Intent(context, TokboxActivity::class.java).apply {
flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
this.putExtras(this#Call.extras)
}
val pendingIntent = PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT)
val notification = NotificationCompat.Builder(context, "OKDOK")
.setSmallIcon(R.drawable.common_full_open_on_phone)
.setContentTitle("OKDOK")
.setContentText("Incoming call from ${extras.getString("docName")}")
.setPriority(NotificationCompat.PRIORITY_MAX)
.setCategory(NotificationCompat.CATEGORY_CALL)
.setFullScreenIntent(pendingIntent, true)
.build()
notification.flags = notification.flags or NotificationCompat.FLAG_INSISTENT
val notificationManager = context.getSystemService(
NotificationManager::class.java)
notificationManager.notify("OKDOK", 0, notification)
I am getting the notification too. But I have two buttons in TokboxActivity. I want them to accept and reject the call. How do I implement that?
I set on my application the notification every 7 hours in this way:
alarmManager = getSystemService(Context.ALARM_SERVICE) as AlarmManager
val intent = Intent(this, AlarmBroadcastReceiver::class.java)
pendingIntent = PendingIntent.getBroadcast(this, REQUEST_CODE, intent, PendingIntent.FLAG_UPDATE_CURRENT)
// Setting the specific time for the alarm manager to trigger the intent, in this example, the alarm is set to go off at 23:30, update the time according to your need
val calendar = Calendar.getInstance()
val next= calendar.get(Calendar.HOUR_OF_DAY) + 7
calendar.timeInMillis = System.currentTimeMillis()
calendar.set(Calendar.HOUR_OF_DAY, next)
calendar.set(Calendar.MINUTE, 0)
calendar.set(Calendar.SECOND, 0)
// Starts the alarm manager
alarmManager.setRepeating(
AlarmManager.RTC_WAKEUP,
calendar.timeInMillis,
AlarmManager.INTERVAL_DAY,
pendingIntent
)
with this class AlarmBroadcastReceiver :
class AlarmBroadcastReceiver : BroadcastReceiver() {
override fun onReceive(context: Context?, intent: Intent?) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
// Create the NotificationChannel
val name = "Alarme"
val descriptionText = "Detalhes do Alarme"
val importance = NotificationManager.IMPORTANCE_DEFAULT
val mChannel = NotificationChannel("AlarmId", name, importance)
mChannel.description = descriptionText
val notificationManager = context?.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
notificationManager.createNotificationChannel(mChannel)
}
// Create the notification to be shown
val mBuilder = NotificationCompat.Builder(context!!, "AlarmId")
.setSmallIcon(R.mipmap.ic_food)
.setContentTitle("Synchronize Fitbit")
.setContentText("Synchronize Fitbit data and log-in SugarFree for don't lose daily data")
.setAutoCancel(true)
.setPriority(NotificationCompat.PRIORITY_DEFAULT)
// Get the Notification manager service
val am = context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
// Generate an Id for each notification
val id = System.currentTimeMillis() / 1000
// Show a notification
am.notify(id.toInt(), mBuilder.build())
The notifications working well, I enter in the application, set the alarm and after 7 hours arrive the notification and so on. I wish that when arrive the notification i can click on it and open the app (maybe in my current home activity) so this alarm wish set automatically after 7 hours.
I saw that I must modify the pendingIntent with my home intent... but I have a
val intent = Intent(this, AlarmBroadcastReceiver::class.java)
that need to call the Alarm Receiver class.
Can anyone help me out?
All you need is to add .setContentIntent in your notification builder.
// Create the notification to be shown
val mBuilder = NotificationCompat.Builder(context!!, "AlarmId")
.setSmallIcon(R.mipmap.ic_food)
.setContentTitle("Synchronize Fitbit")
.setContentText("Synchronize Fitbit data and log-in SugarFree for don't lose daily data")
.setAutoCancel(true)
.setContentIntent(PendingIntent.getActivity(
context, // Context from onReceive method.
0,
Intent(context, HomeActivity::class.java), // Activity you want to launch onClick.
0
)
)
.setPriority(NotificationCompat.PRIORITY_DEFAULT)
.build()
You can find out more here the docs have more information about how to handle tasks such as only single Activity opens at a time.
You need create and set pending intent -
// Create an Intent for the activity you want to start
val resultIntent = Intent(this, YourMainActivity::class.java)
// Create the TaskStackBuilder
val resultPendingIntent: PendingIntent? = TaskStackBuilder.create(this).run {
// Add the intent, which inflates the back stack
addNextIntentWithParentStack(resultIntent)
// Get the PendingIntent containing the entire back stack
getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT)
}
and then set it -
val builder = NotificationCompat.Builder(this, CHANNEL_ID).apply {
setContentIntent(resultPendingIntent)
...
}
with(NotificationManagerCompat.from(this)) {
notify(NOTIFICATION_ID, builder.build())
}
Hope this will work for you.
I want to show this notification as pop-up window or alert dialogue on the lock screen.
public void onMessageReceived(RemoteMessage remoteMessage) {
super.onMessageReceived(remoteMessage);
String title = remoteMessage.getNotification().getTitle();
String body = remoteMessage.getNotification().getBody();
Map<String, String> extraData = remoteMessage.getData();
String brandID = extraData.get("brandID");
String category = extraData.get("category");
Uri defaultSoundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
NotificationCompat.Builder builder = new NotificationCompat.Builder(this, "TAC")
.setContentText(body)
.setContentTitle(title)
.setSound(defaultSoundUri)
.setDefaults(Notification.DEFAULT_ALL) // must requires VIBRATE permission
.setPriority(NotificationCompat.PRIORITY_HIGH) //must give priority to High, Max which will considered as heads-up notification
.setDefaults(Notification.DEFAULT_ALL)
.setSmallIcon(R.drawable.ic_launcher_background);
Intent intent;
if(category.equals("shoes")){
intent = new Intent(this, ReceiveNotification.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
}
else {
intent = new Intent(this, ReceiveNotification.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
}
intent.putExtra("brandID", brandID);
intent.putExtra("category", category);
PendingIntent pendingIntent
= PendingIntent.getActivity(this, 10, intent, PendingIntent.FLAG_UPDATE_CURRENT);
builder.setContentIntent(pendingIntent);
NotificationManager manager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.O){
NotificationChannel notificationChannel = new NotificationChannel("TAC", "demo", NotificationManager.IMPORTANCE_HIGH);
manager.createNotificationChannel(notificationChannel);
}
int id = (int) System.currentTimeMillis();
manager.notify(id, builder.build());
}
To control the level of detail visible in the notification from the lock screen, call setVisibility() and specify one of the following values:
VISIBILITY_PUBLIC shows the notification's full content.
VISIBILITY_SECRET doesn't show any part of this notification on the lock screen.
VISIBILITY_PRIVATE shows basic information, such as the notification's icon and the content title, but hides the notification's full content.
When VISIBILITY_PRIVATE is set, you can also provide an alternate version of the notification content which hides certain details. For example, an SMS app might display a notification that shows You have 3 new text messages but hides the message contents and senders. To provide this alternative notification, first create the alternative notification with NotificationCompat.Builder as usual. Then attach the alternative notification to the normal notification with setPublicVersion().
However, the user always has final control over whether their notifications are visible on the lock screen and can even control that based on your app's notification channels.
For more detail click here