Implementing a Sticky Service in android/flutter - android

I need to add a native sticky background service in a flutter application, in order to achieve 2 things:
Starting at boot time and running in background indefinitely
Exchange data with the main Dart activity, in a message passing fashion
However, I cannot find any kind of useful documentation. It seems that for now, you have to choose to go completely native or giving up using low level features and focus only on the UI (until someone pulls a specific plugin out of the hat).
Thus, my question is the following: what is the easiest way to achieve this sort of integration, starting with a basic flutter project ?
Thank you

Make a Sticky Service using native Android service.
The easiest way to exchange data with the main Dart activity is to use deep links or intents.
Note: if you explain more why do you need that, I think I may be able to give you a better solution.

While you can register a BroadcastReceiver to be activated at BOOT your idea of having a service "running in background indefinitely" is highly discouraged in recent version of Android.
Therefore what can you do is have a Broadcast receiver registered in Manifest that will be activate when BOOT completes (See https://developer.android.com/guide/components/broadcasts for a sample) and from here you can use the available API to schedule work. Check out this link to see what from available API best suite you needs.
While there are more complicated solutions you will find that simply sending Intents between components will do the job.

You can use the method channel
Docs : https://docs.flutter.dev/development/platform-integration/platform-channels?tab=type-mappings-swift-tab

Related

How to run a singleton (shared) service in a library for multiple applications?

I've written a library starting a service in the background. It runs perfectly in all applications.
In order to reduce the RAM usage, I want to avoid running multiple services for different applications. Actually, it's pretty enough to use only one service to get things done.
Firstly, I've written an AIDL file to make IPC between applications/libraries. Defined the service as exported/enabled with signature permission. Since all applications are the exactly the same service, it's not possible to check if any one is up or down. While binding the service to check the condition of the service, it always creates and destroys the own service because of the nature of BIND_AUTO_CREATE flag. That's why not possible to get any kind of info from the exported service if it's really up and running.
Then, I tried to define a Content Provider to the manifest of the library. My aim is to share the service info through it. It's really good mechanism to communicate between exported service and application main process. But it is not usable for multiple instances. Because applications which gets the content provider info from the library use the same authority and so it's not possible to install the second one. It gives an DUPLICATE_PROVIDER_AUTHORITY error.
What's your suggestion about the issue? Is there any option to create a master/slave mechanism? Is it possible to make the service singleton for the application uses the library project?
P.S: Tried broadcast and shared preferences techniques. But they're not effective to listen the callback from the exported service.
You need to put the Service in an APK of its own. It needs to have its own unique package name (in the manifest) which is different from the package names of any of the applications that use it. This is how you make the Service behave as a singleton. Now you can use AIDL and bind to the Service in order to have two-way communication.
Note that in more recent versions of Android, it has become necessary to start a Service using an explicit Intent (ie: the Component must be explicitly specified, you can't use just an ACTION).
Alternative 1:
If the use case permits I think you should not implement the Service.
Make your client implement a service a call your library code. This
is how MediaPlayer and other default android APIs work.
Alternative 2:
Host the service in a separate app..and download the app when the
first call is made from any client. From here onwards there will be
single service handling all the client request.This is how some APIs like adobe
air/ MDM solutions from Airwatch works.
There is no good way you can control a component which is running in other app,unless using broadcast receivers and all.

Differences between Android and iOS regarding Intents and background operations

for my current project I try to figure out the differences between Android and iOS. I only have knowledge in Android and absolutely no idea about iOS.
What I want to know is:
Is there something similar like Intents for iOS? Especially those which indicate changes in Wifi / BT connection like android.bluetooth.device.action.ACL_CONNECTED or android.net.wifi.STATE_CHANGE? Or is there another method to find out about connection changes even if the app is not running / in background mode?
As I understand from
IOS background service (like in Android) enable all time & https://developer.apple.com/library/ios/documentation/iphone/conceptual/iphoneosprogrammingguide/ManagingYourApplicationsFlow/ManagingYourApplicationsFlow.html, having a background service in iOS is only allowed for specific types of apps. So an app which asks for sensor values (like accelerator) on regular basis is not allowed - is this correct?
I am very thankful for answers and also further literature regarding these quesiton!
You can use an implementation of Reachability to get the notifications about Wifi connectivity, but keep in mind these won't wake up your app.
From Apple
From Cocoapods
You can use Core Bluetooth to look for connectivity events. Again these won't wake up your app. I believe you can setup a delegate to a CBCentralManager to find out about that. Check out the docs here.
However, you are correct in saying that you still need to solve the issue of background execution to keep your app awake. For that you need features that actually make background execution useful to a user or Apple won't approve your app. Here are some of your options.
If your app has actual bluetooth features you can use one of those modes (bluetooth-central and bluetooth-peripheral).
If you have a feature that warrants background audio you can use this
If you have a feature that warrants background location you can use CLLocationManager startUpdatingLocation (but this would eat up some serious battery)
You might also be able to set up a system that spams silent remote notifications and then use the remote-notification background mode. This is meant for downloading content
Also keep in mind that a user can basically disable all of these things on you at any time.
Good luck!
Im not sure if this will answer your question directly but it may be helpful. I know in Android that you can you an Intent to switch Activities. Well in iOS in order to switch to another UIViewController (iOS equivalent of activity) you would perform a segue. In prepareForSegue method you can handle what you want to do in the next UIViewController, such as passing variables etc.
You can use Background Fetch in iOS7 you can perform services while the app is asleep/in the background. This wakes the app at regular intervals in the background to perform a task, like refreshing data etc. You may be able to record the accelerometer values here. http://www.appcoda.com/ios7-background-fetch-programming/ has a good tutorial on this.
I hope this is somewhat helpful.

Android StartActivtyForResult() from a Service

First I'm sorry for my english that is not so good :).
I am facing a problem to develop my app.
That is a general architecture scheme of my solution.
http://i.stack.imgur.com/ooTmE.png
To be quick, the app has to decode code bare but with two possible ways:
using exernal device (The constructor provides a sdk containing an android Service to communicate with the device),
use the camera of the mobile using the library Zxing which is possible to manage it with intent.
The goal of my own service is to manage some business code and make transparent the choice of the tool for the user.
I believed that was a good solution but I wanted to implement it and I had different problems.
My main trouble is that I cannot execute StartActivityForResult inside the service.
Do somebody have any suggestions for my problem whether a change in the architecture or a solution for the main problem?
#Laurent' : You have totaly right my service acts as an API adapter.
I will try to make the expected behaviour more clear.
I have an app that needs to recognize (real) objects which have QR codes on their top. This recognition action will be done several times by the user during the life of the app.
The user chooses to launch the recognition by clicking on a button (or otherwise but he knows that the recogntion will start). So no notification is needed.
The thing is he doesn't choose the way to do the recogniton. It is why, as you said, I implement an adapter.
The adapter chooses between :
Camera mobile or external device. The first is an activity coming from the Zxing library. The second one is a service that manages the external device. This service provides an interface to get back result.
One more thing, I need that my whole implementation (adapter and co) can be re-used by other apps that will also need to do recognition.
So my thought was to implement a service as an adapter to answer my two conditions (make transparent the choice for the user - and make the recognition available for other apps).
I hope you understand my problematic.
Given your architecture, your MyOwnService must act as an API adapter : it should provide a unified scanning API and address each external service specificities transparently.
Your expected behaviour is not clear enough to provide a solution that suits your needs but here are a few remarks that can be of some help.
Passive scanning:
Even if there are some workarounds : no activity should be launched from a service (not directly). Never. Bad. Services are background stuff, the most they will be permitted is to hint users with Notifications (this is point 2 of Justin excellent answer).
As a consequence there's nothing as a 'popup Activities' (and that's good!). If you need to continuously scan for barcodes, even when your activity is not run, then the only way to warn users is by using status bar notification.
Active scanning:
Inside your own activity you can bind to your wrapper service and make it start scanning for codebars. When it finds one it has to message your activity. Your Activity message handler has complete access to the UI to inform the user of your findings.
You selected Active Scanning in your edit, your problem is therefore to find a way for your service to actively notify your main application (the one that started the active scanning) that a new item has been scanned successfully.
You do NOT do this by starting a new activity (remember: this is bad) but you can bind to a service and/or use Messages between the wrapper service and the application.
I advice you take the time to read (and more time to comprehend) this android developer article on BoundServices and especially the part about Messengers.
A full example of Two Way Messaging between a Service and an Activity can be found in the following android examples : Service & Activity
Warning: designing robust, full blown AIDL-based services is a tough job.
Two ways you could solve this problem.
1) Have MyOwnService do a callback into MainActivity telling it to launch your ScanActivity.
- This is a better approach if MyOwnService's task is only going to be running while MainActivity is running and if the user would expect the ScanActivity to come up automatically.
2) Have MyOwnService create a notification that will let the user access the ScanActivity.
- This is a better approach if MyOwnService's task might be running longer than the life span of MainActivity. That way, you can let the user know, unobstrusively, that they might want to access the ScanActivity.
So finally I changed my architecture.
I make the choice to delete myOwnService and to create an intermediate activity that will be my API Adaptater.
This activity will have a dialog.theme to look like a dialog box indicating that a recognition is under execution.
If the recognition uses the external device this activity will stay at the foreground otherwise the camera activity will start (Being managed by the intermediate activity).
Thank to that I can manage my result from the intermediate activity and do not have an android strange architecture, keeping my business code for the recognition outside my main app.
Service was not the good choice.
Thanks a lot for you help and your time.

