show toast in specific time every day - java

I want to make simple android app that will show a toast in specific time every day say at 8:00 pm.
How do I do it? On what I should depend? alarm manager and broadcast receiver?
and in broadcast file how can i define between two events,alarm broadcast and receive new incoming sms broadcast using this outgoing call action
if (intent.getAction().equals(Intent.ACTION_NEW_OUTGOING_CALL)) {
if (intent.getAction().equals(TelephonyManager.ACTION_PHONE_STATE_CHANGED)) {

AlarmReceiver.java
public class AlarmReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
// any action you want to perform will come here
Toast.makeText(context, "I'm running", Toast.LENGTH_SHORT).show();
}
}
MainActivity.java
public class MainActivity extends Activity {
private PendingIntent pendingIntent;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
/* Retrieve a PendingIntent that will perform a broadcast */
Intent alarmIntent = new Intent(MainActivity.this, AlarmReceiver.class);
pendingIntent = PendingIntent.getBroadcast(MainActivity.this, 0, alarmIntent, 0);
setAlarm();
}
private void setAlarm() {
AlarmManager manager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
int interval = 1000 * 60 * 20;
/* Set the alarm to start at 8.00 PM */
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
calendar.set(Calendar.HOUR_OF_DAY, 20);
calendar.set(Calendar.MINUTE, 00);
/* Repeating on every 20 minutes interval */
manager.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(),
1000 * 60 * 20, pendingIntent);
}
public void cancelAlarm() {
AlarmManager manager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
manager.cancel(pendingIntent);
Toast.makeText(this, "Alarm Canceled", Toast.LENGTH_SHORT).show();
}
The below class is to keep the alarm even after the device reboot.
DeviceBootReceiver.java
public class DeviceBootReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals("android.intent.action.BOOT_COMPLETED")) {
/* Setting the alarm here */
Intent alarmIntent = new Intent(context, AlarmReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, alarmIntent, 0);
AlarmManager manager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
int interval = 8000;
manager.setInexactRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(), interval, pendingIntent);
Toast.makeText(context, "Alarm Set", Toast.LENGTH_SHORT).show();
}
}
}
In manifest:
Add permission
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
and receivers
<receiver android:name=".AlarmReceiver">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED"/>
</intent-filter>
</receiver>
<receiver android:name=".DeviceBootReceiver"
android:enabled="false">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED"/>
</intent-filter>
</receiver>

Related

How to set alarm for every 10 minutes in Android Application in 9 and 12?

I would like to set a repeating alarm, in android 8 or 9 it works.
The question is how to set it to work it in 12 working parallel with android 8?
This is in the main activity, I set a startAlarm, and there is the missing part how to set the alarm in the case of sdk >= 31. When I start android to test it sends a notification at the beginning of the application but it do not send notification later.
MainActivity.java:
private void startAlarm(long when) {
AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
if (alarmManager.canScheduleExactAlarms()) {
Log.e(TAG, "startAlarm: canScheduleExactAlarms");
}
}
Intent intent = new Intent(this, AlarmReceiver.class);
PendingIntent pendingIntent;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
pendingIntent = PendingIntent.getBroadcast(MainActivity.this, 1, intent,
PendingIntent.FLAG_IMMUTABLE | PendingIntent.FLAG_UPDATE_CURRENT);
} else {
pendingIntent = PendingIntent.getBroadcast(MainActivity.this, 1, intent, 0);
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M){
alarmManager.setExactAndAllowWhileIdle(
AlarmManager.RTC_WAKEUP,
when*1000,
pendingIntent
);
} else {
alarmManager.setExact(
AlarmManager.RTC_WAKEUP,
when*1000,
pendingIntent
);
}
}
I set AlarmReceiver to send notification.
AlarmReceiver:
public class AlarmReceiver 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());
long timeInSec = System.currentTimeMillis() / 1000;
Settings.setLastNotificationSent(timeInSec, context);
}
}
I set the permission in the manifest.
AndroidManifest:
<uses-permission android:name="com.android.alarm.permission.SET_ALARM"/>
<uses-permission android:name="android.permission.SCHEDULE_EXACT_ALARM"/>
<receiver android:name=".receiver.AlarmReceiver"
android:exported="true"
android:enabled="true">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
Probably you have to cancel previous alarm when you receive message in AlarmReceiver. I had the same problem and if i receive message from previous alarm i cancel it and then i can create new one.
private void cancelAlarm(){
Intent intent = new Intent(this, AlarmReceiver.class);
PendingIntent pendingIntent;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
pendingIntent = PendingIntent.getBroadcast(MainActivity.this, 1, intent,
PendingIntent.FLAG_IMMUTABLE | PendingIntent.FLAG_UPDATE_CURRENT);
} else {
pendingIntent = PendingIntent.getBroadcast(MainActivity.this, 1, intent, PendingIntent.FLAG_UPDATE_CURRENT);
}
AlarmManager alarm = (AlarmManager)getSystemService(Context.ALARM_SERVICE);
alarm.cancel(pintent);
pintent.cancel();
}

