I am working on an application inwhich I am using AlarmManager for scheduling things. My Alarm is set. But this Alarm does not invoke BroadcastReceiver written to catch the event. I have searched a great deal but I have not found anything that solves the issue. I am posting my code, please have a look and see if I am missing something.
AlarmManagerClass:
public class ScheduleMessageManager {
Context context;
PendingIntent sender;
AlarmManager am;
public ScheduleMessageManager(Context context) {
this.context = context;
}
public void addAlram(int scheduledMessageID, long scheduledTime) {
// Activate Broadcast Receiver to receive broadcasts
activateBroadcastReceiver();
//Calendar cal = Calendar.getInstance();
Intent intent = new Intent(context, AlarmReceiver.class);
// In reality, you would want to have a unique variable for the request
// code
intent.putExtra("scheduledMessageID", scheduledMessageID);
sender = PendingIntent.getBroadcast(context, scheduledMessageID, intent, PendingIntent.FLAG_UPDATE_CURRENT);
// Get the AlarmManager service
am = (AlarmManager) context.getSystemService(context.ALARM_SERVICE);
am.set(AlarmManager.RTC_WAKEUP, scheduledTime, sender);
Log.e("In ScheduleMessageManage", "***** Alarm is set to the mmessage *****");
}
public void cancelPeriodicSchedule(PendingIntent sender) {
if (am != null) {
if (sender != null) {
am.cancel(sender);
sender.cancel();
}
}
// Deactivate Broadcast Receiver to stop receiving broadcasts
deactivateBroadcastreceiver();
}
private void activateBroadcastReceiver() {
PackageManager pm = context.getPackageManager();
ComponentName componentName = new ComponentName(context, AlarmReceiver.class);
pm.setComponentEnabledSetting(componentName, PackageManager.COMPONENT_ENABLED_STATE_ENABLED, PackageManager.DONT_KILL_APP);
Toast.makeText(context, "activated", Toast.LENGTH_LONG).show();
}
private void deactivateBroadcastreceiver() {
// TODO Auto-generated method stub
PackageManager pm = context.getPackageManager();
ComponentName componentName = new ComponentName(context, AlarmReceiver.class);
pm.setComponentEnabledSetting(componentName, PackageManager.COMPONENT_ENABLED_STATE_DISABLED, PackageManager.DONT_KILL_APP);
Toast.makeText(context, "cancelled", Toast.LENGTH_LONG).show();
}
}
My AlarmReceiver:
public class AlarmReceiver extends BroadcastReceiver {
int pendingIntentID; // same as scheduledMessageID
#Override
public void onReceive(Context context, Intent intent) {
Log.e("In On Receive", "Alarm has Initiated Broadcast Receiver....");
if (intent.hasExtra("scheduledMessageID")) {
pendingIntentID = intent.getExtras().getInt("scheduledMessageID");
Intent sendMessageServiceIntent = new Intent(context, SendMessageService.class);
sendMessageServiceIntent.putExtra("pendingIntentID", pendingIntentID);
context.startService(sendMessageServiceIntent);
}
}
}
OnReceieve() is never called.
In My Manifest.xml
<receiver
android:name="myPackage.AlarmReceiver"
android:enabled="true" >
</receiver>
I am unable to figure out the does the problem lie. Please help me out of it. Thanks.!
A good tutorial on using Broadcast receivers is given in http://www.vogella.com/articles/AndroidBroadcastReceiver/article.html. In essence, your receiver doesn't declare what events it will receive. The declaration in the Manifest file needs something like:
<receiver
android:name="myPackage.AlarmReceiver"
android:enabled="true" >
<intent-filter>
<action android:name="your.company.blah.mybroadcast" />
</intent-filter>
</receiver>
And when you create the intent, it needs
Intent intent = new Intent();
intent.setAction("your.company.blah.mybroadcast");
// All the other things you want to put in the intent
I know that this has been answered already, but just for further reference as I ran into the same issue, make sure that your receiver tags are inside the tags, but not inside any other tag such as activity (that's exactly the issue I had).
Also it helps a great deal to check that your alarm has been successfully registered, to so run:
adb shell dumpsys alarm
You just need to registered your receiver with alarm manager this will call broadcast after every 60 second:
Intent broadcastIntent = new Intent(YourActivity.this, AlarmReceiver.class);
PendingIntent pi = PendingIntent.getBroadcast(this, 0, broadcastIntent, 0);
AlarmManager am = (AlarmManager) getSystemService(ALARM_SERVICE);
long timeInterval = 60 * 1000;
am.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(), timeInterval, pi);
In Manifest:
<receiver
android:name="myPackage.AlarmReceiver"
android:enabled="true" >
</receiver>
Related
I want to do some network job periodically even when app if force closed.
Now it works until it's force closed.
What i am missing?
Also if i add to manifest this: android:process=":remote" - it's not triggering onReceive method (like app is force closed), but in logs i found that:
V/AlarmManager: triggered: cmp=com.cryptorulezz.cryptosignals/.Code.Alarm Pkg: com.cryptorulezz.cryptosignals
My code:
public class Alarm extends BroadcastReceiver
{
#Override
public void onReceive(Context context, Intent intent)
{
PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
PowerManager.WakeLock wl = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "");
wl.acquire();
// Put here YOUR code.
Toast.makeText(context, "Alarm !!!!!!!!!!", Toast.LENGTH_LONG).show(); // For example
System.out.println("ALARM !!!!!!!!!!!!!!!!!!!!");
wl.release();
}
public void setAlarm(Context context)
{
AlarmManager am =(AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
//Intent i = new Intent(context, Alarm.class);
Intent i = new Intent("Coinsider.START_ALARM");
PendingIntent pi = PendingIntent.getBroadcast(context, 0, i, 0);
am.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(), 1000 * 60 * 1, pi); // Millisec * Second * Minute
}
public void cancelAlarm(Context context)
{
Intent intent = new Intent(context, Alarm.class);
PendingIntent sender = PendingIntent.getBroadcast(context, 0, intent, 0);
AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
alarmManager.cancel(sender);
}
}
How i set alarm in MainActivity:
Alarm alarm = new Alarm();
alarm.setAlarm(this);
Manifest:
<receiver android:name=".Code.Alarm" android:exported="false">
<intent-filter>
<action android:name="Coinsider.START_ALARM" >
</action>
</intent-filter>
</receiver>
Once the app gets force killed, it won't receive the intent and the intent filter won't be triggered. To overcome this, I suggest a sort of watchDog, that relies on some system events (like android.intent.action.BOOT_COMPLETED), that simply checks if one of your process is alive, and fires it if not. In the manifest, you 'd have something like this:
<receiver
android:name="it.angelic.receivers.WatchDogSetupReceiver"
android:process=":souliss_process">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED"/>
<action android:name="android.intent.action.USER_PRESENT"/>
</intent-filter>
</receiver>
The class WatchDogSetupReceiver would then check if the dog is alive, and fire a new one if needed:
Intent i = new Intent(ctx, WatchDogEventReceiver.class); // explicit intent
PendingIntent patTheDog = PendingIntent.getBroadcast(ctx, 0, i, PendingIntent.FLAG_CANCEL_CURRENT);
alarmManager.setInexactRepeating(AlarmManager.RTC_WAKEUP, now.getTimeInMillis(), 5000,
patTheDog);
Last, WatchDogEventReceiver would simply do the required un-killable job. It is important that the watchdog stays light, as it will be fired upon every screen on event. This solution is non-optimal, but works even after force-kill:
public class WatchDogEventReceiver extends BroadcastReceiver {
#Override
public void onReceive(final Context ctx, final Intent intent) {
Log.d(Constants.TAG + ":WatchDog", "WatchDog.onReceive() called, looking for Dataservice:");
ActivityManager manager = (ActivityManager) ctx.getSystemService(Context.ACTIVITY_SERVICE);
//Fire Service
Intent eventService = new Intent(ctx, YourDamnService.class);
ctx.startService(eventService);//sempre, ci pensa poi lui
}
I set alarm manager for time control.My purpose continue to time controlling on screen off. While screen is on everything is ok but when i locked to device(screen of) my broadcast receiver not receiver anything
i tried lots of different solution (in Manifest export:false or process:":remote") about similar problem but problem not solved. I need to help. I hope someone solved that problem before.
For set alarm manager
AlarmManager alarmManager = (AlarmManager)
context.getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(context, TimeService.class);
intent.setAction(SETUP_TIMER_FOR_NOTIFICATION);
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 112, intent, PendingIntent.FLAG_UPDATE_CURRENT);
long now = System.currentTimeMillis();
long minute = 1000 * 60;
alarmManager.cancel(pendingIntent);
alarmManager.setInexactRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime() , minute, pendingIntent);
My Receiver
public class TimeService extends WakefulBroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Log.i("TimeService", "onReceive");
Intent timeIntent = new Intent(context, NotificationService.class);
timeIntent.setAction(SETUP_TIMER_FOR_NOTIFICATION);
startWakefulService(context, timeIntent);
}
}
Manifest.xml
<receiver
android:name="service.TimeService"
android:enabled="true"
android:exported="false"
>
<intent-filter>
<action android:name="alarm_timer_for_notification" />
</intent-filter>
</receiver>
setAndAllowWhileIdle this is worked when screen is off and phone in idle mode
In marshmallow introduce the doze mode for battery saving. So the alarm not fired correctly in repeat mode.
So we use
https://developer.android.com/reference/android/app/AlarmManager.html#setAndAllowWhileIdle(int,%20long,%20android.app.PendingIntent)
From marshmallow and up, alarm waked up only 10 min interval,setAndAllowWhileIdle also fire service or notification 10 minutes once when phone is idle (screen is off).
In normal mode time interval working fine (I have checked 3 min's interval)
public class TimeService extends WakefulBroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Log.i("TimeService", "onReceive");
Intent timeIntent = new Intent(context, NotificationService.class);
timeIntent.setAction(SETUP_TIMER_FOR_NOTIFICATION);
startWakefulService(context, timeIntent);
setAlarm(context);
}
public void setAlarm(Context context)
{
Timber.v(TAG +"set Alarm");
PreferencesHelper preferencesHelper =new PreferencesHelper(context);
AlarmManager alarmManager = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(context, TimeService.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, intent, 0);
int intervalInMinutes = preferencesHelper.getInt(context.getResources().getString(R.string.sha_loc_intervals), 1)* 60000;
if (android.os.Build.VERSION.SDK_INT >= 23) {
alarmManager.setAndAllowWhileIdle(AlarmManager.ELAPSED_REALTIME_WAKEUP,
SystemClock.elapsedRealtime()+intervalInMinutes , pendingIntent);
} else if (android.os.Build.VERSION.SDK_INT >= 19
&& android.os.Build.VERSION.SDK_INT < 23) {
alarmManager.setExact(AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime()+intervalInMinutes , pendingIntent);
} else {
alarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime()+intervalInMinutes , pendingIntent);
}
}
public void cancelAlarm(Context context)
{
Timber.v(TAG +"cancel Alarm");
Intent intent = new Intent(context, TimeService.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, intent, 0);
AlarmManager alarmManager = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
alarmManager.cancel(pendingIntent);
}}
<receiver android:name=".TimeService"
android:enabled="true"
android:exported="true"
android:process=":remote">
</receiver>
In MainActivity.class
TimeService timeService =new TimeService();
timeService.setAlarm(MainActivity.this);
You want to take a permission in manifest file.
uses-permission android:name="android.permission.WAKE_LOCK"
WakeLock is a mechanism to keep the device on
I am trying to create a daily alarm to send notifications but somehow notifications are not coming.
I have read a lot about it but none of the solution helps.
CreateAlarm function:
public static void createAlarm (Context ctx, String filename, boolean must_create_alarm)
{
// CreateAlarm is called from main activity onCreate method.
// Hence, using SharedPreference to set alarm only once.
// When need to explicitly set the alarm. Client pass
// must_create_alarm boolean to true
SharedPreferences pref = ctx.getSharedPreferences(filename, Context.MODE_PRIVATE);
boolean create_alarm = pref.getBoolean("MY_ALARM", true);
create_alarm |= must_create_alarm;
if (create_alarm == false) {
Log.w ("ALARM INFO","ALARM ALREADY CREATED");
return;
}
Log.w ("ALARM INFO","CREATED FRESH ALARAM");
pref.edit()
.putBoolean("MY_ALARM", false).commit();
// Set the alarm to start at exactly 11:00 a.m.
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
calendar.set(Calendar.HOUR_OF_DAY, 21);
AlarmManager alarmMgr = (AlarmManager) ctx.getSystemService(ctx.ALARM_SERVICE);
Intent _alarmIntent = new Intent(ctx, AppBroadCastReceiver.class);
_alarmIntent.setAction("android.intent.action.ALARM_KICK_OFF");
PendingIntent pendingIntent = PendingIntent.getBroadcast(ctx, 1, _alarmIntent,
PendingIntent.FLAG_UPDATE_CURRENT);
Log.w("myApp", "SETTING ALARM");
alarmMgr.setInexactRepeating(AlarmManager.RTC_WAKEUP,
calendar.getTimeInMillis(),
AlarmManager.INTERVAL_DAY, pendingIntent); // Setting notification every DAY
}
AppBroadCastReceiver class:
public class AppBroadCastReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals("android.intent.action.BOOT_COMPLETED")) {
Log.w("myApp", "AppBroadCastReceiver DEVICE REBOTTED");
GeneralUtility.createAlarm(context, "designersarres.designersarees", true);
}
else if (intent.getAction().equals("android.intent.action.ALARM_KICK_OFF")) {
// Alarm is fired. Send notification
Log.w("myApp", "AppBroadCastReceiver ALARM");
GetNotificationMsg msg = new GetNotificationMsg(context);
msg.sendNotification();
}
}
}
AndroidManifest.xml:
<!-- Register the Broadcast Receiver -->
<receiver android:name="designersarres.designersarees.AppBroadCastReceiver"
android:enabled="true">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED"/>
<action android:name="android.intent.action.ALARM_KICK_OFF"/>
</intent-filter>
</receiver>
I am stuck on this for last couple of days.
Please let me know what I am missing here or doing something wrong here.
Please let me know if I need to post more code here.
I'm failing to see why this alarm is going off on a reboot...I am setting it 7 days ahead here -
Intent intent = new Intent(MainActivity.this, Reminder.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(
MainActivity.this, 1, intent, 1);
AlarmManager am = (AlarmManager) getSystemService(ALARM_SERVICE);
try {
am.cancel(pendingIntent);
} catch (Exception e) {
System.out.println("Derp");
}
Calendar calendar = Calendar.getInstance();
calendar.add(Calendar.DATE, 7);
long time = calendar.getTimeInMillis();
am.set(AlarmManager.RTC_WAKEUP, time,
pendingIntent);
Here is my manifest that I have set for alarm to stick around on a reboot - Reminder is the class receiving the alarm-
<receiver android:name="com.practicum.notifications.Reminder" >
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
By default, all alarms are canceled when a device shuts down. To prevent this from happening, you can design your application to automatically restart a repeating alarm if the user reboots the device. This ensures that the AlarmManager will continue doing its task without the user needing to manually restart the alarm.
You have to manually reset the alarm once again in Bootup Receiver
public class SampleBootReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals("android.intent.action.BOOT_COMPLETED")) {
// Set the alarm here.
}
}
All alarms are shut off when you power off the Android device.
You need to call setRepeating method
public class AlarmReceiver extends BroadcastReceiver {
private static final int PERIOD=5000;
#Override
public void onReceive(Context ctxt, Intent i) {
scheduleAlarms(ctxt);
}
static void scheduleAlarms(Context ctxt) {
AlarmManager am = (AlarmManager) ctxt.getSystemService(Context.ALARM_SERVICE);
Intent i = new Intent(ctxt, YourService.class);
PendingIntent pi = PendingIntent.getService(ctxt, 0, i, 0);
mgr.setRepeating(AlarmManager.ELAPSED_REALTIME,
SystemClock.elapsedRealtime() + PERIOD, PERIOD, pi);
}
}
Check this answer from CommonsWare.
For future reference, I misunderstood how receving the boot complete action worked. I had the intent filter in both of my receiver classes so they were both running, when instead I needed an intent filter on a new broadcastreceiver class to RESET my alarmmanagers.
I'm trying to call a broadcast receiver at a certain time by setting an alarm. It doesn't appear to be getting called at all. I'm trying to debug with logcat.
My set up for the alarm is something like this:
AlarmManager alarm = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
Calendar notifyAlarm = Calendar.getInstance();
notifyAlarm.set(Calendar.HOUR, 17);
notifyAlarm.set(Calendar.MINUTE, 00);
Intent intent = new Intent(this, AlarmReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(this.getApplicationContext(), 2378530, intent, 0);
alarm.set(AlarmManager.RTC_WAKEUP, notifyAlarm.getTimeInMillis(), pendingIntent);
My receiver is as follows:
public class AlarmReceiver extends BroadcastReceiver {
private static final String TAG ="test receiver";
#Override
public void onReceive(Context context, Intent intent) {
// TODO Auto-generated method stub
Log.v(TAG, "receiver called");
}
}
also in the manifest I have:
</activity>
<receiver android:name="AlarmReceiver"></receiver>
</application>
Any help appreciated.
Thinking about it, I'm not sure you can send a broadcast to a BroadcastReceiver using an explicit Intent as you are doing it...
Intent intent = new Intent(this, AlarmReceiver.class);
Try giving the <receiver section an <intent-filter> example...
<receiver android:name=".AlarmReceiver">
<intent-filter>
<action android:name="com.mypackage.ACTION_DO_SOMETHING" />
</intent-filter>
</receiver>
Then when you create your Intent, do it as follows...
Intent intent = new Intent("com.mypackage.ACTION_DO_SOMETHING");