How to create service in Android and consume it?

I am very new to the Android platform. Now in my app I want to create service and so please give me some info that how to create a service and consume it in my app. And how to start the service when the OS starts up?
All the information that should be necessary, including examples on how to create and consume services, is available directly from the Android documentation here.
It is doubtful that any answer could provide more insight into creating and consuming Services then that link.

Android service-to-activity communication performance

I can find several examples of how to build a service, but I'm having a difficult time finding a working example of how to send messages between an Activity and a Service. From what I can find, I think my options are to use Intents, AIDL, or to use the service object itself as per this question.
In my case, my activity is the only activity that will ever access the service, so a local service will do. When the activity is open, I want to see some status messages from the service, which will be coming in at up to 20 Hz. Are there any limitations on how many messages per second those communications methods will support? Basically, which method is going to be best for my situation?
Thanks.
Since your Actvity and Service are a part of the same app, then no need to use AIDL. You may simply use your Service as a local one.
The limitation is only affected by the performance of your device. There is no cap on requests per second.
Usually there is a context switch involved, that uses quite a lot of cpu (compared to other parts of the transmission), but since you use a local service you don't suffer from that. In any case, 20Hz is not a problem.
The best solution for you would be to use AIDL, and set up a callback that the service can call to report its status.
There is good example of how this is done in the APIDemos.

Categories

Resources