I read several questions here, and have a similar one as well. Non of the answers on another questions manage to solve the issue unfortunately. I know how to create a notification on Button click, yet I failed to create a notification for a specific time. My goal in the following code snippet was to create a notification at 19:00 every day. Here is the code snippet:
MainActivity:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Calendar calendar = Calendar.getInstance();
setAlarm(calendar);
}
public void setAlarm(Calendar calendar) {
Intent alertIntent = new Intent(this, Receiver.class);
AlarmManager am = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
PendingIntent pendingIntent = PendingIntent.getService(this, 0, alertIntent, 0);
calendar.set(Calendar.HOUR_OF_DAY, 19);
calendar.set(Calendar.MINUTE, 00);
am.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(),
24*60*60*1000, pendingIntent);
}
Receiver:
public class Receiver extends BroadcastReceiver{
#Override
public void onReceive(Context context, Intent intent) {
createNotification(context, "Blabla", "Blablablabla", "Alert");
}
public void createNotification(Context context, String msg,
String msgText, String msgAlert) {
PendingIntent pi = PendingIntent.getActivity(context, 0, new Intent(context, MainActivity.class), 0);
NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(context)
.setSmallIcon(R.drawable.clear_dayicon)
.setContentTitle(msg)
.setContentText("msgText")
.setTicker(msgAlert);
mBuilder.setContentIntent(pi);
mBuilder.setDefaults(NotificationCompat.DEFAULT_SOUND);
mBuilder.setAutoCancel(true);
NotificationManager mNotificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
mNotificationManager.notify(1, mBuilder.build());
}
}
Manifest:
// only ones I called after started working with notifications and stuff
<uses-permission android:name="com.android.alarm.permission.SET_ALARM" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
<service android:name=".Receiver2" android:enabled="true">
<intent-filter> <action android:name="NOTIFICATION_SERVICE" /></intent-filter>
</service>
<receiver android:name=".Receiver"/>
Some help would be super appreciated. Since I'm a beginner, I need someone to show me my mistakes. Otherwise, I can't spot them no matter how many docs I read. This code looks fine to me :P
try this:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.HOUR_OF_DAY, 19);
calendar.set(Calendar.MINUTE, 00);
setAlarm(calendar);
}
public void setAlarm(Calendar calendar) {
boolean alarmNoActive = (PendingIntent.getBroadcast(this, 0, new Intent("ALARM"), PendingIntent.FLAG_NO_CREATE) == null);
if(alarmNoActive){
Intent itAlarm = new Intent("ALARM");
PendingIntent pendingIntent = PendingIntent.getBroadcast(this,0,itAlarm,0);
AlarmManager alarmManager = (AlarmManager)getSystemService(ALARM_SERVICE);
AlarmManager alarme = (AlarmManager) getSystemService(ALARM_SERVICE);
am.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(),
24*60*60*1000, pendingIntent);
}
}
In the manifest put this permission:
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"
In application:
<receiver
android:name="path of the BroadcastReceiver.Receiver"
android:label="BroadcastReceiverAux">
<intent-filter>
<action android:name="ALARM" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</receiver>
Related
I'm developing an android application that have daily notification. I have a solution but not enough. My code working after restarting the phone. Users will not restart their devices unless they are required. My notifications will not appear until this time. How can I solve?
BootReceiver.java
public class BootReceiver extends BroadcastReceiver {
private AlarmManager alarmManager;
private PendingIntent pendingIntent;
#Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(context, "Device Booted", Toast.LENGTH_SHORT).show();
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
calendar.set(Calendar.HOUR_OF_DAY, 19);
calendar.set(Calendar.MINUTE, 20);
calendar.set(Calendar.SECOND, 0);
alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
Intent alarmIntent = new Intent(context, AlarmReceiver.class);
pendingIntent = PendingIntent.getBroadcast(context, 1, alarmIntent, 0);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
alarmManager.setExact(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), pendingIntent);
}
}
}
Manifest.xml
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<receiver
android:name=".AlarmReceiver" />
<receiver
android:name=".BootReceiver">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED"/>
</intent-filter>
</receiver>
AlarmReceiver.java -> just notification builder
I am using notifications in my application and everything works well - the notification is showing at desired time to me, even after device reboot.
However, when I click the special button to close all apps, so it closes my app, the notification is not showing at all.
"The special button to close all apps" - I mean the one where you can list all the background apps and then with one click kill them all.
I am testing everything on OnePlus 3T.
Is it possible to run the service again after that "kill all apps" click ?
manifest:
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
...
<receiver
android:name="com.saga.thewitcherquotes.QuoteOfTheDayReceiver"
android:enabled="true"
android:exported="false" >
</receiver>
<receiver android:name="com.saga.thewitcherquotes.DeviceBootReceiver"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
<service
android:name="com.saga.thewitcherquotes.QuoteOfTheDayIntentService"
android:exported="false"></service>
BootReceiver:
public class DeviceBootReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals("android.intent.action.BOOT_COMPLETED")) {
// on device boot compelete, reset the alarm
Intent alarmIntent = new Intent(context, QuoteOfTheDayReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, alarmIntent, PendingIntent.FLAG_UPDATE_CURRENT);
AlarmManager manager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
Calendar current = Calendar.getInstance();
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
calendar.set(Calendar.HOUR_OF_DAY, 21);
calendar.set(Calendar.MINUTE, 30);
if(calendar.before(current))
{
calendar.add(Calendar.DATE, 1);
}
manager.setInexactRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(),
AlarmManager.INTERVAL_DAY, pendingIntent);
}
}
}
The service with notification builder:
public class QuoteOfTheDayIntentService extends IntentService {
private static final int NOTIFICATION_ID = 3;
public QuoteOfTheDayIntentService() {
super("MyNewIntentService");
}
#Override
protected void onHandleIntent(Intent intent) {
Notification.Builder builder = new Notification.Builder(this);
builder.setContentTitle(getString(R.string.quote_of_the_day));
DatabaseHandler db = DatabaseHandler.getInstance(this);
Random generator = new Random();
int id = generator.nextInt(db.getQuotesSize());
Quote quote = db.getQuote(id, null);
builder.setContentText(quote.getQuote());
builder.setSmallIcon(R.drawable.swords);
builder.setAutoCancel(true);
Intent notifyIntent = new Intent(this, MainActivity.class);
notifyIntent.putExtra("id",id-1);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, notifyIntent, PendingIntent.FLAG_UPDATE_CURRENT);
builder.setContentIntent(pendingIntent);
Notification notificationCompat = builder.build();
NotificationManagerCompat managerCompat = NotificationManagerCompat.from(this);
managerCompat.notify(NOTIFICATION_ID, notificationCompat);
}
}
I need your help. I'm stuck with this problem. Alarms work properly. However, when device is rebooted, and the specified time stored in db is in the past (3pm) and current time is 4pm, how can I check to prevent triggering the alarm immediately?
Docs say:
If the stated trigger time is in the past, the alarm will be triggered immediately.
Here's what I've tried so far:
class DeviceBootReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
// Check if successful reboot
if (intent.getAction().equals("android.intent.action.BOOT_COMPLETED")) {
SharedPreferences shared = context.getSharedPreferences(Constants.PREF_NAME, Context.MODE_PRIVATE);
// Check if daily notification is enabled
// If yes, call NotificationPublisher to communicate with NotificationAlarmService
if(shared.getBoolean(Constants.KEY_IS_DAILY_NOTIFIED, false)) {
DBHelper dbHelper = new DBHelper(context);
DBConnector.dbConnect(dbHelper);
int DAILY_NOTIFICATION_ID = Constants.DAILY_VERSE_NOTIFICATION_1_ID;
ArrayList<Notification> notificationList = dbHelper.getNotifications();
Log.e("", "notificationList: " + notificationList.size());
for(Notification obj : notificationList) {
Calendar datetime = Calendar.getInstance();
datetime.set(Calendar.HOUR_OF_DAY, obj.getHourOfDay());
datetime.set(Calendar.MINUTE, obj.getMinute());
datetime.set(Calendar.SECOND, 0);
Calendar now = Calendar.getInstance();
if (now.after(datetime)) {
datetime.add(Calendar.DATE, now.get(Calendar.DATE) + 1);
}
Log.e("BOOT RECEIVER", "" + obj.getHourOfDay() + ":" + obj.getMinute());
Intent myIntent = new Intent(context, NotificationPublisher.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(context,
DAILY_NOTIFICATION_ID++,
myIntent, PendingIntent.FLAG_UPDATE_CURRENT);
AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP,
datetime.getTimeInMillis(), AlarmManager.INTERVAL_DAY,
pendingIntent);
}
}
}
}
AndroidManifest:
<receiver
android:name=".utils.DeviceBootReceiver" >
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
<action android:name="android.intent.action.QUICKBOOT_POWERON" />
</intent-filter>
</receiver>
What seems to be wrong with my code? I'd appreciate any help. Thanks!
I set & check alarm time like this and it works for me now:
Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.HOUR_OF_DAY, alarmTimePicker.getCurrentHour());
calendar.set(Calendar.MINUTE, alarmTimePicker.getCurrentMinute());
Calendar now = Calendar.getInstance();
now.setTimeInMillis(System.currentTimeMillis());
if (calendar.before(now))
calendar.add(Calendar.DAY_OF_MONTH, 1);
A sample code to set repetition of Alarm at interval day.
I have set the Alarm in MainActivity if your want to set Alarm once you can do it by extending Application class and write code to set Alarm inside onCreate.
public class MainActivity extends AppCompatActivity {
private AlarmManager alarmMgr;
private PendingIntent alarmIntent;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
alarmMgr = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(this, AlarmReceiver.class);
alarmIntent = PendingIntent.getBroadcast(this, 0, intent, 0);
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
calendar.set(Calendar.HOUR_OF_DAY, 15);
calendar.set(Calendar.MINUTE, 30);
alarmMgr.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(),
AlarmManager.INTERVAL_DAY, alarmIntent);
}
}
SampleBootReciver - set Alarm after the device is rebooted
public class SampleBootReceiver extends BroadcastReceiver {
private AlarmManager alarmMgr;
private PendingIntent alarmIntent;
#Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals("android.intent.action.BOOT_COMPLETED")) {
alarmMgr = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
Intent intent1 = new Intent(context, AlarmReceiver.class);
alarmIntent = PendingIntent.getBroadcast(context, 0, intent1, 0);
Calendar now = Calendar.getInstance();
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
calendar.set(Calendar.HOUR_OF_DAY, 15);
calendar.set(Calendar.MINUTE, 30);
if (calendar.before(now))
calendar.add(Calendar.DAY_OF_MONTH, 1);
alarmMgr.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(),
AlarmManager.INTERVAL_DAY, alarmIntent);
}
}
}
AlarmReceiver - perform action after Alarm is fired.
public class AlarmReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(context, "I'm running", Toast.LENGTH_SHORT).show();
}
}
I'm just displaying a toast.
Lastly the manifest file -
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.bits.kevz.samplealarm">
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<receiver android:name=".AlarmReceiver">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED"/>
</intent-filter>
</receiver>
<receiver android:name=".SampleBootReceiver"
android:enabled="false">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
</application>
</manifest>
I want you to run above code and check onBootCompleted output.
I am building an android app to display recurring scheduled notification at a specified time of the day.
For this I have created broadcastReceiver using following code:
public class ScheduleNotification extends BroadcastReceiver {
public static final int NOTIFICATION_ID = 1;
#Override
public void onReceive(Context context, Intent intent) {
long when = System.currentTimeMillis();
MainActivity mainActivity = new MainActivity();
String _pasuram_number = mainActivity.get_pasuram_number();
String[] _pasuram_str = mainActivity.get_dd_text(_pasuram_number).split(",");
Log.d("VC", "Notification intent paasuram " + _pasuram_number);
intent.putExtra("pasuramnumber", _pasuram_number);
PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
Intent snoozeIntent = new Intent(context, MainActivity.class);
PendingIntent piSnooze = PendingIntent.getService(context, 0, snoozeIntent, 0);
NotificationCompat.Builder builder = new NotificationCompat.Builder(context);
builder.setSmallIcon(R.drawable.ic_stat_name);
builder.setContentIntent(pendingIntent);
builder.setAutoCancel(true);
builder.setLargeIcon(BitmapFactory.decodeResource(context.getResources(), R.drawable.ic_stat_name));
builder.setContentTitle("Title of the notification");
builder.setContentText(_pasuram_str[9]+"-"+_pasuram_str[11]);
builder.setStyle(new NotificationCompat.BigTextStyle().bigText(_pasuram_str[0] + "-" + _pasuram_str[8]));
Uri alarmSound = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(NOTIFICATION_ID, builder.build());
}
}
In the MainActivity added code to create alarm
private void createScheduledNotification(int days)
{
// Get new calendar object and set the date to now
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
// Add defined amount of days to the date
calendar.set(Calendar.HOUR_OF_DAY, 6);
calendar.set(Calendar.MINUTE, 0);
calendar.set(Calendar.SECOND, 0);
//calendar.add(Calendar.HOUR_OF_DAY, days * 24);
// Retrieve alarm manager from the system
AlarmManager alarmManager = (AlarmManager) getApplicationContext().getSystemService(getBaseContext().ALARM_SERVICE);
// Every scheduled intent needs a different ID, else it is just executed once
int id = (int) System.currentTimeMillis();
// Prepare the intent which should be launched at the date
Intent intent = new Intent(this, ScheduleNotification.class);
// Prepare the pending intent
PendingIntent pendingIntent = PendingIntent.getBroadcast(getApplicationContext(), id, intent, PendingIntent.FLAG_UPDATE_CURRENT);
// Register the alert in the system. You have the option to define if the device has to wake up on the alert or not
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), AlarmManager.INTERVAL_DAY, pendingIntent);
//alarmManager.set(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), pendingIntent);
}
The code compiles fine and application runs, but scheduled notification does not appear as expected.
In the manifest file added receiver as follows:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.vaishnavism.eclass.dinamorudivyaprabandam" >
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<!-- permission required to use Alarm Manager -->
<uses-permission android:name="com.android.alarm.permission.SET_ALARM"/>
<!-- Register the Alarm Receiver -->
<receiver android:name="com.vaishnavism.eclass.dinamorudivyaprabandam.ScheduleNotification"/>
<activity
android:name=".MainActivity"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".SettingsActivity"
android:label="#string/title_activity_settings"
android:parentActivityName=".MainActivity" >
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value="com.vaishnavism.eclass.dinamorudivyaprabandam.MainActivity" />
</activity>
</application>
</manifest>
Any help to resolve the issue is greatly appreciated.
Thanks
Try to use set your alarm like below :
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
calendar.set(Calendar.HOUR_OF_DAY, 6);
calendar.set(Calendar.MINUTE, 0);
int interval = 1000 * 60 * 60 * 24;
Intent myIntent = new Intent(yourActivity.this, ScheduleNotification .class);
pendingIntent = PendingIntent.getBroadcast(UserDashBoardActivity.this, 0, myIntent,0);
/* Repeating on every 24 hours interval */
AlarmManager alarmManager = (AlarmManager)getSystemService(ALARM_SERVICE);
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), interval, pendingIntent);
And you need to start an Alarm When the Device Boots.
For more info refere here.
Hope it will help you.
My apps alarm fires directly after each reboot, not at the specified time and it's not repeating. The alarm I set is ignored.
InitializeAlarm:
public class InitialisiereAlarm extends Activity {
private static final String TAG = "InitialisiereAlarm";
private static AlarmManager am;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_alarm);
aktiviereAlarmDownload();
finish();
}
private void aktiviereAlarmDownload() {
Calendar calAkt = Calendar.getInstance();
calAkt.setTimeInMillis(System.currentTimeMillis());
calAkt.set(Calendar.DAY_OF_WEEK, 2);
calAkt.set(Calendar.HOUR_OF_DAY, 10);
calAkt.set(Calendar.MINUTE, 15);
Intent intent = new Intent(this, StartAlarm.class);
intent.putExtra("alarmCode", "12345");
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 12345,
intent, PendingIntent.FLAG_UPDATE_CURRENT);
AlarmManager am = (AlarmManager) getSystemService(Activity.ALARM_SERVICE);
am.setRepeating(AlarmManager.RTC_WAKEUP, calAkt.getTimeInMillis(),
AlarmManager.INTERVAL_HALF_HOUR, pendingIntent);
}
}
StartAlarm extends BroadcastReceiver, actually the same plus starting another activity:
public class StartAlarm extends BroadcastReceiver {
private static final String TAG = "StartAlarm";
private WakeLock wl;
#Override
public void onReceive(Context context, Intent intent) {
PowerManager pm = (PowerManager) context
.getSystemService(Activity.POWER_SERVICE);
wl = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "SomeTag");
wl.acquire();
Intent intent2 = new Intent();
intent2.setClassName("com.test.testApp",
"com.test.testApp.DoThings");
intent2.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(intent2);
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 12345,
intent2, PendingIntent.FLAG_UPDATE_CURRENT);
Calendar calAkt = Calendar.getInstance();
calAkt.setTimeInMillis(System.currentTimeMillis());
calAkt.set(Calendar.DAY_OF_WEEK, 2);
calAkt.set(Calendar.HOUR_OF_DAY, 10);
calAkt.set(Calendar.MINUTE, 15);
AlarmManager am = (AlarmManager) context.getSystemService(Activity.ALARM_SERVICE);
am.setRepeating(AlarmManager.RTC_WAKEUP, calAkt.getTimeInMillis(),
AlarmManager.INTERVAL_HALF_HOUR, pendingIntent);
}
StartAlarm in the Manifest:
<receiver
android:name=".timer.StartAlarm"
android:enabled="true" >
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
I don't see what I'm doing wrong. Guess there's something I didn't understand... Any help is apprechiated!
Edit:
The problem was, that the alarm layed in the past. Solved it by setting the alarm to a future date by inserting
Calendar cal = Calendar.getInstance();
if (calAkt.compareTo(cal) <= 0) {
calAkt.add(Calendar.MINUTE, 8);
}
Thanks #CommonsWare for the hint
My apps alarm fires directly after each reboot
No, it does not. However, your StartAlarm BroadcastReceiver is getting control at boot time, because that is what you put in your manifest. If you do not want StartAlarm to get control at boot time, then get rid of its <intent-filter> in the manifest.