Specify time delay for sending Notification in Android Studio? - java

I have setup Notification Channels in Android Studio for sending my notifications.
So far, I can send a notification when I click a button.
However, I want to add a delay to when the notification is sent.. for example, send the notification after 20 seconds.
I know there is a function in the AlarmManager for System.getTimeInMillis, that would be related to this, but not sure where to go from here.
Here is my code:
public class MyNotificationPublisher extends Application {
public static final String CHANNEL_1_ID = "channel1";
public static final String CHANNEL_2_ID = "channel2";
#Override
public void onCreate() {
super.onCreate();
createNotificationChannels();
}
private void createNotificationChannels() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
NotificationChannel channel1 = new NotificationChannel(
CHANNEL_1_ID,
"Channel 1",
NotificationManager.IMPORTANCE_HIGH
);
channel1.setDescription("This is Channel 1");
NotificationChannel channel2 = new NotificationChannel(
CHANNEL_2_ID,
"Channel 2",
NotificationManager.IMPORTANCE_LOW
);
channel2.setDescription("This is Channel 2");
NotificationManager manager = getSystemService(NotificationManager.class);
manager.createNotificationChannel(channel1);
manager.createNotificationChannel(channel2);
}
}
}
public class EmailActivity extends AppCompatActivity {
private Button btnSend;
private NotificationManagerCompat notificationManager;
private long tenSeconds = 10000L;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_email);
notificationManager = NotificationManagerCompat.from(this);
btnSend = findViewById(R.id.button_send);
}
public void sendOnChannel1(View v) {
Notification notification = new NotificationCompat.Builder(this, CHANNEL_1_ID)
.setSmallIcon(R.drawable.ic_launcher_foreground)
.setContentTitle("Hi")
.setContentText("Test")
.setPriority(NotificationCompat.PRIORITY_HIGH)
.setCategory(NotificationCompat.CATEGORY_MESSAGE)
.build();
notificationManager.notify(1, notification);
}
}

You can just schedule the notifications to be sent :-
Use the following method :
public void scheduleNotification(Context context, long delay, int notificationId)
{
//delay is after how much time(in millis) from current time you want to schedule the notification
NotificationCompat.Builder builder = new NotificationCompat.Builder(context) .setContentTitle(context.getString(R.string.title)) .setContentText(context.getString(R.string.content)) .setAutoCancel(true) .setSmallIcon(R.drawable.app_icon) .setLargeIcon(((BitmapDrawable) context.getResources().getDrawable(R.drawable.app_icon)).getBitmap()) .setSound(RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION));
Intent intent = new Intent(context, YourActivity.class);
PendingIntent activity = PendingIntent.getActivity(context, notificationId, intent, PendingIntent.FLAG_CANCEL_CURRENT);
builder.setContentIntent(activity); Notification notification = builder.build();
Intent notificationIntent = new Intent(context, MyNotificationPublisher.class);
notificationIntent.putExtra(MyNotificationPublisher.NOTIFICATION_ID, notificationId);
notificationIntent.putExtra(MyNotificationPublisher.NOTIFICATION, notification);
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, notificationId, notificationIntent, PendingIntent.FLAG_CANCEL_CURRENT);
long futureInMillis = SystemClock.elapsedRealtime() + delay;
AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
alarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, futureInMillis, pendingIntent);
}
Then, the receiver class:
public class MyNotificationPublisher extends BroadcastReceiver {
public static String NOTIFICATION_ID = "notification_id";
public static String NOTIFICATION = "notification";
#Override
public void onReceive(final Context context, Intent intent)
{
NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
Notification notification = intent.getParcelableExtra(NOTIFICATION);
int notificationId = intent.getIntExtra(NOTIFICATION_ID, 0);
notificationManager.notify(notificationId, notification);
}
}
Then, call scheduleNotification with the appropriate arguments.

Use a handler to delay the execution of notification sending code
Update your code like that
public void sendOnChannel1(View v) {
Notification notification = new NotificationCompat.Builder(this, CHANNEL_1_ID)
.setSmallIcon(R.drawable.ic_launcher_foreground)
.setContentTitle("Hi")
.setContentText("Test")
.setPriority(NotificationCompat.PRIORITY_HIGH)
.setCategory(NotificationCompat.CATEGORY_MESSAGE)
.build();
new Handler(Looper.getMainLooper()).postDelayed(new Runnable() {
#Override
public void run() {
notificationManager.notify(1, notification);
}
}, 20000);
}

