onReceiver of BroadcastReceiver not called, AlarmManager - android

I am building a cab booking app, I need current location of the cab every 20 seconds.
I have defined a AlarmManager and need it to repeat itself every 20 seconds. But its not repeating itself regularly. Instead it repeated itself after 233 seconds, and just once. What am I doing wrong here ?
My HomeScreen has a inner class OnAlarmReceiver, in the onCreate of my HomeScreen I am calling AlarmManager
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, 20);
mgr.setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP,
cal.getTimeInMillis(), God.UPDATE_PENDING_INTERVAL, pi);
Inner class in HomeScreen
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, PullPendingRequests.class));
}
}
My AndroidManifest file has
<service
android:name="com.taxeeta.support.PullPendingRequests"
android:enabled="true"
android:label="#string/app_name"
android:screenOrientation="portrait"
android:theme="#android:style/Theme.Light.NoTitleBar" />
<receiver android:name=".com.taxeeta.HomeScreen.OnAlarmReceiver" />
</application>
Output of adb shell dumpsys alarm
com.taxeeta
51471ms running, 5248 wakeups
5248 alarms: flg=0x4 cmp=com.taxeeta/.HomeScreen$OnAlarmReceiver
Output of adb shell dumpsys alarm | grep taxeeta
ELAPSED_WAKEUP #7: Alarm{409303b0 type 2 com.taxeeta}
operation=PendingIntent{408ba2d8: PendingIntentRecord{40887be8 com.taxeeta broadcastIntent}}
com.taxeeta
5248 alarms: flg=0x4 cmp=com.taxeeta/.HomeScreen$OnAlarmReceiver

To fix it, I removed the inner class OnAlarmReceiver and fixed the androidmanifest.xml file.
<receiver
android:name="com.taxeeta.support.OnAlarmReceiver"
android:exported="true" >
<intent-filter>
<action android:name="android.intent.action.NOTIFY" />
</intent-filter>
</receiver>

If the answer above doesn't work for you then there is another way to not receive any callbacks when AlarmManager fires an expired alarm. You simply need to check this one out: by sending the wrong Intent on instantiation of PendingIntent. For example you wanted to receive a call onReceive on one of your receivers but you instantiated a PendingIntent via getActivity or getService, but what you actually meant is getReceiver.
When creating instance of PendingIntent, there are many ways to create it (getService, getActivity,getReceiver, getForegroundService:
if you want Activity the receiver of the intent then you:
PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_*);
if you want BroadcastReceiver the receiver of the intent:
PendingIntent.getReceiver(this, 0, intent, PendingIntent.FLAG_*);
if you want a foreground Service the receiver of the intent:
PendingIntent.getForegroundService(this, 0, intent, PendingIntent.FLAG_*);
if you want a Service the receiver of the intent:
PendingIntent.getService(this, 0, intent, PendingIntent.FLAG_*);
Also, make sure you intents are pointing to the correct class. (e.g. creating intents for Activity, Service etc.). You will not receive any call if you pass wrongfully like this:
Intent intent = new Intent(this, MyReceiver.class); // You wanted receiver
// PendingIntent was created in such a way
// you wanted this to be received by an activity.
// you will not receive any call if you set it up like this.
PendingIntent = PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_*);
I also posted similar answer here.
HTH

This piece of code worked for me and make sure you have added reciever in android manifest file.
AlarmManager service = (AlarmManager) context
.getSystemService(Context.ALARM_SERVICE);
Intent i = new Intent(context, OnAlarmReceiver.class);
PendingIntent pending = PendingIntent.getBroadcast(context, 0, i,
PendingIntent.FLAG_CANCEL_CURRENT);
Calendar cal = Calendar.getInstance();
// Start 20 seconds after boot completed
cal.add(Calendar.SECOND, 20);
//
// Fetch every 20 seconds
// InexactRepeating allows Android to optimize the energy consumption
service.setInexactRepeating(AlarmManager.RTC_WAKEUP,
cal.getTimeInMillis(), 1000*20, pending);

The above solutions didn't work for me.
Additionally, registering dynamically via code did the trick:
Intent intent = new Intent();
intent.setAction("android.intent.action.NOTIFY");
//Register the receiver
context.registerReceiver(new OnAlarmReceiver(),new IntentFilter());

