Binding activity to a running service in android - android

I have a service S that starts at boot.
It has a contentobserver C that starts an intentservice X to do some processing.
The default activity A is started by the user.
I want to know if it's possible to bind A to the running service S without stopping it so that I can pass on a resultreceiver R to S that in turn has to be passed on to X.
I want to achieve this so that I can start X again, this time free from C, from the bound service S with R as a parcelable extra.
Via R, a progress dialog is updated in A whenever it's run.
Before trying my luck with resultreceivers, I was using notifications, the one from the support library.
But the problem was that I was building and showing them again for each iteration of a loop.
The alert sound was playing repeatedly for like 300 odd times and that was unpleasant.
Tried my luck with broadcasts but I had some bad experiences. So tossed them away.
Is there any other way around this problem?
My problem could be solved if there's a way to update the notification with building it again.
I'm using 4.1.1 build, API 16 in which setlatesteventinfo seems to be deprecated.
I am still open to go back to the idea of updating a running notification.
Or a different workaround.
Any help will be appreciated.
EDIT:
Using notifications is a way to implement this app in which there would be no need for the resultreceiver and ibinder interfaces.
I can't find the setlatesteventinfo in the API level 16. I'm trying to use the v4 support library. In my implementation, I build a new notification for every iteration of a loop. But I've not figured out a way to keep the sound alert for the first time only and not for the rest. Has anybody succeeded in properly updating a notification?

I want to know if it's possible to bind A to the running service S without stopping it
That is certainly possible. As Hoan pointed out, you need to call bindService() from your activity. This article has some example code on how to do it.
As for the rest of your question, it seems like it could be broken down into several new questions. It's really hard to comprehend and answer all at once.

The android documentation on Bound Services says:
The third parameter is a flag indicating options for the binding. It should usually be BIND_AUTO_CREATE in order to create the service if its not already alive.
Still have to confirm that the onCreate() of service S is not called again though.

Related

Starting an expo/react-native app automatically on boot - what to do in the receiver?

I've figured out how to get android to run some Java code on the systemwide BOOT_COMPLETED event. It's not clear to me what I need to do next to start my app in some form. As a novice android developer, I'm not even sure exactly if I can call into the JS side of the app at this point - is it even initialized?
Right now, on my personal device, the app crashes around this code:
Context context = getApplicationContext();
Intent myIntent = new Intent(context, BootUpHandlerService.class);
context.startService(myIntent);
...on the startService call, I get a BackgroundServiceStartNotAllowedException.
I presume this means I need to call startForegroundService instead, but the android docs say that may not be possible with Android 12.
The docs also seem to suggest I can start a WorkManager task. Given all the code I've written to use WorkManager tasks actually does so from javascript through a 3rd party library, I have no clue how to even do that from Java. All of my code to prepare for the work I want to do in the background and initialize the tasks themselves is in the frontend, running in an expo/react-native context. Sure, poor practice, but I can refactor once I understand what I need to refactor it into.
While I appreciate what they are doing here as an end user who hates the numerous services running in the background on my phone, it does seem confusing for a novice android developer.
What should I do instead? How do I run JS without the frontend to schedule WorkManager tasks? The docs seem to say I can't even do that, not even with a "notification trampoline".

Activity, Service and what kind of communication between?

I'm trying to develop an Android application consists of an Activity and a Service. The Activity launch a process on the Service of indefinite duration, which will be closed from Activity. Do not use then the subclass IntentService, but directly Service. Controlled by onStartCommand and OnDestroy.
I obviously need to pass information from the Activity to the Service: the status of the Service and some strings.
I tried to use LocalBrodcastManager, but when turning the devices or when the activity goes in state onPause, the message will lost. I tried to follow several examples, but with little success. This in particular I could not complete it because of some missing information, evidently deemed obvious, but which are not obvious to me: https://developer.android.com/training/run-background-service/report-status.html
I then tried to use Messenger via IBinder ( Example: Communication between Activity and Service using Messaging ), But the program seems a bit complex and I can not able to fit my needs.
What I need is to launch the service from my activity (possibly make binding automatically?, in case of Messenger use), the Service should signal the Activity to be active, then Service records some points via GPS LocationListener, writes it to a file and should point out, again the Activity, the data that is recording, the file size, etc.
What do you recommend to use to pass this information and can you provide to me some example?
I am actually in the midst of a tutorial explaining and comparing many different approaches to IPC in Android but since it's not ready and because you need an easy fix i'll recommend https://github.com/greenrobot/EventBus.
Also feel free to look in an old but still relevant example me and my friends made a while back here: https://github.com/RanNachmany/AndconLab
Goodluck.

How to trigger a status bar notification without starting the actual view in android?

I am new to android development and I did research on notifications using toast and status bar notification.
And I also managed to execute the code properly to make a notification work!!!
The problem is there are only methods like triggering a notification by clicking a button is available. Other wise I managed to directly call the codes within the method that is called by the button, to make it trigger automatically. But the problem is the view of the corresponding screen is showing up a tleast for a sec and then closing while this notification is triggered.
So how can i write a code that just triggers the notification without popping up the screen even for a second.
I need a result like the way the new SMS alert works...And I did a lot of research on this and all I got was about basic notification. So please help as I am new to this!!!
Using a Service would be the "right" way to do it - and if this is a professional app you are writing, then that's the way to go.
Bear in mind you still need some activities in your application, in order to trigger the service.
If you are just experimenting, then maybe what you need is a cheap hack...
Here's the cheap and nasty way to get your proof-of-concept done:
either - create a transparent Activity so that nothing is displayed when the activity code gets called.
or - create your notification from within the Activity.onCreate() method, and then call finish() at the end of that method. Your activity will never get shown to the user.
To me, it looks like you are just experimenting, and a transparent activity might get you further faster... ymmv
Legendary you need service and handler. Using service you can get data. and using handler you can modify the UI of your app.
here you can get more information on it.
http://developer.android.com/training/notify-user/display-progress.html
Working with handlers and threads in service, Thread.sleep makes the program to hang?

(Reflective) Method call delivers same old results until app is force stopped and restarted (...is there something automatically cached somehow?)

I have a strange problem and hope that someone of you has an idea what happens here.
My app structure is as follows:
I have a main service which registers a broadcast receiver and listens to intents like screen on/off etc. So this service runs indefinitely.
When such an intent is received, I start another service which does the action
Inside this action service I launch an AsyncTask to fetch battery related stats via reflection. After the service is done, it calls stopSelf().
So everything works as expected, except that when the battery related infos have been fetched one time, each subsequent call of the AsyncTask/Reflection methods deliver exactly the same result which has been delivered before.
The battery stats have of course been updated in the meantime, but I do not get the new updated numbers, but always the stats from the first method call.
That is until I go to settings and force stop and restart my app, then I get updated battery statistics again, at least one time, because after that I'm stuck with these numbers again.
So my question:
Could it be that the results of the reflection call are automatically cached somewhere and that each subsequent call doesn't really fetch the new data but just delivers some cached results? What else could be the problem?
I'm thankful for any ideas, I you need some code lemme know :)
Ok, I've found a fix to this :))
The library of Better Battery Stats uses the singleton pattern for a needed class.
It also includes an invalidate() function, which sets the singleton instance to null, so that at the next getInstance() it gets reinitialized.
I'm using now invalidate after each statisitics fetch, and now I get the updated statistics on every call. Although I am still not sure why the Singleton pattern seems to be the root of this issue, it should also work with having one initialized singleton instance...
Well, one does not simply have to understand everything ;-)

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.

Categories

Resources