Related

Android 7.1 and lower double notifications showing

I added scheduled notifications in my app and everything works well except for android version less than 7.1 where double notifications are showing.
Here is my notification publisher class (BroadcastReciever)
public class NotificationPublisher extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
this.context = context;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
createChannels();
}
sendNotification("title", "body", notificationId, activity);
}
#RequiresApi(api = Build.VERSION_CODES.O)
private void createChannels() {
NotificationChannel channel = new NotificationChannel(CHANNEL_ID, CHANNEL_NAME, NotificationManager.IMPORTANCE_DEFAULT);
channel.enableLights(true);
channel.enableVibration(true);
channel.setDescription(CHANNEL_DESCRIPTION);
channel.setLightColor(Color.RED);
channel.setLockscreenVisibility(Notification.VISIBILITY_PUBLIC);
NotificationManager manager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
manager.createNotificationChannel(channel);
}
public void sendNotification(String title, String body, int id, Class activity) {
Intent intents = new Intent(context, activity);
PendingIntent pendingIntent = PendingIntent.getActivity(context, id, intents, PendingIntent.FLAG_UPDATE_CURRENT);
Notification notification = new NotificationCompat.Builder(context, CHANNEL_ID)
.setContentTitle(title)
.setContentText(body)
.setSmallIcon(R.mipmap.ic_launcher)
.setPriority(NotificationCompat.PRIORITY_DEFAULT)
.setStyle(new NotificationCompat.BigTextStyle().setBigContentTitle(title).bigText(body))
.setContentIntent(pendingIntent)
.setAutoCancel(true)
.build();
NotificationManagerCompat.from(context).notify(new Random().nextInt(), notification);
}
}
Here is my code to schedule the notification:
public static void createNotification(Context context) {
AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent("app.action.DISPLAY_NOTIFICATION");
intent.putExtra("notificationId", notificationID);
Calendar calReminder = Calendar.getInstance();
calReminder.setTimeInMillis(System.currentTimeMillis());
calReminder.set(Calendar.HOUR_OF_DAY, 16);
calReminder.set(Calendar.MINUTE, 30);
PendingIntent broadcast = PendingIntent.getBroadcast(context, notificationID, intent, PendingIntent.FLAG_UPDATE_CURRENT);
alarmManager.setInexactRepeating(AlarmManager.RTC_WAKEUP, calReminder.getTimeInMillis(), AlarmManager.INTERVAL_DAY, broadcast);
}
Here is my MainActivity code at app startup:
public class MainActivity extends AppCompatActivity implements NavigationView.OnNavigationItemSelectedListener {
private NotificationPublisher broadcastReceiver;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
broadcastReceiver = new NotificationPublisher();
setNotificationScheduler(this);
}
public static void setNotificationScheduler(Context context) {
AppNotifications.createNotification(context);
}
#Override
protected void onStart() {
super.onStart();
IntentFilter intentFilter = new IntentFilter("app.action.DISPLAY_NOTIFICATION");
intentFilter.addCategory(Intent.CATEGORY_DEFAULT);
registerReceiver(broadcastReceiver, intentFilter);
}
}
I can't find why it is showing double notifications on android 7.1 and lower.
Also just to make sure: is creating notifications on startup wrong? is there a more by the books way to do it?
Thanks in advance.
NotificationManagerCompat notificationManager = NotificationManagerCompat.from(app);
notificationManager.notify(NOTIFICATION_ID, notificationBuilder.build());
Add This Code To Your notification publisher class.

How to make AlarmBootReceiver send notification at specified time?

