I have to develop an application where i have to continuously collect the GPS, accelerometer data [esp. when user is in motion i.e traveling, else it can be relaxed). Also I have to communicate with web server and handle the response from the sever. So for this(handling response ) part application should continuously poll.
Based on response from server I have show UI to the user.
I am not very clear about the design.
Do I have to create activity from where I start service. Should service be ran as a separate thread(this always runs in background).
I am planning to create two services. One service to continuously collect GPS data.
Other service for communicating with the web server[start timer/alarm manager] for polling.
ALso can these two services communicate with each other.
Also after processing the response frm server the service should be able to start user interface to show some form. I am not clear how to handle this.
Also is acquiring wakelock required if I have to collect GPS data continuously.
Please clarify.
Thanks
You can use an AlarmManager for polling. You just need to set the interval. You will notice that most components Application, Service, Activity all are Contexts. So they all can get Application Context. The way to think about communication is that the android message/event is essentially the Intent. So you define your custom Intents. You just need to give them a custom name for the action. Then you use Intent filters. You can do point to point messaging by doing startService, startActivity or you can broadcast the intent. I would recommend that you communicate via broadcasted intents. Message routing is handled using Intent filters. Starting form etc would just be a startActivity(Intent) and the Intent itself could contain using intent.getExtras(). Just so long as you can put it in the Bundle you can pass it and display. So to answer your question, just use Intents for everything. Use broadcasting and filtering for communication and Intents again to start your activity for display.
The May 10th Google I/O had an afternoon session called Android Pro Tips. The first section covered several different approaches to making your app more continuously location aware.
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
What would be good approach to establish communication between different APKs? One app can send request to other apps and wait for response.
I can think of:
1. using BroadCast receivers: send "request" broadcast and receive returned broadcasts (results). This seems nice clean solution, no security problems, but how to get all results back as "one" - usually I will want to send out broadcast to collect app identifications, and get result like array.
2. use sharedUserId between all these apps and gather or execute whatever I need directly on the apps. But here are have couple of more loose ends:
- how do I get list of apps (through list of installed packages?)
- is with sharedUserId and same signature possible to access other app internals? like register/unregister component, etc.?
Thanks!
EDIT:
Have been reading more about ordered broadcasts and so far this seems good way to go. Using order broadcast each of other apps will fill in its own data part and result will be returned back to supplied "final" receiver.
I am using ordered broadcasts. When broadcast is send out, each receiver adds its information and last receiver calls resultReceiver.
I'm developing restful android application, but I'm still newbie to android, and I would like to avoid beginners bed structural design that would cost me troubles latter.
I've read lots of discussions about android services and restful applications, many of them contrary to each other, so I would like to know have I choosen a good approach.
Inspired by this presentation http://www.youtube.com/watch?v=xHXn3Kg2IQE I put my http requests into IntentServices, instead of the Async Task.
I've choose Intent Service because of:
as a services they are not sensitive to foreground/background switching like Activities (won't get killed).
Intent service provides work in separate thread, so the user interface stays responsive.
Since Intent Service cannot run multiple request simultaneously, I've "split" my domain into few groups and for each group I have written my Intent Service. (ends up in: one CRUD set -> one intent service)
This way I got that inside of a group can be only one request running at a time (And this is good for me, since this way it could never be executed for example update and delete at same unit).
And, on the other side, I can run multiple requests at the same time if they are from the other groups, and don't affect each other.
So basically, I have this:
one generic HTTPRequest class that builds requests from name value pairs
UserIntentService - creates user related requests and executes it by using HTTPRequest cass, and proccess request using UserProcessor. Notifies caller by intent with data.
CallIntentService - creates call related requests and executes it by using HTTPRequest cass
and proccess request using CallProcessor. Notifies caller by intent with data.
UserProcessor - parsing response
CallProcessor - parsing response
ServiceHelper - finds and starts right intent service
When using from activity, I use something like this: SeviceHelper.StartService (action, data),
and I get response by local BroadcastReceiver inside of the activity. I register receiver on the OnStart(), and unregister it on the onStop() method of the activity.
Is that a good approach?
Should I have only one IntentService for all calls?
Is it better to have one Service that runs all the time in background, instead of using Intent Service that has to be started for each request?
Is there any other things that can get bad with this approach that I'm missing?
My app is design to get messages from an embedded Bluetooth device. While I was working with sensors which sends data each second or more, it was not such a big deal to broadcast intents to activities. The only visible slow down was when the Bluetooth device flushed its buffer.
Now I need to deal with high refresh rate sensors (such as ECG, every 2ms) so I have to be little more cleaver because the number of intents makes visualization not in real time (there is more measures incoming than displayed).
I try to work with putIntegerArrayListExtra() to send data each 2 seconds but now I get a A.N.R.
Is someone can advise me to deal with lot of intents? (It seems my service memory also grow up to much).
To bypass intents, I have to send an object from a service to an activity. As far I now this is impossible and the reason of Intent.
EDIT:
I had underestimate binding. In fact it enables activities to get from the service an instance of a "DeviceDriver" which register listeners to perform callback. As I can retrieve the instance of the driver in the activity, I can register it as a listener and cut down all intents between service and activities (At least for data exchange).
You can also use binding to pass data from service to intent:
http://developer.android.com/guide/components/bound-services.html
In your case I advice you to not use intents. Try to use thread inside activity or shared memory and synchronization.
I'm using pubnub as a publish/subscribe channel between an android app and a server.
Currently I'm thinking of how I will implement this.
I'm using the provided library for android (https://github.com/pubnub/pubnub-api/tree/master/android) but I think there will be some problems with the application lifecycle if I use it like it is now. (Correct me if i'm wrong)
I was thinking of implementing it as a service
What I want
The service has to keep on running until an hour (negotiable) after the last app usage. That's because we want to have notifications when a message comes in, but the app is not the currently used app.
How do i stop the service after one hour of non-activity of the app? Probably Android will kill it, but I want some control.
The Service must be able to trigger the app to change it's interface when specific messages come in (I was thinking of sending intents from the service when we receive a pubnub message?), pubnub will send data to the service, so I need a way to pass this data to the application (probably save it in a Bundle in the intent?)
I need to listen to multiple pubnub channels (max 2 at the same time), I think I will have to do this in multiple instances of this service?
I think I will do it like this:
Create a service that's started when the app starts
Let the service listen to a pubnub channel
When a message comes in, send an intent and use the intent filters
implement broadcasthandlers to listen to these internal intents
Is this the right way to do this? any hints?
You have an excellent set of questions an detailed points that I will talk about in this answer. You are using Android and you are interested in the conventions and best practices for PubNub Publish/Subscribe scenarios.
Your use case is very common and the best ways to build apps always vary dependent on application needs. However you definitely have the right idea and have asked all the right questions. You just needed some sample code and a direction to get started on implementing the specifics of your application needs. To define your needs in a list:
Connect/Disconnect Ability.
Always-on Background Service that can Send/Receive data and notify other apps via Android Intents.
Connecting to Multiple PubNub Channels at the Same Time.
So to get started I will provide you direct links to some examples and methods:
Create a Service that is Started when when Android Boots: https://github.com/pubnub/pubnub-api/blob/0dfd8028b803332f5641adc909b1a26f87bd7ff1/android/PubnubAndroid/src/com/aimx/androidpubnub/BootReceiver.java
UnSubscribe/Disconnect Example Code when you want to stop listening on a PubNub Channel: https://github.com/pubnub/pubnub-api/blob/0dfd8028b803332f5641adc909b1a26f87bd7ff1/android/PubnubAndroid/src/com/aimx/androidpubnub/MainActivity.java - Listening to multiple channels is easy by placing the blocking pubnub.Subscribe() method inside a Thread.
Regarding your thoughts - This IS the right way to do it:
Create a service that's started when the app starts
Let the Service listen to a PubNub Channel.
When a message comes in, send an intent and use the intent filters.
Implement BroadcastHandlers to listen to these internal intents.