Run Android Notifications when App is closed without GCM/Firebase - android

I am working on an App where I want to show Push Notifications. Please note that since it is my client's requirement NOT to use any third party services, so using GCM/Firebase is out of question.
I am successfully able to show the notification from Service using the below code.
public class SendNotificationService extends Service {
#Override
public void onCreate() {
super.onCreate();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
CharSequence title = "Notification Title";
CharSequence message = "This is a test notification.";
Drawable drawable= ContextCompat.getDrawable(this,R.drawable.brand_icon_color);
Bitmap bitmap = ((BitmapDrawable)drawable).getBitmap();
NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(this)
.setSmallIcon(R.drawable.brand_icon_small_color)
.setLargeIcon(bitmap)
.setAutoCancel(true)
.setContentTitle(title)
.setOngoing(false);
mBuilder.setContentText(message);
mBuilder.setTicker(message);
mBuilder.setWhen(System.currentTimeMillis());
NotificationManager notificationManager = (NotificationManager) this.getSystemService(NOTIFICATION_SERVICE);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, new Intent(), 0);
mBuilder.setContentIntent(pendingIntent);
notificationManager.notify(0, mBuilder.build());
return START_STICKY;
}
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onDestroy() {
Toast.makeText(this, "Notifications Stopped...", Toast.LENGTH_LONG).show();
}
}
I am starting this service through my AsyncTask onPostExecute method.
Intent intentService = new Intent(context, SendNotificationService.class);
context.startService(intentService);
I created this following a number of tutorials and found that if I will go to my Running Apps in Android Settings, I will be able to see this service running. But I was unable to locate any such service.
Now the problem is when I close my Application, the notification also disappears. I want it to stay until the user takes any action.
In addition to this, I want this service to start with phone startup even if the app is not started.

1) Add the permission to the manifest:
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
2) Add a receiver to the manifest to run on boot:
<receiver android:name="com.example.MyBroadcastReceiver">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
In MyBroadcastReceiver.java:
package com.example;
public class MyBroadcastReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Intent startServiceIntent = new Intent(context, MyService.class);
context.startService(startServiceIntent);
}
}

Related

BroadcastReceiver not firing from NotificationManager

I have the following code:
public void sendNotification() {
try {
NotificationCompat.Builder builder = new NotificationCompat.Builder(this);
builder.setSmallIcon(android.R.drawable.ic_dialog_alert);
final Intent intent = new Intent(this, NotifyBroadcastReceiver.class);
//Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse("https://www.journaldev.com/"));
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0, intent, 0);
builder.setContentIntent(pendingIntent);
builder.setLargeIcon(BitmapFactory.decodeResource(getResources(), R.drawable.logo));
builder.setContentTitle("Notifications Title");
builder.setContentText("Your notification content here.");
builder.setSubText("Tap to view the website.");
builder.setAutoCancel(true);
final Intent noted = new Intent(this, NotifyBroadcastReceiver.class);
noted.setAction("com.mawaeed.common.LaunchActivity");
PendingIntent notedpendingIntent = PendingIntent.getBroadcast(this, 0, noted, 0);// PendingIntent.FLAG_UPDATE_CURRENT ) ;
builder.addAction(0, "Noted", notedpendingIntent);
NotificationManager notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
// Will display the notification in the notification bar
notificationManager.notify(1, builder.build());
}catch(Exception exo) {
Toast.makeText(this, exo.toString(),Toast.LENGTH_LONG).show();
}
}
Also I have my BroadcastReceiver
public class NotifyBroadcastReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(context,"ddd",Toast.LENGTH_LONG).show();
Toast.makeText(context,"app",Toast.LENGTH_LONG).show();
}}
I am calling sendNotification from FirebaseMessagingService, Notification appears normally.
public void onMessageReceived(RemoteMessage remoteMessage) {
sendNotification();
}
When clicking on the notification or Noted action, BroadcastReceiver onReceive not calling,
I already registered my BroadcastReceiver in mainafist
<receiver android:name=".NotifyBroadcastReceiver" android:exported="true">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED"/>
<action android:name="android.intent.action.INPUT_METHOD_CHANGED" />
</intent-filter>
</receiver>
The strange thing is I created a new application and copied all the code above to it, and I called the sendNotification from onCreate(), and when clicking on the notification it calls onReceive without problem.
I also tried same with my Application and called sendNotification from onCreate of my main activity, Notification appears but clicking on notification or Noted action not calling onReceive
Why it is not working from my application
I had to uninstall the app first then install it again, and now it works.