I have an AlarmResiver class, it sends notifications if the user has set the time and the toggle switch is on. But this class is bad in that when the device reboots, notifications are no longer received. Then I decided to create an AlarmBootResiver class that will send notifications after the device is rebooted. Now this class is working, but it sends notifications immediately after turning on the device. How to make the AlarmBootResiver send notifications at the time set by the user in the AlarmResiver class ?
AlarmActivity code:
public class AlarmActivity extends AppCompatActivity implements TimePickerDialog.OnTimeSetListener {
private EditText mondayText;
public SwitchCompat mondaySwitch;
SharedPreferences sPref;
String timeText = "";
final String SAVED_TEXT = "saved_text";
boolean switch_On_Off;
public static final String PREFS_NAME = "Switch_On_Off_check";
final Calendar c = Calendar.getInstance();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_alarm);
mondayText = findViewById(R.id.monday_time);
mondaySwitch = findViewById(R.id.switch_monday);
// load SharedPref save text in mondayText and save switch On else Off
loadText();
loadSwitchCheck();
mondaySwitch.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if (mondaySwitch.isChecked()) {
startAlarm(c);
bootStartAlarm(c);
}
saveSwitchCheck();
}
});
mondayText.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
DialogFragment timePicker = new TimePickerFragment();
timePicker.show(getSupportFragmentManager(), "time picker");
}
});
}
#Override
public void onTimeSet(TimePicker view, int hourOfDay, int minute) {
c.set(Calendar.HOUR_OF_DAY, hourOfDay);
c.set(Calendar.MINUTE, minute);
c.set(Calendar.SECOND, 0);
updateTimeText(c);
saveText();
mondaySwitch.setChecked(false);
bootStopAlarm(c);
}
private void updateTimeText(Calendar c) {
timeText = "";
timeText += DateFormat.getTimeInstance(DateFormat.SHORT).format(c.getTime());
mondayText.setText(timeText);
}
public void startAlarm(Calendar c) {
AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(this, AlertReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 1, intent, 0);
if (c.before(Calendar.getInstance())) {
c.add(Calendar.DATE, 1);
}
alarmManager.setExact(AlarmManager.RTC_WAKEUP, c.getTimeInMillis(), pendingIntent);
}
public void bootStartAlarm(Calendar c) {
PackageManager packageManager = AlarmActivity.this.getPackageManager();
ComponentName componentName = new ComponentName(AlarmActivity.this, AlarmBootReceiver.class);
packageManager.setComponentEnabledSetting(componentName,
PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
PackageManager.DONT_KILL_APP);
AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(this, AlarmBootReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 1, intent, 0);
alarmManager.setExact(AlarmManager.RTC_WAKEUP, c.getTimeInMillis(), pendingIntent);
}
public void bootStopAlarm(Calendar c) {
AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(this, AlarmBootReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 1, intent, 0);
alarmManager.setExact(AlarmManager.RTC_WAKEUP, c.getTimeInMillis(), pendingIntent);
PackageManager packageManager = AlarmActivity.this.getPackageManager();
ComponentName componentName = new ComponentName(AlarmActivity.this, AlarmBootReceiver.class);
packageManager.setComponentEnabledSetting(componentName,
PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
PackageManager.DONT_KILL_APP);
}
My AlertReciever
public class AlertReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
NotificationHelper notificationHelper = new NotificationHelper(context);
NotificationCompat.Builder nb = notificationHelper.getChannelNotification();
notificationHelper.getManager().notify(1, nb.build());
}
}
My AlarmBootReciever
public class AlarmBootReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
if (Objects.equals(intent.getAction(), "android.intent.action.BOOT_COMPLETED")) {
NotificationHelper notificationHelper = new NotificationHelper(context);
NotificationCompat.Builder nb = notificationHelper.getChannelNotification();
notificationHelper.getManager().notify(1, nb.build());
}
}
}
My Manifest file
<receiver android:name=".AlertReceiver"/>
<receiver
android:name=".AlarmBootReceiver"
android:enabled="false">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
<action android:name="android.intent.action.QUICKBOOT_POWERON" />
<action android:name="com.htc.intent.action.QUICKBOOT_POWERON" />
<action android:name="android.intent.action.REBOOT" />
</intent-filter>
</receiver>
</application>
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.QUICKBOOT_POWERON" />
<uses-permission android:name="android.permission.VIBRATE" />
My NotificationHelper
public class NotificationHelper extends ContextWrapper {
public static final String channelID = "channelID";
public static final String channelName = "Channel Name";
private NotificationManager mManager;
public NotificationHelper(Context base) {
super(base);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
createChannel();
}
}
#TargetApi(Build.VERSION_CODES.O)
private void createChannel() {
NotificationChannel channel = new NotificationChannel(channelID, channelName, NotificationManager.IMPORTANCE_HIGH);
getManager().createNotificationChannel(channel);
}
public NotificationManager getManager() {
if (mManager == null) {
mManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
}
return mManager;
}
public NotificationCompat.Builder getChannelNotification() {
Intent resultIntent = new Intent(this, DashBoardActivity.class);
PendingIntent resultPendingIntent = PendingIntent.getActivity(this, 1, resultIntent, PendingIntent.FLAG_UPDATE_CURRENT);
return new NotificationCompat.Builder(getApplicationContext(), channelID)
.setContentTitle("ЭЙ ТЫ!")
.setContentText("Пора на тренировку!")
.setSmallIcon(R.drawable.ic_training)
.setAutoCancel(true)
.setContentIntent(resultPendingIntent);
}
}
You can use a BroadcastReceiver for this. This code will work, even if you restart your device or lock the device, the PowerManager does that for you. See here for more information https://developer.android.com/reference/android/os/PowerManager
public class AlarmReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
NotificationCompat.Builder mBuilder =
new NotificationCompat.Builder(context)
.setSmallIcon(YOUR DRAWABLE)
.setContentTitle("YOUR TITLE")
.setAutoCancel(true)
.setLights(0xFFFF0000, 500, 500)
.setColor(context.getResources().getColor(R.color.red))
.setDefaults(NotificationCompat.DEFAULT_SOUND)
.setContentText("THIS IS THE CONTENT OF THE NOTIFICATION");
PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
#SuppressLint("InvalidWakeLockTag") PowerManager.WakeLock wakeLock = pm.newWakeLock((PowerManager.PARTIAL_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP), "TAG");
wakeLock.acquire();
PendingIntent contentIntent = PendingIntent.getActivity(context, 0, new Intent(context, MainActivity.class), PendingIntent.FLAG_UPDATE_CURRENT);
mBuilder.setContentIntent(contentIntent);
NotificationManager mNotificationManager =
(NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
// mNotificationId is a unique integer your app uses to identify the
// notification. For example, to cancel the notification, you can pass its ID
// number to NotificationManager.cancel().
mNotificationManager.notify(0, mBuilder.build());
}
}
You can trigger AlarmReceiver using this in MainActivity for example where you can set your time of trigger, see comment.
public void doNotification() {
AlarmManager alarmManager = (AlarmManager) this.getSystemService(Context.ALARM_SERVICE);
Intent i = new Intent(this, AlarmReceiver.class);
PendingIntent pending = PendingIntent.getBroadcast(this, 0, i, PendingIntent.FLAG_CANCEL_CURRENT);
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
// InexactRepeating allows Android to optimize the energy consumption //ms, s, min
alarmManager.setInexactRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), 1000 * 60 * 60 * 24 * 30, pending); //every month
}

