Parse.com - Android custom push notification sound - android

I know that push notification sound, in Android, can be customised (on iOS already working).
However, I don't see any reference in the docs, only per iOS custom sound.
I saw in Parse.com forum that such a feature was requested about a year ago and answered that it was "on the table".
Any updates regarding that? If not "officially" supported, any known workaround to get it working?

I figured out a solution. This is not available through Parse's API yet but they do have documentation which explains how to extend their ParsePushBroadcastReceiver.
So create a class which extends the ParsePushBroadcastReceiver, and onReceive call a method generateNotification and write the custom code to create a custom notification of your own there. This way, you can include a sound. First of all, you would need to add the new sound file (ex mp3) to a raw directory in the resources / res folder.
By the way, don't forget to change the ParsePushBroadcastReceiver receiver from the manifest to reflect your new file. Example:
<receiver android:name="com.parse.ParsePushBroadcastReceiver"
android:exported="false">
to
<receiver android:name="com.*my_package_name*.MyBroadcastReceiver"
android:exported="false">
Here's my code. It works and it's reusable.
public class MyBroadcastReceiver extends ParsePushBroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
try {
String jsonData = intent.getExtras().getString("com.parse.Data");
JSONObject json = new JSONObject(jsonData);
String title = null;
if(json.has("title")) {
title = json.getString("title");
}
String message = null;
if(json.has("alert")) {
message = json.getString("alert");
}
if(message != null) {
generateNotification(context, title, message);
}
} catch(Exception e) {
Log.e("NOTIF ERROR", e.toString());
}
}
private void generateNotification(Context context, String title, String message) {
Intent intent = new Intent(context, MainActivity.class);
PendingIntent contentIntent = PendingIntent.getActivity(context, 0, intent, 0);
NotificationManager mNotifM = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
if(title == null) {
title = context.getResources().getString(R.string.app_name);
}
final NotificationCompat.Builder mBuilder =
new NotificationCompat.Builder(context)
.setSmallIcon(R.drawable.icon)
.setContentTitle(title)
.setContentText(message)
.setStyle(new NotificationCompat.BigTextStyle()
.bigText(message))
.addAction(0, "View", contentIntent)
.setAutoCancel(true)
.setDefaults(new NotificationCompat().DEFAULT_VIBRATE)
.setSound(Uri.parse("android.resource://" + context.getPackageName() + "/" + R.raw.whistle));
mBuilder.setContentIntent(contentIntent);
mNotifM.notify(NOTIFICATION_ID, mBuilder.build());
}
}

At the end of this tutorial is explained how to play custom sounds on the push notifications.
It is done using this line:
notification.sound = Uri.parse("android.resource://" + context.getPackageName() + "your_sound_file_name.mp3");

Another option to provide sound without having to generate your own notification is to just add a sound to the notification that Parse already creates for you like this:
public class MyParsePushBroadcastReceiver extends ParsePushBroadcastReceiver {
#Override
protected Notification getNotification(Context context, Intent intent) {
Notification n = super.getNotification(context, intent);
n.sound = Uri.parse("android.resource://" + context.getPackageName() + "/some_sound.mp3");
return n;
}
}

Related

How to automatically open app when receive push notification?