For anyone still stuck - make sure your broadcast receiver is not crashing in the background. Make sure to check your LogCat!

Related

Explicit Intent not received by manifest registered receiver

Am trying some example alarm clock and trying to separate the data from the ui using the viewModel examples.
Basically I'm trying to set an alarm and as the docs say when it's time comes the alarmManager should fire the intent supplied and it should be received by a broadcast receiver.
This works all nice and dandy if setting the alarm inside a fragment/activity. But if I try to move the code in another class which is a singleton and it's instance is used in a ViewModelProvider the the broadcast receiver is not receiving the intent from AlarmManager.
The code is as simple as :
Intent intent = new Intent(mContext, AlarmReceiver.class);
Log.d(LOG_TAG, "====+++ " + mContext);
intent.putExtra(ALARM_UNIQUE_ID, mId);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
PendingIntent pi = PendingIntent.getBroadcast(mContext, 123, intent, PendingIntent.FLAG_UPDATE_CURRENT);
Calendar calendarAlarma = Calendar.getInstance();
calendarAlarma.set(Calendar.HOUR_OF_DAY, 11);
calendarAlarma.set(Calendar.MINUTE, 33);
AlarmManager.AlarmClockInfo alarmClockInfo = new AlarmManager.AlarmClockInfo(calendarAlarma.getTimeInMillis(),
null);
AlarmManager mAlarmManager = (AlarmManager) mContext.getSystemService(Context.ALARM_SERVICE);
mAlarmManager.setAlarmClock(alarmClockInfo, pi);
The broadcast receiver is registered in the manifest file. The context object seems to be the same but somehow the intent is never launched or never received.
The receiver part is defined as:
<receiver
android:name=".ui.alarma.AlarmReceiver"
android:exported="true"
android:enabled="true"
>
</receiver>
What is it I am missing ?
PS1:
The alarm icon in the status bar is showing (set) as expected and it disappears when the time for the alarm to start is right. Also the I can see in logcat the following:
onReceive:android.app.action.NEXT_ALARM_CLOCK_CHANGE
But my receiver receives nothing, why ?

How to start activity 5 minutes after exiting an app?

I'm looking for a solution on how to make sort of an alarm that after exiting an app it will start a new activity (or ten minutes if a user chooses to). It would be non-repeating, just one time.
I looked at TimerTask and Handlers, but they seem to be working only when an app is in the foreground. AlarmManager looks like it could do the job, but I don't know how to approach that. Any suggestions?
edit1:
So here is what I have in MainActivity:
Intent intent = new Intent("wake_up");
intent.setFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0, intent, 0);
AlarmManager alarmManager = (AlarmManager)getSystemService(Context.ALARM_SERVICE);
alarmManager.set(AlarmManager.RTC_WAKEUP, 5000, pendingIntent);
This is BroadcasReceiver:
#Override
public void onReceive(Context context, Intent intent) {
Intent i = new Intent();
i.setClassName("(packagename)", "(whole class name)");
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(i);
}
And how I registered it in Manifest (like other activities):
<receiver
android:name="FakeCallBroadcastReceiver" >
</receiver>
I have put Toast in BroadcastReceiver and it works, but it appears immediately - changing time from 5000 to let's say 10000 doesn't change anything.
Add this in onCreate() method in Application instance or main Activity:
Intent intent = new Intent("wake_up");
intent.setFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
PendingIntent pending = PendingIntent.getBroadcast(this, 0, intent, 0);
AlarmManager alarmManager = (AlarmManager)getSystemService(Context.ALARM_SERVICE);
alarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, 5000, pendingIntent);
and start Activity in BroadcastReceiver:
public class AlarmReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
context.startActivity(...);
}
}
Register the BroadcastReceiver with intent filter:
<receiver android:name="AlarmReceiver">
<intent-filter>
<action android:name="wake_up" />
</intent-filter>
</receiver>
Alarm manager is definitely the way to go. You'll need to have a broadcast receiver to receive the alarm, and then set a pending intent in that receiver.
As you mentionned, TimerTask and Handlers won't help you much here.
The easiest way to go with a broadcast receiver is to register it in the android manifest as a broadcast receiver. You can also register them manually, but it's a bit harder conceptually.
Have fun!