How to show notification from broadcast receiver?

I am registering a broadcast receiver from a service. I need to show notification to user if location of device is off the code works fine but receiver does not create notification. I can see logcat messages on changing location status but notification is not created Please check the issue ! And is there any way to update the current notification of the service?
This is Service:
public class LockService extends Service {
BroadcastReceiver mReceiver;
Handler handler;
LocationManager locationManager;
#Override
public IBinder onBind(Intent intent) {
return null;
}
private static final int NOTIF_ID = 1;
#Override
public void onCreate() {
final IntentFilter filter = new IntentFilter(Intent.ACTION_SCREEN_ON);
filter.addAction(Intent.ACTION_SCREEN_OFF);
filter.addAction(Intent.ACTION_USER_PRESENT);
filter.addAction(LocationManager.PROVIDERS_CHANGED_ACTION);
mReceiver = new com.example.fizatanveerkhan.citycops.ScreenReceiver();
registerReceiver(mReceiver, filter);
super.onCreate();
}
private void startForeground() {
startForeground(NOTIF_ID, getMyActivityNotification(""));
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
this.startForeground();
return super.onStartCommand(intent, flags, startId);
}
#Override
public void onDestroy() {
if (mReceiver != null) {
unregisterReceiver(mReceiver);
mReceiver = null;
Log.i("onDestroy Reciever", "Called");
}
super.onDestroy();
}
public class LocalBinder extends Binder {
LockService getService() {
return LockService.this;
}
}
private Notification getMyActivityNotification(String text) {
CharSequence title = "new";
Notification notification = null;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
String NOTIFICATION_CHANNEL_ID = " com.example.fizatanveerkhan.citycops";
String channelName = "My Background Service";
NotificationChannel chan = new NotificationChannel(NOTIFICATION_CHANNEL_ID, channelName, NotificationManager.IMPORTANCE_NONE);
chan.setLightColor(Color.BLUE);
chan.setLockscreenVisibility(Notification.VISIBILITY_PRIVATE);
NotificationManager manager = (NotificationManager) getApplicationContext().getSystemService(Context.NOTIFICATION_SERVICE);
assert manager != null;
manager.createNotificationChannel(chan);
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this, NOTIFICATION_CHANNEL_ID);
notification = notificationBuilder.setOngoing(true)
.setSmallIcon(R.drawable.abc)
.setContentTitle("Service running")
.setContentText("new")
.setPriority(NotificationManager.IMPORTANCE_MIN)
.setCategory(Notification.CATEGORY_SERVICE)
.build();
}
return notification;
}
/* public void updateNotification() {
String text = "Some text that will update the notification";
Notification notification = getMyActivityNotification(text);
NotificationManager mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
mNotificationManager.notify(NOTIF_ID, notification);
}*/
}
And this is broadcast receiver:
public class ScreenReceiver extends BroadcastReceiver {
public static boolean wasScreenOn = true;
private static final int POWER_OFF_TIMEOUT = 500;
private Handler handler = new Handler();
private Runnable powerOffCounterReset = new PowerOfTimeoutReset();
private int countPowerOff = 0;
private boolean screenOff;
//private LockService updateService = new LockService();
private final static String TAG = "LocationProviderChanged";
boolean isGpsEnabled;
boolean isNetworkEnabled;
#Override
public void onReceive(final Context context, final Intent intent) {
if (intent.getAction().matches("android.location.PROVIDERS_CHANGED")) {
Log.i(TAG, "Location Providers changed");
LocationManager locationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
isGpsEnabled = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
isNetworkEnabled = locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
//Start your Activity if location was enabled:
if (isGpsEnabled || isNetworkEnabled) {
Log.i(TAG, "Location Providers on");
}
else {
Log.i(TAG, "Location Providers off");
Notification notification = null;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
String NOTIFICATION_CHANNEL_ID = " com.example.fizatanveerkhan.citycops";
String channelName = "My Background Service";
NotificationChannel chan = new NotificationChannel(NOTIFICATION_CHANNEL_ID, channelName, NotificationManager.IMPORTANCE_NONE);
chan.setLightColor(Color.BLUE);
chan.setLockscreenVisibility(Notification.VISIBILITY_PRIVATE);
NotificationManager manager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
assert manager != null;
manager.createNotificationChannel(chan);
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(context, NOTIFICATION_CHANNEL_ID);
notification = notificationBuilder.setOngoing(true)
.setSmallIcon(R.drawable.abc)
.setContentTitle("Service running")
.setContentText("new")
.setPriority(NotificationManager.IMPORTANCE_MIN)
.setCategory(Notification.CATEGORY_SERVICE)
.build();
NotificationManager mNotificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
mNotificationManager.notify(1, notification);
}
}
}
I can see logcat messages on changing location status but notification is not created
Changing notification code to this solved the problem
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
String NOTIFICATION_CHANNEL_ID = "
com.example.fizatanveerkhan.citycops";
CharSequence name = "My Background Service";
String description = "My Background Service";
int importance = NotificationManager.IMPORTANCE_DEFAULT;
NotificationChannel channel = new NotificationChannel(NOTIFICATION_CHANNEL_ID, name, importance);
channel.setDescription(description);
// Register the channel with the system; you can't change the importance
// or other notification behaviors after this
NotificationManager notificationManager = context.getSystemService(NotificationManager.class);
notificationManager.createNotificationChannel(channel);
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(context, NOTIFICATION_CHANNEL_ID);
notification = notificationBuilder.setOngoing(true)
.setSmallIcon(R.drawable.abc)
.setContentTitle("Service running")
.setContentText("new")
.setPriority(NotificationManager.IMPORTANCE_MIN)
.setCategory(Notification.CATEGORY_SERVICE)
.build();
NotificationManagerCompat notificationManagerq =
NotificationManagerCompat.from(context);
// notificationId is a unique int for each notification that you must define
notificationManagerq.notify(1, notificationBuilder.build());
}
So basically you need to create a foreground notification and update its contents on location change.
You can use the code below to create a foreground notification:-
//for foreground service notification
public Notification showForegroundNotification(String notificationTitle, String notificationBody, Intent intent, ServiceName serviceName) {
String id = mContext.getString(R.string.upload_notification_channel_id);
PendingIntent lowIntent = PendingIntent.getActivity(mContext, 100, intent, PendingIntent.FLAG_ONE_SHOT);
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(mContext, id);
NotificationManager mNotifyManager = (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
CharSequence name = mContext.getString(R.string.upload_notification_channel_name);
String description = mContext.getString(R.string.upload_notification_channel_description); //user visible
int importance = NotificationManager.IMPORTANCE_LOW;
AudioAttributes att = new AudioAttributes.Builder()
.setUsage(AudioAttributes.USAGE_NOTIFICATION)
.setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION)
.build();
NotificationChannel mChannel = new NotificationChannel(id, name, importance);
mChannel.setDescription(description);
mChannel.enableLights(false);
mChannel.enableVibration(false);
mChannel.setVibrationPattern(new long[]{0L});
mChannel.setSound(null, att);
if (mNotifyManager != null) {
mNotifyManager.createNotificationChannel(mChannel);
}
notificationBuilder
.setSmallIcon(R.mipmap.ic_launcher)
.setCategory(NotificationCompat.CATEGORY_SERVICE)
.setVibrate(new long[]{0L})
.setSound(null)
.setColor(ContextCompat.getColor(mContext, R.color.colorPrimary))
.setContentTitle(notificationTitle)
.setAutoCancel(true)
.setContentIntent(lowIntent);
} else {
notificationBuilder.setContentTitle(notificationTitle)
.setSmallIcon(R.mipmap.ic_launcher)
.setCategory(NotificationCompat.CATEGORY_SERVICE)
.setVibrate(new long[]{0L})
.setSound(null)
.setColor(ContextCompat.getColor(mContext, R.color.colorPrimary))
.setAutoCancel(true)
.setContentIntent(lowIntent);
}
if (notificationBody != null) {
notificationBuilder.setStyle(new NotificationCompat.BigTextStyle().bigText(notificationBody));
}
notificationBuilder.setContentText(notificationBody);
return notificationBuilder.build();
}
and you need to call startForegroundService();
private void startForegroundService(){
String dataTitle = SharedPrefer.getLastUpdatedLocationName();
String dataContent = SharedPrefer.getLastUpdatedLocation();
Intent intent = new Intent(WITHU.getAppContext(), MapLocateActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT | Intent.FLAG_ACTIVITY_NEW_TASK);
startForeground(121, showNotification.showForegroundNotification(dataTitle, dataContent, intent, ServiceName.SMART_LOCATION, -1, false));
}
So it will pass the updated location name and location which you can collect from SharedPreference or also can be called directly onLocationChanged.

