Android Recall Service - android

If i am in an activity i call a service b using the following code:
String start = "start";
Intent i = new Intent(QScheduleActivity.this, UploadService.class);
i.putExtra("start", start);
startService(i)
Once i am inside this service, how do i recall the service from within the service if i need to?
Inside the else i am trying to recall the service like this:
Calendar cal = Calendar.getInstance();
cal.add(Calendar.MINUTE, 30);
String start = "start";
Intent i = new Intent(UploadService.this, UploadService.class);
i.putExtra("start", start);
PendingIntent sender = PendingIntent.getBroadcast(this, 192837, i, PendingIntent.FLAG_UPDATE_CURRENT);
AlarmManager am = (AlarmManager) getSystemService(ALARM_SERVICE);
am.set(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), sender);

Inside the else i am trying to recall the service like this:
You are asking for a getBroadcast() PendingIntent. If your goal is to have the alarm call startService(), you should be using a getService() PendingIntent.

Have a look at the AlarmManager class. I think it provides the functionality you need, though perhaps not in quite the way you're describing it.
From the documentation:
This class provides access to the
system alarm services. These allow you
to schedule your application to be run
at some point in the future. When an
alarm goes off, the Intent that had
been registered for it is broadcast by
the system, automatically starting the
target application if it is not
already running. Registered alarms are
retained while the device is asleep
(and can optionally wake the device up
if they go off during that time), but
will be cleared if it is turned off
and rebooted.

Related

PendingIntent with IntentService not working

Following code works perfectly for Activity:
Intent intent = new Intent(context, MyActivity.class);
PendingIntent operation = PendingIntent.getActivity(context,
0,
intent,
PendingIntent.FLAG_UPDATE_CURRENT);
alarmmanager.setExact(AlarmManager.RTC_WAKEUP,
startTime.getTimeInMillis(),
operation);
However, when I do the same thing for IntentService, It works only if startTime and time I set alarm are on the same day. e.g. If I set the alarm today for 5 PM, it will be executed but when I set the alarm today for 5 PM tomorrow, it will not be executed. If this was Activity then it works for both cases.
Intent intent = new Intent(context, MyService.class);
PendingIntent operation = PendingIntent.getService(context,
0,
intent,
PendingIntent.FLAG_UPDATE_CURRENT);
alarmmanager.setExact(AlarmManager.RTC_WAKEUP,
startTime.getTimeInMillis(),
operation);
How to solve this?
The goal here I am trying to achieve is to execute IntentService every day at the exact time.
The goal here I am trying to achieve is to execute IntentService every day at the exact time.
Google has made this progressively harder from release to release. See Android AlarmManager setExact() is not exact. There could be two ways to solve this for your case:
you start an activity, which starts the service (as starting an Activity seems to work for you)
you use either setExactAnd... or setAlarmClock. setAlarmClock also triggers in the new "doze" mode, see https://stackoverflow.com/a/47049705/1587329.
Another way would be to re-think why and if you really need this... or if a JobScheduler could not fit your purpose more easily.
add replace your line with this line :
alarmmanager.setRepeating(AlarmManager.RTC_WAKEUP,
startTime.getTimeInMillis(),
operation);
it will repeat on specific interval you set in alarm manager
Replace the AlarmManager with this code:
alarmManager.setRepeating(AlarmManager.RTC,
timeMills,
AlarmManager.INTERVAL_DAY,
pendingIntent);
Worked for me.
HERE IS a DETAILED ANSWER check link in the bottom for more details.
Hope this will help. Your issue can be probably related to android versions too so do check the link for more details
app gets an instance of the AlarmManager and sets an alarm using a PendingIntent. More on usage and setting alarms is coming in the next section. The AlarmManager is the app side interface to the backing AlarmManagerService. It abstracts the details of the Binder interface, used to communicate with the system process (system_server) hosting the AlarmManagerService. These two components manage the alarm(s) the app has set and will send the PendingIntent correctly. This manager/service architecture is used throughout Android framework and is done for security and isolation purposes. The system_server process is running with privileges which normal apps do not have. If you are unfamiliar with Android’s use of permissions, see this article for more details on app processes and user IDs. These extra permissions are what allows system_server to access the underlying kernel alarm driver. The alarm driver is what manages setting alarms to wake up the device regardless of the sleep state of the SoC.
When the alarm is triggered the device is awakened (if asleep) and the AlarmManagerService is notified of an alarm expiring. It will then send the PendingIntent accordingly. This will cause the appropriate component within MyApp to be activated. If MyApp has not been started or its process is not cached, it will be started so the component can be activated.
basic usage will be as
public class MyActivity extends Activity {
...
private AlarmManager mAlarmMgr;
...
public void onCreate(Bundle savedInstance) {
...
mAlarmMgr = (AlarmManager)getSystemService(Context.ALARM_SERVICE);
...
}
...
}
let’s create a PendingIntent for our MyActivity using the component name.
Intent alarmIntent = new Intent(context, MyActivity.class);
PendingIntent pend = PendingIntent.getActivity(context,
0,
alarmIntent,
PendingIntent.FLAG_UPDATE_CURRENT);
Now that we have our PendingIntent and the AlarmManager, we can set our alarm so our Activity is triggered when the alarm has expired. To do this, we need to figure out when we want our alarm to go off and whether it should wake up the device or just be delivered the next time the device is awakened. Remember, we have two different ways of specifying time for our alarms: elapsed time or calendar (RTC) time. So our options are ELAPSED_REALTIME, ELAPSED_REALTIME_WAKEUP, RTC or RTC_WAKEUP. The _WAKEUP variants are our “aggressive” alarms where we want the device to come out of low power to call our app back. For our sample app, let’s set this up in a custom BroadcastReceiver and have it trigger our Activity about 30 seconds after the device is booted
public class MyBootReceiver extends BroadcastReceiver {
public void onReceive(Context, context, Intent intent) {
...
AlarmManager alarmMgr =
(AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
long wakeTime = SystemClock.elapsedRealtime() + 30000;
alarmMgr.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, wakeTime, pend);
}
}
Now when our device boots and the BOOT_COMPLETED broadcast is sent, our app’s process will be started and our receiver will set an alarm to trigger our Activity to be launched about 30 seconds later. Note that on Android 3.1 devices or newer, you must first manually launch your app before the BOOT_COMPLETED.
CREDIT GOES to writer of this BLOG
if you want to set the repeated alarm using SetExact you are bound to stop all other pending intents on the same time check this link for that here are many examples of how to do it! again credit goes to this writer