Local notifications not showing when app is closed using recent apps by user.

Hi i am making a habit tracker app and when a new habit is created by user i call sendNotification() method for calling notifications at time specified by user.I want to show these notifications everyday at time specified by user.
Now notifications are showing up when app is running or when app is minimized but when i close app (not from settings) notifications are shown.
Here's my code:
private void sendNotification(){
NotificationReceiver.setupAlarm(this, notificationCalendar);
}
public class NotificationReceiver extends WakefulBroadcastReceiver {
public NotificationReceiver() {
}
public static void setupAlarm(Context context, Calendar notificationCalendar) {
AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
PendingIntent alarmIntent = getStartPendingIntent(context);
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, notificationCalendar.getTimeInMillis(),
AlarmManager.INTERVAL_DAY, alarmIntent);
}
#Override
public void onReceive(Context context, Intent intent) {
Intent serviceIntent = NotificationIntentService.createIntentStartNotificationService(context);
startWakefulService(context, serviceIntent);
}
private static PendingIntent getStartPendingIntent(Context context) {
Intent intent = new Intent(context, NotificationReceiver.class);
return PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
}
}
public class NotificationIntentService extends IntentService {
private static final int NOTIFICATION_ID = 1;
public NotificationIntentService() {
super(NotificationIntentService.class.getSimpleName());
}
public static Intent createIntentStartNotificationService(Context context) {
return new Intent(context, NotificationIntentService.class);
}
#Override
protected void onHandleIntent(Intent intent) {
try{
processStartNotification();
}finally {
WakefulBroadcastReceiver.completeWakefulIntent(intent);
}
}
private void processStartNotification() {
// Do something. For example, fetch fresh data from backend to create a rich notification?
NotificationManager notificationManager = (NotificationManager) this
.getSystemService(Context.NOTIFICATION_SERVICE);
Intent notificationIntent = new Intent(this, MainActivity.class);
notificationIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0,
notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT);
Uri alarmSound = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
NotificationCompat.Builder mNotifyBuilder = new NotificationCompat.Builder(this)
.setSmallIcon(R.mipmap.ic_launcher)
.setContentTitle("Habit Time")
.setContentText("Hey time for your habit")
.setAutoCancel(true)
.setContentIntent(pendingIntent)
.setSound(alarmSound)
.setVibrate(new long[]{1000, 1000, 1000, 1000, 1000});
notificationManager.notify(NOTIFICATION_ID, mNotifyBuilder.build());
}
}
//Manifest file
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<receiver android:name=".notification.NotificationReceiver"/>
<service
android:name=".notification.NotificationIntentService"
android:enabled="true"
android:exported="false"/>
The notification won't show until you make a background service for them. Create a background service and send broadcast from that service, this service will keep running weather your app is running or not. You can check this detailed answer.
Make a NotificationService class and extend it like below.
public class NotificationService extends Service{
#Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return null;
}
#SuppressWarnings("deprecation")
#Override
public void onStart(Intent intent, int startId) {
// TODO Auto-generated method stub
super.onStart(intent, startId);
/* send your notification from here, in timely manner */
}
}
Start is from your activity like this
Intent i = new Intent("com.example.package.NotificationService");
startService(i);
This code is written to give you an idea. I didn't test it.
Try the following code: it creates an alarm for a specific time in a day using alarmanager and repeat it daily...
Declare
Calendar cal_alarm;
Now set the calender object for specific time to alarm
SimpleDateFormat dateFormat = new SimpleDateFormat("dd MM yyyy hh:mm a");
String time=""21 12 2016 8:10 AM"
cal_alarm = Calendar.getInstance();
cal_alarm.setTime(dateFormat.parse(time));
Set the alarm
public void set_alarm() {
Calendar calNow = Calendar.getInstance();
long current_time = calNow.getTimeInMillis();
Log.d("ALARM CALENDER VALUES", cal_alarm.toString());
long alarm_time_in_millis = cal_alarm.getTimeInMillis();
//check if time is alreday passed or not
if (alarm_time_in_millis > current_time) {
new Alarm_task(getApplicationContext(), cal_alarm).run();
}
public class Alarm_task implements Runnable {
// The date selected for the alarm
private final Calendar cal;
// The android system alarm manager
private final AlarmManager am;
// Your context to retrieve the alarm manager from
private final Context context;
long alarm_time2;
int _id;
public Alarm_task(Context context, Calendar cal) {
this.context = context;
this.am = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
this.cal = cal;
this._id = (int) System.currentTimeMillis();
alarm_time2 = cal.getTimeInMillis();
//Toast.makeText(getActivity(), alarm_time2 + " ", Toast.LENGTH_SHORT).show();
}
#Override
public void run() {
// Request to start are service when the alarm date is upon us
// We don't start an activity as we just want to pop up a notification into the system bar not a full activity
Intent i = new Intent("com.package_name");
i.setAction("com.package_name");
/** Creating a Pending Intent */
PendingIntent operation = PendingIntent.getActivity(getApplicationContext(), _id, i, PendingIntent.FLAG_UPDATE_CURRENT);
/** Converting the date and time in to milliseconds elapsed since epoch */
long alarm_time = cal.getTimeInMillis();
/** Setting an alarm, which invokes the operation at alart_time each day*/
am.setRepeating(AlarmManager.RTC_WAKEUP, alarm_time, AlarmManager.INTERVAL_DAY, operation);
}
}
Now in manifest define an explicit activity which handle the alarm intent and show popup dialog and notification during alarm time
<activity
android:name=".Prereminder"
android:label="#string/app_name"
android:screenOrientation="portrait"
android:theme="#style/AppTheme.NoActionBar">
<intent-filter>
//same as your alarm task
<action android:name="com.package_name" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
Now in your Prereminder.java
public class Prereminder extends FragmentActivity {
String msg = "Helloo";
public static final int NOTIFICATION_ID = 1;
private NotificationManager mNotificationManager;
NotificationCompat.Builder builder;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_alarm);
sendNotification();
/** Creating an Alert Dialog Window */
Reminder_alert alert = new Reminder_alert();
/** Opening the Alert Dialog Window */
alert.show(getSupportFragmentManager(), "Reminder_alert");
}
private void sendNotification() {
mNotificationManager = (NotificationManager)
this.getSystemService(Context.NOTIFICATION_SERVICE);
//handle notification on click
Intent myintent = new Intent(this, Home_page.class);
myintent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
PendingIntent contentIntent = PendingIntent.getActivity(this, 0, myintent, PendingIntent.FLAG_UPDATE_CURRENT);
NotificationCompat.Builder mBuilder =
new NotificationCompat.Builder(this)
.setSmallIcon(R.drawable.logo_small)
.setContentTitle("Alarm")
.setStyle(new NotificationCompat.BigTextStyle()
.bigText(msg))
.setContentText(msg)
.setAutoCancel(true);
mBuilder.setContentIntent(contentIntent);
mBuilder.getNotification().flags |= Notification.FLAG_AUTO_CANCEL;
mNotificationManager.notify(NOTIFICATION_ID, mBuilder.build());
}
}
Now your Reminder_alert class show the popup dialog during alarm:
public class Reminder_alert extends DialogFragment {
public Dialog onCreateDialog(Bundle savedInstanceState) {
/** Turn Screen On and Unlock the keypad when this alert dialog is displayed */
getActivity().getWindow().addFlags(WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON | WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD);
/** Creating a alert dialog builder */
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
/** Setting title for the alert dialog */
builder.setTitle("ALARM ON");
/** Setting the content for the alert dialog */
builder.setMessage("WAKE UP NOW");
/** Defining an OK button event listener */
builder.setPositiveButton("OK", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
dismiss();
}
});
/** Creating the alert dialog window */
return builder.create();
}
/**
* The application should be exit, if the user presses the back button
*/
#Override
public void onDestroy() {
super.onDestroy();
getActivity().finish();
}
}
1- in simple way first use this function to create alarm
private void createAlarm(Date start_alarm_date, String schedual_type ,String schedule_id){
AlarmManager alarmMgr = (AlarmManager) this.getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(this, PushLocalNotification.AlarmReceiver.class);
intent.setAction("Your_Action_Name"); //this action you will use later
intent.putExtra("Extra", any_extra_you_want_add);// remove if you want add extra
PendingIntent alarmIntent = PendingIntent.getBroadcast(this, 0, intent, 0);
// Set the alarm to start at specific date
Calendar calendar = Calendar.getInstance();
calendar.setTime(date);
// repeat it "daily":
alarmMgr.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(),
AlarmManager.INTERVAL_DAY, alarmIntent);
2- create IntentService and make your receiver extend BroadcastReceiver
public class PushLocalNotification extends IntentService {
private NotificationManager mNotificationManager;
private String mScheduleID;
NotificationCompat.Builder builder;
public PushLocalNotification() {
super("pushLocalNotification");
}
#Override
protected void onHandleIntent(Intent intent) {
// call create local notification here
}
public static class AlarmReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals("Your_action_Name")) {
// call service here.
Intent sendIntent = new Intent(context, PushLocalNotification.class);
sendIntent.putExtra("Extra_name", intent.getStringExtra("Previos_extra_you_add_before"));
context.startService(sendIntent);
}
}
}
private void createNotification() {
NotificationCompat.Builder builder = new NotificationCompat.Builder(this);
//Create Intent to launch this Activity again if the notification is clicked.
Intent i = new Intent(this, MainActivity.class);
i.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
PendingIntent intent = PendingIntent.getActivity(this, 0, i,
PendingIntent.FLAG_UPDATE_CURRENT);
builder.setContentIntent(intent);
// Sets the ticker text
builder.setTicker(getResources().getString(R.string.custom_notification));
// Sets the small icon for the ticker
builder.setSmallIcon(R.drawable.ic_stat_custom);
// Cancel the notification when clicked
builder.setAutoCancel(true);
// Build the notification
Notification notification = builder.build();
// Inflate the notification layout as RemoteViews
RemoteViews contentView = new RemoteViews(getPackageName(), R.layout.notification);
// Set text on a TextView in the RemoteViews programmatically.
final String time = DateFormat.getTimeInstance().format(new Date()).toString();
final String text = getResources().getString(R.string.collapsed, time);
contentView.setTextViewText(R.id.textView, text);
/* Workaround: Need to set the content view here directly on the notification.
* NotificationCompatBuilder contains a bug that prevents this from working on platform
* versions HoneyComb.
* See https://code.google.com/p/android/issues/detail?id=30495
*/
notification.contentView = contentView;
// Add a big content view to the notification if supported.
// Support for expanded notifications was added in API level 16.
// (The normal contentView is shown when the notification is collapsed, when expanded the
// big content view set here is displayed.)
if (Build.VERSION.SDK_INT >= 16) {
// Inflate and set the layout for the expanded notification view
RemoteViews expandedView =
new RemoteViews(getPackageName(), R.layout.notification_expanded);
notification.bigContentView = expandedView;
}
// START_INCLUDE(notify)
// Use the NotificationManager to show the notification
NotificationManager nm = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
nm.notify(0, notification);
}
}
3- final step don't forget to declare service and receiver inside manifest file
<receiver
android:name=".PushLocalNotification$AlarmReceiver"
android:enabled="true">
<intent-filter>
<action android:name="Your_Action_name:)" />
</intent-filter>
</receiver>
<service android:name=".PushLocalNotification" />
be patient and have fun :)
Create a method which contains your Code where you will define your Time or at what time you want to show the notification.This method need to be called from where you want user to ask for notification.
public void getNotification () {
AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
Intent intent = new Intent(getApplicationContext(), Notification_receiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(getApplicationContext(), 100, intent, PendingIntent.FLAG_UPDATE_CURRENT);
intent.setData((Uri.parse("custom://"+System.currentTimeMillis())));
alarmManager.cancel(pendingIntent);
Calendar calendar = Calendar.getInstance();
Calendar now = Calendar.getInstance();
calendar.set(Calendar.HOUR_OF_DAY, 16);
calendar.set(Calendar.MINUTE, 30);
calendar.set(Calendar.SECOND, 00);
if (now.after(calendar)) {
Log.d("Hey","Added a day");
calendar.add(Calendar.DATE, 1);
}
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), AlarmManager.INTERVAL_DAY, pendingIntent);
}
Create a Notification_receiver class which is going to extend Broadcast Receiver here you are going to define your Channel Id as it is perfectly working for API 25 and above this the Notification_receiver class:
import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.graphics.BitmapFactory;
import android.media.RingtoneManager;
import android.net.Uri;
import android.os.Build;
import android.util.Log;
import androidx.core.app.NotificationCompat;
//Created By Prabhat Dwivedi
public class Notification_receiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
NotificationCompat.Builder builder;
PendingIntent pendingIntent;
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
NotificationChannel channel = new NotificationChannel("Your App Name",
"You app Package Name",
NotificationManager.IMPORTANCE_HIGH);
String channel_Id = channel.getId();
CharSequence channel_name = channel.getName();
Log.e("Notification_receiver", "channel_Id :" + channel_Id);
Log.e("channel_name", "channel_name :" + channel_name);
channel.setDescription("Make entry of today's spending now");
notificationManager.createNotificationChannel(channel);
}
builder = new NotificationCompat.Builder(context)
.setSmallIcon(R.drawable.yourapp_logo)
.setChannelId("Your app Name is your Channel Id")
.setContentTitle("Your title")
.setContentText("Your Description")
.setAutoCancel(true);
//nder this you will find intent it is going to define after clicking notification which activity you want to redirect
Intent repeatingIntent = new Intent(context, HomePage.class);
pendingIntent = PendingIntent.getActivity(context, 100, repeatingIntent, PendingIntent.FLAG_UPDATE_CURRENT);
builder.setContentIntent(pendingIntent);
notificationManager.notify(100, builder.build());
}
}
Kindly also add the Notification receiver inside AndroidManifest.xml file
<receiver android:name=".Notification_receiver"/>