How to send notification with background service in Android Studio?

I want to send push notifications in my app but after few minutes android kill my background service and notifications not showing. How to make background service which android will not close?
BackroundService.class
public Context context = this;
public android.os.Handler handler = new Handler();
public static Runnable runnable = null;
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onCreate() {
Log.e("Service", "Service crated!");
runnable = new Runnable() {
public void run() {
Log.e("Service", "Service is still running!");
Toast.makeText(context, "Service is still running", Toast.LENGTH_SHORT).show();
handler.postDelayed(runnable, 50000);
}
};
handler.postDelayed(runnable, 15000);
}
#Override
public void onDestroy() {
}
#Override
public void onStart(Intent intent, int startid) {
Log.e("Service", "Service started by user!");
}
AlarmReceiver.class
#Override
public void onReceive(Context context, Intent intent) {
int notificationId = intent.getIntExtra("ID", 0);
String message = intent.getStringExtra("TEXT");
String tittle = intent.getStringExtra("TITTLE");
Intent mainIntent = new Intent(context, BackgroundService.class);
PendingIntent contentIntent = PendingIntent.getActivity(context, 0, mainIntent, 0);
NotificationManager notificationManager =
(NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
Notification.Builder builder = new Notification.Builder(context);
builder.setSmallIcon(R.drawable.finance43)
.setContentTitle(tittle)
.setContentText(message)
.setWhen(System.currentTimeMillis())
.setAutoCancel(true)
.setContentIntent(contentIntent)
.setPriority(Notification.PRIORITY_HIGH)
.setCategory(Notification.CATEGORY_MESSAGE);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
String channelId = "REMINDERS";
NotificationChannel channel = new NotificationChannel(channelId,
"Reminder",
NotificationManager.IMPORTANCE_DEFAULT);
notificationManager.createNotificationChannel(channel);
builder.setChannelId(channelId);
}
notificationManager.notify(notificationId, builder.build());
}
When I start app i see "Service is still running!" for about 1 hour.