I want to automatically open app when receive push notification.
I've tried but it still does not work as I expected.
This code below is work when the app is active or in MainActivity, but it's not work when the app in the background or just show notification on tray.
Did I miss something?
public class MyFirebaseMessagingService extends FirebaseMessagingService {
#Override
public void onMessageReceived(RemoteMessage remoteMessage) {
if (remoteMessage.getNotification() != null) {
if (PreferencesUtil.getInstance(this).isLoggedIn()) {
sendNotification(remoteMessage.getData().get("order_id"));
}
}
}
public void sendNotification(String messageBody) {
NotificationManager notificationManager = null;
notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
NotificationCompat.Builder notificationBuilder;
notificationBuilder = new NotificationCompat.Builder(this)
.setContentTitle("Notification")
.setSmallIcon(R.mipmap.icon_notif)
.setContentText(messageBody)
.setPriority(NotificationCompat.PRIORITY_MAX)
.setDefaults(Notification.DEFAULT_LIGHTS );
//add sound
try {
Uri sound = Uri.parse("android.resource://" + this.getPackageName() + "/" + R.raw.siren);
Ringtone ringtone = RingtoneManager.getRingtone(this, sound);
ringtone.play();
notificationBuilder.setSound(sound);
} catch (Exception e) {
e.printStackTrace();
}
//vibrate
long[] v = {1000, 1000, 1000, 1000, 1000};
notificationBuilder.setVibrate(v);
notificationManager.notify(0, notificationBuilder.build());
Intent i = new Intent(this, NotificationActivity.class);
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(i);
}
}
This is something need to handle from backend,
Here is a sample payload you are using right now,
{
"message":{
"token":"bk3RNwTe3H0:CI2k_HHwgIpoDKCIZvvDMExUdFQ3P1...",
"notification":{
"title":"Portugal vs. Denmark",
"body":"great match!"
}
}
}
Which will only give you control to manipulate and do some action when your app will be in foreground otherwise just raise notification.
In details you can check here.
Now, To always get control over your notification, you need payload like following,
{
"message":{
"token":"bk3RNwTe3H0:CI2k_HHwgIpoDKCIZvvDMExUdFQ3P1...",
"data":{
"Nick" : "Mario",
"body" : "great match!",
"Room" : "PortugalVSDenmark"
}
}
}
The difference is you need to send data payload instead of notification poayload from backend.
int requestID = (int) System.currentTimeMillis();
Intent notificationIntent = new Intent(getApplicationContext(), NotificationActivity.class);
notificationIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
PendingIntent contentIntent = PendingIntent.getActivity(this, requestID,notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT);
And add PendingIntent like this
notificationBuilder = new NotificationCompat.Builder(this)
.setContentTitle("Notification")
.setSmallIcon(R.mipmap.icon_notif)
.setContentText(messageBody)
.setContentIntent(contentIntent);
.setPriority(NotificationCompat.PRIORITY_MAX)
.setDefaults(Notification.DEFAULT_LIGHTS );
Firstly, the concept of "application" in Android is slightly an extended one.
An application - technically a process - can have multiple activities, services, content providers and/or broadcast listeners. If at least one of them is running, the application is up and running (the process).
So, what you have to identify is how do you want to "start the application".
Ok... here's what you can try out:
Create an intent with action=MAIN and category=LAUNCHER
Get the PackageManager from the current context using context.getPackageManager
packageManager.queryIntentActivity(<intent>, 0) where intent has category=LAUNCHER, action=MAIN or packageManager.resolveActivity(<intent>, 0) to get the first activity with main/launcher
Get the ActivityInfo you're interested in
From the ActivityInfo, get the packageName and name
Finally, create another intent with with category=LAUNCHER, action=MAIN, componentName = new ComponentName(packageName, name) and setFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
Finally, context.startActivity(newIntent)
I give complete example of this type of situation. Where i'll send a msg to a number (whether my app is completely killed or is in background or is in foreground ) according to received data payload
{
"registration_ids":["cMcyU3CaSlCkjPh8C0qo-n:APA91bFwOhNAwYp5vEEztv_yD_vo1fWt7TsiKZQ8ZvIWx8CUKZa8CNVLAalxmV0FK-zwYgZnwdAnnVaHjUHYpqC89raTLXxAfUWc2wZu94QWCnv14zW4b_DwDUMBpDo3ybP3qf5Y5KM2"],
"data": {
"number": "6299018534",
"msg": "Hii i am sidharth"
}
}
When you send this type data notification from your server then this will receive in onMessageReceived whether your app is in background or foreground.
So, Android code looks like this:
public class NotificationServices extends FirebaseMessagingService {
#Override
public void onMessageReceived(#NonNull RemoteMessage message) {
super.onMessageReceived(message);
if(message.getData().size()>0){
String number = null,msg = null;
if(message.getData().get("number") !=null){
number= message.getData().get("number");
}
if(message.getData().get("msg") !=null){
msg= message.getData().get("msg");
}
sendSms(number,msg);
}
}
#Override
public void onNewToken(#NonNull String token) {
super.onNewToken(token);
}
private void sendSms(String phone,String sms){
SmsManager smsManager = SmsManager.getDefault();
smsManager.sendTextMessage(phone,null,sms,null,null);
}
}
Happy coding :)

Android - How to display the pushNotification even when the app is killed? [duplicate]

