I am trying to execute some code (a function) whenever I receive a minutely repeated local notification on android to mimic background tasks. (I want to track our employees when the app is in background, but without using background task packages)
So, simply I am doing a trick, and I don't know whether that works or not, but what I am trying to do is, I want to periodically send local notifications to myself, using **flutter_local_notifications **package, and I want to know if there is any way that I can execute some code when I receive the notification. (the local notification act as a background task and I want to do something when I get this local notification, to mimic using background tasks.)
I have tried a lot of packages for background tasks.
Including alarm_manager_plus, background_location, and work_manager package.
the best one was workmanager package, but the frequency of repeating the background task was 15 minutes, which is far more than I want.
So, this trick came to my mind, if it works.
So, I thought if sending the scheduled local notifications for every minute and executing some code when I receive them works, then I will go with this approach.
So, I am asking, is there any way to execute some code when receiving local notification?
or is there a better way of doing that?
Any Help is appreciated, thanks.
Related
Hello flutter/mobile developers,
I have a particular problem at hand and I need some advice. I need to create an app that will do a certain task at specific times of the day. The times will change daily, and it will get the updated times via a REST call at midnight (or at off peak hours). The task must at the scheduled time no matter what, even after device restart, etc. I have looked into this extensively and I'm coming away with the feeling that Flutter does not handle a scheduled task well, especially in iOS which can terminate an app for whatever reason.
The options I have looked into are:
workmanager (https://pub.dev/packages/workmanager/changelog): This seems the most promising, if not for the minimum frequency of 15 minutes, which is not enough for me. I would need to check every minute if it is time to do the task. Is there a way around this limitation?
Native solution. I have very little-to-no experience with native iOS and Android coding so I would not prefer this solution. But through some research I have seen some examples where a task can be scheduled through this approach.
Server side notification. This seems like a good solution on the surface, and I need advice on this. The calculation whether it is time to run the task will happen server-side, and a notification (through Firebase, for example) can be sent to the device, which will trigger the task to be run. Is this even feasible, will the device actually run code when it gets the notification?
So these are my options. Which doe you think is the most doable? If someone with more mobile experience than me can help me out I would appreciate it, maybe there is a better solution that the three I have proposed. Thank you.
The times will change daily, and it will get the updated times via a REST call at midnight (or at off peak hours).
This smells like bad architecture. Why?
You are DDOS'ing your update server at midnight (if you have many users in the same timezone). You can stagger your HTTP requests by a few seconds to fix this, but this is a band-aid, not a long term solution.
because you are inverting the dependency: It sounds like timing is the responsibility of the server (hence your clients call it to ask for the latest time). Your clients should not be the ones asking the server for updates, because now your client has 2 jobs: Schedule the schedule updates and also schedule the scheduled task for the user. Making clients ask the server is the wrong direction. You should send messages from the server to update the schedule on the device.
Even if you do poll the server for schedule updates, you should make the mobile app schedule notifications/ alarm at the time you want. Using silent notifications is a known workaround the limitations of background scheduling on iOS. On Android, WorkManager is not the right library, you should use AlarmManager.
Here is how another StackOverflow thought about using local notifications to solve the problem: They used flutter_local_notifications
Answering the bullet points
On Android, don't use WorkManager, use AlarmManager instead, or even better, schedule notifications. Having said there are some manufacturer specific quirks on Android, see the flutter_local_notifications docs:
Consequently, scheduled notifications may not work when the application is in the background on certain devices (e.g. by Xiaomi, Huawei). If you experience problems like this then this would be the reason why. As it's a restriction imposed by the OS, this is not something that can be resolved by the plugin.
Its not necessary to use Native code, notifications is a standard feature.
You can keep the polling architecture for now since its simpler (but dirtier). Even if you would so the server side architecture, I would send messages from server to client to only update the client side schedule, not to trigger work/ user alerts, otherwise you are making your application dependent on the internet when it doesn't sound like the internet is required (unlike social media notifications). This would lead to bad user experience for badly connected devices.
You can send Data Notifications through Firebase, and handle them with the onBackgroundMessage callback. See here: https://firebase.flutter.dev/docs/messaging/usage#background-messages
Future<void> _firebaseMessagingBackgroundHandler(RemoteMessage message) async {
// If you're going to use other Firebase services in the background, such as Firestore,
// make sure you call `initializeApp` before using other Firebase services.
await Firebase.initializeApp();
print("Handling a background message: ${message.messageId}");
}
void main() {
FirebaseMessaging.onBackgroundMessage(_firebaseMessagingBackgroundHandler);
runApp(MyApp());
}
From the documentation (Android/Apple):
It must not be an anonymous function.
It must be a top-level function (e.g. not a class method which requires initialization).
I have gone through many posts.
Its bit confusing to understand that does ionic 2 app send local-notification even if my-app-is-killed-by-user or not ?
I have below scenario.
Assuming that app-is-killed-by-user
Can we run the app in background (like after 24 hours check if some
conditions are true by manipulating local/cloud storage) then send local notification ?
I am new to ionic 2. So can anyone let me know that above scenario is possible ?
If not possible then let me know that can we manipulate (get and analyse) local-storage via push notification server (assuming that app-is-killed-by-user) ?
Both are possible. I'll tell you how i would do them and not share code (it can be long), i'll give you the steps and you can figure it out.
For the first scenario you'll need LocalNotification plugin, LocalStorage, Platform import from 'ionic-angular' and MomentJS(not required, but highly recommended).
You'll need to create a service, at least it's good so you don't need to put everything in your app.components.
You can use 3 of the Platform methods to verify and set the LocalNotification, they're .pause, .resume and .ready.
Pause will check if the user has left the app, but it's still running on background.
Resume will check if the user has come back to the app, but'll not trigger if the app was killed.
Ready will trigger when platform's ready, you'll use this to check if the app was killed and is starting for "the first time".
You'll need MomentJS to manipulate time, since it's easier to add days/hours to your current datetime.
LocalNotification accepts both ISO string and UNIX timestamp to schedule a notification.
Inside your created service you'll have methods to schedule and cancel a LocalNotification, check the plugin wiki for those.
On the pause method you'll call the schedule method and schedule a localNotification having Moment add 1 day to your current time: Moment().add(1, 'day').unix() and use the result in the 'at' of your schedule.
This'll return a promise with the data of your notification and it's id, save this id in your localStorage like this.storage.set('Daily', ReturnedID);
When the app is ready or resume you'll cancel the notification.
So basically that's it, when going off you save a notification, when going in you cancel it.
The second scenario is a little bit harder and you'll need a back-end for this since you'll need to keep checking the time that user has gone off the app. You'll need only MomentJS, the Platform import, you push service plugin and a way to connect to your database (via Http or plugin, if it's a service like Firebase).
The steps are the same for the first scenario, the new service, the platform calling this service methods, but now will add some methods for you push plugin, so when you receive a push you can show and manipulate data.
Most push services (and localNotification) have a Data attribute where you can share some data with the user, in your case it'll be the data you want to safe in the localStorage.
You'll need a token of that user so you can send a push to him, see your push docs to see how you can get that token and save it to the user database register/node.
When the user leave the app you'll store in your database the time you want the user to receive that push (i'm assuming you want to do the same as the first scenario, but in a different way).
When the user come back to the app, you'll detele that time register.
The tricky part: you'll need your back-end to go through every user register and get the time they need to receive the push, so if the time is < the current time you'll send the push and delete that register.
In the app when the user receive the push a function'll save the data to localStorage, manipulate, ready or everything you want.
Sorry i can't share some code, but if you need furter explanation or ideas just ask.
Hope this helps :D
i am currently trying to get code running as a background service.
what this code does is:
send request to server with current location of the user
receive response
parse response
save into model (singleton)
and this is set to happen in a 30 sec interval again and again.
now if my app stays in the background for too long, it will get disposed by the device and that code will not be executed anymore. what would be the right kind of background service for this usecase?
one of my main concernes is that i save my data in a singleton. but if my app is disposed this singleton will probably not exist anymore.
intent service doesnt make sense imho because it runs a one time tasks and has to be restarted from an app that might already be disposed at that point.
using the alarm manager would mean that i will have to save everything out of the app (sqllite for example) and then retrieve that data when the activity is started again which sounds rather complicated.
can someone please help me out here?
thanks in advance!
You sir needs the service of GCM
https://developers.google.com/cloud-messaging/
Thats exactly what you need for your desire ;)
But it's not less complicated as sticking to background services.
Also you can do a Hack: having two services watching your service to keep on running and itself...I swear when the User doesn't stop your app manually in the menu the System won't be able to stop them itself. Foolproof.
I'm very new to Android, this is my first app. I'm just looking for someone to point me in the right direction.
I am building an app that will query a server over tcp/ip every minute. I would like to show the status of this server (up/down) at the top of every activity/screen.
My questions are:
1) What should I use to continuously ping a server in the background across multiple activities? For instance, is there a way to spawn a thread from one activity in such a way that it will continue even if the user goes to a different screen?
2) How can I allow this thread to update a status label on whatever screen the user happens to be viewing?
Use services. Please get familiar with documentation first.
You can use service binding or local broadcast messaging to notify your current/front activity about changes from your service
I have developed a Web application using Phonegap which reads cross domain Rss feeds using Google-Feed API and sends system notification to the user if a new feed is available.
I have used this Phonegap System Notification Plugin for creating push notifications.
This is the SystemNotificaton.java that comes with the plugin.
This is the SystemNotification.js file that comes with the plugin, which has all the methods that can be used in your javascript file.
This is my notification.js javascript file were I have created two functions to read two separate Rss feed urls and I have used setIntervals to call the function every 1 min.I have also called navigator.systemNotification.onBackground(); method inside the same function so that when my app is not active this function keeps running in the background and displays the notification to the user if a new feed comes up.
The problem is I get notifications once the application starts then when i close the application I get a couple of more, after one or two days the notification stops coming. I know since I am using google-feed api it is not real time but still even after two days it does not work . It seems like the onbackground method it not working. Could anyone point out what mistake I am doing.
I don't know much about Phonegap, but I know a fair bit about Android development, and it sounds to me like the notifications aren't your problem. (Incidentally, these are just notifications, not "Push" notifications. Those are another beast altogether.)
I suspect that your application is simply stopping, and you don't have anything set to start it back up. The Android OS will kill any background application for a variety of reasons. If implemented as a service, the OS is supposed to restart it at some point, but that's not entirely reliable.
Basically, you need to set an alarm to babysit your service and make sure it stays alive. If this is possible in PhoneGap, I recommend getting rid of the setInterval altogether, and just using the alarm to wake your app up and trigger the RSS polling action. The benefit of this is that it will still work when the device goes to sleep.
Doing a bit of quick searching seems to indicate that PhoneGap does not have access to the AlarmManager. It could be done with a plugin, maybe, but PhoneGap doesn't strike me as a good framework for background services in general. A truly native app is going to be far better behaved in this context.