I have a service that runs every hour by a shot in my AlarmManager startAPP.class (main activity) in onCreate, as follows:
Intent it = new Intent("SINC");
PendingIntent p = PendingIntent.getBroadcast(StartAPP.this, 0, it, 0);
Calendar c = Calendar.getInstance();
c.setTimeInMillis(System.currentTimeMillis());
c.add(Calendar.SECOND, inicio);
AlarmManager alarm = (AlarmManager) getSystemService(ALARM_SERVICE);
long time = c.getTimeInMillis();
alarm.setRepeating(AlarmManager.RTC_WAKEUP, time, repetir, p);
Everything ok. The service is triggered exactly as it should. But how is that a download is done execution is somewhat slow (minutes) 1 or 2. And this time the android triggers a dialog stating that the application stopped responding and asks if I want to close or wait.
How do I get this service does not display this message (dialog). Because from what I read services are used for processing time consuming and downloading files.
The service extends BroadcastReceiver
public class Sinc extends BroadcastReceiver
Note: if I tell the dialog I want to wait, the whole service process is successfully completed. (all files are downloaded)
Thanks
You should have your Sinc class inherit from IntentService instead of BroadcastReceiver and modify your PendingIntent to be a service intent instead of a broadcast intent.
Related
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
I want to schedule a service to run every minute and check if my app is still running. (I want to reopen the application if it is closed).
Also, I still want this service to run every minute if my application was force killed by task manager.
Thanks!
Also, I still want this service to run every minute if my application was force killed by task manager
This is not possible as of Android 3.1. If the user goes into Settings and force=stops your app, nothing of your app will run again, until the user manually launches one of your components.
If your process is terminated for other reasons (e.g., ordinary task-killer app from the Play Store, swiping your task away from the Recent Tasks list), your alarms scheduled with AlarmManager should remain intact, per Lucifer's suggestion.
im writing a "Parent Control" app which is installed on the child's phone.
Any child sufficiently intelligent to use a phone will be sufficiently intelligent to reboot their device in safe mode and get rid of your app.
Use AlarmManager class, it works even if your device is in sleep mode.
private static Intent alarmIntent = null;
private static PendingIntent pendingIntent = null;
private static AlarmManager alarmManager = null;
// First Creating an Intent
alarmIntent = new Intent ( context, yourClass.class );
// Create an Pending Intent which will Broadcast the Intent
pendingIntent = PendingIntent.getBroadcast(context, 234324243, alarmIntent, 0 );
// Set the AlarmManager class
alarmManager = ( AlarmManager ) context.getSystemService( ConstantCodes.ALARM_SERVICE );
// Set Repeating time interval
alarmManager.setRepeating( AlarmManager.RTC_WAKEUP, Interval * 1000, Interval * 1000, pendingIntent );
AlarmManager consumes lesser battery power than TimerTask or Thread. It works like painless AsyncTask.
I am making a personal organizer. From the calendar the user can choose the day and then can make a date with a specific hour. At this date and hour the application should show an other activity, which is the notification. User can make just one note for day. So the pk of each note is YYYYMMDD.
So, I wants to know that what I've done is right or not.
I've a service which is started with application. The onStartCommand of the service checks if in the current date there is a note in the db and, if there is, he calls the Activity Notification. I've a runnable thread which is looping each minute and it update the date if the service, because the date of the onStartCommand is static. If the date getted by the runnable is equal to onStartCommand's date then keep cycling, else I start the service again with:
Intent myIntent = new Intent(Receiver.this, NotificaSuoneria.class);
startActivity(myIntent);
In this way I haven't any troubles, but I want to know if the runnable thread could be killed by android, because if killed I can't check the alarms of the others days.
And, when I restart the service each time update the date, the old runnable thread will be killed or will were a lot of threads?
P.S.
I don't use the AlarmManager for schedule the alarm. If the datenow have some engagement with alarms I calculate the time left and sleep for this time, then I'll start the notification activity. Sorry for my poor english.
You should use AlarmManager for this with a loop like following edited
try {
cntxt = createPackageContext("your.app.package",CONTEXT_IGNORE_SECURITY);
} catch (NameNotFoundException e) {
// handle exception here
e.printStackTrace();
}
Intent myIntent = new Intent(cntxt , yourreciever.class);
PendingIntent pi;
AlarmManager alarmManager;
for(int i=0;i<=timesinday;i++)
{
pi=PendingIntent.getBroadcast(cntxt, i,myIntent, 0);
alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
alarmManager.set(AlarmManager.RTC_WAKEUP, currentcal.getTimeInMillis(),pi);
}
Do not forget to add NotificaSuoneria in Android Menifest as a Reciever. If you you want alarm to goes off every day you should use
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP,todaycal.getTimeInMillis(),AlarmManager.INTERVAL_DAY,pendingIntent);
#Meesta I am editing the answer you do not have to mention activity here Intent myIntent = new Intent(Receiver.this, here.class); here will be the reciever class from wher you can start your activity also see http://androidword.blogspot.in/2010/10/how-to-use-broadcast-receiver.html and try to add flag_new_activitywhen starting the activity from broadcast reciever
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.
Hi i have written reminder code in service onstart().and when user insert date-time and insert record at that time service called by startservice() function,but only service is starting when i insert record i.e i am getting reminder when it get call from my activity.but i want reminder after 3days or something so how should i keep service always on so that i can get reminder in future? or how should i make connection of service keep alive?should i called bindservice() frunction from my any activity or what?
thanks in advance---
Don't let your Service run all the time. It consumes battery and memory when not neccessary¹.
Rather schedule a PendingIntent via the AlarmManager thats starts the service at the relevant point in time to do it's work. When done, kill the service again.
In general androids services are used different then services/daemons on a "normal" computer. They have a task that they execute, then they quit (usually via Service.stopSelf()) until someone starts them again to do more work.
Here is a small example how the AlarmManager is used:
// get a calendar with the current time
Calendar cal = Calendar.getInstance();
// add 15 minutes to the calendar object
cal.add(Calendar.MINUTE, 15);
Intent intent = new Intent(ctx, YourService.class);
PendingIntent pi = PendingIntent.getService(this, 123, intent,
PendingIntent.FLAG_UPDATE_CURRENT);
AlarmManager am = (AlarmManager) getSystemService(ALARM_SERVICE);
am.set(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), pi);
This launches the intent to start YourService in 15 minutes from now. There is plenty of documentation for sending intents this way, search a bit around.
¹ Which will eventually frustrate your users: "Why does this app waste my battery?" is a pretty common question
Firstly no need of service,you can useAlarManagerClass Link Alarmanger class for schedule events and show alert at specific time and date. If you want show messages after some long duration then schedule a Pending-intent via the AlarmManager thats starts the service at the relevant point in time to do it's work. When done, kill the service again as per tell by above answers . In addition you can store your data into shared preferences for permanently. You can retrieve it at any time for resheulding it on device reboot or for other purpose.
Sometimes, it may be necessary for your android app to complete a task sometime in the future. In order to do this, you must schedule an activity (can also be a service) to be run using Android’s AlarmManager. This post will show:
* How to set up a receiver for the scheduled event
* How to create an activity from this receiver
* Using the AlarmManager and the created classes to successfully receive and process a scheduled event
Creating a BroadcastReceiver
The first thing you will need is a receiver to receive the event. There are several key aspects to have for the receiver to work properly. First create a class that extends BroadcastReceiver and override and implement the necessary onReceive(Context context, Intent intent) method. The following is a basic example using a Toast message:
package com.justcallmebrian.alarmexample;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.widget.Toast;
import android.os.Bundle;
public class AlarmReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
try {
Bundle bundle = intent.getExtras();
String message = bundle.getString("alarm_message");
Toast.makeText(context, message, Toast.LENGTH_SHORT).show();
} catch (Exception e) {
Toast.makeText(context, "There was an error somewhere, but we still received an alarm", Toast.LENGTH_SHORT).show();
e.printStackTrace();
}
}
}
In the previous example, we are simply just printing out the message supplied by the String passed in under the name of alarm_message. For those who are not familiar with Toast, it is basically a short and quick message given to the user. Here you can find more information on Toast.
Besides actually creating the class to receive the event, you must also declare it within AndroidManifest.xml. The following is the line that should be added before the closing of the application tag (before ).
Basically this states that the class AlarmReceiver is available and will start a private process. Once that is done, your BroadcastReceiver is ready to go.
Setting up an Event using AlarmManager
In order to receive an event, you obviously must schedule the event. There are three ways of scheduling an event (a one time event using the set method, a repeating event using the setRepeating method and finally using the setInexactRepeating). This tutorial will cover the one time alarm using the set method. For more information regarding the other events, you can view AlarmManager.
The following code snippet will get the AlarmManager and set an event to occur 5 minutes from the current time:
// get a Calendar object with current time
Calendar cal = Calendar.getInstance();
// add 5 minutes to the calendar object
cal.add(Calendar.MINUTE, 5);
Intent intent = new Intent(ctx, AlarmReceiver.class);
intent.putExtra("alarm_message", "O'Doyle Rules!");
// In reality, you would want to have a static variable for the request code instead of 192837
PendingIntent sender = PendingIntent.getBroadcast(this, 192837, intent, PendingIntent.FLAG_UPDATE_CURRENT);
// Get the AlarmManager service
AlarmManager am = (AlarmManager) getSystemService(ALARM_SERVICE);
am.set(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), sender);
This code snippet basically obtains a new Calendar object and adds 5 minutes to it. An Intent is created with the AlarmReceiver which we created earlier. The more important piece of the code is setting the FLAG_UPDATE_CURRENT flag. Without this flag, the message being passed as an Extra will be lost and not obtained by the receiver.
With these code snippets you should be able to create and run some tasks in the BroadcastReceiver. However, sometimes you may wish to start a new activity (or service) on the alarm event. In order to do this, you would want to have the AlarmReceiver create and start the new Activity.
Starting an Activity from BroadcastReceiver
Starting an activity within a Receiver has an extra flag that is needed. We will change the previous onReceive for AlarmReceiver to get this done:
#Override
public void onReceive(Context context, Intent intent) {
try {
Bundle bundle = intent.getExtras();
String message = bundle.getString("alarm_message");
Intent newIntent = new Intent(context, AlarmActivity.class);
newIntent.putExtra("alarm_message", message);
newIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(newIntent);
} catch (Exception e) {
Toast.makeText(context, "There was an error somewhere, but we still received an alarm", Toast.LENGTH_SHORT).show();
e.printStackTrace();
}
}
Now you would only have to create the new AlarmActivity as you would do any other Activity. Don’t forget to include the newly created activity in the AndroidManifest.xml file.