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
Related
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.
As everyone might know, there are two primary types of services in Android: started and bound (I'm not counting started and bound services, as they're mostly the same as just started services).
You can find tons of tutorials on how to use bound services or how to bind to started service, but there are actually no answer on why would anyone use bound (not-started) services within the application process (in other words - without IPC)?
Is there any (hidden?) profit from using bound service (let's say for some sort of processing) over using standard threading tools (AsyncTaks, Executors, plain threads)? Would it worth boilerplate code for connection of such service?
Some context
Question appeared after digging through sources of Google Camera. They're creating a bound (once again - not-started) service for saving images. What is the point? Why not just used some Executor? Am I missing something important?
If that is a bound service, then there is no way it would help to persist saving progress while device configuration is changing (i.e. device is rotated). So I see no advantages.
Started Service is useful in case where there is need for no or very limited (one-way) interaction between starting component i.e. Activity or BroadcastReceiver, and the started service. For instance, a fire-and-forget background download. You give the downloader service a URL, start the service and forget all about it. The only way the downloader service ever interacts with the user is using Notifications. The Activity might as well go on the backstack in the meantime, you don't care. Note that in this case, the service is serving the Activity which started it, and there is no requirement for it to be available generically to other Activities.
On the other hand, bound service is a more generic service or one that needs to serve multiple activities, and more over, needs multiple bidirectional interactions i.e. Activity sends a message to Service, then Service sends a message back to Activity and so on. Consider the example of background music player service, where you pass the music file or remote stream URI/URL to the service, then another activity could change the volume or switch to another track etc. A message back from service to activity could be that the mp3 file is incomplete or corrupted, or a track completed message.
In fact, I came to this question looking for the answer to this exact question, but found the answer quite satisfactorily and complete in the link provided by #SagarPikhwal. Admittedly, I'm a newbie as far as Android programming is concerned, so the above is all as per what I understood !
Edit:
Realized that I didn't answer (to the best of my abilities), the other part of the question about the code you saw for Google Camera. I think the reason why they create a bound service is because Camera is a common shared resource, and there could be multiple users of that system resource simultaneously. The activity using the camera service to capture an image or video is not the exclusive user. The Google Camera application is yet another user of the camera hardware, while there could others, and all of them served by the bound-service.
I'm a beginner in android development and I'm trying to implement an android udp client, which connects to a java server and sends/receives some packets from it.In this process it collects some data (like round-trip delay etc), which is used to measure the QoS of that particular network. I have tried implementing the connection and sending/receiving data using Java Threads, but the application crashes, and hangs if i try to use more than 2 threads. So I'm looking for alternatives. While going through this site as well as some other links I found that in android multiple threads can be implemented using AsyncTask, Handler etc. Also I found that the Service class also helps to run a background service in an app. Please suggest which approach among these would be the best to achieve my purpose.
Thanks in advance.
You can use AasyncTask to do this and as you mentioned service may be useful too, where u can let your application do whatever it wants in background , if user needs to use application by its interface then AsyncTask must be used to avoid Crashing
There is not one right answer that can be applied as a broad stroke to how to do Android multi-threading. There are a few different ways to approach it based on what your specific needs are.
Any long running, blocking call, in Android will result in the application crashing.
The most common solution is to use an AsyncTask though. For example, when I want to make a call out to a web API endpoint for some XML data within an Activity I would in this case use an AsyncTask and kick off the calls from within doInBackground.
This is not an appropriate solution though if the wait time is longer, or possibly an unknown wait time. Or in a situation where there will always be waiting such as a message queuing service. In this type of situation it may be best to write a separate app based on extending the Service class. Then you can send/receive notifications to/from the service from your primary application in a similar manner to how you would communicate with a web service.
I'm currently learning to develop for Android and I'm having a somewhat hard time figuring out when and how to use services. I have already seen the numerous questions asked about very similar things, but I can't quite find the exact answer to my questions.
I have an app which talks to a restful api. I fetch several lists which I would like to cache in memory and only update if the user hits a refresh button, or certain activities are created. If a list is refreshed, sometimes several activities need to be notified, so that they update their content (if they are on screen at the time). I store the data I retrieve in value objects.
On a non-android app I would usually create a sort of dataproxy class in a singleton pattern. I could ask the dataproxy to update its data via http request, and then it would send some kind of system-wide notification as soon as the data is changed, so the interested views can all be updated. I hope this makes sense.
My question is now: How do I do this the android way? Do I bind and unbind to a dataproxy service, which I can actively ask to fetch certain data? Should I do my non-persistent caching in this service or somewhere else? Do I need AIDL, or can I just use normal objects for moving data between a service and an activity? Although I find the android dev guide pretty well written and useful, I haven't found much information on services best practice.
Thank you in advance!
How do I do this the android way?
You assume that there is a single "android way".
Do I bind and unbind to a dataproxy service, which I can actively ask to fetch certain data?
You can either bind, or send commands via startService().
Should I do my non-persistent caching in this service or somewhere else?
If you're sure that you only want it to be in RAM, I'd lean towards static data members. Make the service be the "do-er", not the store.
That being said, I'd treat this more as a synchronization pattern, with the real store being a database or directory, with a cache in RAM. Users will find this less frustrating -- under your current plan, if they are in your app, then take a phone call for a while, they'll have to have you download all the data again.
Do I need AIDL, or can I just use normal objects for moving data between a service and an activity?
If they are all in the same process, normal objects is fine via binding, or use Intent extras for the command pattern.
Now, back to:
How do I do this the android way?
Option #1: Wrap your store in a ContentProvider and use ContentObserver for changes.
Option #2: Have your service send a broadcast to your package when the data changes, so the foreground activity can find out about the change via a BroadcastReceiver registered via registerReceiver(). Other activities simply grab a fresh look at the data in onResume() -- the only one that immediately needs to know of the data change is the one the user is interacting with, if any.
Option #3: Use the binding pattern with the service, and have the foreground activity register a listener with the service. The service calls the listener when data is updated. Once again, ather activities simply grab a fresh look at the data in onResume()
Option #4: Cook up your own listener system as part of your static data members, being very very careful to avoid memory leaks (e.g., static reference to an activity or service that is destroyed, preventing its garbage collection).
There are probably other options, but this should get you started.
The Google IO session mentioned by Andrew Halloran:
http://www.google.com/events/io/2010/sessions/developing-RESTful-android-apps.html
Check out the Google I/O session videos. I implemented REST api calls the easy BUT wrong way. It wasn't until watching this Google I/O video that I understood where I went wrong. It's not as simple as putting together an AsyncTask with a HttpUrlConnection get/put call.
I've asked various questions related to one goal: how to develop an Android app that plots bluetooth data forever in real-time. I now have a new question from a different angle. To be fair to new readers I will cover some of the same background, but basically the question is in the title.
I found some open source code Bluetooth that apparently creates a background thread which updates the screen with new data it receives over a bluetooth connection. Then when I launch my Plot activity I can see the bluetooth background thread continue to write bluetooth data to Logcat. So I know for a fact the bluetooth background thread is still running when I launch my Plot activity.
Again, my goal is to plot the bluetooth data that is continually provided by the bluetooth background thread. I have succeeded as follows: since this bluetooth background thread seems to run continually and just won't die, I decided to use its update() method to call my static Plot.plotData() method to plot the data. And this works. It will will run endlessly with out a problem - receiving bluetooth data and plotting it via periodic calls from the bluetooth background method update() to my static Plot.plotData() method.
Although I have received some negative feedback regarding my solution, I have found sharing data across Activities where Edward Falk says sharing static data is OK. Here Edward Falk asks: "Are the activities all in the same application? [yes] Same task? [not sure] It seems to me that you could just store the data in a static variable accessible by all of the activities." Well I tried static data and it worked, but I switched to a static method Plot.plotData() which seems to work better for me.
The latest feedback I have received from one person #emmby that says my static Plot.plotData() goes against the following: "It sounds like you're looking for an in-memory way to share data, and that's simply not the way the Android activity model works." But what am I else to do? I thought that an Android phone has a limited amount of RAM for running Activities (one at a time), threads, handlers, Services, AnycTasks, etc. And an SD card for persisting data.
#emmby seem to say that in order to share data from a bluetooth background thread to my Plot activity (Plot.plotData()) that I must use the SD card. This doesn't sound right. After all I have it working using my static method Plot.plotData().
Frankly I don't see anything wrong with my solution primary because those who criticize it do not follow up with a definitive alternative.
If you find my solution deficient please speak up and provide a definitive solution. Otherwise I will take Edward Faulk's solution as the best one.
If I understood you correctly, your thread is running at the background even when none of the activities display data obtained by that thread. For example, let's consider scenario:
You started your bluetooth thread.
Your activity A started and now read data from that thread.
Your activity A is backgrounded (for example user navigates away via "Recent" tasks).
Your activity is idle but bluetooth thread still consumes cpu and power.
If you don't use your bluetooth data you shouldn't run the thread. You can introduce some kind of counter that tracks number of clients that use your thread's data. And if counter drops to zero - thread stops/pauses.
But Android has built-in solution for such cases. You can introduce service which will be bound by different activities and will have DataSource interface with getNextData function. See Bounded Services for more details.
When there are no clients bound to service Android will stop the service. This way you completely decouple Activities from thread. Your bluetooth thread is now managed by Service. And Service is now managed by Android.
In your case Local Service should be enough to share data between your thread and activities.