How to keep service alive when remove app from stack

I want to show notification every minute using Alarm Manager, I have implemented below code, it's working fine but the problem is when I remove app from stack the service is not running.
I want keep alive, I have tried START_STICKY in onStartCommand and also used onTaskRemoved but it's same.
I also tried to implement using WakefulIntentService but the problem is same. My code is below.
In MainActivity
Intent myIntent = new Intent(NotificationDemo.this, MyReceiver.class);
myIntent.putExtra("title", "2 minutes");
Random random = new Random();
int m = random.nextInt(9999 - 1000) + 1000;
Log.d("m::: In Notification", m + "");
myIntent.putExtra("id", m);
pendingIntent = PendingIntent.getBroadcast(NotificationDemo.this, m, myIntent, 0);
AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
// alarmManager.setRepeating(AlarmManager.RTC, System.currentTimeMillis(),alarmManager.Inte pendingIntent);
alarmManager.setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP,
SystemClock.elapsedRealtime(),
1 * 60 * 1000,
pendingIntent);
MyService
public class MyAlarmService extends Service {
private NotificationManager mManager;
#Override
public IBinder onBind(Intent arg0) {
// TODO Auto-generated method stub
return null;
}
#Override
public void onCreate() {
// TODO Auto-generated method stub
super.onCreate();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
String title = intent.getStringExtra("title");
int id = intent.getIntExtra("id", 0);
mManager = (NotificationManager) this.getApplicationContext().getSystemService(this.getApplicationContext().NOTIFICATION_SERVICE);
Intent intent1 = new Intent(this.getApplicationContext(), MainActivity.class);
Notification notification = new Notification(R.mipmap.ic_launcher, title, System.currentTimeMillis());
intent1.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_CLEAR_TOP);
Log.d("id::", id + "");
PendingIntent pendingNotificationIntent = PendingIntent.getActivity(this.getApplicationContext(), id, intent1, PendingIntent.FLAG_UPDATE_CURRENT);
notification.flags |= Notification.FLAG_AUTO_CANCEL;
// notification.setLatestEventInfo(this.getApplicationContext(), "AlarmManagerDemo", "This is a test message!", pendingNotificationIntent);
NotificationCompat.Builder builder = new NotificationCompat.Builder(MyAlarmService.this);
notification = builder.setContentTitle(title)
.setContentText("Hellooo...")
.setTicker("Good Evening...")
.setSmallIcon(android.R.drawable.ic_btn_speak_now)
.setVibrate(new long[]{1000, 1000, 1000, 100})
.setLights(5, 5, 5)
.setContentIntent(pendingNotificationIntent).build();
mManager.notify(id, notification);
startForeground(1337, notification);
return START_STICKY;
}
#Override
public void onDestroy() {
// TODO Auto-generated method stub
super.onDestroy();
// sendBroadcast(new Intent("IWillStartAuto"));
}
#Override
public void onTaskRemoved(Intent rootIntent) {
super.onTaskRemoved(rootIntent);
// sendBroadcast(new Intent("IWillStartAuto"));
// Intent intent = new Intent(getApplicationContext(),MyReceiver.class);
// sendBroadcast(intent);
}
}
and this is my receiver
public class MyReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
String title = intent.getStringExtra("title");
int id = intent.getIntExtra("id", 0);
Intent service1 = new Intent(context, MyAlarmService.class);
service1.putExtra("title", title);
service1.putExtra("id", id);
context.startService(service1);
}
}
In Manifest
<receiver android:name=".MyReceiver">
<!--<intent-filter>
<action android:name="IWillStartAuto"/>
</intent-filter>-->
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
<service
android:name=".MyAlarmService"
android:enabled="true"
android:stopWithTask="false" />
You need to start your service in foreground.
You are missing something this in your service OnCreate() method.
startForeground(1337, notification);
return START_STICKY;
And don't stop your service in your activities or fragments onDestroy() methods.
I tested this code on my phone with android 6.0 and on emulator with android 7.0 in both is working fine, even removing the application from the stack. The notification still working even removing the receiver code.
You can try with receiver configuration process=":remote" to keep receiver alive. I faced with this problem and here is my solution.
Did you try the code with any other output statements? Notifications are, off-late, not being fired for me either - I might blame Instant Run, nevertheless could you try replacing the notification-firing code snippet with maybe something like a Toast? Since Toasts don't work in services, maybe you could try creating a file in your external storage directory whenever the service starts to know that maybe it's up and running?

