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
Related
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 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>
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'm trying to use notification in my application in monodroid
the code that i wrote works well but when i reboot the device, the notification stopped and an alert pops up and says "Unfortunately app-name has stopped"
i really don't know how to solve it. please help. thanks
main activity :
Calendar calendar = Calendar.GetInstance(Java.Util.TimeZone.Default);
calendar.Set(Calendar.Year, DateTime.Now.Year);
calendar.Set(Calendar.Month, DateTime.Now.Month);
calendar.Set(Calendar.DayOfYear, DateTime.Now.DayOfYear);
calendar.Set(Calendar.HourOfDay,12);
calendar.Set(Calendar.Minute, 00);
calendar.Set(Calendar.Second, 00);
calendar.Set(Calendar.Millisecond, 00);
NotificationReceiver Notifications = new NotificationReceiver();
Notifications.StartNotify(this, calendar.TimeInMillis);
manifest.xml :
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<uses-sdk android:minSdkVersion="15" android:targetSdkVersion="15" />
<!-- Permission to start Alarm on device reboot -->
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<application android:allowBackup="true" android:icon="#drawable/LogoLifeTime" android:label="#string/ApplicationName" android:theme="#style/AppTheme">
<activity android:name=".Main_Activity" android:label="#string/ApplicationName"></activity>
<receiver android:name=".NotificationReceiver" android:enabled="true" android:exported="true">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
<!-- Will not be called unless the application explicitly enables it -->
<receiver android:name=".DeviceBootReceiver" android:enabled="false">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
</application>
</manifest>
notificationreceiver :
[BroadcastReceiver]
[IntentFilter(new[] { Intent.ActionBootCompleted })]
class NotificationReceiver : BroadcastReceiver
{
PowerManager.WakeLock w1;
public override void OnReceive(Context context, Intent intent)
{
PowerManager pm = (PowerManager)context.GetSystemService(Context.PowerService);
w1 = pm.NewWakeLock(WakeLockFlags.Partial, "NotificationReceiver");
w1.Acquire();
CreateNotification(context);
w1.Release();
}
void CreateNotification(Context context)
{
var nMgr = (NotificationManager)context.GetSystemService(Context.NotificationService);
var notification = new Notification(Resource.Drawable.LogoLifeTime, "LTP");
var pendingIntent = PendingIntent.GetActivity(context, 0, new Intent(context, typeof(check_daily_tasks_activity)), PendingIntentFlags.OneShot);
notification.SetLatestEventInfo(context,"hello dear", pendingIntent);
notification.Defaults |= NotificationDefaults.Sound | NotificationDefaults.Vibrate | NotificationDefaults.Lights;
notification.Flags = NotificationFlags.ShowLights | NotificationFlags.AutoCancel;
notification.LedARGB = Color.Blue;
notification.LedOnMS = 1;
notification.LedOffMS = 1;
nMgr.Notify(0, notification);
}
public void StartNotify(Context context, long alertTime)
{
AlarmManager am = (AlarmManager)context.GetSystemService(Context.AlarmService);
Intent intent = new Intent(context, this.Class);
PendingIntent pi = PendingIntent.GetBroadcast(context, 0, intent, 0);
am.SetRepeating(AlarmType.RtcWakeup, alertTime, AlarmManager.IntervalDay, pi);
}
}
DeviceBootReceiver :
[BroadcastReceiver]
public class DeviceBootReceiver : BroadcastReceiver
{
public override void OnReceive(Context context, Intent intent)
{
if (intent.Action.Equals("android.intent.action.BOOT_COMPLETED"))
{
Calendar calendar = Calendar.GetInstance(Java.Util.TimeZone.Default);
calendar.Set(Calendar.Year, DateTime.Now.Year);
calendar.Set(Calendar.Month, DateTime.Now.Month);
calendar.Set(Calendar.DayOfYear, DateTime.Now.DayOfYear);
calendar.Set(Calendar.HourOfDay, 12);
calendar.Set(Calendar.Minute, 00);
calendar.Set(Calendar.Second, 00);
calendar.Set(Calendar.Millisecond, 00);
NotificationReceiver Notifications = new NotificationReceiver();
Notifications.StartNotify(context, calendar.TimeInMillis);
Intent alarmIntent = new Intent(context, typeof(NotificationReceiver));
PendingIntent pendingIntent = PendingIntent.GetBroadcast(context, 0, alarmIntent, 0);
AlarmManager manager = (AlarmManager)context.GetSystemService(Context.AlarmService);
manager.SetInexactRepeating(AlarmType.RtcWakeup, calendar.TimeInMillis, AlarmManager.IntervalDay, pendingIntent);
Toast.MakeText(context, "Alarm Setsds", ToastLength.Short).Show();
}
}
}
I had a similar problem: if i closed the app through a task manager, the BroadcastReceivers stopped working. You try to build app in release mode sign app and publish in Ad-Hoc Distribution
Good Luck.
I am calling a Alarm every 30 seconds. It is not being called. What am I doing wrong.
AlarmManager mgr = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
Intent i = new Intent(this, OnAlarmReceiver.class);
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
PendingIntent pi = PendingIntent
.getBroadcast(this, 0, i, PendingIntent.FLAG_CANCEL_CURRENT);
Calendar cal = Calendar.getInstance();
cal.add(Calendar.SECOND, 30);
mgr.setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP, cal.getTimeInMillis(), 1000 * 30, pi);
My OnAlarmReceiver
public class OnAlarmReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
// PullPendingRequests.acquireStaticLock(context);
Toast.makeText(context, "Don't panik but your time is up!!!!.", Toast.LENGTH_LONG).show();
Log.d("Taxeeta:PullPendingRequets", "CallService Location");
context.startService(new Intent(context, DriverService.class));
}
}
My Manifest contents for Alarm and Service
<service
android:name="com.taxeeta.DriverService"
android:enabled="true"
android:label="#string/app_name"
android:screenOrientation="portrait"
android:theme="#android:style/Theme.Light.NoTitleBar" />
<receiver
android:name="com.taxeeta.support.OnAlarmReceiver"
android:exported="true" >
<intent-filter>
<action android:name="android.intent.action.NOTIFY" />
</intent-filter>
</receiver>
Fixed it by changing the code to, thanks to
Calendar cal = Calendar.getInstance();
cal.add(Calendar.SECOND, 5);
AlarmManager am = (AlarmManager) getSystemService(ALARM_SERVICE);
Intent notifyintent = new Intent(this, OnAlarmReceiver.class);
notifyintent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
notifyintent.setAction("android.intent.action.NOTIFY");
PendingIntent notifysender = PendingIntent.getBroadcast(this, 0, notifyintent,
PendingIntent.FLAG_UPDATE_CURRENT);
am.setInexactRepeating(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), 20 * 1000,
notifysender);