I am having trouble setting the notification icon on android studio.
I set up the drawable folder like so:
And I've also set the default icon in my AndroidManifest.xml file:
<meta-data
android:name="com.google.firebase.messaging.default_notification_icon"
android:resource="#drawable/notification_icon" />
And here I'm setting the icon field to notification_icon: https://developers.google.com/cloud-messaging/http-server-ref#downstream-http-messages-json (p.s. I'm aware that's GCM, but it works. I'm receiving the notification with everything besides the icon)
What am I missing? All I see is a white square inside a grey circle.
This is my backend code: Pushex.push(%{title: user.name, body: "message goes here", badge: 1, sound: "default", icon: "notification_icon"}, to: user.fcm_token, using: :gcm) (https://github.com/tuvistavie/pushex)
Fixed it... this is so stupid. Was inspired by this answer:
https://stackoverflow.com/a/28387744/1555312
I made my notification icon my app icon:
<meta-data
android:name="com.google.firebase.messaging.default_notification_icon"
android:resource="#mipmap/ic_launcher" />
And then the magic line in android/app/build.gradle...
defaultConfig {
targetSdkVersion 20 // this has to be < 21
...
}
Hope I save hours of someone else's life
With SDK 9.8.0 however, you can override the default! In your AndroidManifest.xml you can set the following fields to customise the icon and color:
<meta-data
android:name="com.google.firebase.messaging.default_notification_icon"
android:resource="#drawable/notification_icon" />
<meta-data android:name="com.google.firebase.messaging.default_notification_color"
android:resource="#color/google_blue" />
and
<manifest>
<application
android:icon="#drawable/icon"
android:label="#string/app_name">
<!-- Add your meta-data here-->
<activity
android:name=".MainActivity"
android:label="#string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
Check this code. It may help you.
public class MyFirebaseMessagingService extends FirebaseMessagingService {
private static final String TAG = "FCM Service";
#Override
public void onMessageReceived(RemoteMessage remoteMessage) {
Uri defaultSoundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
Intent intent = new Intent(getApplicationContext(), YourClass.class);
PendingIntent contentIntent = PendingIntent.getActivity(getApplicationContext(), NotificationID.getID(), intent,
PendingIntent.FLAG_UPDATE_CURRENT);
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(getApplicationContext())
.setSmallIcon(getNotificationIcon())
.setContentTitle(remoteMessage.getData().get("title"))
.setContentText(remoteMessage.getData().get("body"))
.setAutoCancel(true)
.setSound(defaultSoundUri)
.setStyle(new NotificationCompat.BigTextStyle().bigText(remoteMessage.getData().get("body")))
.setContentIntent(contentIntent);
NotificationManager notificationManager =
(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(NotificationID.getID(), notificationBuilder.build());
}
private int getNotificationIcon() {
boolean useWhiteIcon = (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP);
//If the build version is higher than kitkat we need to create Silhouette icon.
return useWhiteIcon ? R.mipmap.ic_notification : R.mipmap.ic_launcher;
}
public static class NotificationID {
private static final AtomicInteger c = new AtomicInteger(0);
public static int getID() {
return c.incrementAndGet();
}
}
}
If the build version is higher than kitkat we need to create Silhouette icon. For that online tool is available
Refer:https://romannurik.github.io/AndroidAssetStudio/icons-notification.html
I am using the FCM plugin and here is what worked for me (September 2019):
In config.xml (yourapp/config.xml)
Add the following to the tag at the end
xmlns:android="http://schemas.android.com/apk/res/android"
It should look something like this now:
<widget id="com.mydomain.app" version="1.0.0" xmlns="http://www.w3.org/ns/widgets" xmlns:cdv="http://cordova.apache.org/ns/1.0" xmlns:android="http://schemas.android.com/apk/res/android">
Or simply, copy the above line, replace the value of widget id, with your own.
In the same config.xml file:
Just before the tag corresponding to , add this:
<config-file parent="/manifest/application/" target="app/src/main/AndroidManifest.xml">
<meta-data android:name="com.google.firebase.messaging.default_notification_icon" android:resource="#drawable/fcm_push_icon" />
</config-file>
Visit the following link:
Notification Icon Generator
Upload a White version (single color) of your logo on a Transparent background. If you upload a colored version, you will get a dark gray icon, which would look nasty. If you don't have a white version of your logo, get it designed. Leave the rest of the settings as they are. For the Name textbox value, enter: fcm_push_icon. Then click on the Blue colored round shaped button to download the zip file.
Unzip the zip file that you just downloaded it the above step and extract its contents to a folder. You will notice that it contains a res folder. If you open this folder, it will contain other folders with the following names:
drawable-hdpi
drawable-mdpi
drawable-xhdpi
drawable-xxhdpi
drawable-xxxhdpi
Each of those folders will contain a PNG icon by the name "fcm_push_icon.png". The only difference between the icons in those different folders is their size.
Open the following file path in your app (If it doesn't exist, create it as shown below):
yourApp/platforms/android/app/src/main/res
Simply copy all the 5 folders listed in in the point 4 above, to the location shown just above i.e. into the res folder i.e. into yourApp/platforms/android/app/src/main/res
That's it! Now just build your app. Whenever you receive a notification, you will see your app icon in the notifications (at least on Android).
If anyone has figured out how to make colored icons appear in the Android notifications, please share your solution.
Related
I am using a foreground service. With it I have to show notification and add an icon to the status bar like this:
val notification = Builder(this, CHANNEL_ID)
.setContentTitle("adf")
.setSmallIcon(R.drawable.ic_baseline_settings_input_component_24)
.setBadgeIconType(NotificationCompat.BADGE_ICON_SMALL)
.setSmallIcon(R.drawable.ic_baseline_settings_input_component_24,2)
.setContentText("ewr").build()
startForeground(1, notification)
Text displayed correctly but icon doesn't changed and shows only the default Android's icon. How can I add a custom icon?
Did you add this into your android manifest xml?
<application
android:icon="#drawable/icon"
android:label="#string/app_name">
<!-- Add your meta-data here-->
<meta-data
android:name="com.google.firebase.messaging.default_notification_icon"
android:resource="#drawable/ic_baseline_settings_input_component_24" />
...
</application>
I am new to learning flutter. My flutter app has a native android background service on kotlin where I have a socket running and whenever the socket listens to something I generate a notification using NotificationCompat.Builder.
But I am unable to bring the Flutter app back to foreground when ever the user taps on the notification.
I have tried creating a pendingintent and passing it to notificationbuilder setContentIntent() but nothing happens on tap.
shownotification function on Native background service:
fun shownotification (){
packageNamer = this.getPackageName()
launchIntent = this.getPackageManager().getLaunchIntentForPackage(packageName)
var className = launchIntent?.getComponent()!!.className.javaClass
intent.action = "SELECT_NOTIFICATION"
intent.setClass(this,className)
pendingIntent = PendingIntent.getActivity(this, 1, intent, PendingIntent.FLAG_UPDATE_CURRENT)
var builder = NotificationCompat.Builder(this, "notifications")
.setOngoing(true)
.setContentIntent(pendingIntent)
.setFullScreenIntent(pendingIntent, true)
.setSmallIcon(R.drawable.common_google_signin_btn_icon_dark)
.setContentTitle("My notification")
.setContentText("Much longer text that cannot fit one line...")
.setStyle(NotificationCompat.BigTextStyle()
.bigText("Much longer text that cannot fit one line..."))
.setPriority(NotificationCompat.PRIORITY_HIGH)
manager?.notify(456,builder.build())
}
AndroidManifest.xml file:
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
<!-- io.flutter.app.FlutterApplication is an android.app.Application that
calls FlutterMain.startInitialization(this); in its onCreate method.
In most cases you can leave this as-is, but you if you want to provide
additional functionality it is fine to subclass or reimplement
FlutterApplication and put your custom class here. -->
<application
android:name=".MyApplication"
android:label="bizzyb_demo"
android:icon="#mipmap/ic_launcher">
<service android:name=".MyService" android:exported="true" android:enabled="true"/>
<activity
android:name=".MainActivity"
android:launchMode="singleTop"
android:theme="#style/LaunchTheme"
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
android:hardwareAccelerated="true"
android:windowSoftInputMode="adjustResize">
<!-- This keeps the window background of the activity showing
until Flutter renders its first frame. It can be removed if
there is no splash screen (such as the default splash screen
defined in #style/LaunchTheme). -->
<meta-data
android:name="io.flutter.app.android.SplashScreenUntilFirstFrame"
android:value="true" />
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
<intent-filter>
<action android:name="FLUTTER_NOTIFICATION_CLICK" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
</application>
What am I doing wrong here. I believe I am missing something very obvious here as I am new to mobile apps development.
Your expert feedbacks will be appreciated.
Thanks
You need to include click_action: FLUTTER_NOTIFICATION_CLICK as a "Custom data" key-value-pair in the notification payload.
Bundle bundle = new Bundle();
bundle.putString(Constants.EXAM_ID,String.valueOf(lectureDownloadStatus.getExamId()));
var builder = NotificationCompat.Builder(this, "notifications")
.setOngoing(true)
.setContentIntent(pendingIntent)
.setFullScreenIntent(pendingIntent, true)
.setSmallIcon(R.drawable.common_google_signin_btn_icon_dark)
.setContentTitle("My notification")
.setContentText("Much longer text that cannot fit one line...")
.setStyle(NotificationCompat.BigTextStyle()
.bigText("Much longer text that cannot fit one line..."))
.setPriority(NotificationCompat.PRIORITY_HIGH)
.setExtras(bundle) // Set the bundle
I am using firebase_messaging: ^5.0.1 package to achieve push notifications, everything is working fine in IOS whereas coming to the android when my mobile application running background I am receiving a notification but it is not navigating to the respective screens, it just opens the default screen. How to achieve navigation to that particular screen.
PS: I implemented click_action functionality that's the reason it's working fine in iOS but Android it shows the below message
W/FirebaseMessaging( 8260): Missing Default Notification Channel metadata in AndroidManifest. Default value will be used.
Here is my AndroidManifest:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.check">
<!-- io.flutter.app.FlutterApplication is an android.app.Application that
calls FlutterMain.startInitialization(this); in its onCreate method.
In most cases you can leave this as-is, but you if you want to provide
additional functionality it is fine to subclass or reimplement
FlutterApplication and put your custom class here. -->
<application
android:name="io.flutter.app.FlutterApplication"
android:label="Cargill FC"
android:icon="#mipmap/ic_launcher">
<activity
android:name=".MainActivity"
android:launchMode="singleTop"
android:theme="#style/LaunchTheme"
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
android:hardwareAccelerated="true"
android:allowBackup="false"
android:fullBackupContent="false"
android:windowSoftInputMode="adjustResize">
<!-- This keeps the window background of the activity showing
until Flutter renders its first frame. It can be removed if
there is no splash screen (such as the default splash screen
defined in #style/LaunchTheme). -->
<meta-data
android:name="io.flutter.app.android.SplashScreenUntilFirstFrame"
android:value="true" />
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
<intent-filter>
<action android:name="FLUTTER_NOTIFICATION_CLICK" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
Push notificatio code:
#override
void initState() {
super.initState();
tabController = new TabController(length: 2, vsync: this);
_firebaseMessaging.configure(
onMessage: (Map<String, dynamic> message) async {
onFirebaseMessage(message);
},
onLaunch: (Map<String, dynamic> message) async {
print("onLaunch: $message");
},
onResume: (Map<String, dynamic> message) async {
print("onResume: $message");
},
);
_firebaseMessaging.requestNotificationPermissions(const IosNotificationSettings(sound: true, badge: true, alert: true));
_firebaseMessaging.onIosSettingsRegistered.listen((IosNotificationSettings settings) {
print("Settings registered: $settings");
});
_firebaseMessaging.getToken().then(registerFirebaseTokenForUser);
}
Here onMessage is the only thing working perfectly in Android. I want to achieve the same when it is running background.
For those who are not able to find "string.xml", you can find it under: android>app>src>main>res>values. It is not the same as styles.xml. If you do not have one yet, you can create one:
Right click "values" folder,
Click New/Values Resource File
Copy, and paste the following text:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="default_notification_channel_id" translatable="false">fcm_default_channel</string>
</resources>
Maksim has a pretty solid answer here including links to the official docs. You need to add a the following meta-data tag in you Manifest:
<meta-data
android:name="com.google.firebase.messaging.default_notification_channel_id"
android:value="#string/default_notification_channel_id"/>
And in string.xml you can declare default_notification_channel_id in the following way:
<string name=“default_notification_channel_id”>Channel ID</string>
Then you must provide an attribute with that specific id when sending push notifications.
EDIT
It is possible to have multiple meta-data tags in your AndroidManifest.xml:
<meta-data
android:name="io.flutter.app.android.SplashScreenUntilFirstFrame"
android:value="true" />
<meta-data
android:name="com.google.firebase.messaging.default_notification_channel_id"
android:value="#string/default_notification_channel_id"/>
Adding FLUTTER_NOTIFICATION_CLICK is required to be sent, for onResume and onLunch to be executed.
{
"notification": {...},
"click_action": "FLUTTER_NOTIFICATION_CLICK"
}
For my golang server, this meant adding the AndroidConfig
message := &messaging.Message{
Topic: topic,
Notification: &messaging.Notification{/* */}
Data: data,
APNS: &messaging.APNSConfig{/* */}
Android: &messaging.AndroidConfig{
Notification: &messaging.AndroidNotification{
ClickAction: "FLUTTER_NOTIFICATION_CLICK",
},
},
}
1- At first, add this meta code after </activity> tag in AndroidManifest.xml which located in path <flutter project path>/android/app/src/main/AndroidManifest.xml
<meta-data
android:name="com.google.firebase.messaging.default_notification_channel_id"
android:value="#string/notification_channel_id" />
Note: If you set this meta inside <activity> the code will not work.
2- Modify file (or create new file if not exists) in this path <flutter project path>/android/app/src/main/res/values/string.xml to be like this:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="default_notification_channel_id" translatable="false">fcm_default_channel</string>
</resources>
This will solve the problem Missing Default Notification Channel metadata in AndroidManifest. Default value will be used.
But after that, you need to create this channel in Android, to do that go to file <flutter project path>//android/app/src/main/kotlin/com/examble/project_name/Application.kt and add this function:
private fun createChannel(){
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
// Create the NotificationChannel
val name = getString(R.string.default_notification_channel_id)
val channel = NotificationChannel(name, "default", NotificationManager.IMPORTANCE_HIGH)
val notificationManager: NotificationManager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
notificationManager.createNotificationChannel(channel)
}
}
Then call it from onCreate() function:
override fun onCreate() {
super.onCreate()
createChannel()
.........
}
Adding 'click_action': 'FLUTTER_NOTIFICATION_CLICK' to my notification's data solved this for me
If your flutter version is greater than 1.12 you don't need to create any file like Application.java or Application.kt just add the below meta value to you AndroidManifest file
<meta-data
android:name="com.google.firebase.messaging.default_notification_channel_id"
android:value="high_importance_channel" />
Reference: https://firebase.flutter.dev/docs/messaging/overview/
I want to create a notification from my app when a new picture is taken from the camera app. I want to achieve this when my app is not running. I am using Broadcast receiver to do this.
Here is my Code...
In Android Manifest..
<receiver
android:name=".receivers.CameraEventReceiver"
android:label="CameraEventReceiver"
android:enabled="true">
<intent-filter>
<action android:name="android.hardware.action.NEW_PICTURE" />
<data android:mimeType="image/*" />
</intent-filter>
</receiver>
In my receiver class
public class CameraEventReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
NotificationManager manager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O){
NotificationChannel channel = new NotificationChannel("CHANNEL_ID", "my channel name", NotificationManager.IMPORTANCE_HIGH);
manager.createNotificationChannel(channel);
}
NotificationCompat.Builder builder = new NotificationCompat.Builder(context, "CHANNEL_ID")
.setColor(ContextCompat.getColor(context, R.color.colorPrimary))
.setSmallIcon(R.mipmap.ic_launcher)
.setContentTitle("Picture Taken")
.setContentText("here is the uri : "+intent.getData())
.setDefaults(NotificationCompat.DEFAULT_VIBRATE)
.setAutoCancel(true);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN && Build.VERSION.SDK_INT < Build.VERSION_CODES.O){
builder.setPriority(NotificationCompat.PRIORITY_HIGH);
}
manager.notify(222, builder.build());
}
}
It is working fine for Android 6.0 when the app is running...
But it is not working for newer versions. What can I do to achieve this?
I want it to support for all devices with android versions greater than 4.1 (JELLY_BEAN)
Thanks in advance
But it is not working for newer versions.
Correct. Those broadcasts are no longer supported. See the Android 7.0 release notes.
What can I do to achieve this?
Take the picture yourself, whether using ACTION_IMAGE_CAPTURE, the camera APIs, or libraries (e.g., Fotoapparat, CameraKit-Android).
There is no direct replacement for that broadcast, and there was no requirement for camera apps to trigger that broadcast anyway.
You could use JobScheduler and addTriggerContentUri() to monitor the MediaStore for changes. However, I do not know how you would limit it to only pictures taken by a camera app.
I have implemented when new SMS arrived and i was facing the same issue. I have put below lines in my manifest file.
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
<action android:name="android.intent.action.INPUT_METHOD_CHANGED" />
</intent-filter>
I don't know anything about push notification. I am trying to learn. but I don't understand.
I have one table MySQL database in server system. When any changes are made in the table I want display notification on an android mobile app.
Can anyone provide any suggestions?
actually now recently mostly use for push notification FCM inside that u project ....
best link for build the push notication: link
steps for perform push notification -
Firebase Cloud Messaging Tutorial for Android
Go to firebase console and create a new project.
Now put your app name and select your country.
Now click on Add Firebase to Your Android App.
Now you have to enter your projects package name and click on ADD APP.
After clicking add app you will get google-services.json file.
On App side
Now come back to your android project. Go to app folder and paste google-services.json file
Now go to your root level build.gradle file and add the following code.
a. Add this line
classpath 'com.google.gms:google-services:3.0.0'
b. Add this line
compile 'com.google.firebase:firebase-messaging:9.0.0'
Now sync your project.
Create a class named MyFirebaseInstanceIDService.java and write the following code:
public class MyFirebaseInstanceIDService extends FirebaseInstanceIdService {
private static final String TAG = "MyFirebaseIIDService";
#Override
public void onTokenRefresh() {
//Getting registration token
String refreshedToken = FirebaseInstanceId.getInstance().getToken();
//Displaying token on logcat
Log.d(TAG, "Refreshed token: " + refreshedToken);
}
private void sendRegistrationToServer(String token) {
//You can implement this method to store the token on your server
//Not required for current project
}
}
Now create MyFirebaseMessagingService.java and write the following code:
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.media.RingtoneManager;
import android.net.Uri;
import android.support.v4.app.NotificationCompat;
import android.util.Log;
import com.google.firebase.messaging.FirebaseMessagingService;
import com.google.firebase.messaging.RemoteMessage;
/**
*
*/
public class MyFirebaseMessagingService extends FirebaseMessagingService {
private static final String TAG = "MyFirebaseMsgService";
#Override
public void onMessageReceived(RemoteMessage remoteMessage) {
//Displaying data in log
//It is optional
Log.d(TAG, "From: " + remoteMessage.getFrom());
Log.d(TAG, "Notification Message Body: " + remoteMessage.getNotification().getBody());
//Calling method to generate notification
sendNotification(remoteMessage.getNotification().getBody());
}
//This method is only generating push notification
//It is same as we did in earlier posts
private void sendNotification(String messageBody) {
Intent intent = new Intent(this, MainActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent,
PendingIntent.FLAG_ONE_SHOT);
Uri defaultSoundUri= RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this)
.setSmallIcon(R.mipmap.ic_launcher)
.setContentTitle("Firebase Push Notification")
.setContentText(messageBody)
.setAutoCancel(true)
.setSound(defaultSoundUri)
.setContentIntent(pendingIntent);
NotificationManager notificationManager =
(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(0, notificationBuilder.build());
}
}
Now we have to define the above services in our AndroidManifest.xml file. So go to manifest and modify as follows.
<!-- Adding Internet Permission -->
<uses-permission android:name="android.permission.INTERNET"/>
<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>
<!--
Defining Services
-->
<service
android:name=".MyFirebaseMessagingService">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT"/>
</intent-filter>
</service>
<service
android:name=".MyFirebaseInstanceIDService">
<intent-filter>
<action android:name="com.google.firebase.INSTANCE_ID_EVENT"/>
</intent-filter>
</service>
</application>
finally
Go to firebase console and select the app you created.
From the left menu select notification.
Click on new message.
Enter message, select single device and paste the token you copied and click on send. The same as I did on the video, and check your device
here is a good explanation about this:
http://quickblox.com/developers/SimpleSample-messages_users-android
The overall steps are:
Create a google API project
Enable push notifications for the project and get a API key
Get a registration ID through android app (each device has a registration ID for a specific application)
Create a server application to send your push messages as push notifications through google servers by GSM
Create a notification when you get the push notification on the application side
It's not something i can write all here by details. Use Google for every step.
The first thing - Google Push Notifications are called GCM (Google Cloud Messaging). Wrong name usage might lead you to wrong information or tutorial. The other thing, you should rely on Developer. In this case start from Google Developers website, where you will find most of basic info and code examples to start with. https://developers.google.com/cloud-messaging/.
Update
GCM is deprecated, you should use Firebase Cloud Messaging (FCM)
You can check out Firebase... Check out this link
https://firebase.google.com/docs/cloud-messaging/
This link is sufficient to learn about Push Notifications
And as for sending notification when data in database changes, make your API send a request to FCM server so that it delivers necessary data to clients.