Can't swipe-delete a notification from service

I have a service which downloads data, runs in a separate process (so that it doesn't die/restart when the app is closed) and shows a notification with it's progress. I want to be able to stop the service if the user swipe-deletes the notification, but have so far been unable to do it. Relevant code below:
DatabaseDownloadService.java
public class DatabaseDownloadService extends Service
{
private final static int NOTIFICATION_ID = 1337;
private final static String NOTIFICATION_DISMISSAL_TAG = "my_notification_dismissal_tag";
private NotificationManager mNotificationManager;
#Override
public void onCreate()
{
super.onCreate();
mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
Notification notification = getNotification("Downloading database...");
startForeground(NOTIFICATION_ID, notification);
startDownloadingStuff();
}
private Notification getNotification(String text)
{
NotificationDismissedReceiver receiver = new NotificationDismissedReceiver();
registerReceiver(receiver, new IntentFilter(NOTIFICATION_DISMISSAL_TAG));
Intent intent = new Intent(this, NotificationDismissedReceiver.class);
PendingIntent deleteIntent = PendingIntent.getBroadcast(this, NOTIFICATION_ID, intent, 0);
return new NotificationCompat.Builder(this)
.setSmallIcon(R.mipmap.ic_launcher)
.setContentTitle("My Awesome App")
.setContentText(text)
.setDeleteIntent(deleteIntent)
.build();
}
public class NotificationDismissedReceiver extends BroadcastReceiver
{
#Override
public void onReceive(Context context, Intent intent)
{
int notificationId = intent.getExtras().getInt(NOTIFICATION_DISMISSAL_TAG);
Toast.makeText(context, "Download cancelled", Toast.LENGTH_SHORT).show();
// Do more logic stuff here once this works...
}
}
}
AndroidManifest.xml
<application
... properties and activities go here...>
<service
android:name=".DatabaseDownloadService"
android:process=":dds_process"
android:enabled="true"/>
<receiver
android:name="com.myapp.DatabaseDownloadService$NotificationDismissedReceiver"
android:exported="false"/>
</application>
As far as I can tell, the .setDeleteIntent() should make the notification swipe-deletable, which should then send a broadcast, which should then be caught by my NotificationDismissedReceiver. However, as it stands, I can't even swipe-delete the notification, and I never see the "Download cancelled" Toast...
You can call to stop the service from foreground, passing false, means not remove the notification. For Android N and above, you can pass STOP_FOREGROUND_DETACH also.
stopForeground(false);
After that you can stop the service by yourself also.
stopSelf();
Instead of using startForeground(), use :
NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify("tag", NOTIFICATION_ID, notification);

Notification created in BroadcastReceiver doesn't work, on app close

This is my code. It works fine, if I use this in a separate Android studio project. But when I integrate the code to another project it is causing a problem.
If app is open I am able to receive the notifications. But on app close, the notifications are not received.
Also I have observed one thing - I set my alarm at 1:10 (let's say) and close, and re-open the app at 1.09. I am receiving the notification at 1.10 !!.
I am not able to identify what's happening. Please tell me even if am doing silly mistake, Thank you.
public class BroadCast {
public void broadcastIntent(int selected, Context context, long userMilli) {
Intent intent = new Intent(context.getApplicationContext(), ReminderReceiver.class);
Bundle bundle = new Bundle();
bundle.putInt("selected", selected);
intent.putExtras(bundle);
intent.setAction("android.media.action.DISPLAY_NOTIFICATION");
intent.addCategory("android.intent.category.DEFAULT");
Calendar calendar = Calendar.getInstance();
long curMilli = calendar.getTimeInMillis();
PendingIntent pendingIntent = PendingIntent.getBroadcast(context.getApplicationContext(), selected, intent, PendingIntent.FLAG_UPDATE_CURRENT);
AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
if(Build.VERSION.SDK_INT > Build.VERSION_CODES.KITKAT)
alarmManager.setExact(AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime() + (userMilli-curMilli), pendingIntent);
else
alarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime() + (userMilli-curMilli), pendingIntent);
}
}
Above code creates an intent and broadcast using alarmManager.
public class ReminderReceiver extends BroadcastReceiver {
public ReminderReceiver() {
}
#Override
public void onReceive(Context context, Intent intent) {
Bundle bundle = intent.getExtras();
int selected = bundle.getInt("selected");
sendNotification(context, selected);
}
private void sendNotification(Context context, int selected) {
String notificationContentText = "String to display";
NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
NotificationCompat.Builder builder = new NotificationCompat.Builder(context);
builder.setSmallIcon(R.drawable.alarm)
.setContentTitle("Title")
.setPriority(Notification.PRIORITY_MAX)
.setSound(RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION))
.setContentText(notificationContentText)
.setColor(Color.rgb(58,95,205));
notificationManager.notify(selected, builder.build());
}
}
Above code building the notification
This is my AndroidManifest file
<receiver
android:name=".ReminderReceiver"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="android.media.action.DISPLAY_NOTIFICATION"/>
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</receiver>
It was not the problem of BroadcastReceiver or the Service. I had to change my notification settings in my mobile. I use Asus, there you have to check power management option. If it is in power saving mode then the notifications are denied on app close.

