I've developed a foreground service which should handle a Bluetooth Low Energy communication between a specific HW device.
This service has got an activity in which you can set up some parameters to manage the service, anyway it works with the activiy killed too.
The service contains a BootReceiver too and it is started with the device boot.
Now, my aim is to create another projects with one or more activityes, those one have to communicate with the service and excange data.
I've looked for an aswer on the net and those are the results:
Bind and interface
It seems like this one is the correct one but it is a lot complicated and it involves a lot of code for a little data.
Broadcast receiver
Broadcast receiver is easy to implement, but what if i should read some data from bluetooth each 100ms for example? I don't think this is the correct way.
Which is the correct way of implementing a communication like that?
In android we have several ways to share data between application, it's depend on - how many data do you want to share between applications, cyber issues, Battery consumption and timing issues:
1) You can use aidl in both app in order to share data, please be aware that you are not able to send objects, you should convert the data to parcelable or byte-array. pros - great solutions for short data.
2)SharedPreferences and use the same android:sharedUserId="android.uid.share" on both application - not recommended due a battery consumption and timing issue, great to share big data.
3)You can use client/server model and open a unix socket on bot applications - pros - reliable and can be secured, cons - short battery life.
4)Broadcast receiver - [not recommended] due a potentially timing issue.
5)using shared file at sdcard - not recommended.
Related
I want to develop an Android application that satisfies the following specifications:
Record data from a sensor (for example the accelerometer) at an
approximate rate of 10-30 Hz.
Upload this raw data to a remote server (for example using TCP
sockets).
The user interface should be minimum, just a pair of buttons to start
or stop the recording and transmission of the data.
All the process should be unnoticeable for the user and keep working
when the screen goes off for several hours.
Battery life is not critical (it should last several hours).
Vision: I would like to analyse in quasi-real time the sensor measurements of a group of users without their intervention (apart from starting the application).
After some research, I could manage to perform these tasks separately and inefficiently. I've tried classes such as Service and IntentService, SensorEventListener, etc. I don't know if I should use Thread, Service or IntentService for each task. Specifically, I have serious problems to communicate them.
My questions:
What class(es) do you recommend to use in order to solve this
problem?
What task should be done on each of them?
If the tasks are performed in different entities (threads, services,
intentservices, etc.), how should I intercommunicate them (I'm
thinking about the recording and uploading tasks)?
I am asking for the best-practice structure to solve my problem. You do not need to go into details in terms of developing/coding the solution.
Thank you very much and feel free to ask if something is not clear enough.
David
UPDATE:
After some more research and thanks to DROIDcoder, I manage to design a skeleton for my app:
Main UI: Activity object presenting two buttons (start/stop) that
will launch a Service with the usual startService/stopService methods
Background: Service object
Awake when screen goes off: the service requests a power lock in onCreate() and releases the power lock in onDestroy(). Find more info here: https://developer.android.com/training/scheduling/wakelock.html#cpu
Log sensor values: implement SensorEventListener in the Service as usual
Upload sensor values to server: use AsyncTask in the service as described here: How to use AsyncTask
Data formatting and transmission: use GSON library + HttpClient as described here: How to send POST request in JSON using HTTPClient?
Testing: use the website http://www.jsontest.com/ to test the JSON queries
As this is only a proposition, I add it as an edition. I will post a detailed answer when the whole system works.
The questions remains: can you think about a better design for the application?
Thanks again!
Finally what I have done:
Issue 1: record data from a sensor on the background for a long period of time.
Solved using the class Service to initialize the sensor and listen for callbacks.
Issue 2: communicate the Activity class holding the UI with the Service class.
Solved using the startService(Intent myMessage) method from the Activity class combined with a switch in the onStartCommand() method from the Service class to classify the message.
Issue 3: communicate the Service class with the Activity class.
Solved registering a custom BroadcastReceiver in the Activity and sending Intents from the Service. I've used it to update a progress bar (in the Activity) during the file uploading (in the Service). An exceptional tutorial can be found here.
Issue 4: upload data to a remote server.
Solved using AsyncTask inside the Service like in this site.
here are my suggestion
Upload this raw data to a remote server
You can use JSON parsing for server communications. you will use AsynTask(Background Thread) for background data uploading
All the process should be unnoticeable for the user and keep working when the screen goes off for several hours.
You should use services for background long term processing
As relatively new to the android platform I was given the task of implementing a email client. For this I want to use an service that allways run in the background (client should allways receive emails as soon as the server gets them, requirement from the customer).
Now I've looked into the Service's in android, but can't seem to find any good answer on whether or not the Service should be local or remote.
What would the main advantages/disadvantages be with choosing one over the other? Bare in mind the Service must be running at all times. I know, I know. BAD. But it is essential to core features of the application.
First, the correct/efficient way to do instant notifications from a remote server like this on Android is to use Google Cloud Messaging. GCM lets you remotely wake up the device by sending an Intent to your application, which you can then use as a signal to fetch the message from the server, post a notification to the status bar, etc.
Doing what you're describing with an eternally running service will have a significant effect on battery life unless you get everything exactly right. Keeping the phone awake all the time is not a viable option. Use GCM and do not roll your own solution for this.
But since your question was more general about whether to run a service in a separate process, in general simpler is better and in this case simpler means running in the same process. You'll have access to all of the various elements of your app's process in memory and in general you will probably have a much easier time. Your events will all happen on the same main thread's Looper. Everything will be much more straightforward.
If you don't already have a very good reason for using a separate process for your service, you should run it in the same process.
Generally I don't know the reason why you can want to use another process. If you will - you'll have to deal with Inter-process communications, with all this AIDL, Parcels etc.
And if you will keep the same process - it will be much easier to transfer the data between your components.
The only reasons to make several processes I think is to try to avoid Android Heap budget limitation. You can try to move heavy objects between processes and try to double your limit. However I think you don't need this, also it's bad way too.
So I will recommend not to play with processes and keep things as simple as possible.
Good luck
I'm writing an application with 3 mapactivities, and i've implemended a local service(like google tutorial) that recives update from location manager, to share location data from gps between these activities.
Now i want to put every activity in separated process to follow google's suggestion.
So my question is how I have to proced??
Implement and AIDL interface for remote services or register every mapactivity to location listener??
Thanks for answers and sorry for my bad english :P
If it's just a single application that needs location information, then using a remote service and AIDL is an unnecessary complication. The easiest way would be to have a local service with which the activities can bind, then have the service use sendBroadcast() to send location information. The activities can then register a BroadcastReceiver to pick up this data.
First the rationale:
That quote in the Javadoc is a bit... weird. If you understand "running" as being between onResume() and onPause(), then normally two Activities belonging to the same Application cannot "run simultaneously". You would probably have to mess with the Application class or the OS itself to have it behave otherwise.
To wit, I'm actually developing an app at the moment that uses several MapActivity subclasses and haven't encountered any problems so far (i.e. 40+h of development and testing, both on emulators and a device).
Therefore I would suggest:
Try to implement your app as a single-process activity with a local service and just run with it.
If you don't want to do that (can't blame you ;) ), or you encounter any problems, I would suggest starting out with a MapView, perhaps encapsulated within a Fragment. Here's a discussion to get you started.
In short, due to Android's practical fragmentation, keeping your Activities in one process and commiting more time by starting with a more bare-bones implementation will be a safer, ultimately less time-consuming and probably more efficient approach than artificially splitting your app and potentially gritting your teeth on the IPC. At least in my opinion.
After some research i think the best way is to implement IPC with a messenger like described in Android doc http://developer.android.com/guide/topics/fundamentals/bound-services.html#Messenger.. I'll test this solution an report here the result..
Best tutorial is http://developer.android.com/reference/android/app/Service.html#RemoteMessengerServiceSample where is implemented a 2 way communication from client and service..
My team is working on an Android project which consists of several Android applications which exchange data (on the same phone). The idea is to have several applications which are collecting some data and send this data to the main application. The main challenge here is to do the exchange as cheap as possible in terms of CPU load & battery usage.
As far as I know, there are two ways to achieve inter-process communications:
Intents & activities - one activity catches the intents of another
Remote methods (through AIDL)
I wonder which of these is more efficient in the following scenarios:
Very frequent messages/method calls with very little data sent/traffic (e.g. just passing a bunch of primitives)
Less frequent messages/method calls with large traffic chunks (e.g. collect data and periodically send a few KB/MB of data)
Very frequent messages/method calls with large data chunks exchanged
I would appreciate any help, either in terms of comparison or a reference/link to a benchmark.
I think for 1) you'd be best with a remote service and for 2) and 3) you'd be better off writing to files or a database. Intents are more for infrequent interprocess communication and starting apps and services.
You could also try to use native code to create a shared memory as an alternative option. Check out this link for details:
http://www.androidenea.com/2010/03/share-memory-using-ashmem-and-binder-in.html
I suggest you use the Unix domain sockets mechanism to address scenario 3). The high frequency will make the use of files/databases complicated, and according to this answer, using Android's IPC is not recommended performance wise, since every object has to be converted to (and back from) a Parcel which takes time.. You can also use Unix pipes but it has some restrictions:
How to create named pipe (mkfifo) in Android?
https://groups.google.com/forum/#!topic/android-ndk/lD-V7Nxe5y4
How to use unix pipes in Android
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.