In my project, i'm using pushbot to push the notifications to the device. Now it is displaying the app logo but i want a particular say "R.drawable.alert" to be displayed instead of the app logo. So how to go about it. Below i'm posting the code for the Custom Handler class. I'm working with pushbots.
Custom Handler class
public class customHandler extends BroadcastReceiver
{
private static final String TAG = "customHandler";
#Override
public void onReceive(Context context, Intent intent)
{
String action = intent.getAction();
android.util.Log.d(TAG, "action=" + action);
// Handle Push Message when opened
if (action.equals(PBConstants.EVENT_MSG_OPEN)) {
//Check for Pushbots Instance
Pushbots pushInstance = Pushbots.sharedInstance();
if(!pushInstance.isInitialized()){
com.pushbots.push.utils.Log.d("Initializing Pushbots.");
Pushbots.sharedInstance().init(context.getApplicationContext());
}
//Clear Notification array
if(PBNotificationIntent.notificationsArray != null){
PBNotificationIntent.notificationsArray = null;
}
HashMap<?, ?> PushdataOpen = (HashMap<?, ?>) intent.getExtras().get(PBConstants.EVENT_MSG_OPEN);
android.util.Log.w(TAG, "User clicked notification with Message: " + PushdataOpen.get("message"));
//Report Opened Push Notification to Pushbots
if(Pushbots.sharedInstance().isAnalyticsEnabled()){
Pushbots.sharedInstance().reportPushOpened( (String) PushdataOpen.get("PUSHANALYTICS"));
}
//Start lanuch Activity
String packageName = context.getPackageName();
Intent resultIntent = new Intent(context.getPackageManager().getLaunchIntentForPackage(packageName));
resultIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK| Intent.FLAG_ACTIVITY_CLEAR_TASK);
resultIntent.putExtras(intent.getBundleExtra("pushData"));
Pushbots.sharedInstance().startActivity(resultIntent);
// Handle Push Message when received
}else if(action.equals(PBConstants.EVENT_MSG_RECEIVE)){
HashMap<?, ?> PushdataOpen = (HashMap<?, ?>) intent.getExtras().get(PBConstants.EVENT_MSG_RECEIVE);
android.util.Log.w(TAG, "User Received notification with Message: " + PushdataOpen.get("message"));
}
}
}
All you have to do it ,Upload icon to server, and in server pushbots >"Custom Payload" ,write in Key=largeIcon, and Value=URL of icon.
Image Example
More information in here: PushBots tutorial
Related
I have implemented a Broadcast Receiver that listens for new messages in Xamarin Android and I get the Originating Address and the message body of the Sms and the I set the earlier as the title of the notification and the later as the body of the notification. There is just one problem, my notification does not look like the notifications of the usual sms app as for the notification of the usual sms app then it has a drop down that when clicked the entire message body can be seen with a button for calling the sender or replying. The body of my notification does not show the message that exceeds the screen. I think it should break and fit the message inside the notification container but that does not happen. help me make my app display the message received in an inbox style fashion and to display like other apps. I am using the following Xamarin Android code
[BroadcastReceiver(Permission =Manifest.Permission.BroadcastSms,Enabled = true)]
[IntentFilter(new string[] {Telephony.Sms.Intents.SmsDeliverAction})]
//define the class that implements this broadcast receiver
public class SMSReceiver : BroadcastReceiver
{
public override void OnReceive(Context context, Intent intent)
{
if (intent.Action == Telephony.Sms.Intents.SmsDeliverAction)
{
Toast.MakeText(context, "new sms received", ToastLength.Short).Show();
//publish a notification on this new sms received
Bundle bundle = intent.Extras;
SmsMessage[] msgs = null;
var smsText = new Java.Lang.StringBuilder();
if (Build.VERSION.SdkInt > BuildVersionCodes.Kitkat)
{
msgs = Telephony.Sms.Intents.GetMessagesFromIntent(intent);
foreach(var text in msgs)
{
smsText.Append(text.MessageBody+"\n");
}
}
//declare the notification id
int notification_id = 0;
var inbox = new NotificationCompat.InboxStyle();
inbox.SetBigContentTitle(msgs[0].OriginatingAddress);
foreach(var text in msgs)
{
inbox.AddLine(text.MessageBody + "\n");
}
//build the notification for the message
NotificationCompat.Builder builder = new NotificationCompat.Builder(context)
.SetSmallIcon(Resource.Drawable.ic_chat).SetLargeIcon(BitmapFactory.DecodeResource(Resources.System, Resource.Drawable.ic_chat))
.SetAutoCancel(true)
.SetStyle(inbox)
.SetDefaults(NotificationCompat.DefaultAll);
//call the notification manager so it can build and deliver the
//message to the os
NotificationManager notificationManager=(NotificationManager)context.GetSystemService(Context.NotificationService);
//android 8 introduced a new requirement for setting the notification id using
//a notification channel
if (Build.VERSION.SdkInt >= BuildVersionCodes.Q)
{
string channel_Id= "channel_id";
NotificationChannel channel = new NotificationChannel(channel_Id, "Channel human readable content", NotificationImportance.Default);
notificationManager.CreateNotificationChannel(channel);
builder.SetChannelId(channel_Id);
;
}
notificationManager.Notify(notification_id,builder.Build());
}
}
}
Did some research on making FCM notification work some devices when the application is killed by the user(swiped away by the user from the app tray) or killed by the system OS but did not find any solution would appreciate if you can provide with solution or tell me what i am dong wrong. The notification is a data payload
#Override
public void onMessageReceived(RemoteMessage remoteMessage) {
// TODO: Handle FCM messages here.
// If the application is in the foreground handle both data and notification messages here.
// Also if you intend on generating your own notifications as a result of a received FCM
// message, here is where that should be initiated.
notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
String payload = "",notification_message = "", channelId ="", channelName="AAA", channelDescription="";
Log.d(TAG, "From: " + remoteMessage.getFrom());
String title = null, body = null;
if(remoteMessage.getNotification() != null) {
Log.d("REMOTE_DATA",remoteMessage.getNotification().getBody());
title = remoteMessage.getNotification().getTitle();
body = remoteMessage.getNotification().getBody();
}
if(remoteMessage.getData() != null) {
if(remoteMessage.getData().get("title") != null)
title = remoteMessage.getData().get("title");
if(remoteMessage.getData().get("message") != null)
body = remoteMessage.getData().get("message");
if(remoteMessage.getData().get("channelName") != null)
channelName = remoteMessage.getData().get("channelName");
}
}
//Setting up Notification channels for android O and above
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
Log.e(TAG, "onMessageReceived: => " + android.os.Build.VERSION.SDK_INT);
if(notificationChannels.containsKey(channelName)) {
JSONObject channelData = (JSONObject) notificationChannels.get(channelName);
try {
channelId = channelData.getString("channelId");
channelName = channelData.getString("channelName");
channelDescription = channelData.getString("channelDescription");
} catch (JSONException e) {
e.printStackTrace();
}
NotificationChannel notificationChannel = notificationManager.getNotificationChannel(channelId);
if (notificationChannel == null)
setupChannel(channelId, channelName, channelDescription);
}
}
Log.d(TAG, "Notification Message Body: " + title);
Log.d(TAG, "Notification Message Body: " + body);
if(title != null && body != null) {
apptivity_variable.createNotification(channelId,title, body);
db.insertNotification(title, body, remoteMessage.getData().toString());
}
}
Try registering another service to identify the app in the background to trigger the service
public class FirebaseBackgroundService extends BroadcastReceiver{
private static final String TAG = "FirebaseService";
#Override
public void onReceive(Context context, Intent intent) {
Log.d(TAG, "I'm in!!!");
if (intent.getExtras() != null) {
for (String key : intent.getExtras().keySet()) {
Object value = intent.getExtras().get(key);
Log.e("FirebaseDataReceiver", "Key: " + key + " Value: " + value);
if(key.equalsIgnoreCase("gcm.notification.body") && value != null) {
Bundle bundle = new Bundle();
Intent backgroundIntent = new Intent(context, BackgroundSyncJobService.class);
bundle.putString("push_message", value + "");
backgroundIntent.putExtras(bundle);
context.startService(backgroundIntent);
}
}
}
}
}
Also, don't forget to register it in your manifest.xml
<receiver android:exported="true" android:name=".FirebaseBackgroundService" android:permission="com.google.android.c2dm.permission.SEND">
<intent-filter>
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
</intent-filter>
</receiver>
I had same issue and after searching and working around, I have found that user need to enable autostart and battery optimization permission manually for more details refer this link
This issue is generally coming most of the Chinese phones to optimize battery etc.
this link will solve your problem
There are two different types of push messages priorities in FCM: normal priority and high priority. Only high priority pushes will wake your application up when it's in background and is the subject of Doze Mode restrictions. You can read more about it in this article
To make priority of your push message high, you have to add this section to the body of your push message:
"android":{"priority":"high"}
More information about push messages is available here
I am really stuck and want to push notification only to specific user using Firebase. I know the FCM method and have got the token. But this tutorial or other tutorials that I've followed are making me send push notification to both users including the sender. I just want to get notification on Recipient Device. Its been a long day , I've been working on this problem.
Looking for some key or UID of the Recipient now. Is it to be fetched from token that I have : FirebaseInstanceId.getInstance().getToken();
Update : I am not able to store and retrieve token (device token) and other children and also am able to log the message in firebase "Functions" tab , but still not able to push the notification to the device . I am testing it on emulator .Should I test it on real device ?
My Node.js code:
const functions = require('firebase-functions');
const admin = require('firebase-admin');
admin.initializeApp(functions.config().firebase);
var rootRef =
functions.database.ref('/notifications/{user_id}/{notification_id}');
exports.sendNotification = rootRef.onWrite(event => {
const user_id = event.params.user_id;
const notification_id = event.params.notification_id;
var request = event.data.val();
var payload = {
data: {
title : "New Message from ",
body: "userName has sent you message",
icon: "default",
}
};
console.log('We have a notification for device token: ', user_id );
console.log('Checking if getting inside the node -- ', request.user );
admin.messaging().sendToDevice(user_id, payload)
.then(function(response){
console.log('This was the notification Feature',response);
})
.catch(function(error){
console.log('Error sending message ',error);
})
})
MyFirebaseMEssagingService.java
public class MyFirebaseMessagingService extends FirebaseMessagingService
{
private static final String TAG = "FCM Service";
#Override
public void onMessageReceived(RemoteMessage remoteMessage) {
// TODO: Handle FCM messages here.
// If the application is in the foreground handle both data and
notification messages here.
// Also if you intend on generating your own notifications as a result
of a received FCM
// message, here is where that should be initiated.
//remoteMessage.getNotification().getBody());
if(remoteMessage.getNotification()!=null){
Map<String,String> payload = remoteMessage.getData();
// String title =
remoteMessage.getNotification().getTitle();
// String message =
remoteMessage.getNotification().getBody();
// Log.d(TAG, "Message Notification Title : " + title);
// Log.d(TAG, "Message Notification Body: " + message);
System.out.println("Messaging Service : Title - " + payload.get("title")
+ " , body - " + payload.get("body"));
sendNotification(payload);
}
}
#Override
public void onDeletedMessages(){
}
private void sendNotification(Map<String,String> payload){
NotificationCompat.Builder builder = new
NotificationCompat.Builder(this);
builder.setSmallIcon(R.mipmap.ic_launcher);
builder.setContentTitle("Firebase Push
Notification"+payload.get("title"));
builder.setContentText("Notification Text : "+ payload.get("body"));
Intent intent = new Intent(this, ChatWindow.class);
TaskStackBuilder stackBuilder = TaskStackBuilder.create(this);
stackBuilder.addNextIntent(intent);
PendingIntent pendingIntent =
stackBuilder.getPendingIntent(0,PendingIntent.FLAG_UPDATE_CURRENT);
builder.setContentIntent(pendingIntent);
NotificationManager notificationManager = (NotificationManager)
getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(0, builder.build());
}
}
FirebaseIDService.java:
public class FirebaseIDService extends FirebaseInstanceIdService {
private static final String TAG = "FirebaseIDService";
#Override
public void onTokenRefresh() {
// Get updated InstanceID token.
String refreshedToken = FirebaseInstanceId.getInstance().getToken();
Log.d(TAG, "Refreshed token: " + refreshedToken);
DatabaseReference firebase ;//= new Firebase("https://materialtabs-
b5734.firebaseio.com//messages");
firebase =
FirebaseDatabase.getInstance().getReferenceFromUrl("https://materialtabs-
b5734.firebaseio.com//notifications/");
// TODO: Implement this method to send any registration to your app's
servers.
sendRegistrationToServer(refreshedToken);
}
/**
* Persist token to third-party servers.
*
* Modify this method to associate the user's FCM InstanceID token with any
server-side account
* maintained by your application.
*
* #param token The new token.
*/
private void sendRegistrationToServer(String token) {
// Add custom implementation, as needed.
System.out.println("Reading Token : "+ token);
}
}
And I am starting my 'MyFirebaseMessagingService.java' inside my MainActivity file in "onCreate()"
as "startService(new Intent(this, MyFirebaseMessagingService.class));"
Please help me. I think I am missing some minor details or it could be major, not sure !
For that, you need to store the firebase token of the recipient's device and then whenever you want to send the notification to the recipient you have to retrieve the token of the recipient's from the database and then you can send the notification using that token to the only recipient.
sorry for my bad english.
I sending push notification from my codeigniter web to android app, I have 3 devices to test it.
My first device, it works well for me.
And then in my second and third device my android didn't receive any message.
I tried to send notification from my firebase console, then I choose target is user segment with my package name. All of my devices receive the message.
Then I tried to send notification using topic, which is my topic is global. Only my first device receives the message.
Here's my code :
public static final String TOPIC_GLOBAL = "global";
public static final String REGISTRATION_COMPLETE = "registrationComplete";
public static final String PUSH_NOTIFICATION = "pushNotification";
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();
} else if (intent.getAction().equals(Config.PUSH_NOTIFICATION)) {
// new push notification is received
String message = intent.getStringExtra("message");
Toast.makeText(getApplicationContext(), "Push notification: " + message, Toast.LENGTH_LONG).show();
// txtMessage.setText(message);
}
}
};
private void displayFirebaseRegId() {
SharedPreferences pref = getApplicationContext().getSharedPreferences(Config.SHARED_PREF, 0);
String regId = pref.getString("regId", null);
Log.e(TAG, "Firebase reg id: " + regId);
if (!TextUtils.isEmpty(regId))
{
//Toast.makeText(getApplicationContext(),regId,Toast.LENGTH_LONG).show();
}
// Toast.makeText(getApplicationContext(), regId, Toast.LENGTH_LONG).show();
else
Toast.makeText(getApplicationContext(),"Firebase Reg Id is not received yet!)",Toast.LENGTH_LONG).show();
}
I have created an application that receives push notifications from PushBots.
I am successfully receiving the Push Notifications but I want to store the push data in SharedPreferences and display it another activity containing a RecyclerView.
I know Content providers is a better approach, but I want to stick with SharedPreferences as of now.
Here's my custom Broadcast Receiver
public class customHandler extends BroadcastReceiver
{
private static final String TAG = "customHandler";
#Override
public void onReceive(Context context, Intent intent)
{
String action = intent.getAction();
Log.d(TAG, "action=" + action);
// Handle Push Message when opened
if (action.equals(PBConstants.EVENT_MSG_OPEN)) {
//Check for Pushbots Instance
Pushbots pushInstance = Pushbots.sharedInstance();
if(!pushInstance.isInitialized()){
Log.d("Initializing Pushbots.");
Pushbots.sharedInstance().init(context.getApplicationContext());
}
//Clear Notification array
if(PBNotificationIntent.notificationsArray != null){
PBNotificationIntent.notificationsArray = null;
}
HashMap<?, ?> PushdataOpen = (HashMap<?, ?>) intent.getExtras().get(PBConstants.EVENT_MSG_OPEN);
Log.w(TAG, "User clicked notification with Message: " + PushdataOpen.get("message"));
//Report Opened Push Notification to Pushbots
if(Pushbots.sharedInstance().isAnalyticsEnabled()){
Pushbots.sharedInstance().reportPushOpened( (String) PushdataOpen.get("PUSHANALYTICS"));
}
//Start Main Activity On CLicking Notification
String packageName = context.getPackageName();
Intent resultIntent = new Intent(context.getPackageManager().getLaunchIntentForPackage(packageName));
resultIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK| Intent.FLAG_ACTIVITY_CLEAR_TASK);
resultIntent.putExtras(intent.getBundleExtra("pushData"));
Pushbots.sharedInstance().startActivity(resultIntent);
// Handle Push Message when received
}else if(action.equals(PBConstants.EVENT_MSG_RECEIVE)){
HashMap<?, ?> PushdataOpen = (HashMap<?, ?>) intent.getExtras().get(PBConstants.EVENT_MSG_RECEIVE);
Log.w(TAG, "User Received notification with Message: " + PushdataOpen.get("message"));
}
}
}
Create a custom PushData class and use Gson library to save as a string your data.
Here is a clean example
try it.
public void addNotification(String notification) {
// get old notifications
String oldNotifications = getNotifications();
if (oldNotifications != null) {
oldNotifications += "|" + notification;
} else {
oldNotifications = notification;
}
editor.putString(KEY_NOTIFICATIONS, oldNotifications);
editor.commit();
}
public String getNotifications() {
return pref.getString(KEY_NOTIFICATIONS, null);
}
and get it
String oldNotification = AppController.getInstance().getPrefManager().getNotifications();
List<String> messages = Arrays.asList(oldNotification.split("\\|"));
For putting string in SharedPreferences :
SharedPreferences settings = getSharedPreferences(PREFS_NAME, 0);
SharedPreferences.Editor editor = settings.edit();
editor.putString(key, value);
editor.commit();
For getting shared preferences in fragment :
SharedPreferences prefs = getActivity().getSharedPreferences(MY_PREFS_NAME, MODE_PRIVATE);
String name = prefs.getString(key, "default value");
1. Initialize Shared Preference variables in onReceive method like below ,
SharedPreferences prf = context.getSharedPreferences("YOUR_PREFERENCE_NAME", Context.MODE_PRIVATE);
SharedPreferences.Editor editor = prf.edit();
2. Save Push Message to shared preference when receive,
................
................
// Handle Push Message when received
}else if(action.equals(PBConstants.EVENT_MSG_RECEIVE))
{
HashMap<?, ?> PushdataOpen = (HashMap<?, ?>) intent.getExtras().get(PBConstants.EVENT_MSG_RECEIVE);
Log.w(TAG, "User Received notification with Message: " + PushdataOpen.get("message"));
String message=(String) PushdataOpen.get("message");
editor.putString("push_message", message);
editor.commit();
}
3. Get saved push message from shared preference for display,
SharedPreferences prf = context.getSharedPreferences("YOUR_PREFERENCE_NAME", Context.MODE_PRIVATE);
String message=prf.getString("push_message", "");