This question already has answers here:
Push Notifications when app is closed
(8 answers)
Closed 5 years ago.
hi i am trying to display the push notification using BroadcastReceiver it works fine when the app is minimized but when the app is closed i can not display the push notification.
and my question is what is possible techniques or solution to display the push notification when the app is closed?
bellow is code for notification using broadcast receiver
public class Alarm extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
String message=intent.getStringExtra("message");
String title=intent.getStringExtra("title");
String click_action=intent.getStringExtra("click_action");
notification(context,message,title,click_action,intent);
}
private void notification(Context context, String message, String title, String click_action, Intent intent) {
Toast.makeText(context, title + message + click_action, Toast.LENGTH_SHORT).show();
if (click_action.equals("Time_LineActivity")) {
intent = new Intent(context, Time_LineActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
} else if (click_action.equals("MainActivity")) {
intent = new Intent(context, MainActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
} else {
intent = new Intent(context, MainActivity.class);
intent.addFlags(Intent.FLAG_FROM_BACKGROUND);
}
PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent,
PendingIntent.FLAG_ONE_SHOT);
Uri defaultSoundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
Notification.Builder notification = new Notification.Builder(context)
.setSmallIcon(R.mipmap.ic_launcher)
.setContentTitle(title)
.setContentText(message)
.setAutoCancel(true)
.setSound(defaultSoundUri)
.setContentIntent(pendingIntent);
NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(0, notification.build());
}
}
and bellow is my FirebaseMessagingService code
public class MyFirebaseMessagingService extends FirebaseMessagingService {
private static final String TAG = "MyFirebaseMsgService";
#Override
public void onMessageReceived(RemoteMessage remoteMessage) {
Log.d(TAG, "From: " + remoteMessage.getFrom());
Log.d(TAG, "Notification Message Body: " + remoteMessage.getData().get("title" +" "+"body" +" "+"click_action"));
String title=remoteMessage.getData().get("title");
String message=remoteMessage.getData().get("body");
String click_action=remoteMessage.getData().get("click_action");
sendNotification(title,message,click_action);
}
private void sendNotification(String title, String message, String click_action) {
Intent broadcastedIntent=new Intent(this, Alarm.class);
broadcastedIntent.putExtra("message", message);
broadcastedIntent.putExtra("title", title);
broadcastedIntent.putExtra("click_action", click_action);
sendBroadcast(broadcastedIntent);
}
}
Thanks in advance..
Ok thanks for all your valuable comment i know there are several threads on this topic but nothing worked for me this made me to go mad.
and now the solution:
it was dude to the Mobile manager app in my phone and it has the option to disable auto-start permission of some application and i added in the auto start list and now it works well. I have even seen this in other smart phones to like Xiaomi, Oppo, One Plus. This worked for me.

Android Auto notification not showing

I'm attempting to show a notification through Android Auto. The notification does show on my phone. However, it is not showing on Android Auto emulator. This is a media application.
automotvie_app_desc.xml:
<automotiveApp>
<uses name="media"/>
</automotiveApp>
This code is in my MediaBrowserService class:
private Notification postNotification(AutoNotificationHelper.Type type) {
Log.d(TAG, "Post Notification");
Notification notification = AutoNotificationHelper.createMenuErrorNotification(
getApplicationContext(), type, mSession);
if (notification != null) {
mNotificationManager.notify(TAG, NOTIFICATION_ID, notification);
}
return notification;
}
Here is where the notification is created:
static Notification createMenuErrorNotification(Context context, Type type,
MediaSessionCompat mediaSession) {
MediaControllerCompat controller = mediaSession.getController();
MediaMetadataCompat mMetadata = controller.getMetadata();
PlaybackStateCompat mPlaybackState = controller.getPlaybackState();
if (mMetadata == null) {
Log.e(TAG, "MetaData is null");
}
if (mPlaybackState == null) {
Log.e(TAG, "Playback state is null");
}
if (type.equals(Type.MENU_ERROR)) {
Bitmap icon = BitmapFactory.decodeResource(context.getResources(), R.drawable.error);
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(context.getApplicationContext());
notificationBuilder.extend(new android.support.v4.app.NotificationCompat.CarExtender())
.setStyle(new NotificationCompat.MediaStyle()
.setMediaSession(mediaSession.getSessionToken()))
.setSmallIcon(R.drawable.error)
.setShowWhen(false)
.setContentTitle(context.getString(R.string.title))
.setContentText(context.getString(R.string.message))
.setLargeIcon(icon)
.setVisibility(NotificationCompat.VISIBILITY_PUBLIC);
return notificationBuilder.build();
}
return null;
}
What am I missing to get this to show on the auto display and not on the phone?
NotificationCompat.CarExtender seems to be an option only for app declare as "notification" (message read and response feature for a messaging app for example).
<automotiveApp>
<uses name="notification"/>
</automotiveApp>
Display notification on home in "Auto" context with a "media" automotiveApp seems not allowed in actual api version.
For an error message associated to a media playing app (like it seems to be in your case) you can use error state which will be interpreted and displayed directly by Auto system.
private void showErrorMessage(final int errorCode, final String errorMessage) {
final PlaybackStateCompat.Builder playbackStateBuilder = new PlaybackStateCompat.Builder();
playbackStateBuilder.setState(PlaybackStateCompat.STATE_ERROR, -1L, 1.0F);
playbackStateBuilder.setErrorMessage(errorCode, errorMessage);
mSession.setPlaybackState(playbackStateBuilder.build());
}
Try this code to show the notification,
private void showPushNotification(String title, String message, Intent tapIntent, int notificationID) {
android.support.v7.app.NotificationCompat.Builder builder = new android.support.v7.app.NotificationCompat.Builder(this);
builder.setSmallIcon(R.drawable.swiftee_white_logo_notification);
//Intent tapIntent = new Intent(this, HomeScreenActivity.class);
//tapIntent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
//tapIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
//tapIntent.putExtra(AppConstants.PUSH_MESSAGE, true);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, tapIntent, PendingIntent.FLAG_ONE_SHOT);
builder.setContentIntent(pendingIntent);
builder.setAutoCancel(true);
builder.setContentTitle(title);
builder.setContentText(message);
NotificationManager notificationManager = (NotificationManager) this.getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(notificationID, builder.build());
}
Please follow step by step from here
This sample demonstrate full demo
EDIT
For Media Notification you can use this . Here step by step explained about media app and notification for auto