Cannot getApplicationContext() from BroadcastReceiver

My Application is asking me to create a method for getResources() or getApplicationContext().
Are these methods not allowed to be called in a BroadcastReceiver?
#Override
public void onReceive(Context context, Intent arg1) {
createNotification(Calendar.getInstance().getTimeInMillis());
}
public void createNotification(long when) {
Bitmap largeIcon = BitmapFactory.decodeResource(context.getResources(),
R.drawable.stamptwo);
int smalIcon = R.drawable.stamptwoxhdpi;
Intent intent = new Intent(context.getApplicationContext(),
Lockscreen.class);
intent.putExtra(NOTIFICATION_DATA, notificationData);
intent.setData(Uri.parse("content://" + when));
PendingIntent pendingIntent = PendingIntent.getActivity(
context.getApplicationContext(), 0, intent,
Intent.FLAG_ACTIVITY_NEW_TASK);
NotificationManager notificationManager = (NotificationManager) context
.getApplicationContext().getSystemService(
Context.NOTIFICATION_SERVICE);
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(
context.getApplicationContext())
.setWhen(when)
.setContentText(notificationContent)
.setContentTitle(notificationTitle)
.setSmallIcon(smalIcon)
.setAutoCancel(true)
.setTicker(notificationTitle)
.setLargeIcon(largeIcon)
.setDefaults(
Notification.DEFAULT_LIGHTS
| Notification.DEFAULT_VIBRATE
| Notification.DEFAULT_SOUND)
.setContentIntent(pendingIntent);
Notification notification = notificationBuilder.build();
notificationManager.notify((int) when, notification);
}
}
Another alternative to #Pankaj Kumar solution is to store the concept as a data field inside the onReceive method :
public class MyReceiver extends BroadcastReceiver {
private Context context;
#Override
public void onReceive(Context context, Intent arg1) {
this.context = context;
createNotification(Calendar.getInstance().getTimeInMillis());
}
public void createNotification(long when) {
// and use
// context.getApplicationContext()
}
 }
