I am creating an app which when needed would send a notification with sound. It is important that the notification would be heard even on silent or "do not disturb" so I want to ride the phone's Alarm volume.
I'm using and modifying code from an open source package react-native-alarm-notification
Here's some of my code-
// some code for creating the alarm object and getting the settings
// creating the builder
NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(context, channelID)
.setSmallIcon(smallIconResId)
.setContentTitle(title)
.setContentText(message)
.setTicker(alarm.getTicker())
.setPriority(NotificationCompat.PRIORITY_MAX)
.setAutoCancel(alarm.isAutoCancel())
.setVisibility(NotificationCompat.VISIBILITY_PUBLIC)
.setCategory(NotificationCompat.CATEGORY_ALARM)
.setSound(null)
.setDeleteIntent(createOnDismissedIntent(context, alarm.getId()));
if (alarm.isPlaySound()) {
// THE IMPORTANT BIT
mBuilder.setSound(RingtoneManager.getDefaultUri(RingtoneManager.TYPE_RINGTONE),
AudioManager.STREAM_ALARM);
}
...//more settings
// set tag and push notification
Notification notification = mBuilder.build();
String tag = alarm.getTag();
if (tag != null && !tag.equals("")) {
mNotificationManager.notify(tag, notificationID, notification);
} else {
Log.i(Constants.TAG, "Notification done");
mNotificationManager.notify(notificationID, notification);
}
The problem is that the notification still defaults to Android 13's notification sound setting, and not using the Alarm volume setting.
Well I don't know if what I tried to do is possible but I found a different solution.
Basically I created a separate audio interface using MediaPlayer, that whenever a notification is sent, it also starts an alarm, and when the notification is dismissed, it stops the alarm.
Related
I can't seem to figure out why I can'y get my actions to show up on a remote notification. I have seen several tutorials on making it happen, and followed them, still no actions show up. The end goal is to have a "Reply" action where you can type in a response and send a reply through the notification, much like the standard text message notification.
I couldn't get that to show up, so I decided to add a second action, that is just a basic action, neither are showing up. I'll post up my sendNotification method, hopefully someone can see what I am doing wrong...
private void sendNotification(String body, String id) {
Intent i;
PendingIntent pi;
if(user.role.equals(Strings.roleMember) { //This is just to separate logic
i = new Intent(this, NotificationReceiver.class);
pi = PendingIntent.getBroadcast(this, 0, i, 0);
} else {
i = new Intent(this, AgentChatActivity.class);
pi = PendingIntent.getActivity(this, 0, i, 0);
}
i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
i.putExtra(Strings.chatID, id);
RemoteInput input = new RemoteInput.Builder(Strings.textReply).setLabel("Reply").build();
NotificationCompat.Action replyAction = new NotificationCompat.Action.Builder(android.R.drawable.ic_dialog_info, "Reply", pi)
.addRemoteInput(input).build();
NotificationCompat.Builder builder = new NotificationCompat.Builder(this, Strings.channelID)
.setSmallIcon(R.drawable.ic_stat_notify)
.setContentTitle("New Message")
.setContentText(body)
.setAutoCancel(true)
.setCategory(NotificationCompat.CATEGORY_MESSAGE) //I have tried without this too
.setPriority(NotificationCompat.PRIORITY_MAX)
.addAction(replyAction)
.addAction(android.R.drawable.ic_dialog_alert, "reply", pi); //this is the second I added just to test
NotificationManager manager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
NotificationChannel channel = new NotificationChannel(Strings.channelID, "General Messages", NotificationManager.IMPORTANCE_HIGH);
manager.createNotificationChannel(channel);
}
manager.notify(0, builder.build());
}
According to everything I have seen online, that should have actions attached to the notification, however I run it in the emulator (Pixel 6 API 27) and the notification shows up, but no actions are on it. I have tried without the second action, I have tried with only the second action, nothing shows up, just the basic notification. My build settings are set to minSdk 21, compileSdk and targetSdk 33. I would be more than happy to post any more code or anything else anyone needs, I can't figure it out. Thank you.
I am sharing two images please have a look on it you will understand my problem
in fist image notification comes successfully as shown better me notification but
I want it to come and show first on main screen as shown in second image just this telegram notification.
public void onMessageReceived(RemoteMessage remoteMessage) {
super.onMessageReceived(remoteMessage);
Uri notification = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
Ringtone r = RingtoneManager.getRingtone(getApplicationContext(), notification);
// r.play();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
r.setLooping(false);
}
// vibration
Vibrator v = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE);
long[] pattern = {100, 300, 300, 300};
v.vibrate(pattern, -1);
int resourceImage = getResources().getIdentifier(remoteMessage.getNotification().getIcon(), "drawable", getPackageName());
NotificationCompat.Builder builder = new NotificationCompat.Builder(this, "CHANNEL_ID");
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
builder.setSmallIcon(R.mipmap.betterme);
} else {
builder.setSmallIcon(R.mipmap.betterme);
}
Intent resultIntent = new Intent(this, SplashScreen.class);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 1, resultIntent, PendingIntent.FLAG_UPDATE_CURRENT);
builder.setContentTitle(remoteMessage.getNotification().getTitle());
builder.setContentText(remoteMessage.getNotification().getBody());
builder.setContentIntent(pendingIntent);
builder.setStyle(new NotificationCompat.BigTextStyle().bigText(remoteMessage.getNotification().getBody()));
builder.setAutoCancel(true);
builder.setOngoing(true);
builder.setPriority(NotificationCompat.PRIORITY_MAX);
builder.setSound(notification);
mNotificationManager = (NotificationManager) getApplicationContext().getSystemService(Context.NOTIFICATION_SERVICE);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
String channelId = "Your_channel_id";
NotificationChannel channel = new NotificationChannel(
channelId,
"Channel human readable title",
NotificationManager.IMPORTANCE_HIGH);
AudioAttributes audioAttributes = new AudioAttributes.Builder()
.setUsage(AudioAttributes.USAGE_NOTIFICATION)
.build();
channel.setSound(notification, audioAttributes);
mNotificationManager.createNotificationChannel(channel);
builder.setChannelId(channelId);
}
mNotificationManager.notify(100, builder.build());
}
}
first image
second image
If I understand correctly, you would like to have a heads up notification.
Note, that the android system decides when to make a notification a heads up notification and has the final say - not you the developer. Here you can find some examples when it does so: https://developer.android.com/guide/topics/ui/notifiers/notifications#Heads-up
Make sure that your setup reflects these. From your sample it seems to be the case, but maybe you have changed the notification channel settings (from the app settings), which override your code preferences (the user has precedence over the app).
Additionally, note that if you swipe the heads up notification in a upward direction (not sideways), Android starts a cool off time, where no heads up notifications from that app appears for a few seconds (or more). You can try that with Telegram or any other app as well. After the cool-off time, it starts showing up again like a heads up notification. This is a way Android utilises to prevent apps to be annoying to users.
Seems there is no problem in the notification. But your channel is already created with normal notification and you update to IMPORTANCE_HIGH for NotificationChannel.
Once the channel is created with priority it cannot be changed. So you can either change the channel id or uninstall and reinstall and test it.
How can I switch all these settings on programmatically?
I noticed when you install WhatsApp they are all switched on in the beginning(look at the image below).
But I can not find a way to turn them on programmatically.
Here is how I send notifications:
private void sendNotification(Intent intent){
Context context = NotificationService.this;
//open the activity after the notification is clicked
Intent intent1 = new Intent(getApplicationContext(),MainActivity.class);
PendingIntent pIntent = PendingIntent.getActivity(context, 0, intent1, 0);
Notification.Builder builder = new Notification.Builder(context)
.setTicker("Notification")
.setContentTitle("Important Message")
.setContentText("This is an example of a push notification using a Navigation Manager")
.setSmallIcon(R.drawable.ic_add)
.setContentIntent(pIntent);
NotificationManager notificationManager = (NotificationManager) context.getSystemService(context.NOTIFICATION_SERVICE);
Uri alarmSound = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
//These are necessary for the notification to pop up
if(Build.VERSION.SDK_INT < Build.VERSION_CODES.O){
builder.setPriority(Notification.PRIORITY_MAX);
builder.setSound(alarmSound);
builder.setLights(Color.BLUE, 500, 500);
}
//after android O we must use notification channels
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
{
String channelId = "Your_channel_id";
NotificationChannel channel = new NotificationChannel(
channelId,
"Reminder to remind to review your notes",
NotificationManager.IMPORTANCE_HIGH);
if(alarmSound != null){
AudioAttributes att = new AudioAttributes.Builder()
.setUsage(AudioAttributes.USAGE_NOTIFICATION)
.setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION)
.build();
channel.setSound(alarmSound,att);
}
channel.setLightColor(Color.BLUE);
channel.enableVibration(true);
channel.setDescription("Hello Dear friends"); //this is to test what this is
channel.setLockscreenVisibility(Notification.VISIBILITY_PUBLIC);
channel.setVibrationPattern(new long[]{300, 300, 300});
notificationManager.createNotificationChannel(channel);
builder.setChannelId(channelId);
}
Notification notification = builder.build();
notificationManager.notify(0, notification);
}
I also added this permission to manifest:
<uses-permission android:name="android.permission.ACCESS_NOTIFICATION_POLICY" />
Update:
Using this code on the emulator, I get the heads-up notification. But on my Xiaomi device, there is no heads-up notification. It just appears on the status bar. If I manually turn on the floating notification (which you can see in the photo) then I will get heads-up notification. But they are switched off by default. When you install Whatsapp they are all switched on.
Is that a kind of privilege for Whatsapp as it is famout? or is there a way to do it?
By default, when you install a app, the system register's default notification channel (on low priority) that doesn't support head up notification by default, it's turned off. You can't control that.
But what you can do it create your own notification channel with highest priority and then register it on app run once.
After that just pass the channel Id with your notification builder so that system shows the head's up notification which you want.
More information can be found here https://developer.android.com/training/notify-user/channels
I have tried for this but unable to set these settings programmatically. Instead of this I have used following method to open notification settings screen to enable notification sounds/vibration.
private void openNotificationSettingsForApp(String channelId) {
// Links to this app's notification settings.
Intent intent = new Intent();
intent.setAction("android.settings.APP_NOTIFICATION_SETTINGS");
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.O && channelId!=null){
intent.setAction(Settings.ACTION_CHANNEL_NOTIFICATION_SETTINGS);
intent.putExtra(Settings.EXTRA_CHANNEL_ID,channelId);
intent.putExtra("android.provider.extra.APP_PACKAGE", getPackageName());
}
intent.putExtra("app_package", getPackageName());
intent.putExtra("app_uid", getApplicationInfo().uid);
startActivity(intent);
}
I am having a situation in which I need to update two notifications simultaneously. I have a service which plays audio and while playing the audio I used to show a notification of the player. Also in another activity I have a download method which downloads some audio and during download I need to show a notification of the download progress. So in some case if both the above thing is occuring then I need to show two different notifications together both having different Notification ID and different Notification Channel.
During download its progress changes every seconds and therefore the download notification get updated every seconds. And during this if anyone changes the audio source then the player notification is required to update and this cause my problem, the player notification doesn't get updated and I saw this happen only when the download notification is getting updated otherwise when there is no download notification to be updated then everything works fine.
I am using AsyncTask to download and showing notification using
#Override
protected void onPreExecute() {
notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
notificationBuilder = new NotificationCompat.Builder(context.get(), NOTIFICATION_CHANNEL_DOWNLOADING_ID)
.setProgress(100, 0, true)
.setContentTitle(context.get().getString(R.string.downloading) + "-" + name)
.setContentText("0%")
.setSmallIcon(R.mipmap.notification)
.setChannelId(NOTIFICATION_CHANNEL_DOWNLOADING_ID)
.setContentIntent(pendingIntent)
.addAction(0, context.get().getResources().getString(R.string.cancel), cancelIntent)
.setAutoCancel(true);
NotificationChannel mChannel;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
CharSequence name = "Download Notification";
int importance = NotificationManager.IMPORTANCE_LOW;
mChannel = new NotificationChannel(NOTIFICATION_CHANNEL_DOWNLOADING_ID, name, importance);
notificationManager.createNotificationChannel(mChannel);
}
notificationManager.notify(102, notificationBuilder.build());
}
#Override
protected String doInBackground(String... strings) {
//all the downloading stuff
publishProgress(progress_value);
....
}
#Override
protected void onProgressUpdate(Integer... progress) {
notificationBuilder.setContentText(progress[0] + "%");
notificationBuilder.setProgress(100, progress[0], false);
//notification getting update every seconds due to continuous change in progress
notificationManager.notify(102, notificationBuilder.build());
}
Now in my player service -
notification = new NotificationCompat.Builder(this, NOTIFICATION_CHANNEL_ID)
.setLargeIcon(BitmapFactory.decodeResource(getResources(), R.mipmap.app_icon2))
.setContentTitle(getString(R.string.app_name))
.setContentIntent(pendingIntent)
.setSmallIcon(R.mipmap.notification)
.setTicker(Constant.arrayList_play.get(Constant.playPos).getMp3Name())
.setChannelId(NOTIFICATION_CHANNEL_ID)
.setOnlyAlertOnce(true);
NotificationChannel mChannel;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
CharSequence name = "Music Playback";
int importance = NotificationManager.IMPORTANCE_LOW;
mChannel = new NotificationChannel(NOTIFICATION_CHANNEL_ID, name, importance);
mNotificationManager.createNotificationChannel(mChannel);
}
mNotificationManager.notify(101, notification.build());
I have tried changing the progress update duration by increasing the interval then the player notification works properly when the later's notification is not getting update.
Can anyone please help me a little in this matter and thanks in advance.
The Notification IDs should be different
mNotificationManager.notify(Notification_ID, notification.build());
Android Heads-up notification appears for a few seconds then disappears from the home screen and stays in the status bar and Notification Drawer. Is there any way to show notification pop up on the home screen until the user interacts?
You require to create new Activity for that which will open when notification received.
On received notification you need set payload in data as key-pair values because otherwise it will be handle By Android OS.
This will help- Android Activity as a dialog
How to handle notification when app in background in Firebase
If you don't mind turning your notification into a snackbar, you can show one that doesn't go away till user interacts with it:
public void showSnakbarIndef(final View rootView, String message, String actionMessage) {
Snackbar.make(rootView, message, Snackbar.LENGTH_INDEFINITE)
.setAction(actionMessage, new View.OnClickListener() {
#Override
public void onClick(View v) {
//exit or other action according to notification
}
})
.show();
}
Use setOngoing(true) and setAutoCancel(true) in Notification.Builder like so:
notification = new Notification.Builder(getApplicationContext())
.setLargeIcon(BitmapFactory.decodeResource(getResources(), R.drawable.ic_launcher))
.setSmallIcon(R.drawable.ic_launcher)
.setOngoing(true)
.setAutoCancel(true)
.setContentText(contentText)
.setContentIntent(contentIntent)
setFullScreenIntent in NotificationCompat.Builder