Flutter-foreground-task: how to change the callback interval - android

I'm using flutter_foreground_task, and I try to change the callback interval.
I tried several things, but no one works:
In _receivePort's listening function that handles messages from onEvent::_sendPort?.send(message):
I tried to _closeReceivePort(), then _stopForegroundTask(), then _initForegroundTask with a different interval, and finally _startForegroundTask
The same without _closeReceivePort
I tried to only _initForegroundTask again with another interval and _startForegroundTask (so that it restarts)
I also tried 1, 2 and 3 in a Timer callbcak function called after the _receivePort listening function has finished (mutex protection)
For 3: the foreground task still work, but at the same interval.
For 1: I don't really understand, it seems the foreground task still runs, but my _receivePort listening function is not called anymore.
What would you advise to do change the OnEvent interval ?
Thanks for help.

Related

(Android) How to run multiple instances of a service

anyone knows how i can make multiple instances of same service class work seperately, am working on a taxi meter app where i have a "Counter" service which will calculate for me the distance and add locations to database for each client, in my mainactivity i made three instance of the same service and started everyone seperately but it doesn't seem to work as expected(only i made a toast in every service start action but it seem to appear for just one client).
i know i have read in several treads that it's no possible to make multiple instance of services work at the same time but this is the only way i could do to make a taxi meter that supports multi clients at the same thing.
As rightly pointed out, we cannot have multiple instances of service. A service can only have one instance. Each subsequent call to startService, the method onStartCommand is called again.
But,suppose the onStartCommand instantiates a Timer object to repeat a task every 30 secs. Each subsequent call to startService, a new instance of object Timer is created...!
Now concider following use case:
timer is set up to log "Hello World" after every 30 sec
1st startService command is issued at 16:00:00
for next 2 mins, you should see 5 "Hello World" printed at
-16:00:00
-16:00:30
-16:01:00
-16:01:30
-16:02:00
Now 2nd startService command is issued at 16:02:10, for next 2 mins, you should see "Hello World" printed as follows:
-16:02:10 (2nd call)
-16:02:30 (1st call)
-16:02:40 (2nd call)
-16:03:00 (1st call)
-16:03:10 (...)
-16:03:30
-16:03:40
-16:04:00
So after 2nd call, two instances of the Timer class exist. But only one Service instance.

Take action for every two minutes of inactivity (no user interaction)

I am trying to write to a file whenever the user has not interacted with the application for 2 minutes. Currently am having base activity in which I have overriden the onUserInteraction method. In this method the float time variable is reset and onResume I subtract the time with the current time to check if two minutes have passed. This works fine but sometimes acts crazy. Second approach was using the postDelayed method of the Handler and start a thread. This works perfectly but does not include the case when the app goes to background or the device goes to sleep.Is there a way to cover all these cases. ahve researched a lot. Also came across Wakeful Intent service but read that it is expensive.
Is there a way to cover all these cases.
Yes. ... and it is expensive. Waking the phone up, every 2 minutes is going to drain the battery like crazy.
That said, the answer to your question is that you need to use the AlarmManager, probably in concert with either the WakefulIntentService or the WakefulBroadcastReceiver. Create a PendingIntent and schedule it for delivery every 2 minutes.
I don't know a way of tracking inactivity but there is a way to track user activity. You can catch a callback called onUserInteraction() in your activities that is called every time the user does any interaction with the application. I'd suggest doing something like this:
#Override
public void onUserInteraction(){
MyTimerClass.getInstance().resetTimer();
}
If your app contains several activities, why not put this method in an abstract super class (extending Activity) and then have all you activities extending it.

Using RoboSpice support for offline background task {combining countdowntimer with robospice}

I am performing an activity that takes long time(offline). I am sending and receiving(reading) sms in my app for this i am using a count down timer class which has a listener onTick() and onFinish(). in the onTick() listener i am checking if there is any new message and if there is any new message from the expected message it will stop the timer and display it on my screen. Everything seems to be okay. the problem arises when i leave and re-enter the app or change the orientation.
While working with network calls robospice takes care of all these activity transition problems. So I want to solve the above issue using robospice. I have seen the robospice offline example in the github. But there LoadDataFromNetwork() doesn't handle any listeners. It just performs a prolonged task.
If I had correlated the offline example with my problem then what I have to do is just call the spiceManager.execute() method inside my onTick() listener and the loadDataFromNetwork() will just read the message from my inbox and check if there is any message of desired kind and return that to the requestListeners. But that's not what I want. I want robospice to moderate the complete timer class.
I couldn't get how to fire robospice requestlisteners only when I read the specific required message as the reading activity is performed in timer ontick() Listener.
Is it actually possible with robospice to do like this ?? If not please give me a solution to deal with the actual problem mentioned in the first paragraph.
If you're switching to using RoboSpice then there doesn't seem to be any need for a CountDownTimer, you could implement your own polling in loadDataFromNetwork. This will be executed in a worker thread in a Service so blocking this thread will not affect your UI.
So a simple for loop with sleeps should get the same result.
One thing to be wary of is the number of threads your SpiceService is configured to work with. If this is a very long running task and you're using the default single worker thread then I believe you'll block subsequent SpiceRequests. If you haven't already subclassed the SpiceService class you can do so and override the getThreadCount method to return an int greater than 1.

Is it necessary to stop timers on activity/view/fragment stop?

Is it necessary to stop manually timed tasks (with Handler) when the activity stops / view is detached / etc. Or will the system just remove them?
I have, for example, a Runnable which I use to update a TextView each second. When the user leaves the activity, do I have to call removeCallbacks(task)?
I tried both (remove and not) and they work, but I don't know if the timer keeps running unnecessarily or this can lead to exceptions under certain circumstances.
Thanks in advance.
yes it has to be handled or cancelled., while you are using the Timer Task it should be cancelled before the respective task or activity or app closes., otherwise it will process its content even after the instance closed too....

Take action when system clock changes minute?

My Android app has a TextView telling the user the data age ("13 minute ago"). I currently update this every second using a Runnable to catch when the minute changes with a notifyDataSetChanged() to my adapter. But this is causing garbage collection every second...
Is there another method to trigger a TextView update (or take general action) when the system clock changes minute without checking every second for such a change?
Since you already set up a Runnable and callback, use modulo to calculate when the next update should happen:
handler.postDelayed(runnable,
DateUtils.MINUTE_IN_MILLIS - System.currentTimeMillis % DateUtils.MINUTE_IN_MILLIS);
This will run the callback when the next minute occurs whether it is 59, 30, or 1 second(s) away. As a note, if the Runnable only updates one TextView don;t forget to switch to DateUtils.HOUR_IN_MILLIS when the event is an hour old, no sense updating "1 hour ago" every minute.
You may find methods like DateUtils.getRelativeTimeSpanString() useful for creating the "x minutes ago" strings.
While Sam's answer is perfectly good, I'm just adding this because it fits the question so perfectly. There is actually a broadcast sent by the system every minute when the clock changes. It is Intent.ACTION_TIME_TICK and you can only receive it using a BroadCastReceiver that was registered manually in your code, not through the manifest. See the documentation here.
User the Timer object with fixed period.
The methods take a TimerTask object.
See the Timer documentation from google
REMEMEBER to cancel the timer when stopping the activity
There is prettier solution for this besides Sam's great answer.
Make use of http://developer.android.com/reference/android/text/format/DateUtils.html to find the time span and register for android.intent.action.TIME_TICK where you'll be updating the time in the listview.
Here is another same question and answer

Categories

Resources