I have an android service to fetch data from the web that runs every fifteen minutes
public class SparkService extends Service {
Handler handler;
public SparkService() {
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.e("Starting Sevice", "Starting Service Successfully.");
if (handler == null) {
handler = new Handler(new Handler.Callback() {
#Override
public boolean handleMessage(Message msg) {
fetchDataFromServer();
handler.removeMessages(120);
handler.sendEmptyMessageDelayed(120, 15 * 60 * 1000);
return true;
}
});
}
handler.sendEmptyMessageDelayed(120, 15 * 60 * 1000);
return Service.START_STICKY;
}
}
I have found the service to be unreliable at times and seems like it's not being called if the app is inactive for a certain period of time. I want to replace the service with an AlarmManager service instead. My app is currently in production. Can I just delete the SparkService class and add another Alarm service class without affecting existing users who update the app? Or would I have to stop this SparkService in my app update so the app can function properly?
Your app is your entry point. So if it's killed that means all services related to its process will also be killed, like if you kill the svchost.exe process in Windows all sub processes like Windows update service will be stopped too and will not be running again until you launch the update manager.
The same goes for your app: the only way that a Service won't be stopped by killing your app (and I'm not sure about that but it can be) is if the Service is created with its own process using a special tag in the Manifest.
I think in your case you didn't set that tag so the Service will be only scheduled once your app is launched after the update and in that case the Service will behave according to the new code.
To answer your first question even if you delete the service from your update users with the old version will not be affected until they update there version with the new one
Now for using Alarm manger to trigger update from your backend as you said it's a good practice as the alarm manager have different set that you can use depending or your need below a short example how to use it
// Get alarm manager instance
AlarmManager alarmManager = (AlarmManager)getApplicationContext().getSystemService(Context.ALARM_SERVICE);
Calendar calendar;
Intent intent;
PendingIntent pendingIntent;
// Schedule
intent = new Intent(getApplicationContext(), YourCustomBroadcastReceiver.class);
pendingIntent = PendingIntent.getBroadcast(getApplicationContext(), 0, intent, 0);
calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
calendar.add(Calendar.SECOND, 1); // first time
alarmManager.setRepeating(
AlarmManager.RTC_WAKEUP,
calendar.getTimeInMillis(),
60*5*1000,//Each five minutes
pendingIntent
);
And in your broadcast receiver
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
public class YourBroadcastReceiver extends BroadcastReceiver{
publicYourBroadcastReceiver() {}
#Override
public void onReceive(Context context, Intent intent) {
Intent serviceIntent = new Intent(context.getApplicationContext(),YourService.class);
context.startService(serviceIntent);
}
}
And here for more details about alarm manager
http://developer.android.com/training/scheduling/alarms.html
Related
I'm developing an app that need to do some check in the server every certain amount of time. The check consist in verify if there are some notification to display. To reach that goal I implemented Service, Alarm Manager and Broadcast Reciever. This is the code that I'm using so far:
public class MainActivity {
...
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
...
setRecurringAlarm(this);
}
/**
*
* #param context
*/
private void setRecurringAlarm(Context context) {
Calendar updateTime = Calendar.getInstance();
Intent downloader = new Intent(context, MyStartServiceReceiver.class);
downloader.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, downloader, PendingIntent.FLAG_CANCEL_CURRENT);
AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, updateTime.getTimeInMillis(), 60000, pendingIntent);
}
...
}
Receiver class
public class MyStartServiceReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Intent dailyUpdater = new Intent(context, MyService.class);
context.startService(dailyUpdater);
Log.e("AlarmReceiver", "Called context.startService from AlarmReceiver.onReceive");
}
}
Service class
public class MyService extends IntentService {
public MyService() {
super("MyServiceName");
}
#Override
protected void onHandleIntent(Intent intent) {
Log.e("MyService", "Service running!");
// TODO Do the hard work here
this.sendNotification(this);
}
private void sendNotification(Context context) {
// TODO Manage notifications here
}
}
Manifest.xml
<!--SERVICE AND BROADCAST RECEIVER-->
<service
android:name=".MyService"
android:exported="false"/>
<receiver
android:name=".MyStartServiceReceiver"
android:process=":remote"/>
The code works fine, the task in the service will be excecuted periodically. The problem is that the service is destroyed when the app is forced to close. I need to keep alive the service, capable to execute the task, even if the user has closed the app, so the user can be updated via notifications. Thank you for your time!
You can't. If the app is forced closed, that means either its crashed (in which case the service has to be stopped as it may no longer work correctly) or the user force closed it in which case the user wants the app to stop- which means the user doesn't want the service to run. Allowing a service to be automatically restarted even if the user stops it would be basically writing malware into the OS.
In fact, Android went the exact opposite (and correct) way- if the user force stops an app, NOTHING of the app can run until the user runs it again by hand.
You may go through this. I hope this will solve your problem. If you want to keep awake your service it is practically not possible to restart the app which is forced close. So if you disable force stop your problem may be solved.
I'm trying to get a process timer to run and keep it running in the background on android (starts with a button click).
The timer must be on 30 seconds and should even continue growing application in the background (with home button and power / screen off).
How can I do this? I tried with service and handler but not working ...
EDIT
My service tracking (process with 30 sec)
public class TrackingService extends IntentService {
private Handler mHandler;
private Runnable mRunnable;
public TrackingService() {
super("TrackingService");
}
public TrackingService(String name) {
super(name);
}
#Override
protected void onHandleIntent(Intent intent) {
long timer = 30000;
mHandler = new Handler();
mRunnable = new Runnable() {
#Override
public void run() {
//TODO - process with update timer for new 30 sec
mHandler.postDelayed(this, timer);
}
};
mHandler.postDelayed(mRunnable, timer);
}
}
My click button:
mButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//TODO - start first time and it continued every 30 seconds and continue in the background
startService(Intent intent = new Intent(this, TrackingService.class));
}
});
Ok, first of all, I really don't know if I got your question quite right.
But I think you want a timer that's being executed every 30 seconds ,if i'm not mistaken.
If so, do as following:
AlarmManager
Note: 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.
Example:
in your onClick() register your timer:
int repeatTime = 30; //Repeat alarm time in seconds
AlarmManager processTimer = (AlarmManager)getSystemService(ALARM_SERVICE);
Intent intent = new Intent(this, processTimerReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
//Repeat alarm every second
processTimer.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(),repeatTime*1000, pendingIntent);
And your processTimerReceiver class:
//This is called every second (depends on repeatTime)
public class processTimerReceiver extends BroadcastReceiver{
#Override
public void onReceive(Context context, Intent intent) {
//Do something every 30 seconds
}
}
Don't forget to register your receiver in your Manifest.XML
<receiver android:name="processTimer" >
<intent-filter>
<action android:name="processTimerReceiver" >
</action>
</intent-filter>
</receiver>
If you ever want to cancel the alarm:
use this to do so:
//Cancel the alarm
Intent intent = new Intent(this, processTimerReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0, intent, 0);
AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
alarmManager.cancel(pendingIntent);
Hope this helps you out.
PS: if this is not exactly what u want, please leave it in the comments, or if someone wants to edit this, please do so.
Oh god, don't ever use AlarmManager for 30s timers. It's kind of an overkill and also put a significant drain on device resources (battery, CPU...).
Perhaps you could try using a real background Service instead of IntentService as IntentService tends to shut itself down when it runs out of work. Not sure if this is the case here, but it's worth a try.
I've this IntentService:
public class ServiceUpdateNewResults extends IntentService{
private void setAlarmToCheckUpdates() {
Calendar calendar = Calendar.getInstance();
//calendar.add(Calendar.DAY_OF_YEAR, 1); //dema
//calendar.set(Calendar.HOUR_OF_DAY, 22); //a les 10
calendar.add(Calendar.SECOND, 20);
Intent myIntent = new Intent(this.getApplicationContext(), ReceiverCheckUpdates.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(this.getApplicationContext(), 0, myIntent,0);
AlarmManager alarmManager = (AlarmManager)this.getApplicationContext().getSystemService(this.getApplicationContext().ALARM_SERVICE);
alarmManager.set(AlarmManager.RTC, calendar.getTimeInMillis(), pendingIntent);
}
public ServiceUpdateNewResults() {
super("ServiceUpdateNewResults");
}
#Override
protected void onHandleIntent(Intent intent) {
//fem les coses.
//Toast.makeText(this.getApplicationContext(), "holaa", Toast.LENGTH_LONG).show();
setAlarmToCheckUpdates();
Log.d("debugging","hello");
}
}
And this is calling a BroadCastReceiver every 20 seconds, which ends up calling this service, and this is going to happen "forever". (in a future it will be 1 day, not 20 seconds).
This is the Receiver:
public class ReceiverCheckUpdates extends BroadcastReceiver{
Context context;
#Override
public void onReceive(Context context, Intent intent){
this.context = context;
Intent service1 = new Intent(context, ServiceUpdateNewResults.class);
context.startService(service1);
}
}
This is working perfectly, but if I stop the app from Android settings, the service is also stopped. I want to avoid this. I want that if the App is closed, the service should keep working.
Is it possible?
Actually, when is a service killed ?
if I stop the app from Android settings, the service is also stopped
If by "stop the app from Android settings", you mean that you press the Force Stop button, your app will not run again until something manually runs one of your components (e.g., user launches your activity). More specifically in this case, your alarms are unscheduled.
I want to avoid this.
Then do not press the "Force Stop" button.
I want that if the App is closed, the service should keep working.
In any non-"Force Stop" scenario, the alarms will keep firing (at least until the device falls asleep, given your current implementation).
The IntentService is part of your app. If the system destroys your app, it will destroy the IntentService. You can reduce the chances of this happening by putting the IntentService in a separate process, but you can't stop the system from destroying an IntentService. You can make it highly unlikely that the system will destroy a Service; to do that, you use a "foreground" Service. However, you should avoid doing this unless you really really need to. In addition, you can't have a foreground IntentService, so you'll have to add your own background Handler and HandlerThread.
I am working on an app that will relay information about its location to a remote server. I am intending to do it by doing a simple HTTP post to the web-server and all is simple and fine.
But according to the spec, the app needs to execute itself from time to time, lets say once in every 30 mins. Be independent of the interface, meaning which it needs to run even if the app is closed.
I looked around and found out that Android Services is what needs to be used. What could I use to implement such a system. Will the service (or other mechanism) restart when the phone restarts?
Thanks in advance.
Create a Service to send your information to your server. Presumably, you've got that under control.
Your Service should be started by an alarm triggered by the AlarmManager, where you can specify an interval. Unless you have to report your data exactly every 30 minutes, you probably want the inexact alarm so you can save some battery life.
Finally, you can register your app to get the bootup broadcast by setting up a BroadcastReceiver like so:
public class BootReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(Intent.ACTION_BOOT_COMPLETED)) {
// Register your reporting alarms here.
}
}
}
You'll need to add the following permission to your AndroidManifest.xml for that to work. Don't forget to register your alarms when you run the app normally, or they'll only be registered when the device boots up.
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
Here is a semi-different way to keep the service going forever. There is ways to kill it in code if you'd wish
Background Service:
package com.ex.ample;
import android.app.Service;
import android.content.*;
import android.os.*;
import android.widget.Toast;
public class BackgroundService extends Service {
public Context context = this;
public Handler handler = null;
public static Runnable runnable = null;
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onCreate() {
Toast.makeText(this, "Service created!", Toast.LENGTH_LONG).show();
handler = new Handler();
runnable = new Runnable() {
public void run() {
Toast.makeText(context, "Service is still running", Toast.LENGTH_LONG).show();
handler.postDelayed(runnable, 10000);
}
};
handler.postDelayed(runnable, 15000);
}
#Override
public void onDestroy() {
/* IF YOU WANT THIS SERVICE KILLED WITH THE APP THEN UNCOMMENT THE FOLLOWING LINE */
//handler.removeCallbacks(runnable);
Toast.makeText(this, "Service stopped", Toast.LENGTH_LONG).show();
}
#Override
public void onStart(Intent intent, int startid) {
Toast.makeText(this, "Service started by user.", Toast.LENGTH_LONG).show();
}
}
Here is how you start it from your main activity or wherever you wish:
startService(new Intent(this, BackgroundService.class));
onDestroy() will get called when the application gets closed or killed but the runnable just starts it right back up.
I hope this helps someone out.
The reason why some people do this is because of corporate applications where in some instances the users/employees must not be able to stop certain things :)
http://i.imgur.com/1vCnYJW.png
EDIT
Since Android O (8.0) you have to use JobManager for scheduled tasks. There is a library called Android-Job by Evernote which will make periodic background work a breeze on all Android versions. I have also made a Xamarin Binding of this library.
Then all you need to do is the following:
In your application class:
public class MyApp extends Application {
#Override
public void onCreate() {
super.onCreate();
JobManager.create(this).addJobCreator(new MyJobCreator());
}
}
Create the following two classes YourJobCreator and YourSyncJob(Where all the work will be done. Android allocates time for all the background jobs to be run. For android versions < 8.0 it will still run with an Alarm manager and background service as per normal)
public class MyJobCreator implements JobCreator {
#Override
#Nullable
public Job create(#NonNull String tag) {
switch (tag) {
case MySyncJob.TAG:
return new MySyncJob();
default:
return null;
}
}
}
public class MySyncJob extends Job {
public static final String TAG = "my_job_tag";
#Override
#NonNull
protected Result onRunJob(Params params) {
//
// run your job here
//
//
return Result.SUCCESS;
}
public static void scheduleJob() {
new JobRequest.Builder(MySyncJob.TAG)
.setExecutionWindow(30_000L, 40_000L) //Every 30 seconds for 40 seconds
.build()
.schedule();
}
}
You should schedule your service with alarm manager, first create the pending intent of service:
Intent ii = new Intent(getApplicationContext(), MyService.class);
PendingIntent pii = PendingIntent.getService(getApplicationContext(), 2222, ii,
PendingIntent.FLAG_CANCEL_CURRENT);
Then schedule it using alarm manager:
//getting current time and add 5 seconds to it
Calendar cal = Calendar.getInstance();
cal.add(Calendar.SECOND, 5);
//registering our pending intent with alarmmanager
AlarmManager am = (AlarmManager) getSystemService(ALARM_SERVICE);
am.set(AlarmManager.RTC_WAKEUP,cal.getTimeInMillis(), pi);
this will launch your service after 5 seconds of current time. You can make your alarm repeating.
You can use Alarm Manager to start Service at specified time and then repeat alarm in specified interval. When alarm goes on you can start service and connect to server and make what you want
I was wondering if it's possible (and if it is how) to start up my app at a specific time, something like an alarmclock which goes off at a specific time.
Let's say I want my app to start up at 8 in the morning, is that feasable ?
You can do it with AlarmManager, heres a short example. First you need to set the alarm:
AlarmManager am = (AlarmManager) con.getSystemService(Context.ALARM_SERVICE);
Date futureDate = new Date(new Date().getTime() + 86400000);
futureDate.setHours(8);
futureDate.setMinutes(0);
futureDate.setSeconds(0);
Intent intent = new Intent(con, MyAppReciever.class);
PendingIntent sender = PendingIntent.getBroadcast(con, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
am.set(AlarmManager.RTC_WAKEUP, futureDate.getTimeInMillis(), sender);
Next, You need to create a reciever with some code to execute your application: (ie- starting your app):
public class MyAppReciever extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
startActivity(new Intent(context, MyAppMainActivity.class));
}
}
You are probably looking for AlarmManager, which let's you start services / activities / send broadcasts at specific intervals or a given time, repeating or not. This is how you write memory friendly background services in android. AlarmManager is sort of like cron in unix. It allows your background service to start, do its work, and get out of memory.
You probably do not want to start an activity (if that's what you meant by "application"). If you want to alert the user that something has happened, add an alarm that starts a receiver at a given time, and have the receiver add a notification. The notification can open the application when clicked. That's less invasive than bringing some potentially unwanted activity to the foreground.
there is a very good tutorial: http://www.javacodegeeks.com/2012/09/android-alarmmanager-tutorial.html
here is the c&p:
Android AlarmManager tutorial
by Rakesh Cusat on September 20th, 2012 | Filed in: Android Core
While writing an application, need arises to schedule execution of code in future. You may require AlarmManager to schedule your work at a specified time. AlarmManager accesses to system alarm and schedules the execution of code even when the application is not running.
Project Information: Meta-information about the project. Platform Version : Android API Level 10.
IDE : Eclipse Helios Service Release 2
Emulator: Android 4.1
Prerequisite: Preliminary knowledge of Android application framework, and Intent Broadcast receiver.
AlarmManager:
AlarmManager has access to the system alarm services. With the help of AlarmManager you can schedule execution of code in future. AlarmManager object can’t instantiate directly however it can be retrieved by calling Context.getSystemService(Context.ALARM_SERVICE). AlarmManager is always registered with intent. When an alarm goes off, the Intent which has been registered with AlarmManager, is broadcasted by the system automatically. This intent starts the target application if it is not running. It is recommended to use AlarmManager when you want your application code to be run at a specific time, even if your application is not currently running. For other timing operation handler should be used because it is easy to use. Handler is covered in other tutorial.
Method Description
set() Schedules an alarm for one time.
setInexactRepeating() Schedules an alarm with inexact repeating. Trigger time doesn’t follow any strict restriction.
setRepeating() Schedules an alarm with exact repeating time.
setTime() Sets the system’s wall clock time.
setTimeZone() Sets the system’s default time zone.
Check out the AlarmManager documention for more info.
In this tutorial let’s learn to create one-time timer and the repeating timer, and also to cancel the repeating timer. Here timer and alarm have been used interchangeably, but in this tutorial context both of them have the same meaning.
Example Code:
Let’s create three buttons start repeating timer, cancel repeating timer and one-time timer in the layout file. These buttons are attached with methods i.e startRepeatingTimer, cancelRepeatingTimer and onetimeTimer respecitively. These methods will be defined in the Activity class. The layout file is shown below(activity_alarm_manager.xml).
<linearlayout android:layout_height='match_parent'
android:layout_width='match_parent' android:orientation='vertical'
xmlns:android='http://schemas.android.com/apk/res/android'
xmlns:tools='http://schemas.android.com/tools'>
<button android:id='#+id/btStart' android:layout_height='wrap_content'
android:layout_width='match_parent' android:onclick='startRepeatingTimer'
android:padding='#dimen/padding_medium' android:text='#string/btStart'
tools:context='.WidgetAlarmManagerActivity'/>
<button android:id='#+id/btCancel' android:layout_height='wrap_content'
android:layout_width='match_parent' android:onclick='cancelRepeatingTimer'
android:padding='#dimen/padding_medium' android:text='#string/btCancel'
tools:context='.WidgetAlarmManagerActivity'/>
<button android:id='#+id/btOneTime' android:layout_height='wrap_content'
android:layout_width='match_parent' android:onclick='onetimeTimer'
android:padding='#dimen/padding_medium' android:text='#string/btOneTime'
tools:context='.WidgetAlarmManagerActivity'/>
</linearlayout>
We are going to define the BroadcastReciever which handles the intent registered with AlarmManager. In the given class onReceive() method has been defined. This method gets invoked as soon as intent is received. Once we receive the intent we try to get the extra parameter associated with this intent. This extra parameter is user-defined i.e ONE_TIME, basically indicates whether this intent was associated with one-time timer or the repeating one. Once the ONE_TIME parameter value has been extracted, Toast message is displayed accordingly. Helper methods have also been defined, which can be used from other places with the help of objects i.e setAlarm(), cancelAlarm() and onetimeTimer() methods. These methods can also be defined somewhere else to do operation on the timer i.e set, cancel, etc. To keep this tutorial simple, we have defined it in BroadcastReceiver.
setAlarm(): This method sets the repeating alarm by use of setRepeating() method. setRepeating() method needs four arguments:
type of alarm,
trigger time: set it to the current time
interval in milliseconds: in this example we are passing 5 seconds ( 1000 * 5 milliseconds)
pending intent: It will get registered with this alarm. When the alarm gets triggered the pendingIntent will be broadcasted.
cancelAlarm(): This method cancels the previously registered alarm by calling cancel() method. cancel() method takes pendingIntent as an argument. The pendingIntent should be matching one, only then the cancel() method can remove the alarm from the system.
onetimeTimer(): This method creates an one-time alarm. This can be achieved by calling set() method. set() method takes three arguments:
type of alarm
trigger time
pending intent
package com.rakesh.alarmmanagerexample;
import java.text.Format;
import java.text.SimpleDateFormat;
import java.util.Date;
import android.app.AlarmManager;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.os.PowerManager;
import android.widget.Toast;
public class AlarmManagerBroadcastReceiver extends BroadcastReceiver {
final public static String ONE_TIME = 'onetime';
#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, 'YOUR TAG');
//Acquire the lock
wl.acquire();
//You can do the processing here.
Bundle extras = intent.getExtras();
StringBuilder msgStr = new StringBuilder();
if(extras != null && extras.getBoolean(ONE_TIME, Boolean.FALSE)){
//Make sure this intent has been sent by the one-time timer button.
msgStr.append('One time Timer : ');
}
Format formatter = new SimpleDateFormat('hh:mm:ss a');
msgStr.append(formatter.format(new Date()));
Toast.makeText(context, msgStr, Toast.LENGTH_LONG).show();
//Release the lock
wl.release();
}
public void SetAlarm(Context context)
{
AlarmManager am=(AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(context, AlarmManagerBroadcastReceiver.class);
intent.putExtra(ONE_TIME, Boolean.FALSE);
PendingIntent pi = PendingIntent.getBroadcast(context, 0, intent, 0);
//After after 5 seconds
am.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(), 1000 * 5 , pi);
}
public void CancelAlarm(Context context)
{
Intent intent = new Intent(context, AlarmManagerBroadcastReceiver.class);
PendingIntent sender = PendingIntent.getBroadcast(context, 0, intent, 0);
AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
alarmManager.cancel(sender);
}
public void setOnetimeTimer(Context context){
AlarmManager am=(AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(context, AlarmManagerBroadcastReceiver.class);
intent.putExtra(ONE_TIME, Boolean.TRUE);
PendingIntent pi = PendingIntent.getBroadcast(context, 0, intent, 0);
am.set(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(), pi);
}
}
Given below is the manifest file. Here, WAKE_LOCK permission is required because the wake lock is being used while processing in onReceive() method present in AlarmManagerBroadcastReceiver class. AlarmManagerBroadcastReceiver has been registered as broadcast receiver.
<manifest android:versioncode='1' android:versionname='1.0'
package='com.rakesh.alarmmanagerexample'
xmlns:android='http://schemas.android.com/apk/res/android'>
<uses-sdk android:minsdkversion='10' android:targetsdkversion='15'/>
<uses-permission android:name='android.permission.WAKE_LOCK'/>
<application android:icon='#drawable/ic_launcher'
android:label='#string/app_name' android:theme='#style/AppTheme'>
<activity android:label='#string/title_activity_alarm_manager'
android:name='com.rakesh.alarmmanagerexample.AlarmManagerActivity'>
<intent-filter>
<action android:name='android.intent.action.MAIN'/>
<category android:name='android.intent.category.LAUNCHER' />
</intent-filter>
</activity>
<receiver android:name='com.rakesh.alarmmanagerexample.AlarmManagerBroadcastReceiver'>
</receiver>
</application>
</manifest>
Now let’s define the activity class which defines some methods. These methods are going to handle the button clicks. Here in this class we create an instance of AlarmManagerBroadcastReciever which will help us to access setAlarm(), cancelAlarm() and setOnetime(). Rest of the code is easy to understand.
package com.rakesh.alarmmanagerexample;
import com.rakesh.alarmmanagerexample.R;
import android.os.Bundle;
import android.app.Activity;
import android.content.Context;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Toast;
import android.support.v4.app.NavUtils;
public class AlarmManagerActivity extends Activity {
private AlarmManagerBroadcastReceiver alarm;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_alarm_manager);
alarm = new AlarmManagerBroadcastReceiver();
}
#Override
protected void onStart() {
super.onStart();
}
public void startRepeatingTimer(View view) {
Context context = this.getApplicationContext();
if(alarm != null){
alarm.SetAlarm(context);
}else{
Toast.makeText(context, 'Alarm is null', Toast.LENGTH_SHORT).show();
}
}
public void cancelRepeatingTimer(View view){
Context context = this.getApplicationContext();
if(alarm != null){
alarm.CancelAlarm(context);
}else{
Toast.makeText(context, 'Alarm is null', Toast.LENGTH_SHORT).show();
}
}
public void onetimeTimer(View view){
Context context = this.getApplicationContext();
if(alarm != null){
alarm.setOnetimeTimer(context);
}else{
Toast.makeText(context, 'Alarm is null', Toast.LENGTH_SHORT).show();
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.activity_widget_alarm_manager, menu);
return true;
}
}
Once you are done with the coding, just execute the project and you will find the similar kind of application running in your emulator.
Please download https://github.com/rakeshcusat/Code4Reference/tree/master/AndroidProjects/AlarmManagerExamplecode, if you need reference code.
Reference: Tutorial on Android AlarmManager from our JCG partner Rakesh Cusat at the Code4Reference blog.
http://code4reference.com/2012/07/tutorial-on-android-alarmmanager/