Android: Resetting repeating AlarmManager from within called service

I've set a repeating alarm on a service and decided that it's most convenient to reset the alarm from within the called service. The reason is that the service already has code to check if it's within a user-defined schedule (time range). When it's outside the time range, it resets the alarm to start at the future time selected by the user. Maybe I'm approaching this wrong but I'll put this question out there and see what you think.
An activity kicks off the service by creating a repeating alarm:
//Activity
Calendar cal = Calendar.getInstance();
Intent intent = new Intent(getApplicationContext(), MyService.class);
intent.setData(Uri.parse("MyService://identifier"));
PendingIntent pIntent = PendingIntent.getService(getApplicationContext(), 0, intent, 0);
AlarmManager alarm = (AlarmManager)getSystemService(ALARM_SERVICE);
alarm.setInexactRepeating(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(),
intervalInMins*60000, pIntent);
The service has something like this:
//Service
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Uri Action = intent.getData();
try {
if (Action.equals(Uri.parse("MyService://identifier"))) {
//Simplifying the code here: CalculatedOffset is determined from the current time
//and scheduled start time. intervalInMins is read from settings.
if (!WithinSchedule()) {
Calendar cal = Calendar.getInstance();
PendingIntent pIntent = PendingIntent.getService(getApplicationContext(), 0, intent, 0);
AlarmManager alarm = (AlarmManager)getSystemService(ALARM_SERVICE);
alarm.setInexactRepeating(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis() + CalculatedOffset,
intervalInMins*60000, pIntent);
}
}
} catch (NullPointerException np) {
np.printStackTrace();
}
return Service.START_REDELIVER_INTENT;
}
I was hoping to re-use the intent to reset the repeating alarm. With this new code, I'm seeing multiple alarms stack up firing rapidly in succession around when the start time hits. It should not spaz out like that, but should fire at regular intervals as it did before the scheduling reset. I need to catch it in the debugger but haven't been able to determine the exact conditions yet. Is my understanding of alarms completely off base here? Is there a better way to do this?
Addendum: A wrinkle in this is that I'm using RootTools to gain superuser privileges in order to work around Android 4.2's airplane mode. This hasn't been a problem before the scheduling, but I'm suspicious whether su is blocking for a long time while the alarms stack up.
Re-using the intent inside the service that receives the alarm does work. I've switched from using a Repeating Alarm to a single-shot alarm which gets re-armed every time the service is called. Unfortunately this didn't fix the problem of the alarms stacking. The culprit is definitely su blocking. It may be RootTools or su itself. I need to update the library from 2.6 to 3.x and see if that makes any difference.

Android - start alarm service immediately?

