I have been having difficulties lately getting many specific functions to work on Android Studio. Recently I am working on trying to display simple notifications. They never show up. I feel like I have tried everything at this point. Here's my code.
public class NotificationReceiver extends BroadcastReceiver {
private final String TAG = NotificationReceiver.class.getSimpleName();
#Override
public void onReceive(Context context, Intent intent) {
Intent notificationIntent = new Intent(context, ScrollingActivity.class);
TaskStackBuilder taskStackBuilder = TaskStackBuilder.create(context);
taskStackBuilder.addParentStack(ScrollingActivity.class);
taskStackBuilder.addNextIntent(notificationIntent);
PendingIntent pendingIntent = taskStackBuilder.getPendingIntent(100, PendingIntent.FLAG_UPDATE_CURRENT);
NotificationCompat.Builder builder = new NotificationCompat.Builder(context, "channel");
Notification notification = builder.setContentTitle("My Test Notification")
.setContentText("This is some sample test notification. (Congratulations!)")
.setTicker("New Message Alert!")
.setSmallIcon(R.mipmap.ic_launcher)
.setContentIntent(pendingIntent).build();
NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(0, notification);
}}
Here's the method I use to call the notification.
public void setRepeatingNotification(){
Calendar repeatCalendar = Calendar.getInstance();
repeatCalendar.set(Calendar.HOUR_OF_DAY, 21);
repeatCalendar.set(Calendar.MINUTE, 40);
repeatCalendar.set(Calendar.SECOND, 10);
Intent intent = new Intent(ScrollingActivity.this, NotificationReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(ScrollingActivity.this, 100, intent, PendingIntent.FLAG_UPDATE_CURRENT);
AlarmManager alarmManager = (AlarmManager)getSystemService(ALARM_SERVICE);
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, repeatCalendar.getTimeInMillis(), AlarmManager.INTERVAL_DAY, pendingIntent);
Toast.makeText(ScrollingActivity.this, "Repeating Notification Set", Toast.LENGTH_LONG).show();
}
Here's the manifest.
<?xml version="1.0" encoding="utf-8"?>
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
<uses-permission android:name="android.permission.SET_ALARM"/>
<uses-permission android:name="android.permission.INTERNET"/>
<application
android:name=".MainApplication"
android:allowBackup="true"
android:icon="#mipmap/skillset_v3"
android:label="#string/app_name"
android:roundIcon="#mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="#style/AppTheme"
>
<activity
android:name=".ScrollingActivity"
android:label="#string/app_name"
android:screenOrientation="portrait"
android:theme="#style/AppTheme.NoActionBar">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".TaskViewActivity"
android:label="#string/title_activity_task_view"
android:parentActivityName=".ScrollingActivity"
android:screenOrientation="portrait"
android:theme="#style/AppTheme.NoActionBar">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value="com.example.jermaineoliver.aswitch.ScrollingActivity" />
</activity>
<activity
android:name=".MasteryViewActivity"
android:label="#string/title_activity_mastery_view"
android:parentActivityName=".ScrollingActivity"
android:screenOrientation="portrait"
android:theme="#style/AppTheme.NoActionBar">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value="com.example.jermaineoliver.aswitch.ScrollingActivity" />
</activity>
<service
android:name="TaskTrackingService"/>
<receiver android:name=".NotificationReceiver"/>
</application>
Please help! I have been working on this forever.
It has to do with NotificationChannel. In Android Oreo and up you can create a NotificationChannel like this:
NotificationManager notificationManager =
(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
String channelId = "my_channel_id";
CharSequence channelName = "My Channel";
int importance = NotificationManager.IMPORTANCE_DEFAULT;
NotificationChannel notificationChannel = new NotificationChannel(channelId, channelName, importance);
notificationChannel.enableLights(true);
notificationChannel.setLightColor(Color.RED);
notificationChannel.enableVibration(true);
notificationChannel.setVibrationPattern(new long[]{1000, 2000});
notificationManager.createNotificationChannel(notificationChannel);
Then you create your Notification as below:
NotificationManager notificationManager =
(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
int notifyId = 1;
String channelId = "my_channel_id";
Notification notification = new Notification.Builder(MainActivity.this)
.setContentTitle("My Message")
.setContentText("My test message!")
.setSmallIcon(R.drawable.ic_notification)
.setChannel(channelId)
.build();
notificationManager.notify(id, notification);
This way The notification will use the proper notification channel and will be displayed correctly. You can also create groups for notification channels. Read more here:
Documenation - NotificationChannel
Examples
Surprised no one jumped on this one. I found the answer. The API level was mismatched. Apparently NotificationChannel is required for Notifications using versions higher than Oreo. When I tried it on a lower API it worked. Knowing that kind of led my hand towards being able to get it to work. If anyone else has this problem let me know, maybe I can help.
Related
My app receive FCM and show as notification. So I create the notification like this:
val notificationManager = getSystemService(NOTIFICATION_SERVICE) as NotificationManager
/**
* Notification Channel
*/
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
val notificationChannel = NotificationChannel(id, "Notification", NotificationManager.IMPORTANCE_HIGH)
notificationChannel.description = "This is notification channel"
notificationChannel.enableLights(true)
notificationChannel.lightColor = Color.RED
notificationChannel.enableVibration(true)
notificationChannel.vibrationPattern = longArrayOf(0, 1000, 500, 500)
notificationManager.createNotificationChannel(notificationChannel)
}
val messageNotification = NotificationCompat.Builder(this, id)
.setContentIntent(resultPendingIntent)
.setAutoCancel(true)
.setDefaults(Notification.DEFAULT_ALL)
.setWhen(System.currentTimeMillis())
.setSmallIcon(R.drawable.ic_baseline_delivery_dining_24)
.setLargeIcon(bitmap)
.setContentTitle("${getString(R.string.new_orders)} ${tableNumber}")
.setContentText("${orderNumber} ${name}")
/**
* Main Notification
*/
val summaryNotification = NotificationCompat.Builder(this, id)
.setContentIntent(resultPendingIntent)
.setAutoCancel(true)
.setWhen(System.currentTimeMillis())
.setStyle(
NotificationCompat.InboxStyle()
.setSummaryText("Incoming orders")
)
.setSmallIcon(R.drawable.ic_baseline_delivery_dining_24)
.setLargeIcon(bitmap)
.setContentTitle("${getString(R.string.new_orders)} ${tableNumber}")
.setContentText("${orderNumber} ${name}")
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
summaryNotification.setGroup(BuildConfig.APPLICATION_ID)
messageNotification.setGroup(BuildConfig.APPLICATION_ID)
summaryNotification.setGroupSummary(true)
}
notificationManager.notify(value, messageNotification.build())
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N)
notificationManager.notify(1, summaryNotification.build())
I set the PendingIntent like this:
val resultPendingIntent = PendingIntent.getActivity(
this,
intent = Intent(this, NotificationActivity::class.java).apply {
putExtra(ORDER_ID, message.data["id"])
},
PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_ONE_SHOT or PendingIntent.FLAG_MUTABLE
)
The manifest.xml like this:
<application
android:name=".App"
android:allowBackup="false"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:roundIcon="#mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="#style/Theme.MyStyle">
...
<service
android:name=".service.NotificationMessage"
android:enabled="true"
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/logo_icon" />
<meta-data
android:name="com.google.firebase.messaging.default_notification_channel_id"
android:value="#string/default_notification_channel_id" />
</application>
When I open the app normally, every time I click the incoming notification. it's always work as expected. The app will go to my NotificationActivity.
But when my app doesn't opened, then I click the incoming notification. The app will running, then go to NotificationActivity directly. after that, when the next notification incoming, nothing to happen when I click. just disappear after clicked.
How to getting the notification click to work every time when I run the app from notification?
I am a newbie in android development.
I create a background service for receive pushNotification (with our own socket service, not FCM).
And now my device receive message and show notification successfully. But when I click the notification, it not return to my app.
When I click notification, show the error below:
ActivityManager: Unable to start service Intent { cmp=com.my.app/package.name.AppActivity } U=0: not found
Here is my code:
public static void setNotification(Service service, String message) {
NotificationManager manager = (NotificationManager) service.getSystemService(NOTIFICATION_SERVICE);
String appName = service.getString(R.string.app_name);
Uri alarmSound = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
NotificationCompat.Builder builder = new NotificationCompat.Builder(service)
.setContentTitle(appName)
.setContentText(message)
.setContentIntent(getDefaultIntent(service))
.setWhen(System.currentTimeMillis())
.setOngoing(false)
.setAutoCancel(true)
.setDefaults(Notification.DEFAULT_VIBRATE)
.setSmallIcon(R.drawable.icon)
.setLargeIcon(BitmapFactory.decodeResource(service.getResources(), R.drawable.icon))
.setSound(alarmSound);
Notification notification = builder.build();
notification.flags |= Notification.FLAG_AUTO_CANCEL;
manager.notify(1, notification);
}
private static PendingIntent getDefaultIntent(Service service) {
Intent intent = new Intent(service, AppActivity.class);
PendingIntent pendingIntent = PendingIntent.getService(service, 0, intent, PendingIntent.FLAG_CANCEL_CURRENT);
return pendingIntent;
}
}
MainActivity setting in AndroidManifest.xml
<activity android:name="package.name.AppActivity" android:configChanges="orientation|screenSize" android:label="#string/app_name" android:launchMode="singleTask" android:screenOrientation="landscape" android:theme= "#android:style/Theme.NoTitleBar.Fullscreen" android:enabled="true" android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
Please guide me what I am missing or doing wrong in this code. Many thanks.
I pass same id in padding intent and manager.notify(0, notification);
And use PendingIntent.getActivity instead of PendingIntent.getService
it works!
I got the problem you only cancel the current notification thats why Intent is not firing the activity Change your Pending intent
from
PendingIntent.FLAG_CANCEL_CURRENT);
to
PendingIntent.FLAG_UPDATE_CURRENT
| PendingIntent.FLAG_ONE_SHOT);
When push notification is received while the app is not running and the user presses on notification, it just disappears and the log says:
2019-10-22 12:42:45.747 23260-23260/de.app.test.staging E/FirebaseMessaging: Notification pending intent canceled
Here is the SplashActivity that is supposed to be launched as a Launcher Activity:
<activity
android:name="de.app.test.login.SplashActivity"
android:screenOrientation="portrait"
android:exported="true"
android:theme="#style/Theme.AppCompat.Light.NoActionBar.FullScreen">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
What can the issue be here?
For anyone looking for an answer, the back-end was sending the "click_action" to notification, therefore there was no intent filter for that Activity.
For me the click_action is "OPEN_ACTIVITY_1" so I just added one more intent-filter to my SplashActivity like this:
<intent-filter>
<action android:name="OPEN_ACTIVITY_1" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
you need to set pendingIntent object in notificationBuilder instance like
mBuilder = new NotificationCompat.Builder(this, CHANNEL_ID);
Intent intent = new Intent(context, TargetActivity.class));
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent, 0);
builder.setContentIntent(pendingIntent);
Please note that CHANNEL_ID is for build version greater or equal to Oreo
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
CHANNEL_ID = createNotificationChannel(CHANNEL_ID, "channelName");
}
#RequiresApi(Build.VERSION_CODES.O)
private String createNotificationChannel(String channelId, String channelName) {
// Create the NotificationChannel, but only on API 26+ because
// the NotificationChannel class is new and not in the support library
String description = "description";
NotificationChannel channel = new NotificationChannel(channelId, channelName, NotificationManager.IMPORTANCE_NONE);
channel.setLightColor(Color.BLUE);
channel.setLockscreenVisibility(Notification.VISIBILITY_PRIVATE);
channel.setDescription(description);
// Register the channel with the system; you can't change the importance
// or other notification behaviors after this
mNotificationManager.createNotificationChannel(channel);
return channelId;
}
Forground app:
You need a PendingIntent to open app.
Try this:
NotificationManager notificationManager = (NotificationManager) context
.getSystemService(Context.NOTIFICATION_SERVICE);
Notification notification = new Notification(icon, message, when);
Intent notificationIntent = new Intent(context, SplashActivity.class);
notificationIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP
| Intent.FLAG_ACTIVITY_SINGLE_TOP);
PendingIntent intent = PendingIntent.getActivity(context, 0,
notificationIntent, 0);
notification.setLatestEventInfo(context, title, message, intent);
notification.flags |= Notification.FLAG_AUTO_CANCEL;
notificationManager.notify(0, notification);
If Activity is in background or closed then notification message is shown in the notification center for app launcher activity.
You can use a BroadcastReceiver class. When you close the app, broadcast can listen this action. So, if you create a BroadcastReceiver class, you don't take this problem.
public class ClosedBroadcastReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
context.startForegroundService(new Intent(context, HomePage.class));
} else {
context.startService(new Intent(context, HomePage.class));
}
}
}
More Information:
https://firebase.google.com/docs/cloud-messaging/android/receive
I have a notification that have an action "Open Dial". I want when I click on "Open dial" action. My notification will disappear and Dial will appear.
I tried setAutocancel(true) and set notification.flags = Notification.FLAG_AUTO_CANCEL but these not working.
I know that I can't use SetAutocancel and set Flag_Auto_Cancel when I set action for my notification. If i want do that, I must use cancel(id) function of NotificationManager.
My idea to do that is sending an IntentFilter and using BroadcastReceiver to receive it When "Open Dial" is clicked.
But I don't know how I can do that because Intent.Action_Dial is an activity. If I use PendingIntent.getBroacast(), functions in onReceive() of Broadcast will work, but Dial won't show. Anyone know how I can resolve this problem ?.
This is my notication:
NotificationCompat.Builder builder = new NotificationCompat.Builder(this);
builder.setContentTitle("Notification");
builder.setContentText("This is notification");
builder.setSmallIcon(R.mipmap.ic_launcher);
builder.setTicker("This is ticker");
Intent intent = new Intent(Intent.ACTION_DIAL);
PendingIntent pendingIntent = PendingIntent.getActivity(this, MSG_B, intent, PendingIntent.FLAG_UPDATE_CURRENT);
builder.addAction(R.mipmap.ic_launcher, "Dial", pendingIntent);
builder.setAutoCancel(true);
Notification notification = builder.build();
notification.flags = Notification.FLAG_AUTO_CANCEL;
NotificationManager manager = (NotificationManager)this.getSystemService(NOTIFICATION_SERVICE);
manager.notify(id, notification);
this is my receiver
NotificationCompat.Builder builder;
Notification notification;
NotificationManager manager;
#Override
public void onReceive(Context context, Intent intent) {
manager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
if(intent.getAction().equals("download")){
Log.d("LOG","Download");
showNotify(3, context);
DownloadFileFromURL downloadFileFromURL = new DownloadFileFromURL();
downloadFileFromURL.execute("http://freebigpictures.com/wp-content/uploads/2009/09/river-edge.jpg");
}
else if(intent.getAction().equals("android.intent.action.DIAL")){
Log.d("LOG", "cacel Dial");
manager.cancel(NotificationServices.MSG_B);
}
else if(intent.getAction().equals("cancelActivity")){
Log.d("LOG","cacel Activity");
manager.cancel(NotificationServices.MSG_B);
}
else {
Log.d("LOG","Fail ABC");
}
}
This is mainifest
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<activity
android:name=".activity.MainActivity"
android:label="#string/app_name"
android:theme="#style/AppTheme.NoActionBar">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service
android:name=".services.NotificationServices"
android:enabled="true"
android:exported="true">
</service>
<receiver android:name=".broadcast.BroadcastReceiverImage">
<intent-filter>
<action android:name="download"/>
<action android:name="cancelDial"/>
<action android:name="cancelActivity"/>
<action android:name="android.intent.action.DIAL"></action>
</intent-filter>
</receiver>
</application>
The solution is to start the Activity in the BroadcastReceiver, after cancelling the Notification. Here is the code for the PendingIntent:
Intent intent = new Intent();
intent.setAction("cancelDial");
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, MSG_B, intent, PendingIntent.FLAG_UPDATE_CURRENT);
and the code for the BroadcastReceiver:
else if(intent.getAction().equals("cancelDial")){
Log.d("LOG", "Cancel Dial");
Intent intent = new Intent(Intent.ACTION_DIAL);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(intent);
manager.cancel(NotificationServices.MSG_B);
}
Hopefully it will help someone in the future.
I am checking Firebase Cloud Messaging to send notification. Have implemented it already and its receiving notification when app is in open state. But if I close app, its no longer gives notification. Is there any solution for this.
Code:
WebRequest wRequest;
wRequest = WebRequest.Create("https://fcm.googleapis.com/fcm/send");
wRequest.Method = "post";
wRequest.ContentType = " application/json;charset=UTF-8";
wRequest.Headers.Add(string.Format("Authorization: key={0}", AppId));
wRequest.Headers.Add(string.Format("Sender: id={0}", SenderId));
string postData = "{\"registration_ids\":[\"" + regIds + "\"], \"data\": "+ value +"}";
Byte[] bytes = Encoding.UTF8.GetBytes(postData);
wRequest.ContentLength = bytes.Length;
Stream stream = wRequest.GetRequestStream();
stream.Write(bytes, 0, bytes.Length);
stream.Close();
WebResponse wResponse = wRequest.GetResponse();
Messaging service-
public class MessagingService extends FirebaseMessagingService {
#Override
public void onMessageReceived(RemoteMessage remoteMessage) {
Map<String, String> data = remoteMessage.getData();
sendNotification(data);
}
public void showMessage(Map<String, String> serverData) {
Intent i = new Intent(this,MainActivity.class);
i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
PendingIntent pendingIntent = PendingIntent.getActivity(this,0,i,PendingIntent.FLAG_UPDATE_CURRENT);
NotificationCompat.Builder builder = new NotificationCompat.Builder(this)
.setAutoCancel(true)
.setContentTitle(serverData.get("Title"))
.setContentText(serverData.get("Message"))
.setSmallIcon(R.drawable.common_google_signin_btn_icon_dark)
.setContentIntent(pendingIntent);
NotificationManager manager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
manager.notify(Integer.parseInt(serverData.get("ItemId")),builder.build());
}
private void sendNotification(Map<String, String> serverData) {
Intent intent = new Intent(this, MainActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
PendingIntent pendingIntent = PendingIntent.getActivity(this,0 /* request code */, intent,PendingIntent.FLAG_UPDATE_CURRENT);
long[] pattern = {500,500,500,500,500};
Uri defaultSoundUri= RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
NotificationCompat.Builder notificationBuilder = (NotificationCompat.Builder) new NotificationCompat.Builder(this)
.setSmallIcon(R.drawable.common_google_signin_btn_icon_dark)
.setContentTitle(serverData.get("Title"))
.setContentText(serverData.get("Message"))
.setAutoCancel(true)
.setVibrate(pattern)
.setLights(Color.BLUE,1,1)
.setSound(defaultSoundUri)
.setContentIntent(pendingIntent);
NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(Integer.parseInt(serverData.get("ItemId")), notificationBuilder.build());
}
}
Main activity-
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
FirebaseMessaging.getInstance().subscribeToTopic("test");
FirebaseInstanceId.getInstance().getToken();
}
}
Manifest-
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="test.com.firebasenotify">
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service android:name=".MessagingService">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT" />
</intent-filter>
</service>
<service android:name=".InstanceIDService">
<intent-filter>
<action android:name="com.google.firebase.INSTANCE_ID_EVENT" />
</intent-filter>
</service>
</application>
</manifest>
There was no issue with the code. I was using Mi note 4, and somehow it does not show notification in Mi4 when app is closed. I tested with other android device and its working fine.
Thanks to Tim Castelijns and Frank van Puffelen for participating in the conversation.
There's good solution and explanation about that issue here. You need to set high priority for notification to tell android react immediately, otherwise it takes couple of minutes to display received notification.
I used Legacy Server Key instead of Server Key it had worked for me.
adding time_to_live key in your POST Payload will solve this problem.The value of this parameter must be a duration from 0 to 2,419,200 seconds, and it corresponds to the maximum period of time for which FCM stores and attempts to deliver the message. "time_to_live" : 3 Refer Firebase Docs
As per FCM docs onMessageReceived() won't be called when app is in the background. You should send a notification object on order to show it up in the system tray and when user clicks it the launcher activity will be open with data as extras with the intent. For payloads you should use data object. see docs and Receive Messages in an Android App