Broadcast receiver never receives intent

I have a problem with receiving notification. I am sure it is sent as I see log for sending. But I never receive it as I never see log or notification. I am not quiet sure what I am doing wrong.
And I don't want repeating alarm.
Using Nexus 7 on Marshmallow.
PracticeWordsActivity.java
public void setAlarm(int day){
alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
alarmIntent = new Intent(PracticeWordsActivity.this,AlarmReceiver.class);
pendingIntent = PendingIntent.getBroadcast(this, 0, alarmIntent, 0);
//alarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, System.currentTimeMillis()+15000, pendingIntent);
alarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime()+15000, pendingIntent);
Log.e(TAG,"Lift off");
}
AlarmService
public class AlarmService extends IntentService
{
private static final int NOTIFICATION_ID = 1;
private static final String TAG = "AlarmService";
private NotificationManager notificationManager;
private PendingIntent pendingIntent;
public AlarmService() {
super("AlarmService");
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
return super.onStartCommand(intent,flags,startId);
}
#Override
protected void onHandleIntent(Intent intent) {
Log.e(TAG,"Alarm Service has started.");
Context context = this.getApplicationContext();
notificationManager =
(NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
Intent mIntent = new Intent(this,MainActivity.class);
Bundle bundle = new Bundle();
bundle.putString("test", "test");
mIntent.putExtras(bundle);
pendingIntent = PendingIntent.getActivity(context, 0, mIntent, PendingIntent.FLAG_UPDATE_CURRENT);
Resources res = this.getResources();
NotificationCompat.Builder builder = new NotificationCompat.Builder(this);
builder.setContentIntent(pendingIntent)
.setSmallIcon(R.drawable.ic_launcher)
.setLargeIcon(BitmapFactory.decodeResource(res, R.drawable.ic_launcher))
.setTicker("TITLE")
.setAutoCancel(true)
.setContentTitle("TITLE2")
.setContentText("SUBJECT");
notificationManager =(NotificationManager)getSystemService(NOTIFICATION_SERVICE);
notificationManager.notify(NOTIFICATION_ID, builder.build());
Log.e(TAG,"Notifications sent.");
}
AlarmReceiver.java
public class AlarmReceiver extends WakefulBroadcastReceiver {
private static final String TAG = "AlarmReceiver";
Intent intent;
PendingIntent pendingIntent;
NotificationManager notificationManager;
#Override
public void onReceive(Context context, Intent intent) {
Log.e(TAG, "BroadcastReceiver has received alarm intent.");
Intent service1 = new Intent(context, AlarmService.class);
context.startService(service1);
}
}
AndroidManifest.xml
I have set receiver and service after declaring last activity in AndroidManifest.
...
</activity>
<receiver android:name=".AlarmReceiver"
android:enabled="true"/>
<service android:name=".AlarmService" />
</application>
You're using AlarmManager.ELAPSED_REALTIME_WAKEUP to set the alarm. ELAPSED_REALTIME_WAKEUP means time elapsed since the device booted up.
If you want the alarm to be triggered 15 seconds after you set it, use:
alarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime()+15000, pendingIntent);
or
alarmManager.set(AlarmManager.RTC_WAKEUP, System.currentTimeMillis()+15000, pendingIntent);
Also, I see you're triggering the alarm in WAKEUP mode and in your broadcast receiver you're starting a service. There is a chance that the device will go back to sleep before the service gets started. You can use WakefulBroadcastReceiver to prevent that.
You don't need to worry about repeating alarms, if you use the same intent to set a new alarm, the previous alarm that is using the same intent will be canceled.

How to Schedule Notification in Android

I'm trying to set notification for a time in the future.
I have the code for creating a notification but I can't find an option to schedule it.
How can I schedule notifications?
NOT FOR USE IN OREO+ (edit)
The answers above are good - but don't consider the user's potential to restart the device (which clears PendingIntent's scheduled by AlarmManager).
You need to create a WakefulBroadcastReceiver, which will contain an AlarmManager to schedule deliver a PendingIntent. When the WakefulBroadcastReceiver handles the intent - post your notification and signal the WakefulBroadcastReceiver to complete.
WakefulBroadcastReceiver
/**
* When the alarm fires, this WakefulBroadcastReceiver receives the broadcast Intent
* and then posts the notification.
*/
public class WakefulReceiver extends WakefulBroadcastReceiver {
// provides access to the system alarm services.
private AlarmManager mAlarmManager;
public void onReceive(Context context, Intent intent) {
//// TODO: post notification
WakefulReceiver.completeWakefulIntent(intent);
}
/**
* Sets the next alarm to run. When the alarm fires,
* the app broadcasts an Intent to this WakefulBroadcastReceiver.
* #param context the context of the app's Activity.
*/
public void setAlarm(Context context) {
mAlarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(context, WakefulReceiver.class);
PendingIntent alarmIntent = PendingIntent.getBroadcast(context, 0, intent, 0);
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
//// TODO: use calendar.add(Calendar.SECOND,MINUTE,HOUR, int);
//calendar.add(Calendar.SECOND, 10);
//ALWAYS recompute the calendar after using add, set, roll
Date date = calendar.getTime();
mAlarmManager.setExact(AlarmManager.RTC_WAKEUP, date.getTime(), alarmIntent);
// Enable {#code BootReceiver} to automatically restart when the
// device is rebooted.
//// TODO: you may need to reference the context by ApplicationActivity.class
ComponentName receiver = new ComponentName(context, BootReceiver.class);
PackageManager pm = context.getPackageManager();
pm.setComponentEnabledSetting(receiver, PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
PackageManager.DONT_KILL_APP);
}
/**
* Cancels the next alarm from running. Removes any intents set by this
* WakefulBroadcastReceiver.
* #param context the context of the app's Activity
*/
public void cancelAlarm(Context context) {
Log.d("WakefulAlarmReceiver", "{cancelAlarm}");
mAlarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(context, WakefulReceiver.class);
PendingIntent alarmIntent = PendingIntent.getBroadcast(context, 0, intent, 0);
mAlarmManager.cancel(alarmIntent);
// Disable {#code BootReceiver} so that it doesn't automatically restart when the device is rebooted.
//// TODO: you may need to reference the context by ApplicationActivity.class
ComponentName receiver = new ComponentName(context, BootReceiver.class);
PackageManager pm = context.getPackageManager();
pm.setComponentEnabledSetting(receiver, PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
PackageManager.DONT_KILL_APP);
}
BootReceiver
public class BootReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(Intent.ACTION_BOOT_COMPLETED)) {
context = ApplicationActivity.class;
AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(context, WakefulReceiver.class);
PendingIntent alarmIntent = PendingIntent.getBroadcast(context, 0, intent, 0);
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
//// TODO: use calendar.add(Calendar.SECOND,MINUTE,HOUR, int);
//calendar.add(Calendar.SECOND, 10);
//ALWAYS recompute the calendar after using add, set, roll
Date date = calendar.getTime();
alarmManager.setExact(AlarmManager.RTC_WAKEUP, date.getTime(), alarmIntent);
}
}
}
AndroidManifest.xml
<receiver android:name=".WakefulReceiver"/>
<receiver android:name=".BootReceiver"
android:enabled="false">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED"/>
</intent-filter>
</receiver>
You need to use PendingIntent and BroadCastReceiver for this -
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);
}
Also, you need to show notification in your 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);
}
}
Finally, call scheduleNotification() with appropriate arguments and you are good to go!