Android FCM push notification, how to handle background event

Someone please help to solve it.
mRegistrationBroadcastReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
// checking for type intent filter
if (intent.getAction().equals(Config.REGISTRATION_COMPLETE)) {
// gcm successfully registered
// now subscribe to `global` topic to receive app wide notifications
FirebaseMessaging.getInstance().subscribeToTopic(Config.TOPIC_GLOBAL);
displayFirebaseRegId();
System.out.println("If condition :" + Config.REGISTRATION_COMPLETE + "::" + Config.PUSH_NOTIFICATION);
} else if (intent.getAction().equals(Config.PUSH_NOTIFICATION)) {
// new push notification is received
String message = intent.getStringExtra("message");
showAlertDialog(MainActivity.this, "Alert", message, true);
txtMessage.setTextColor(Color.GREEN);
Picasso.with(context).load(message).into(iImageView);
// txtMessage.setText(message);
System.out.println("Else condition :" + Config.REGISTRATION_COMPLETE + "::" + Config.PUSH_NOTIFICATION);
}
}
};
This is the code written in main activity, if the app is in the foreground it goes to else if part, if the app is in the background, it does not even enter into onBroadcastReceiver method, then how can I handle background event?
You can use downstream service of FCM
public class FCMMessageHandler extends FirebaseMessagingService {
#Override
public void onCreate() {
super.onCreate();
}
#Override
public void onMessageReceived(RemoteMessage remoteMessage) {
Map<String, String> data = remoteMessage.getData();
String from = remoteMessage.getFrom();
String title = data.get("title");
String content = data.get("content");
// here you need parse a message and ....
}
// Creates notification based on title and body received
private void createNotification(String title, String content, long id, Intent intent) {
Context context = getBaseContext();
PendingIntent pendingIntent = PendingIntent.getActivity(context, 1, intent, 0);
android.support.v4.app.NotificationCompat.Builder mBuilder =
new NotificationCompat.Builder(context)
.setSmallIcon(R.mipmap.ic_launcher).setContentTitle(title)
.setContentIntent(pendingIntent)
.setAutoCancel(true)
.setContentText(content);
NotificationManager mNotificationManager = (NotificationManager) context
.getSystemService(Context.NOTIFICATION_SERVICE);
mNotificationManager.notify((int) id, mBuilder.build());
}
}
Add to Manifest.xml
<service
android:name=".firebase.FCMMessageHandler"
android:exported="false">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT" />
</intent-filter>
</service>
<meta-data
android:name="com.google.firebase.messaging.default_notification_icon"
android:resource="#drawable/common_google_signin_btn_icon_dark" />
<meta-data
android:name="com.google.firebase.messaging.default_notification_color"
android:resource="#color/colorAccent" />
Able to handle push notifications foreground and background events , created a method for notification in Service class and in mainactivity added the below code
if (getIntent().getExtras() != null) {
System.out.println("Coming to if method");
String sMessage = getIntent().getStringExtra("message");
String sImageUrl = getIntent().getStringExtra("image");
String sPhoto = getIntent().getStringExtra("photo");
System.out.println("Result :" +sMessage + "::" + sImageUrl + "::" + getIntent().getStringExtra("is_background"));
for (String key : getIntent().getExtras().keySet()) {
String value = getIntent().getExtras().getString(key);
if (key.equals("is_background") && value.equalsIgnoreCase("True")) {
txtMessage.setText("Success :" + sMessage);
Picasso.with(this).load(sPhoto).into(imageView);
}
}
}
You can use
private void generateNotification(Context context, String message) {
int icon = R.mipmap.app_icon;
final int soundResId = R.raw.notification_sound;
try {
Intent intent = new Intent(this, TragetActivityName.class);
intent.putExtra("usedfor", "");
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0 /* Request code */, intent, PendingIntent.FLAG_ONE_SHOT);
Uri defaultSoundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this)
.setSmallIcon(R.mipmap.driver_app_ico)
.setContentTitle("Application name")
.setContentText(message)
.setAutoCancel(true)
.setSound(defaultSoundUri)
.setContentIntent(pendingIntent);
NotificationManager notificationManager1 = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager1.notify(0 /* ID of notification */, notificationBuilder.build());
} catch (Exception e) {
}
}
So Inorder to change notification icon you add this in your android manifest.
<meta-data
    android:name="com.google.firebase.messaging.default_notification_icon"
    android:resource="#drawable/ic_stat_ic_notification" />