Cant get AlarmManager and broadcast working

No matter how I try, I cannot get the alarmManager and receiver to work - there seem to be SO many different ways to do it from what i've searched, but nothing seems to work.
I have in Manifest:
<receiver android:name="AlarmReceiver" />
I am using inner class for broadcastReceiver:
private class AlarmReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Log.d("ALARM","TRIGGERED");
Notification(filteredList.get(0).getTitle());
}
}
I call function SetAlarm to start the manager:
private void SetAlarm(long time) {
AlarmManager alarm_mgr = (AlarmManager)(this.getSystemService( Context.ALARM_SERVICE ));
Intent intent = new Intent(MainActivity.this, AlarmReceiver.class);
//PendingIntent pi = PendingIntent.getService(MainActivity.this, 0, intent, 0);
PendingIntent pi = PendingIntent.getBroadcast(this, 111, intent, PendingIntent.FLAG_UPDATE_CURRENT);
Calendar calendar = Calendar.getInstance();
alarm_mgr.set(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), pi);
Log.d("ALARMSET", "Alarm " + calendar.getTime().toString());
}
As you can see, in the receiver I have a notification call - I won't post because I know this works, but there is also a log that is not working.
For testing purposes I've set time to current time using the Calendar function.
You can see the pendingIntent, i have tried both getService and getBroadcast, I can't figure out which I need, but neither works anyway.
I'm sure I'm missing something, i don't know what, and I can't seem to find any answers at Google.
Is the AlarmReceiver ok as an inner class ? I have put it there because I need access to my "filteredList" List object.
thx
I am using inner class for broadcastReceiver:
This will not work. Android has to be able to create an instance of your BroadcastReceiver, and it cannot do so. At best, your BroadcastReceiver could be a static nested class, but then you would have to fix your manifest entry to refer to the outer class:
<receiver android:name="OuterClass$AlarmReceiver" />
No, actually the BroadcastReceiver needs to be public.Only then you can register it in manifest and access them. Place the AlarmReceiver code in a separate .java file. You will see the log inside the BroadcastReceiver.
try this
private AlarmManager alarmMgr;
private PendingIntent alarmIntent;
...
alarmMgr = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(context, AlarmReceiver.class);
alarmIntent = PendingIntent.getBroadcast(context, 0, intent, 0);
// Set the alarm to start at 8:30 a.m.
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
calendar.set(Calendar.HOUR_OF_DAY, 8);
calendar.set(Calendar.MINUTE, 30);
// setRepeating() lets you specify a precise custom interval--in this case,
// 20 minutes.
alarmMgr.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(),
1000 * 60 * 20, alarmIntent);
For more details.. Look this
I stucked 1 day for this problem, and finally solved this.
AlarmManager is used to generate a broadcast every 30 seconds, and a broadcast receiver is used to receive the message and execute ...
So the main problem is the following 2 steps
1. In the AndroidManifist.xml a action filter needed.
<receiver android:name="com.istep.gps.straight.MyTimerReceiver">
<intent-filter>
<action android:name="com.istep.gps.straight.MyTimerReceiver.Action"/>
</intent-filter>
</receiver>
2. The most important is the Intent need to be empty, no AAA.class
private void initTimer(Context context) {
Intent intent = new Intent().setAction("com.istep.gps.straight.MyTimerReceiver.Action")
.putExtra("id",UniqueID.getID(context));
PendingIntent sender = PendingIntent.getBroadcast(context, 18, intent, 0);
AlarmManager am = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
am.setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime(), 1000 * 30, sender);
}
When you use calendar, you should setTimeInMillis
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());

How to display the notification using service?

