I am trying to handle it this way: in BroadcastReceiver start AlarmManager repeated action, it will send intents to IntentService, service writes log. Now as I see from the log, BroadcastReceiver receives intent, starts AlarmManager, but IntentService never fires. What can be wrong here?
Manifest:
<receiver android:name=".wakefullBroadcastReciever.SimpleWakefulReciever" android:enabled="true" android:exported="false">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED"/>
<action android:name="START"/>
</intent-filter>
</receiver>
<service
android:name=".wakefulService.NotificationWakefulIntentService"
android:enabled="true">
<intent-filter>
<action android:name="NOTIFY_INTENT" />
</intent-filter>
</service>
WakefulReciever:
public class SimpleWakefulReciever extends WakefulBroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
if (!App.isRunning) {
Log.d("wakefull", "start");
Intent startIntent = new Intent(context, NotificationWakefulIntentService.class);
startIntent.setAction(Utils.NOTIFY_INTENT);
PendingIntent startPIntent = PendingIntent.getBroadcast(context, 0, startIntent, 0);
AlarmManager am = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
am.setRepeating(AlarmManager.RTC_WAKEUP,
SystemClock.elapsedRealtime() + 3000, 5000, startPIntent);
App.isRunning = true;
}
}
}
IntentService:
public class NotificationWakefulIntentService extends IntentService {
public NotificationWakefulIntentService() {
super("NotificationWakefulIntentService");
}
#Override
protected void onHandleIntent(Intent intent) {
Log.d("time",(System.currentTimeMillis()/1000)+"");
}
}
You're defining an explicit Service Intent, but calling getBroadcast() instead of getService().
Change the following:
PendingIntent startPIntent = PendingIntent
.getBroadcast(context, 0, startIntent, 0);
To this:
PendingIntent startPIntent = PendingIntent
.getService(context, 0, startIntent, 0);
Also, this is not how WakefulBroadcastReceiver works. It's a helper class and its purpose is to provide a WakeLock until your Service finishes its work.
You achieve nothing by simply extending WakefulBroadcastReceiver, a WakeLock is guaranteed during onReceive() anyway.
To answer your comment below:
You should set an exact alarm to fire every hour (check out this answer), start your IntentService from onReceive() by calling WakefulBroadcastReceiver.startWakefulService(), do your stuff in onHandleIntent() and call WakefulBroadcastReceiver.completeWakefulIntent() when finished.
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 have following schema BOOT_COMPLETE intent ->BroadcastReciever starts, then starting WakefullBroadcastReceiver -> sending intent to NotificationIntentService.
But my WakefullBroadcastReceiver is never working, if i change schema to BOOT_COMPLETE intent ->BroadcastReciever-> sending intent to NotificationIntentService. everething works perfectly
BroadcastReceiver:
public class BootBroadcastReciever extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
if (!App.isRunning) {
Log.d("wakefull", "start");
Intent startIntent = new Intent("SOMEACTION");
//startIntent.setAction(Utils.NOTIFY_INTENT);
PendingIntent startPIntent = PendingIntent.getService(context, 0, startIntent, 0);
AlarmManager am = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
am.setRepeating(AlarmManager.RTC_WAKEUP,
SystemClock.elapsedRealtime() + 3000, 5000, startPIntent);
App.isRunning = true;
}
Log.e("bool",App.isRunning+"");
}
}
WakefulBroadcastReceiver:
public class SimpleWakefulReciever extends WakefulBroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Log.e("wakefull","received");
Intent service = new Intent(context, NotificationWakefulIntentService.class);
startWakefulService(context,service);
}
}
NotificationIntentService:
public class NotificationWakefulIntentService extends IntentService {
public NotificationWakefulIntentService() {
super("NotificationWakefulIntentService");
}
#Override
protected void onHandleIntent(Intent intent) {
Log.d("time",(System.currentTimeMillis()/1000)+"");
SimpleWakefulReciever.completeWakefulIntent(intent);
}
}
Manifest:
<receiver android:name=".broadCastReciever.BootBroadcastReciever" android:enabled="true" android:exported="false">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED"/>
<action android:name="START"/>
</intent-filter>
</receiver>
<receiver android:name=".wakefullBroadcastReciever.SimpleWakefulReciever">
<intent-filter>
<action android:name="SOMEACTION"/>
<action android:name="WAKEFUL"/>
</intent-filter>
</receiver>
<service
android:name=".wakefulService.NotificationWakefulIntentService"
android:enabled="true">
<intent-filter>
<action android:name="NOTIFY_INTENT" />
</intent-filter>
</service>
First, get rid of all <intent-filter> elements other than the one wrapping <action android:name="android.intent.action.BOOT_COMPLETED"/>. Never put an <intent-filter> on a component unless you want arbitrary third-party apps to start that component whenever they want to.
Then, replace:
Intent startIntent = new Intent("SOMEACTION");
PendingIntent startPIntent = PendingIntent.getService(context, 0, startIntent, 0);
with:
Intent startIntent = new Intent(context, SimpleWakefulReciever.class);
PendingIntent startPIntent = PendingIntent.getBroadcast(context, 0, startIntent, 0);
This fixes your Intent to no longer use the action string and fixes your PendingIntent to use getBroadcast(), since you are trying to trigger a BroadcastReceiver.
Then, replace 5000 with a value of at least 60000, since you cannot have a repeating alarm more frequently than that on Android 5.1+.
I have used broadcast receiver with alarm manager to hit webservices for every 60 seconds,seems its working fine when i have used my broadcast receiver in different class but its not calling when i declare a receiver with in my activity
my code is below
public static void startAlarm(Context context) {
Intent locationAlarm = new Intent(context, GetLocation.class);
AlarmManager alarms = (AlarmManager) context
.getSystemService(Context.ALARM_SERVICE);
Calendar updateTime = Calendar.getInstance();
PendingIntent recurringAlarm = PendingIntent.getBroadcast(context, 0,
locationAlarm, PendingIntent.FLAG_CANCEL_CURRENT);
alarms.setRepeating(AlarmManager.RTC_WAKEUP,
updateTime.getTimeInMillis() + 500, UPDATE_INTERVAL,
recurringAlarm);
}
Broadcast receiver :
public class GetLocation extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
LogUtil.d("Started Service");
}
}
My Manifest file :
<receiver android:name="com.sample.sample.listeners$GetLocation" >
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
kindly correct my mistake. my Started service method never called
You have a typo in your manifest file. You have put $GetLocation instead of .GetLocation
<receiver android:name="com.sample.sample.listeners.GetLocation" >
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
In my manifest file I have declared the receiver. (as follows)
<receiver android:name=".OnAlarmReceive" />
however, once I shut down my application, I am not able to get the alarms and the notifications. Apparently, a call to the OnReceive in my Broadcast receiver is never made.
public class OnAlarmReceive extends BroadcastReceiver
{
#Override
public void onReceive(Context context, Intent arg1)
{
//various stuff
}
}
Inside the MainActivity, my alarm manager class is as the follows.
AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
Intent intent = new Intent("MY_ALARM_NOTIFICATION");
intent.setClass(this, OnAlarmReceive.class);
intent.putExtra("message", message);
PendingIntent pendingIntent = PendingIntent
.getBroadcast(MainActivity.this, 0, intent,
PendingIntent.FLAG_UPDATE_CURRENT);
Calendar timeCal = Calendar.getInstance();
timeCal.set(Calendar.HOUR_OF_DAY, hour);
timeCal.set(Calendar.MINUTE, minutes);
alarmManager.set(AlarmManager.RTC_WAKEUP, timeCal.getTimeInMillis(), pendingIntent);
and my manifest as is follows :
<receiver android:name=".OnAlarmReceive">
<intent-filter android:priority="1">
<action android:name="MY_ALARM_NOTIFICATION"/>
</intent-filter>
</receiver>
What should I do in order to receive the notifications/alarms even if I have shut off my app. Background service ?
you should add intent-filter in manifest,as
receiver android:name=".SmsBroadCastReceiver">
<intent-filter android:priority="20">
<action android:name="android.provider.Telephony.SMS_RECEIVED"/>
</intent-filter>
</receiver>
As Gong Cong says, you need to declare which events your receiver should listen.
For example :
<receiver android:name=".OnAlarmReceive">
<intent-filter>
<action android:name="MY_ALARM_NOTIFICATION"/>
</intent-filter> </receiver>
and then when your set your alarm, use an intent with your action :
Intent intent = new Intent("MY_ALARM_NOTIFICATION");
intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
PendingIntent pi = PendingIntent.getBroadcast( this, 0, intent, 0 );
Your code is working fine!
All you have to do is to change this line:
alarmManager.set(AlarmManager.RTC_WAKEUP, timeCal.getTimeInMillis(),
pendingIntent);
With this line:
alarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP,
SystemClock.elapsedRealtime() + 5000, pendingIntent);
And the code in the "onReceive" will run after 5000ms (5sec) even when app is not running
In My understanding, In some cased depending on the way of implementations, OS has authority to adjust the alarm set time. So try to use AlarmManager.set(...), AlarmManager.setexact(...) etc accordingly. In Some cases, depending on the manufacturer(Custom Android OS), there is a possibility that the OS is blocking fire alarm.
Adding android:exported="true" for receiver in manifest file helped me to receive alarms (and thus, wake the application) even when application was shut-down (intentionally by me, removing app from task list).
1.Declare the receiver in the Manifest-file:
<receiver android:name="your.package.name.TestAlarmReceiver"></receiver>
Always remember that the whole Android-System is case sensitive. So check your spelling is correct in the AndroidMainfest.xml.
2.If you create a PendingIntent for your Receiver, please add an requestCode - even it is a random number! Without your onReceive code never get called!
The function which start AlarmManager should look like below:
public static void scheduleTestAlarmReceiver(Context context) {
Intent receiverIntent = new Intent(context, TestAlarmReceiver.class);
PendingIntent sender = PendingIntent.getBroadcast(context, 123456789, receiverIntent, 0);
AlarmManager alarmManager = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
alarmManager.setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime()+startDelay, someDelay, sender);
}
BroadcastReceiver class:
package your.package.name;
public class TestAlarmReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent arg1) {
// your code here!
}
}
The original article: Why my BroadcastReceiver does not get called?
I have the following problem. I have 2 classes. 1 is called AlarmService and the other is called TimeAlarm which extends BroadcastReceiver.
The App should do the following thing: It should generate a new Alarm to a time specified in the preferences (Which it already does...) also in Logcat i can see how the Alarm gets triggered. But the problem is, that the Notification which should be shown does not show up in the StatusBar.
Here is all the code i have for this:
AndroidManifest.xml:
<receiver android:name="com.ikalma.alarmmanager.TimeAlarm">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
AlarmService.java:
private Context context;
private PendingIntent mAlarmSender;
public AlarmService(Context context) {
this.context = context;
Intent notifyIntent = new Intent(Intent.ACTION_MAIN);
notifyIntent.setClass(context, myActivity.class);
mAlarmSender = PendingIntent.getBroadcast(context, 0, notifyIntent, 0);
}
public void startAlarm(int stunde, int minute) {
Calendar updateTime = Calendar.getInstance();
updateTime.set(Calendar.HOUR_OF_DAY, stunde);
updateTime.set(Calendar.MINUTE, minute);
updateTime.set(Calendar.SECOND, 00);
AlarmManager am = (AlarmManager) context
.getSystemService(Context.ALARM_SERVICE);
am.setRepeating(AlarmManager.RTC_WAKEUP, updateTime.getTimeInMillis(),
AlarmManager.INTERVAL_DAY, mAlarmSender);
}
TimeAlarm.java:
#Override
public void onReceive(Context context, Intent intent) {
Log.e("TEST", "onReceive() called...");
}
The Receiver in the Manifest is inside of the Tag so that should not be a problem.
The problem is, that if i restart my device, it gets called. But not if an Alarm gets triggered.
But the onReceive() method should also be called if an alarm gets triggered, shouldn't it?
Thanks for your help!
your intent filter is only listening to boot complete intents and not your own alarm broadcast intent action. update your intent filter so that your broadcast intent is also received (that means for your special case add the action of Intent.ACTION_MAIN to your intent filter)
<receiver android:name="com.ikalma.alarmmanager.TimeAlarm">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
<action android:name="android.intent.action.MAIN" />
</intent-filter>
</receiver>