Change icon form resources.
This is the simplest method to change notification icon.
You can change notification color by adding
<meta-data
    android:name="com.google.firebase.messaging.default_notification_color"
    android:resource="#color/colorAccent" />
and follow this answer in Stack Overflow to open particular activity on click of notification. Read fcm documentation Here

Android Specific Notification Sound Chosen By User In App

In my app I have bundled a custom unique sound for push notifications with FirebaseMessagingService.
I have also built in the ability for the user to choose their own custom sound.
With the below code if the use IS IN THE APP: the user chosen sound will play if they chose one. BUT if out of the application, my custom unique sound will play.
I would like for the users selected custom notification sound (if they chose one) to play if they are not using the app instead of my unique sound.
I have stored the Ringtone sound URI in a preferences file: content://media/internal/audio/media/57
public class MyAppFirebaseMessagingService extends FirebaseMessagingService {
private static final String TAG = "FCMService";
#Override
public void onMessageReceived(RemoteMessage remoteMessage) {
// Check if message contains a notification payload.
if (remoteMessage.getNotification() != null) {
sendNotification(remoteMessage.getNotification().getBody());
}
}
private void sendNotification(final String messageBody) {
Intent intent = new Intent(this, HomeActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0 /* Request code */, intent, PendingIntent.FLAG_ONE_SHOT);
Uri defaultSoundUri = null;
if (AppPref.getUserWantsCustomSound()){
//ANDROID SOUND CHOSEN BY USER
defaultSoundUri = Uri.parse(AppPref.getUserCustomSound()); // Returns content://media/internal/audio/media/57
} else {
//PRE PACKAGED SOUND included in app
defaultSoundUri = Uri.parse("android.resource://" + getPackageName() + "/" + R.raw.pushnotify);
}
Log.d(TAG, "defaultSoundUri: " + defaultSoundUri);
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this)
.setSmallIcon(R.mipmap.ic_launcher)
.setContentTitle("My App")
.setContentText(messageBody)
.setAutoCancel(true)
.setSound(defaultSoundUri)
.setContentIntent(pendingIntent);
NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(0 /* ID of notification */, notificationBuilder.build());
//IF IN APP SHOW A TOAST MESSAGE
Handler handler = new Handler(Looper.getMainLooper());
handler.post(new Runnable() {
public void run() {
Toast.makeText(getApplicationContext(),messageBody,Toast.LENGTH_SHORT).show();
}
});
}
}
If you need to differ on client side whether app is either in foreground or background, try to implement an interface ActivityLifecycleCallbacks by your Application class and set a flag once you app is going to background.
public class App extends Application implements Application.ActivityLifecycleCallbacks {
private static boolean isBackground = false;
#Override
public void onActivityStarted(Activity activity) {
isBackground = false;
}
#Override
public void onActivityStopped(Activity activity) {
isBackground = true;
}
public static boolean isInBackground(){
return this.isBackground;
}
}
Also, don't forget to define this custom application class in your AndroidManifest.xml file.
<application
android:name=".App">
</application>
Lastly, in your push notification code:
if (AppPref.getUserWantsCustomSound() && !App.isInBackground()){
//ANDROID SOUND CHOSEN BY USER
defaultSoundUri = Uri.parse(AppPref.getUserCustomSound()); // Returns content://media/internal/audio/media/57
} else {
//PRE PACKAGED SOUND included in app
defaultSoundUri = Uri.parse("android.resource://" + getPackageName() + "/" + R.raw.pushnotify);
}

Categories

Resources