My app needs to do some background task after boot completed and also in sleep mode.
So I'm using WakefulIntentService to avoid flow problem in sleep mode and it works well.
But when I'm trying to use the boot receiver for continuing data flow after boot completed it gives some strange error and also not working sometimes.
Here is my Boot Receiver class where I am trying to do multiple task.
public class OnBootReceiver extends BroadcastReceiver {
private static final int SERVICE_PERIOD = 300000; // 5 minutes currently
// private static final int HANDLER_PERIOD = 300000 * 12; // 1 hour
// currently
private static final String TAG = "OnBoot";
private Context mContext;
private int mInterval = 1000 * 60 * 60 * 2; // 2 hours by default, can be
// changed later
private Handler mHandler;
#Override
public void onReceive(Context context, Intent intent) {
mContext = context;
AlarmManager mgr = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
Intent i = new Intent(context, OnServiceReceiver.class);
PendingIntent pi = PendingIntent.getBroadcast(context, 0, i, 0);
mgr.setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP,
SystemClock.elapsedRealtime() + 60000, SERVICE_PERIOD, pi);
mHandler = new Handler();
startRepeatingTask();
}
Runnable mStatusChecker = new Runnable() {
#SuppressWarnings("unchecked")
#Override
public void run() {
SharedPreferences mSharedPreferences = mContext
.getSharedPreferences(KEY_USER_ID, 0);
String UserId = mSharedPreferences.getString(KEY_USER_ID, "0");
new SyncValidater(mContext, UserId).execute();
mHandler.postDelayed(mStatusChecker, mInterval);
}
};
void startRepeatingTask() {
mStatusChecker.run();
}
void stopRepeatingTask() {
mHandler.removeCallbacks(mStatusChecker);
}
}
In this class I have written two tasks. the first one is starting another broadcast receiver which starts the wakeful service(same as github example). And the second one starts one handler which starts one AsyncTask class to do some server transaction in every two hours. But sometimes the handler starts in random time and sometimes stop.
So here I'm confusing that is my app requires two boot receivers ?
is there any other option to do these multiple tasks in the current receiver ?
please help. Thanks
And the second one starts one handler which starts one AsyncTask class to do some server transaction in every two hours
No, your second task will run once and probably never again, because your process is terminated in the meantime.
So here I'm confusing that is my app requires two boot receivers ?
No.
is there any other option to do these multiple tasks in the current receiver ?
Use two AlarmManager events, each with their own period. One is your current AlarmManager event. The other is one you create in support of your every-two-hour work to be done.
Related
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 need to ping server(api call) in every 10 mins, api call should be working if my application runs in background. Please suggest me the better option.
Right now I used Service, but it get finish after some time if my application is in background(due to GC clear).
How to avoid GC clear if application runs in background. Please help me.
If you want to restart your service automatically after being killed, set the service sticky.
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
return START_STICKY;
}
You can use Handler for that. A Handler allows you to send and process Message and Runnable objects associated with a thread's MessageQueue. Each Handler instance is associated with a single thread and that thread's message queue.
There are two main uses for a Handler: (1) to schedule messages and runnables to be executed as some point in the future; and (2) to enqueue an action to be performed on a different thread than your own.
Example :
private final static int TIMEINTERVAL = 600000; //10 minutes
Handler mHandler;
Runnable mHandlerTask = new Runnable()
{
#Override
public void run() {
// call your api here.
ApiCall();
mHandler.postDelayed(mHandlerTask, TIMEINTERVAL);
}
};
private void startTask(){
//run your Task
mHandlerTask.run();
}
private void stopTask()
{
// stop your Task
mHandler.removeCallbacks(mHandlerTask);
}
You can also use AlarmManager and set a repeating alarm from your Activity which will invoke the receiver every 10 minutes:
AlarmManager alarmManager=(AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
Intent i = new Intent(context, AlarmReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, intent, 0);
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP,System.currentTimeMillis(),600000,
pendingIntent);
BroadcastReceiver:
public class Receiver extends BroadcastReceiver
{
#Override
public void onReceive(Context context, Intent intent)
{
//Call your API
}
}
Registerd Receiver in your Manifest.xml
<receiver
android:name="com.YourPackage.AlarmReceiver"
android:exported="false">
I want to call a specific patch of code regularly after 60 seconds to get the updated data in the application. I am wondering where i should put the code in the Main Android activity. Any help will be appreciated
thanks
You can use Timer Class of Java's util package. It will allow you to execute a specific code again & again on a regular interval. Have a look at the example which executes on every 5 seconds.
use services and broadcast receivers in android.
// Restart service every 30 seconds
private static final long REPEAT_TIME = 1000 * 30;
#Override
public void onReceive(Context context, Intent intent) {
AlarmManager service = (AlarmManager) context
.getSystemService(Context.ALARM_SERVICE);
Intent i = new Intent(context, MyStartServiceReceiver.class);
PendingIntent pending = PendingIntent.getBroadcast(context, 0, i,
PendingIntent.FLAG_CANCEL_CURRENT);
Calendar cal = Calendar.getInstance();
// Start 30 seconds after boot completed
cal.add(Calendar.SECOND, 30);
//
// Fetch every 30 seconds
// InexactRepeating allows Android to optimize the energy consumption
service.setInexactRepeating(AlarmManager.RTC_WAKEUP,
cal.getTimeInMillis(), REPEAT_TIME, pending);
refer this site for more information.
http://www.vogella.com/articles/AndroidServices/article.html
import android.os.Handler;
public class ExecuteEveryMinuteExample {
private static final int DELAY_IN_MILLIS = 60000;
private final Handler handler;
private final Runnable task;
public ExecuteEveryMinuteExample(Handler handler, Runnable runnable) {
this.handler = handler;
this.task = new Task(runnable);
}
public void start() {
handler.postDelayed(task, DELAY_IN_MILLIS);
}
public void stop() {
handler.removeCallbacks(task);
}
private class Task implements Runnable {
private Runnable task;
private Task(Runnable runnable) {
this.task = runnable;
}
#Override
public void run() {
task.run();
start();
}
}
}
This "timer" is associated with Activity lifecycle, remember to stop it in Activity#onDestroy or better in Activity#onPause. Also checkout Timer, ScheduledThreadPoolExecutor and TimerTask they may suit your needs better.
I'm building an app that will trigger notifications at specific time-intervals during the users waking hours.
I have an alarmManager running inside of a service. The service is explicitly started via button click on the main activity and has the alarmManager executing notifications during specific time invervals. How would I go about stopping the notifications during certain hours of the day? I do not want these notification to be fired, for instance, while the user is sleeping.
My code that is currently firing notifications at user-set intervals is below (imports removed....this is long enough already):
public class FartSmackinChunks extends Service {
public Notification scheduleNotification;
public AlarmManager alarmScheduleManager;
public PendingIntent alarmScheduleIntent;
private Boolean autoUpdateBoolean = true;
private int intervalsGoneByInt = 0;
private Notification notification;
public static final int NOTIFICATION_ID = 1;
#Override
public void onCreate() {
// TODO: Actions to perform when service is created.
int icon = R.drawable.icon;
String tickerText = "INTERVAL FIRED";
long when = System.currentTimeMillis();
scheduleNotification = new Notification(icon, tickerText, when);
alarmScheduleManager = (AlarmManager)getSystemService(Context.ALARM_SERVICE);
String ALARM_ACTION;
ALARM_ACTION = ScheduleAlarmReceiver.ACTION_REFRESH_SCHEDULE_ALARM;
Intent intentToFire = new Intent(ALARM_ACTION);
alarmScheduleIntent = PendingIntent.getBroadcast(this, 0, intentToFire,
0);
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
SharedPreferences mySharedPreferences =
PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
boolean autoUpdateBoolean =
mySharedPreferences.getBoolean("storedAutoUpdateBoolean", false);
String updateFreq =
mySharedPreferences.getString("storedInitialAverageTimeInterval", "00:00:00");
SimpleDateFormat dfInterval = new SimpleDateFormat("hh:mm:ss");
Date intervalTimeAsDateObject = null;
long updateFreqMilliLong;
try {
intervalTimeAsDateObject = dfInterval.parse(updateFreq);
} catch (ParseException e) {
e.printStackTrace();
}
updateFreqMilliLong = intervalTimeAsDateObject.getTime() - 18000000;
if (autoUpdateBoolean) {
int alarmType = AlarmManager.ELAPSED_REALTIME_WAKEUP;
long timetoRefresh = SystemClock.elapsedRealtime() +
updateFreqMilliLong;
alarmScheduleManager.setInexactRepeating(alarmType,
timetoRefresh, updateFreqMilliLong, alarmScheduleIntent);
notifications();
} else alarmScheduleManager.cancel(alarmScheduleIntent);
return Service.START_NOT_STICKY;
};
private void notifications() {
**notification stuff in here***
}
#Override
public IBinder onBind(Intent intent) {
// TODO: Replace with service binding implementation.
return null;
}
#Override
public void onDestroy() {
this.alarmScheduleManager.cancel(alarmScheduleIntent);
}
}
.....and my broadcast receiver implementation here:
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
public class ScheduleAlarmReceiver extends BroadcastReceiver {
public static final String ACTION_REFRESH_SCHEDULE_ALARM
= "com.application.ACTION_REFRESH_SCHEDULE_ALARM";
#Override
public void onReceive(Context context, Intent intent) {
Intent startIntent = new Intent(context, SmokerReducerService.class);
context.startService(startIntent);
}
}
I'm having a little difficulty wrapping my brain around how this should be implemented.
I was thinking to rework this code so that the alarmManager is fired at waketime and stopped at sleepTime, all while inside the service is a Timer that fires the notification method at specific intervals? Is there a better way to go about doing this?
Any input would be appreciated. I've been trying to work this out in my head for days now.
Thanks
EDIT:
#anyone who comes across this intending to use a Timer for daily notifications:
A timer which runs inside of a service will be paused by the runtime when the device is put to sleep (ie...the user puts the phone in standby). Therefor, using a Timer to fire notifications at specific time intervals won't work correctly within a service because when Android pauses the service, it also pauses the timer, which throws off the interval.
The correct way to do this is to use AlarmManager with an array of pending intents to set alarms at specific times during the day. This ensures that even if the phone is put in standby, the notifications (or whatever you want to happen at that time) will still be executed.
I was thinking to rework this code so that the alarmManager is fired at waketime and stopped at sleepTime, all while inside the service is a Timer that fires the notification method at specific intervals? Is there a better way to go about doing this?
To my mind, forget thinking of a 'better' way, it seems the only way. Using a timer to control (enable/disable) another timer isn't so strange and makes complete sense to me.
Greetings,
I'm trying to write a clock widget that displays Epoch time and I need it to update every second. Currently I'm doing this using a Service that uses a Handler:
public class EpochService extends Service {
private static final String TAG = "EpochService";
// the time
private static long mTime;
// ui components
private static RemoteViews mViews;
private static ComponentName mComponent;
private static AppWidgetManager mManager;
// handler
private static Handler mHandler = new Handler();
#Override
public void onStart(Intent intent, int id){
Log.i(TAG, "start");
// register the receiver
IntentFilter filter = new IntentFilter();
filter.addAction(Intent.ACTION_SCREEN_OFF);
filter.addAction(Intent.ACTION_SCREEN_ON);
registerReceiver(mIntentReceiver, filter);
// set up ui
mViews = new RemoteViews(this.getPackageName(), R.layout.main);
mManager = AppWidgetManager.getInstance(this);
mComponent = new ComponentName(this, Clock.class);
// start
mHandler.removeCallbacks(mEpochTimerTask);
mHandler.postDelayed(mEpochTimerTask, 1000);
}
#Override
public void onDestroy(){
// unregister receiver to prevent memory leak
mHandler.removeCallbacks(mEpochTimerTask);
unregisterReceiver(mIntentReceiver);
}
#Override
public IBinder onBind(Intent intent) {
return null;
}
/**
* The broadcast receiver - handles screen off events to stop drawing
*/
private static BroadcastReceiver mIntentReceiver = new BroadcastReceiver(){
#Override
public void onReceive(Context context, Intent intent) {
if(intent.getAction().equals(Intent.ACTION_SCREEN_OFF)){
Log.i(TAG, "stop drawing");
mHandler.removeCallbacks(mEpochTimerTask);
}
else {
Log.i(TAG, "start drawing");
mHandler.removeCallbacks(mEpochTimerTask);
mHandler.postDelayed(mEpochTimerTask, 1000);
}
}
};
/**
* Run the Epoch Timer
*/
private static Runnable mEpochTimerTask = new Runnable(){
#Override
public void run() {
Log.i(TAG, "run");
mTime = System.currentTimeMillis() / 1000;
mViews.setTextViewText(R.id.time, Long.toString(mTime));
mManager.updateAppWidget(mComponent, mViews);
mHandler.postAtTime(mEpochTimerTask, SystemClock.uptimeMillis() + 1000);
}
};
}
The problem I'm having is that over time, my home screen appears to get noticeably laggy. I'm fairly new to Android so I'm not sure if what I'm doing is the correct approach or if there's a better way to achieve this (maybe with AsyncTask?). Is there a way to update a widget frequently without suffering from UI lag? If I need to post more code, please let me know. My widget simply starts and stops this service, and my appwidget-provder has android:updatePeriodMillis="0".
Thanks in advance for the help.
I'm trying to write a clock widget
that displays Epoch time and I need it
to update every second.
Please don't. Your users will attack you with pitchforks. Doing a remote procedure call every second will slow down the device considerably and will drain the battery.
If you want a clock on the home screen that updates every second, write a custom home screen, so it can all be done in a single process.
The problem I'm having is that over
time, my home screen appears to get
noticeably laggy.
This is to be expected.
Is there a way to update a widget
frequently without suffering from UI
lag?
No. The default update frequency is every 30 minutes, not every second.