Displaying push notification while app is not open

I'm trying to create notifications for my app that sends notifications when a certain task is due. Each task has a deadline time so I want to send a notification for each task when their deadline has passed.
My main class is called RecyclerViewDemoActivity and inside the onCreate() I have this:
public void setNotification()
{
Intent intent=new Intent(this,NotificationClass.class);
AlarmManager manager=(AlarmManager)getSystemService(Activity.ALARM_SERVICE);
PendingIntent pendingIntent= PendingIntent.getService(this, 0, intent, 0);
// hardcoding the time just for this example
manager.set(AlarmManager.RTC_WAKEUP,1449208683000,pendingIntent);
}
and I have a NotificationClass that looks like this:
public class NotificationClass extends Service {
#Override
public void onCreate()
{
Intent resultIntent=new Intent(this, RecyclerViewDemoActivity.class);
PendingIntent pIntent=PendingIntent.getActivity(this,0,resultIntent,0);
Notification nBuilder= new Notification.Builder(this)
.setContentTitle("This task is due!")
.setContentIntent(pIntent)
.setSmallIcon(R.mipmap.ic_launcher)
.build();
NotificationManager notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
nBuilder.flags |=Notification.FLAG_AUTO_CANCEL;
notificationManager.notify(1,nBuilder);
}
#Override
public IBinder onBind(Intent intent) {
return null;
}
}
Manifest:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.grokkingandroid.samplesapp.samples.recyclerviewdemo" >
<uses-permission android:name="android.permission.READ_CALENDAR"></uses-permission>
<uses-permission android:name="android.permission.WRITE_CALENDAR"></uses-permission>
<application
android:name="com.teamvallartas.autodue.RecyclerViewDemoApp"
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity
android:name="com.teamv.RecyclerViewDemoActivity"
android:label="#string/app_name"
android:configChanges="orientation"
android:screenOrientation="portrait">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
I looked at this resource for the code above and also Vogella's resource on notifications but I don't know why this is not working.
Check if onCreate of Service class is getting called. If it is, then the problem is "You placed your code at wrong method.".
You need to move code into onStartCommand(Intent intent, int flags, int startId).
Like
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Intent resultIntent=new Intent(this, RecyclerViewDemoActivity.class);
PendingIntent pIntent=PendingIntent.getActivity(this,0,resultIntent,0);
Notification nBuilder= new Notification.Builder(this)
.setContentTitle("This task is due!")
.setContentIntent(pIntent)
.setSmallIcon(R.mipmap.ic_launcher)
.build();
NotificationManager notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
nBuilder.flags |=Notification.FLAG_AUTO_CANCEL;
notificationManager.notify(1,nBuilder);
// If we get killed, after returning from here, restart
return START_STICKY;
}
Update your manifest and add this entry to it
<service android:name=".NotificationClass" />
you can do it in this way ,
1st > create one local broadcast receiver ,
inside onReceive() method , put your code stuff for generate notification
,that is your setNotification() method .
2nd > you just register that broadcast receiver inside onCreate() and unregister it inside onPause() or onDestory() method . like this ...
ReceiverActivity.java
public void onCreate(Bundle savedInstanceState) {
...
// Register your broadcast receiver here ...
// with actions named "custom-event-name"...
LocalBroadcastManager.getInstance(this).registerReceiver(mMessageReceiver,
new IntentFilter("custom-event-name"));
}
protected void onDestroy() {
// Unregister your receiver
LocalBroadcastManager.getInstance(this).unregisterReceiver(mMessageReceiver);
super.onDestroy();
}
//here comes our receiver ...
// Our handler for received Intents. This will be called whenever an Intent
// with an action named "custom-event-name" is broadcasted.
private BroadcastReceiver mMessageReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
//called setNotification() here ...
}
};
Now let suppose you want to generate notification on click event of your button then fire intent like this,
Intent intent = new Intent("custom-event-name");
// You can also include some extra data.
intent.putExtra("message", "Its me!!!!");
LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
your **setNotification()**should be like this ..
public void Notification(Context context, String message) {
// Set Notification Title
String strtitle = context.getString(R.string.notificationtitle);
// Open NotificationView Class on Notification Click
Intent intent = new Intent(context, NotificationView.class);
// Send data to NotificationView Class
intent.putExtra("title", strtitle);
intent.putExtra("text", message);
// Open NotificationView.java Activity
PendingIntent pIntent = PendingIntent.getActivity(context, 0, intent,
PendingIntent.FLAG_UPDATE_CURRENT);
// Create Notification using NotificationCompat.Builder
NotificationCompat.Builder builder = new NotificationCompat.Builder(
context)
// Set Icon
.setSmallIcon(R.drawable.logosmall)
// Set Ticker Message
.setTicker(message)
// Set Title
.setContentTitle(context.getString(R.string.notificationtitle))
// Set Text
.setContentText(message)
// Add an Action Button below Notification
.addAction(R.drawable.ic_launcher, "Action Button", pIntent)
// Set PendingIntent into Notification
.setContentIntent(pIntent)
// Dismiss Notification
.setAutoCancel(true);
// Create Notification Manager
NotificationManager notificationmanager = (NotificationManager) context
.getSystemService(Context.NOTIFICATION_SERVICE);
// Build Notification with Notification Manager
notificationmanager.notify(0, builder.build());
}

Categories

Resources