I am implementing FCM(Firebase cloud messaging) for push notifications. I could get push notification from the server using my service class successfully. But, how do I send data(messages) from the service class to the activity?
Service.java
public class Service extends FirebaseMessagingService {
private static final String TAG = "MyFirebaseMsgService";
#Override
public void onMessageReceived(RemoteMessage remoteMessage) {
sendNotification(remoteMessage.getNotification().getBody());
}
private void sendNotification(String messageBody) {
Intent intent = new Intent(this, FCMActivity.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);
notificationBuilder.setDefaults(Notification.DEFAULT_VIBRATE);
notificationBuilder.setLights(Color.RED, 1000, 300);
NotificationManager notificationManager =
(NotificationManager)
getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(0, notificationBuilder.build());
}
}
FCMActivity.java
public class FCMActivity extends AppCompatActivity {
private TextView mTextView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_fcm);
mTextView = (TextView) findViewById(R.id.txt);
}
}
There are several options, among those are:
Register a BroadcastReceiver inside your Activity with an IntentFilter for your custom action (action is just a String identifier for a broadcast message type), and send the broadcast from service using LocalBroadcastManager.getInstance().sendBroadcast(Intent intent) method
Use an event bus, for example the very popular GreenRobot EventBus library. See https://github.com/greenrobot/EventBus#eventbus-in-3-steps for explanation.
Both of these options require registering and unregistering a listener / receiver inside your Activity, which is best done in onResume/onPause for events that should trigger UI changes.
Additionally, you can bind to the service from your Activity.
You should use IBinder in your service and ServiceConnection in your Activity
Related
I have problem - it is not possible to return to the main activity after clicking on the received notification. The notification itself is not clickable. The notification is triggered in the onPause method (in the background)
My main activity is MainActivity, which is setting up notification via PendingIntent and AlarmManager
public class MainActivity extends AppCompatActivity {
private NotificationManager notificationManager;
private static final int NOTIFY_ID = 1;
private static final String CHANNEL_ID = "CHANNEL_ID";
NotificationPublisher notificationPublisher;
Button b1;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
createNotificationChannel();
}
private void createNotificationChannel() {
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.O) {
CharSequence name = "LemubitReminderChannel";
String description = "Channel for Lemubit Reminder";
int importance = NotificationManager.IMPORTANCE_DEFAULT;
NotificationChannel channel = new NotificationChannel("notifyLemubid", name, importance);
channel.setDescription(description);
notificationManager = (NotificationManager) getApplicationContext().getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.createNotificationChannel(channel);
}
}
private void reminderMethod (){
Toast.makeText(this, "Напоминание о запуске фонового уведомления", Toast.LENGTH_SHORT).show();
Intent intent = new Intent(getApplicationContext(), NotificationPublisher.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK);
PendingIntent pendingIntent = PendingIntent.getBroadcast(getApplicationContext(), 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
long inPauseTime = System.currentTimeMillis();
long ten = 2 * 1000;
alarmManager.set(AlarmManager.RTC_WAKEUP, inPauseTime + ten, pendingIntent);
}
#Override
protected void onPause() {
super.onPause();
reminderMethod();
}
}
Broadcast receiver
public class NotificationPublisher extends BroadcastReceiver {
public void onReceive(Context context, Intent intent) {
int unicode = 0x1F62D;
NotificationCompat.Builder builder = new NotificationCompat.Builder(context, "notifyLemubid")
.setAutoCancel(true)
.setContentTitle("текст " + getEmojiByUnicode(unicode))
.setContentText("текст")
.setSmallIcon(R.drawable.ic_launcher_background)
.setPriority(NotificationCompat.PRIORITY_DEFAULT);
NotificationManagerCompat notificationManagerCompat = NotificationManagerCompat.from(context);
notificationManagerCompat.notify(200, builder.build());
}
public String getEmojiByUnicode(int unicode){
return new String(Character.toChars(unicode));
}
}
You need to set the contentIntent on the Notification, then, when the user clicks the Notification, the contentIntent will be dispatched. If you want the user to open an Activity of your app, then just create an Intent to your Activity, wrap that in a PendingIntent and call setContentIntent() on the `Notification. There's hundreds of howtos and tutorials for how to do this, just search a bit.
I am trying to create an app that will open another app at a specified time. To do this, I used an AlarmManager that starts a service. It works just fine if my app is open when the alarm is triggered. I get a notification that the service started, and the other app opens. However, if my app is in the background (after pressing the home button), and the alarm triggers, I get a notification that the service started, but the other app does not launch. What am I doing wrong? I am testing this on a Pixel 3 emulator running API level 29 (Android 10/Q).
MainActivity.java
public class MainActivity extends AppCompatActivity {
public static final int REQUEST_CODE=101;
public static int aHour;
public static int aMinute;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
public void setAlarm() {
AlarmManager am = (AlarmManager) getSystemService(ALARM_SERVICE);
Intent intent = new Intent(this, amReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, REQUEST_CODE, intent, PendingIntent.FLAG_UPDATE_CURRENT);
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
calendar.set(Calendar.HOUR_OF_DAY, aHour);
calendar.set(Calendar.MINUTE, aMinute);
am.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), pendingIntent);
}
//Some code that sets aHour and aMinute
//Some code that triggers setAlarm()
}
amReciever.java
public class amReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Intent i = new Intent(context, launcherService.class);
ContextCompat.startForegroundService(getApplicationContext(), i);
}
}
launcherService.java
public class launcherService extends Service {
public static final String CHANNEL_ID = "ForegroundServiceChannel";
#Override
public void onCreate() {
super.onCreate();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
createNotificationChannel();
Intent notificationIntent = new Intent(this, MainActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(this,
0, notificationIntent, 0);
Notification notification = new NotificationCompat.Builder(this, CHANNEL_ID)
.setContentTitle("Foreground Service")
.setContentText("App is launching.")
.setSmallIcon(R.drawable.ic_launcher_foreground)
.setContentIntent(pendingIntent)
.build();
startForeground(1, notification);
Intent launcher = getApplicationContext().getPackageManager().getLaunchIntentForPackage("com.example.app");
if (launcher != null) {
startActivity(launcher);
}
return START_NOT_STICKY;
}
#Override
public IBinder onBind(Intent intent) {
return null;
}
private void createNotificationChannel() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
NotificationChannel serviceChannel = new NotificationChannel(
CHANNEL_ID,
"Foreground Service Channel",
NotificationManager.IMPORTANCE_DEFAULT
);
NotificationManager manager = getSystemService(NotificationManager.class);
manager.createNotificationChannel(serviceChannel);
}
}
}
AndroidManifest.xml
<uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
<service android:name=".launcherService"
android:enabled="true"
android:exported="true" />
As of Android 10 (API level 29), you cannot start activities from the background anymore.
There are a number of exceptions to this rule that may or may not apply to your given scenario.
If none of the exceptions apply, you might want to consider displaying a high-priority notification, possibly with a full-screen Intent.
I am new to android programming and just started working on my first app recently. I am trying to create a daily notification that a user would get at the same time every day. I've looked through documentation and some tutorials and came up with this. For some reason the code below does not work. It has no errors, runs just fine, but doesn't do the job and I can't seem to find the problem. There is also some code that is responsible for re-scheduling notifications when the device restarts but I don't think the problem lies there since I don't even get the initial notifications.
MainActivity.java
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
show = (Button)findViewById(R.id.btn_show);
show.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
startAlarm(true,true);
}
});
myWebView = (WebView)findViewById(R.id.webView1);
WebSettings webSettings = myWebView.getSettings();
webSettings.setJavaScriptEnabled(true);
myWebView.loadUrl("http://google.com");
myWebView.setWebViewClient(new WebViewClient());
}
private void startAlarm(boolean isNotification, boolean isRepeat) {
AlarmManager manager = (AlarmManager)getSystemService(Context.ALARM_SERVICE);
Intent myIntent;
PendingIntent pendingIntent;
// SET TIME HERE
Calendar calendar= Calendar.getInstance();
calendar.set(Calendar.HOUR_OF_DAY,14);
calendar.set(Calendar.MINUTE,45);
myIntent = new Intent(MainActivity.this,AlarmNotificationReceiver.class);
pendingIntent = PendingIntent.getBroadcast(this,0,myIntent,0);
if(!isRepeat)
manager.set(AlarmManager.RTC_WAKEUP, SystemClock.elapsedRealtime()+3000,pendingIntent);
else
manager.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), AlarmManager.INTERVAL_DAY,pendingIntent);
}
AlarmNotificationReciever.Java
public class AlarmNotificationReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
NotificationCompat.Builder builder = new NotificationCompat.Builder(context);
Intent myIntent = new Intent(context, MainActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(
context,
0,
myIntent,
FLAG_ONE_SHOT );
builder.setAutoCancel(true)
.setDefaults(Notification.DEFAULT_ALL)
.setWhen(System.currentTimeMillis())
.setSmallIcon(R.mipmap.ic_launcher)
.setContentTitle("Zodiac")
.setContentIntent(pendingIntent)
.setContentText("Check out your horoscope")
.setDefaults(Notification.DEFAULT_LIGHTS | Notification.DEFAULT_SOUND)
.setContentInfo("Info");
NotificationManager notificationManager = (NotificationManager)context.getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(1,builder.build());
}
}
It should basically schedule a notification at 14:45 after pressing the button but for some reason it doesn't.
Since Android Oreo, implicit broadcast receivers won’t work when
registered in the AndroidManifest.xml
To use Implicit Receivers in your application, you need to define them programmatically in your code, using
registerReceiver().
3.Using registerReceiver() we can programmatically register and unregisterReceiver() during the lifecycle of the activity. This way
implicit receivers would only be called when our
activity/application is alive and not at other times.
we working fine:
[public class MainActivity extends AppCompatActivity {
Button show;
WebView myWebView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// register custom intent filter
*registerReceiver(new AlarmNotificationReceiver(),new IntentFilter(Intent.ACTION_BATTERY_CHANGED));*
\[enter image description here\]\[1\]
show = (Button)findViewById(R.id.btn_show);
show.setOnClickListener(new View.OnClickListener() {
#RequiresApi(api = Build.VERSION_CODES.N)
#Override
public void onClick(View v) {
startAlarm(true,true);
}
});
myWebView = (WebView)findViewById(R.id.webView1);
WebSettings webSettings = myWebView.getSettings();
webSettings.setJavaScriptEnabled(true);
myWebView.loadUrl("http://google.com");
myWebView.setWebViewClient(new WebViewClient());
}
#RequiresApi(api = Build.VERSION_CODES.N)
private void startAlarm(boolean isNotification, boolean isRepeat) {
AlarmManager manager = (AlarmManager)getSystemService(Context.ALARM_SERVICE);
Intent myIntent;
PendingIntent pendingIntent;
// SET TIME HERE
Calendar calendar= Calendar.getInstance();
calendar.set(Calendar.HOUR_OF_DAY,14);
calendar.set(Calendar.MINUTE,45);
myIntent = new Intent(MainActivity.this,AlarmNotificationReceiver.class);
pendingIntent = PendingIntent.getBroadcast(this,0,myIntent,0);
if(!isRepeat)
manager.set(AlarmManager.RTC_WAKEUP, SystemClock.elapsedRealtime()+3000,pendingIntent);
else
manager.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), AlarmManager.INTERVAL_DAY,pendingIntent);
}
}][1]
1)But the above code may not work in all versions i.e notofication will not came oreo(8.0) and above.beacause of NotificationBuilder is depricated and background execution limits.Go to
2)Use Notification Channel .like below
use this code.hope its works fine!!!
void issueNotification()
{
// make the channel. The method has been discussed before.
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
makeNotificationChannel("CHANNEL_1", "Example channel", NotificationManager.IMPORTANCE_DEFAULT);
}
// the check ensures that the channel will only be made
// if the device is running Android 8+
NotificationCompat.Builder notification =
new NotificationCompat.Builder(this, "CHANNEL_1");
// the second parameter is the channel id.
// it should be the same as passed to the makeNotificationChannel() method
notification
.setSmallIcon(R.mipmap.ic_launcher) // can use any other icon
.setContentTitle("Notification!")
.setContentText("This is an Oreo notification!")
.setNumber(3); // this shows a number in the notification dots
NotificationManager notificationManager =
(NotificationManager)getSystemService(NOTIFICATION_SERVICE);
assert notificationManager != null;
notificationManager.notify(1, notification.build());
// it is better to not use 0 as notification id, so used 1.
}
I'm trying to make a notification appear in the notification manager from a non activity class, but I can't make it happen
public void showNotification(Context context) {
NotificationCompat.Builder mBuilder =
new NotificationCompat.Builder(context)
//.setSmallIcon(R.drawable.notif1)
.setContentTitle("Car crash occure!")
.setContentText("Tap to view location.");
PendingIntent contentIntent = PendingIntent.getActivity(context, 0,
new Intent(context, MapsActivity.class), 0);
mBuilder.setContentIntent(contentIntent);
mBuilder.setDefaults(Notification.DEFAULT_SOUND);
mBuilder.setAutoCancel(true);
NotificationManager mNotificationManager =
(NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
mNotificationManager.notify(0, mBuilder.build());
}
Use Intent Service instead of Activity
public static class NotificationActionService extends IntentService {
public NotificationActionService() {
super(NotificationActionService.class.getSimpleName());
}
#Override
protected void onHandleIntent(Intent intent) {
String action = intent.getAction();
if (ACTION_1.equals(action)) {
Log.d("ACTION_NOTIFICATION", "Notification Clicked");
}
// TODO: handle action 1.
// If you want to cancel the notification: NotificationManagerCompat.from(this).cancel(NOTIFICATION_ID);
}
}
Is it possible (and if yes how) to make push notification sound repeat until it's read? I am creating app that notifies user about new event in app, but user needs to read notification as soon as possible. When user "reads" notification it should stop ringing. Here's code:
public class GCMIntentService extends IntentService {
String mes;
HelperGlobals glob;
public GCMIntentService() {
super("GcmIntentService");
}
#SuppressLint("SimpleDateFormat")
protected void onHandleIntent(Intent intent) {
Bundle extras = intent.getExtras();
glob = (HelperGlobals) getApplicationContext();
GoogleCloudMessaging gcm = GoogleCloudMessaging.getInstance(this);
String messageType = gcm.getMessageType(intent);
// .... Doing work here
GcmBroadcastReceiver.completeWakefulIntent(intent);
}
public void createPush(String title, String msg, Intent intent) {
Uri soundUri = Uri.parse("android.resource://example.project.com/" + R.raw.notification);
Context context = getApplicationContext();
Intent notificationIntent = new Intent(context, DoNothing.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP
| Intent.FLAG_ACTIVITY_SINGLE_TOP
| Intent.FLAG_ACTIVITY_NEW_TASK);
PendingIntent pIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0);
Notification n = new Notification.Builder(this)
.setContentTitle(title)
.setContentText(msg)
.setSmallIcon(R.drawable.ic_launcher)
.setContentIntent(pIntent)
.setAutoCancel(true).build();
n.defaults |= Notification.DEFAULT_VIBRATE;
//n.defaults |= Notification.DEFAULT_SOUND;
n.sound = soundUri;
NotificationManager notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
notificationManager.notify(0, n);
}
}
And BroadcastReceiver:
public class GcmBroadcastReceiver extends WakefulBroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Log.d("BukuLog", "Receiver");
// Explicitly specify that GcmMessageHandler will handle the intent.
ComponentName comp = new ComponentName(context.getPackageName(),
GCMIntentService.class.getName());
// Start the service, keeping the device awake while it is launching.
startWakefulService(context, (intent.setComponent(comp)));
setResultCode(Activity.RESULT_OK);
}
}
like this:
Notification note = mBuilder.build();
//here
note.flags = Notification.FLAG_INSISTENT;
mNotificationManager.notify(1, note);
int FLAG_INSISTENT : Bit to be bitwise-ored into the flags field that if set, the audio will be repeated until the notification is cancelled or the notification window is opened.
follow android developer