I have created an On Boot Receiver to repeatedly call a wakeful intent service every 5 minutes but cannot figure out how to start the service immediately when the app is installed..? I do not want to rely on the user rebooting their device before it starts to run!
Here is my code so far :
public class OnBootReceiver extends BroadcastReceiver {
private static final int PERIOD = 300000; // check every 5 minutes
#Override
public void onReceive(Context context, Intent intent) {
AlarmManager mgr = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
Intent i = new Intent(context, OnAlarmReceiver.class);
PendingIntent pi = PendingIntent.getBroadcast(context, 0, i, 0);
mgr.setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime() + 60000, PERIOD, pi);
}}
Can anyone help me out pls? :)
If you want to set an alarmmanager to start your service when the app is installed, then it's not possible. It's a OS limitation, security if you will. But if you want to start the service in the moment the app starts, just call it, it will keep runing.
Essentially, since the Application object is created when the application is started and when the BOOT_COMPLETED Intent is received, you could register with the AlarmManager in the onCreate method in your custom Application class. Just be aware that the Application object is instantiated every time the process starts, which includes cases where the process is temporarily killed to save resources. But if you don't change the PendingIntent in any way, it should be no problem to register over and over again.
However, it is not possible to start the application when it is installed, there has to be some user interaction first.

Starting alarm service in android

In my application i want to use alarm service for specific period of time.I'm taking start time and end time values from user and saving it in database,Now i want to start a alarm service at start time and alarm should go off at end time specified by user.I'm new to this topic and not able to understand how to implement this...Any help will be appreciated.Thank u..
This is how you implement an alarm manager. But you will need to read about Calendar object in android also.
String alarm = Context.ALARM_SERVICE;
Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.HOUR_OF_DAY, 8);//Just an example setting the alarm for the 8th hour of a day.
calendar.set(Calendar.MINUTE, 0);
calendar.set(Calendar.SECOND,0);
calendar.set(Calendar.MILLISECOND, 0);
AlarmManager am = (AlarmManager)getActivity().getSystemService(alarm);
//This is the intent that is launched when the alarm goes off.
Intent intent = new Intent("WAKE_UP");
PendingIntent sender = PendingIntent.getBroadcast(getActivity(), 0, intent, 0);
//If the user wants the alarm to repeat then use AlarmManager.setRepeating if they just want it one time use AlarmManager.set().
am.setRepeating(AlarmManager.RTC_WAKEUP,calendar.getTimeInMillis() , AlarmManager.INTERVAL_DAY, sender);
}
Also you will need to register a BroadCast Receiver to except the intent when the alarm sets it off.
You create the BroadCast reciever and register it in your manifest to receive the intent from the alarm.
http://www.vogella.de/articles/AndroidServices/article.html
Here is a great tutorial to help you understand better
The key is to use the AlarmManager with a pending intent.
mAlarmSender = PendingIntent.getService(AlarmService.this,
0, new Intent(AlarmService.this, AlarmService_Service.class), 0);
Then you create the AlarmManager from the current context:
AlarmManager am = (AlarmManager)getSystemService(ALARM_SERVICE);
And schedule the previously created pending intent.
am.setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP,
firstTime, 30*1000, mAlarmSender);
On schedule the AlarmService_Service service will be called, or you can put another intent like open a specific activity.
Here is the complete example of how you can schedule an alarm: AlarmService.java

pendingintent on alarms for android

When setting a service to go off at particular time, I use the AlarmManager system service.
Everything goes off without a problem, service is called and actions take place.
When the alarm time is reached, the service starts, and at this point I get the system time (System.currentTimeMillis()). I'm guessing this wont be the actual time the service start. Is there a way to get the time that was set for this PendingIntent?
ie
Set alarm for 9am.
DoStuffService starts at 9am.
DoStuffService knows it was supposed to start at 9am, and uses this value for future functions.
When you create an intent for your alarm, you could put extra data, including time of the alarm, into it like this:
Intent intent = new Intent("action name");
//put extra data into the intent:
intent.putExtra("alarm_time_hours", hours);
intent.putExtra("alarm_time_minutes", minutes);
PendingIntent sender = PendingIntent.getBroadcast(getApplicationContext(), 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
AlarmManager am = (AlarmManager) getSystemService(ALARM_SERVICE);
am.set(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), sender);
Then in your receiver or service you need to get this extra data from received intent. Use something like this:
Bundle bundle = intent.getExtras();
if(bundle.containsKey("alarm_time_hours")) {
int hours = bundle.getInt("alarm_time_hours");
}
if(bundle.containsKey("alarm_time_minutes")) {
int minutes = bundle.getInt("alarm_time_minutes");
}
Is there a way to get the time that was set for this PendingIntent?
No, sorry.
However, it should not be terribly difficult for you to determine it yourself. Following your example, if your service reports that it is now 09:00:02.36, you should be able to round down to determine that this is the 9am alarm.

Categories

Resources