I currently have a service running in my Android application that makes a wifi scan at a set interval and returns the results.
I was then passing the data using an aidl interface and to do this I had to bind the service to my Activity I was passing the data to.
However the design has changed and I now need to be able to send the data that the Service returns to just a normal class that does not extend an Activity.
So I want to pass the data from the service just to another class that doesn't extend Activity and then be able to use that data in a method of that class.
So I was wondering how I would go about this if it is possible?
EDIT:
Actually is this even the correct way to implement the following:
I have an application that will have no User Interface (not exactly none altogether but VERY minimal).
I want it to scan for Wifi access points at regular intervals, check the connected state of Wifi and check the connected level of the currently connected access point.
It also listens for the OUT_GOING_CALL broadcast and traps the call if connected to wifi and then pops up a dialog that tells the user the call has been blocked and offers the user cheaper options than Gsm if there are any.
I currently use the Broadcasts to get the Scan Results and to get changes in the connected Level of the wifi connection also.
However I had thought that moving these to a service of my own would be a good idea, however would I be better leaving them as Broadcast Recievers in Non Activtiy and Non Service classes and just make the main Engine of the application a service that turns on and off these broadcasts from there Classes (Objects) ?
Related
I'm developing an app that communicates with an embedded device via BLE (Bluetooth Low Energy). The app allows the user to send commands via an activity. Meanwhile the app needs to send location data in the background. The location data must be sent constantly, even if the activity is closed and opened multiple times over the day.
I cannot separate the continues location updates from the command requests. Because all BLE transmissions must be synchronized by one queue to prevent simultaneous transmissions which would cause package loss.
After reading the official guide (https://developer.android.com/guide/components/services#Basics), my first idea was to use a foreground service because the service must not be terminated when the activity is closed. That works fine for sending the location data. However, for sending the commands I have to communicate with the service after it has been started. I read that it's not recommended to use both startService() and bindService() but instead to decide for one way. As far as I understood a bound service can be destroyed when the referencing context (the activity in my case) is destroyed. So I guess binding to the service is not an option for me.
Another approach to talk to a started service is to send commands using broadcasts and receiving them in the service (sending commands from Activity to Service in android).
But I think there must be a better solution that I miss. What came to my mind is simply calling startService() every time I want to send a Bluetooth command. I guess that would work. But is it good practice? Effectively, I would call startService() dozens of times during a typical use case before calling stopService().
Oh wow... I read through the whole guide but overlooked this sentence in the method documentation:
startService()
Every call to this method will result in a corresponding call to the target service's onStartCommand(Intent, int, int) method, with the intent given here. This provides a convenient way to submit jobs to a service without having to bind and call on to its interface.
https://developer.android.com/reference/android/content/Context#startService(android.content.Intent)
Hope it helps in case that someone stumbles across it..
You don't have to bind the service to anything. It's enough to start it and then make sure you call startForeground on it. That will keep your process running without being killed by the system. You don't have to place your BLE code in the service class but can have it wherever you want.
I am developing an application where I am streaming live sensor data via bluetooth, then have several Activities that can work on this live stream of data to display it in different ways (e.g. statistics, histogram, trend charts etc.)
I need to maintain the bluetooth link across Activities, and I also need to maintain receiving the data into a buffer across Activities (e.g. you can be viewing the data in the trend chart activity, then hop across into a statistics Activity without it clearing the data.)
How I've done it is to extend application and have it hold a custom class which holds all the relevant Bluetooth objects (bluetooth device, IOstreams.) Then when the user initiates the connection through the front page Activity, the bluetooth connection is opened and a service is started that reads the data from the input stream, converts it and stores it into a arraylist. Then any of the display Activities work on this ArrayList.
That works great. But I can't work out how to close the bluetooth connection and service when the application is either killed, or placed into the background. As it's important to ensure the bluetooth connection is closed properly, or else it can be difficult to re-establish a connection.
About the best I've come up with so far is to implement a task transition timer as described in this post https://stackoverflow.com/a/15573121/3015368, and have it close the connection and service if the timer completes.
I was hoping there might be a better way of doing this?
you can stop services by making an intent which points to ur service class and call this function if your service is running it kills it if its not running then it wont do anything
stopService(/* intent name*/)
u can do that in onPause() method which is automatically called when ur app goes to the background
then if you need to restart the service u can call onResume() which is also automatically called when ur app gains focus
hence: u need to override onPause() and onResume() methods.
I have two problems:
I know that for connection activity and remote-service I have to use AIDL.
I tried this and it's work but I can find only one way connections example. In simple words - reading something from service (by activity). But I need solve for sending some data to activity (by or from service). It's so important because the service have to send some information to activity immediatly after some its events (obtain data from the net).
Is it way to bring to front again closed application (activity) from the remote service?
Any suggestions would be greatly appreciated.
Regards
Artik
It's so important because the service have to send some information to activity immediatly after some its events (obtain data from the net).
You can use AIDL for two-way communication. You would need to expose not only the service interface, but a callback interface, via AIDL, with the client having the .Stub of the callback and supplying an instance of it in a parameter to a method on the service interface. This gets a bit complex -- here are a pair of sample apps from my book that demonstrate the technique:
Service
Client
Is it way to bring to front again closed application (activity) from the remote service?
Your service can call startActivity(), but generally that is a bad idea. The user may be in the middle of doing something else, when all of a sudden your activity pops into the foreground. Occasionally, the user may deem your activity to be more important, but not always. Consider using a Notification instead, to let the user know that there is something in your app that needs the user's attention.
First, create a private resultreceiver variable in your service. Then create a method to set this resultreceiver via a connected activity. Then use AIDL to pass on a resultreceiver to the running service from the activity via the method you just made. Then in the service use resultreceiver.send if the resultreceiver is not null.
A few examples to get you started
http://lalit3686.blogspot.com/2012/06/how-to-update-activity-from-service.html?m=1
http://chrisrisner.com/31-Days-of-Android--Day-28–Intents-Part-3--Service-Intents
I'm writing a Bluetooth remote control application to control my Bluetooth enabled robot, but I have a hard time understanding the workflow of an Android application. I know what I want, but it's not very easy to do. Other responses haven't been satisfactory.
Here's a rough application layout I want:
If you have a better idea of how to do this thing I'd be happy to consider.
Mainly my problem is accessing the connection thread/service (whatever the name is) from the connect method of the main activity and from the control activity, how do I pass the reference? I know that the main activity can disappear when in a sub-activity of the application, so I'd have to pass the reference by getExtra() probably, but it only takes a String variable...
One method you might like to consider is using a Bound Service. This can be made to return an IBinder interface, allowing access to the service's public methods. You can make any of your activities bind to the service and thus pass/retrieve data to/from the service.
If you need the service to communicate with the activities immediately (e.g for lost connection), then the service could use sendBroadcast to inform activities which had registered a BroadcastReceiver to listen for the intent sent in the broadcast.
I have a class that starts a Bluetooth reading thread and another that receives/decodes what's read from that port and produces some output logs depending on the information read.
In my design, those 2 components form a service for my application (multiple activities) from where I would like to start/stop getting the output logs on a continuous basis (typical frequency of 2-3 logs per second).
My questions:
1) Should I derive from Service or IntentService. The doc says about IntentService: "This is the best option if you don't require that your service handle multiple requests simultaneously". This may be my case since the main activity will start/stop the service...
2) What would be the appropriate way to catch the service events? Does the BroadcastReceiver is appropriate for this type of communication?
3) I may need to occasionally send some stuff to the Bluetooth port. So, I'll have to pass information from my application to the service. Does the PendingIntent should be used for that?
Thank you!
Should I derive from Service or IntentService
IntentService is designed for discrete tasks, not stuff that would run indefinitely until the user manually stops it. I would use Service.
What would be the appropriate way to catch the service events? Does the BroadcastReceiver is appropriate for this type of communication?
That is certainly one approach. You might use the LocalBroadcastManager from the Android Support package to reduce overhead and keep everything private to your app. Have your activities register a receiver in onResume() and remove it in onPause(). The foreground activity will then be notified of events.
I may need to occasionally send some stuff to the Bluetooth port. So, I'll have to pass information from my application to the service. Does the PendingIntent should be used for that?
No, I would have the activity simply send a command to the service via startService(), with the data to be passed included in extras on the Intent. If you have data that cannot be packaged as extras, you may need to consider binding to the service, so you can get a richer API, though this makes configuration changes more annoying.