You will need to use context.getResources() or context.getApplicationContext() so pass the context to createNotification method.
Try this
public class NotificationAlarm extends BroadcastReceiver {
public static final String NOTIFICATION_DATA = "NOTIFICATION_DATA";
String notificationData = "";
String notificationContent = "Content";
String notificationTitle = "Title";
#Override
public void onReceive(Context context, Intent arg1) {
createNotification(context,Calendar.getInstance().getTimeInMillis());
}
public void createNotification(Context mContext,long when) {
Bitmap largeIcon = BitmapFactory.decodeResource(mContext.getResources(),
R.drawable.stamptwo);
int smalIcon = R.drawable.stamptwoxhdpi;
Intent intent = new Intent(mContext, Lockscreen.class);
intent.putExtra(NOTIFICATION_DATA, notificationData);
intent.setData(Uri.parse("content://" + when));
PendingIntent pendingIntent = PendingIntent.getActivity(
mContext, 0, intent,
Intent.FLAG_ACTIVITY_NEW_TASK);
NotificationManager notificationManager = (NotificationManager) mContext
.getSystemService(Context.NOTIFICATION_SERVICE);
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(
mContext)
.setWhen(when)
.setContentText(notificationContent)
.setContentTitle(notificationTitle)
.setSmallIcon(smalIcon)
.setAutoCancel(true)
.setTicker(notificationTitle)
.setLargeIcon(largeIcon)
.setDefaults(
Notification.DEFAULT_LIGHTS
| Notification.DEFAULT_VIBRATE
| Notification.DEFAULT_SOUND)
.setContentIntent(pendingIntent);
Notification notification = notificationBuilder.build();
notificationManager.notify((int) when, notification);
}
}

Categories