I am using alarm manger to set broadcast on 2am every day. Alarm manager working fine in normal scenarios but it failing in below scenario.
I am scheduling alarm manager #1am, change the time to 1.58am and switch off the device and switch on the phone after 5mins(i.e 2.03am). In this scenario my alarm is not triggering for same day and every other days.
Can some one help me with this scenario
//Alarm manager
//timeToTwoAm is calculate time to 2AM from current time
alarmMgr.setInexactRepeating(AlarmManager.RTC_WAKEUP,timeToTwoAm,
AlarmManager.INTERVAL_DAY, alarmIntent);
Your alarms will not be persisted. After a reboot all your registered alarms are removed.
2 solutions would be helpful:
1. Register a BOOT_COMPLETED broadcast receiver:
AndroidManifest.xml
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<receiver android:name=".notification.alarm.OnBootReceiver">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
And in your OnBootReceiver simply register your alarms at AlarmManager again.
2. Use JobScheduler-API (>= API 21) or GcmNetworkManager (PlayServices)
Depending on your use case it would also be possible to use the new GcmNetworkMaanger, which allows persisting a Job during reboot.
Add Service to your Manifest:
<service
android:name=".LoadWeatherService"
android:exported="true" android:permission="com.google.android.gms.permission.BIND_NETWORK_TASK_SERVICE">
<intent-filter>
<action android:name="com.google.android.gms.gcm.ACTION_TASK_READY" />
</intent-filter>
</service>
In your service declare the things to do:
public class LoadWeatherService extends GcmTaskService {
public void onInitializeTasks() {
super.onInitializeTasks();
// Reregister your Job after update of Google Play Services
}
#Override
public int onRunTask(TaskParams taskParams) {
// Do your stuff
return GcmNetworkManager.RESULT_SUCCESS;
}
}
Subscribe your Job
String tag = "myperiodicTask";
PeriodicTask periodicTask = new PeriodicTask.Builder().setService(LoadWeatherService.class)
.setRequiredNetwork(Task.NETWORK_STATE_CONNECTED).setPeriod(60L).setFlex(10L)
.setTag(tag).setPersisted(true).build();
GcmNetworkManager.getInstance(this).schedule(periodicTask);
Please notice: This is only a sample from my app, you have to adjust this regarding your needs.
Further Reading about GcmNetworkManager: https://developers.google.com/cloud-messaging/network-manager
Related
In my code I have a broadcast reciever
<receiver
android:name=".alarm.AlarmReceiver"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.TIME_SET" />
</intent-filter>
<intent-filter>
<action android:name="com.BalDroid.YekNegah.alarm.dailyAction"
/>
</intent-filter>
</receiver>
I schedule alarm in this receiver in onReceive method
PendingIntent pi = PendingIntent.getBroadcast(context, AlarmRow.getId(mycursor), i, PendingIntent.FLAG_UPDATE_CURRENT);
if (Build.VERSION.SDK_INT >= 21) {
AlarmManager.AlarmClockInfo alarmInfo = new AlarmManager.AlarmClockInfo(
mycal.getTimeInMillis(),pi);
mgr.setAlarmClock(alarmInfo,pi);
// Create a Pending intent to show Alarm Details
}
although receiver run but alarm not trigger with mgr.setAlarmClock. But when I use
mgr.setExactAndAllowWhileIdle alarm trigger
(because of setAlarmClock accuracy I have to use setAlarmClock in my code)
And when I schedule mgr.setAlarmClock from MainActivity (when start application manually) it works.
I cant find the solution!!.
(I don't know why is not work from receiver).
My app also called setAlarmClock on AlarmManager, however the event didn't trigger. The reason for me was the default restriction of background processes by the manufacturer(my phone is Xiaomi).
Go to Settings -> Your application and find background restriction options. Turn the restrictions off and setAlarmClock must work.
As a conclusion, the result depends on manufacturer's default settings.
I have implemented Job scheduler in my project and it works fine in the case if the app is in background or if the app is killed. But it is not working if the device is rebooted. I have included
JobInfo.Builder mBuilder = new JobInfo.Builder(TASK_ID, mComponentName);
mBuilder.setPersisted(true);
in my builder and
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
in application manifest file.This is how I have added my service to manifest
<service
android:name="com.xxx.xxxx.service.MyJobService"
android:permission="android.permission.BIND_JOB_SERVICE" />
Is there anything else to be included?
Thanks in advance
Register a BroadCastReciever for detecting BOOT_COMPLETED.
<receiver android:name="com.example.startuptest.StartUpBootReceiver">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
And in your BroadcastReceiver:
public class StartUpBootReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
if (Intent.ACTION_BOOT_COMPLETED.equals(intent.getAction())) {
Log.d("startuptest", "StartUpBootReceiver BOOT_COMPLETED");
...
}
}
}
Once a user runs any activity in your app once, you will receive the BOOT_COMPLETED broadcast after all future boots.
I know it is an old question, and you probably already have the solution, but the issue likely was, that JobService caches the UUIDs of the apps that have the permission. You will need to reinstall your app and it is gonna be alright.
Source:
https://android.googlesource.com/platform/frameworks/base/+/5d34605/services/core/java/com/android/server/job/JobSchedulerService.java
You need to call the setPersisted(boolean isPersisted) method.
You can find it in the doc https://developer.android.com/reference/android/app/job/JobInfo.Builder.html#setPersisted(boolean)
i am building a small widget for learning purpose, it simply has an configuration activity where i set the update interval. it works normally and i can create multiple instance of it.
but when i reboot the phone the alarm manager stops, and the widget won't update.
after some search and google'ng i learned that i have to add a BOOT COMPLETE receiver
but after several attempts i failed to implement so any one has an i idea about how to add that or any good source code example on widgets.
To do something at boot you simply do following.
First in the manifest, this is added under application tag:
<receiver android:name="AlarmReceiver">
<intent-filter>
<action android:name="packagename.ACTION"/>
<action android:name="packagename.ACTION2"/>
</intent-filter>
</receiver>
<receiver android:name="BootSetter" >
<intent-filter>
<action
android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
In order for this to work you need to add permission to receive the Broadcast in the manifest with following line:
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
Then you have a class BootSetter:
public class BootSetter extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
// Do your stuff
}
}
There is a similar post, though not completly the same here. It's about running an alarm every day at noon.
I think you are setting alarm manager in class other then AppWidgetProvider extended class(widget class) .Better you should set an alarmmanager in OnUpdate method AppWidgetProvider extended class (widget class)then there will be no need of setting the alarm again after boot.
My question is.
In Android is there a way to create a service which can stay alive even you restart the mobile phone, until it does not perform its task,
For example alarm application. If you restart your mobile it will be triggered without any problem.
In android All services behave like this or do we have some solution for that?
Kindly explain in detail.
It will take 2 steps:
(1) First Create a BroadcastReceiver and start the service in this receiver's onReceive() method:
public class MyReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Intent service = new Intent(context, YourService.class);
context.startService(service);
}
}
(2) Now decalre this receiver in manifest like this:
<receiver android:name=".MyReceiver" >
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
This way your Service will always be running and will start even if the phone is restarted. For more details , refer to this link:
http://www.vogella.com/articles/AndroidServices/article.html
is there a way to create a service which can stay alive even you
restart the mobile phone
No. All running services are killed when turning off a phone.
For example alarm application. If you restart your mobile it will be
triggered without any problem.
Yes, but it's not because the service stayed alive. It's because the alarm app respond to the android.intent.action.BOOT_COMPLETED intent.
What you can do is creating a BoradcastReceiver that responds to this intent and that start your service.
The problem is that the user can kill this service manually. If you want to build an alarm clock, you should not have a service always running in the background.
You should make use of the AlarmManager and PendingIntent.
Something like in your manifest :
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<receiver
android:name=".broadcasts.InitReceiver"
android:exported="false" >
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
<action android:name="android.intent.action.TIME_SET" />
<action android:name="android.intent.action.TIMEZONE_CHANGED" />
</intent-filter>
</receiver>
And something like this for the broadcast.
public class InitReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
// Schedule your alarms again.
}
}
And you should schedule alarms like this :
Intent intent = new Intent(context, Ring.class);
intent.setData(alarmUri);
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_CANCEL_CURRENT);
AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
alarmManager.set(AlarmManager.RTC_WAKEUP, ringTime, pendingIntent );
Where Ring is the broadcast that handles the alarm ring.
In Android is there a way to create a service which can stay alive even you restart the mobile phone, until it does not perform its task,
No, if we interpret your request literally. All processes are terminated when you restart the device, just as all processes are terminated when you turn off the device.
For example alarm application. If you restart your mobile it will be triggered without any problem.
That is because the "alarm application" is getting control at boot time, via an ACTION_BOOT_COMPLETED BroadcastReceiver, and is rescheduling its alarm with AlarmManager.
Similarly, a service implementing a download queue would get control at boot time, via an ACTION_BOOT_COMPLETED BroadcastReceiver, at which time it would determine what yet needs to be downloaded and return to that work.
Check out the Services documentation. You want the START_STICKY flag which will make the system restart your service if it is ever terminated due to low memory etc.
To handle device restart...
Manifest
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<service
android:name=".BootService"
android:label="Boot Service" >
<intent-filter>
<action android:name="com.my.package.BootService" />
</intent-filter>
</service>
<receiver
android:name=".receiver.BootReceiver"
android:enabled="true"
android:exported="true"
android:label="Boot Receiver" >
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
Source
public class BootReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Log.d(this.getClass().getName(), "Boot Receiver onReceive()");
if ("android.intent.action.BOOT_COMPLETED".equals(intent.getAction()))
{
// Fire up your service.
Intent serviceIntent = new Intent("com.my.package.BootService");
serviceIntent.putExtra(Constants.BOOT_LAUNCH_EXTRA, true);
context.startService(serviceIntent);
}
}
}
public class BootService extends IntentService {
public BootService()
{
super("BootService");
}
#Override
protected void onHandleIntent(Intent intent) {
Log.d(this.getClass().getName(), "Boot Service onHandleIntent()");
if(intent.hasExtra(Constants.BOOT_LAUNCH_EXTRA))
{
//...
}
}
}
My idea is to set an alarm for a specific date in my application, but I want to be able to have the alarm ringing at the set date, even if my application isn't running at all.
How can I achieve this?
Thanks in advance!
I'd start a service when the device is booted - that service should take care about the alarming when the time has come.
To make your service be started at boot time you need the following things in your AndroidManifest.xml
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
in the <manifest> tag
<receiver android:name="com.yourpackage.AlarmingBroadcastReceiver">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
in your <application> tag
Additionally you need your AlarmingBroadcastReceiver, should look something like that to start the service:
public class AlarmingBroadcastreceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Intent startServiceIntent = new Intent(context, AlarmingService.class);
context.startService(startServiceIntent);
}
}
whereas AlarmingService.class is the class name of your service that finally takes care about the alarming stuff
You will need to create a onBoot BroadCast Receiver so when the device is started your application will get control to set up alarms.