I was trying to display the notifications using background service for which I wrote 3 classes. The service should run in background even if the appllication closed and and it should start running automatically so I used ,
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<receiver android:name="com.s2si.ucom.ui.UcomBroadcastReceiver" >
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
So in onReceive() of BroadcastReceiver class I am starting the service using,
Intent service = new Intent(context, AlarmService.class);
context.startService(service);
In service class I am using AlarmManager to set particular interval so that I can display notification for every period of time. and finally I am invoking the BroadcastReceiver class to display the notification using AlarmManager. The problem is I am not getting the output :-(...instead of that I am getting error like, Couldn't load memtrack module (No such file or directory)... I am literally new to android coding...Can any one help me how to display notifications in such manner..and let me know what I did wrong above...Thanks much :-).
code in onCreate() method of service class,
Intent intent = new Intent(context, NotificationServiceReceiver.class);
PendingIntent sender = PendingIntent
.getBroadcast(context, 0, intent, 0);
// We want the alarm to go off 5 seconds from now.
long firstTime = SystemClock.elapsedRealtime();
firstTime += 5 * 1000;// start 5 seconds after first register.
// Schedule the alarm!
AlarmManager alarmManager = (AlarmManager) context
.getSystemService(ALARM_SERVICE);
alarmManager.setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP,
firstTime, 5000, sender);// 5seconds interval
in short this is how you create a broadcast
private static final String ACTION_ALARM = "your.company.here.ACTION_ALARM";
public static void createAlarm(){
Intent alarmIntent = new Intent();
alarmIntent.setAction(ACTION_ALARM);
PendingIntent pi = PendingIntent.getBroadcast(context, 0, alarmIntent, 0);
AlarmManager am = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
am.set(AlarmManager.RTC_WAKEUP, timestamp for alarm, pi);
}
public void onReceive(...){
//whatever is supposed to happen on receive
}
and you need to declare that broadcastreceiver and the actionname its supposed to receive in manifest:
<receiver
android:name="your.company.here.AlarmReciever">
<intent-filter>
<action android:name="your.company.here.ACTION_ALARM" />
</intent-filter>
</receiver>

Android Alarm Manager with broadcast receiver registered in code rather than manifest

I want to use an alarm to run some code at a certain time. I have successfully implemented an alarm with the broadcast receiver registered in the manifest but the way i understand it, this method uses a separate class for the broadcast receiver.
I can use this method to start another activity but I cant use it to run a method in my main activity?
(how can I notify a running activity from a broadcast receiver?)
So I have been trying to register my broadcast receiver in my main activity as explained in the answer above.
private BroadcastReceiver receiver = new BroadcastReceiver(){
#Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(context, "hello", Toast.LENGTH_SHORT).show();
uploadDB();
}
};
public void onResume() {
super.onResume();
IntentFilter filter = new IntentFilter();
filter.addAction(null);
this.registerReceiver(this.receiver, filter);
}
public void onPause() {
super.onPause();
this.unregisterReceiver(this.receiver);
}
However I have been unable to get this to work with alarm manager, I am unsure as to how i should link the alarm intent to the broadcast receiver. Could anyone point me to an example of registering an alarm manager broadcast receiver dynamically in the activity? Or explain how i would do this?
How about this?
Intent startIntent = new Intent("WhatEverYouWant");
PendingIntent startPIntent = PendingIntent.getBroadcast(context, 0, startIntent, 0);
AlarmManager alarm = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
alarm.set(AlarmManager.RTC_WAKEUP, triggerTime, startPIntent);
And then in your Manifest.xml file:
<receiver android:name="com.package.YourOnReceiver">
<intent-filter>
<action android:name="WhatEverYouWant" />
</intent-filter>
</receiver>
So as far as I know you still have to declare the receiver in the Manifest. I'm not sure if you can set it to a private instance inside of your activity. You could declare an onReceive inside of your activity and call that (if the BroadcastReceiver has an interface. I don't know if it does.)
Start a alarm intent from where you want to start alarm. write below code from where you want to start to listen the alarm
Intent myIntent = new Intent(getBaseContext(), **AlarmReceiver**.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(getBaseContext(), 0, myIntent, 0);
AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
calendar.add(Calendar.MINUTE, shpref.getInt("timeoutint", 30));
alarmManager.set(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), pendingIntent);
And in broadcast receiver write the code you want to receive. And in menifest write below
<receiver android:name=".AlarmReceiver" android:process=":remote"/>
You can also put repetitive alarm also.
Hope it help!

Categories

Resources