Restoring alarms makes app crash

What I'm trying to do; the user picks a date he wants to be notified at with DatePicker, and then I add the name, the id, the release date and the alertTime (The time in milliseconds converted from the user's chosen time) as an entry in the alarms database called myAlarmsDB, which is simple SQL. And when it gets called by the OnReceive() method I delete the entry from the database, all is good except when I close my device; the alarms don't get restored and makes my app crash with no stack-trace. Any idea what might be the problem?
public class AlertReceiver extends BroadcastReceiver {
String name = "";
int id = 0;
String releaseDate = "";
// Called when a broadcast is made targeting this class
#Override
public void onReceive(Context context, Intent intent) {
Intent intActivity = new Intent(context, MainActivity.class);
intActivity.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(intActivity);
if("android.intent.action.BOOT_COMPLETED".equals(intent.getAction())) {
Toast.makeText(context, "BOOT" , Toast.LENGTH_LONG).show();
// Set the alarm here.
Intent alertIntent = new Intent(context, AlertReceiver.class);
AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
for (Alarm alarm : MyApp.myAlarmsDB.getAllData()) {
alertIntent.putExtra("id", Integer.parseInt(alarm.get_id()));
alertIntent.putExtra("name", alarm.get_name());
alertIntent.putExtra("releaseDate", alarm.get_releaseDate());
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, Integer.parseInt(alarm.get_id()), alertIntent, PendingIntent.FLAG_UPDATE_CURRENT);
alarmManager.set(AlarmManager.RTC_WAKEUP, Long.valueOf(Integer.parseInt(alarm.get_alertTime())), pendingIntent);
}
}
id = intent.getIntExtra("id", -1);
name = intent.getStringExtra("name");
releaseDate = intent.getStringExtra("releaseDate");
//delete from database
MyApp.myAlarmsDB.deleteFromId(String.valueOf(id));
}
}
How I set the alarms
public void setAlarm(View view) {
Calendar cal = Calendar.getInstance();
cal.set(Calendar.YEAR, yearDate);
cal.set(Calendar.MONTH, monthDate);
cal.set(Calendar.DAY_OF_MONTH, dayDate);
long alertTime = cal.getTimeInMillis();
Intent alertIntent = new Intent(this, AlertReceiver.class);
// store id
alertIntent.putExtra("id", mainId);
alertIntent.putExtra("name", name);
alertIntent.putExtra("releaseDate", releaseDate);
Alarm alarm = new Alarm(String.valueOf(mainId), name, releaseDate, String.valueOf(alertTime));
MyApp.myAlarmsDB.addAlarm(alarm);
AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, mainId, alertIntent, PendingIntent.FLAG_UPDATE_CURRENT);
alarmManager.set(AlarmManager.RTC_WAKEUP, alertTime, pendingIntent);
}
Permissions:
<receiver android:name=".AlertReceiver"
android:permission="android.permission.RECEIVE_BOOT_COMPLETED" >
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>

Categories