I want to create a simple Service (based on the ApiDemos\app\AlarmService_Service example)
In the service's thread I want to add a record to a local DB every 15Sec.
But the problem is that the DataSource I created (with the help of http://www.vogella.com/articles/AndroidSQLite/article.html article) needs Context object in order to initiate the DataSource.
In the near future I'll want a service like this example to run also when the device booted.
So my qustion is how can I use sqlite in situation where I have no Context?
So my qustion is how can I use sqlite in situation where I have no Context?
Service inherits from Context, and so you have a Context. Bear in mind that you need to have a singleton SQLiteOpenHelper (or SQLiteDatabase) if you expect other threads to also be using the database.
BTW, that sample is quite possibly the worst Google has ever published. I am not completely clear on why the user wants you to "add a record to a local DB every 15Sec" in the background, but that sample:
will fail to keep the device awake
displays a Notification for no particular reason
has you roll your own thread rather than using IntentService which handles that for you
does not handle multiple commands sent to the service
has a largely pointless Binder
etc.
The proper way to use AlarmManager with _WAKEUP alarms is either to use my WakefulIntentService or the Android Support package's WakefulBroadcastReceiver.
I have published a sample using WakefulIntentService with AlarmManager and an equivalent sample using WakefulBroadcastReceiver.
Related
I have specific case to ping my server every 10-60 minutes (it still depends) but only when app is opened.
This feature is created to inform that session is still open where session is defined as period from app open to app close. I don't have to worry about process kill.
What is better to use? AlarmManager or Handler.postDelayed() ?
The targeted platform is android tv so imagine the case is when watching film in context of my app for example.
Personally I first thought to use AlarmManager but I realized it's way more code to produce compared the circumstances.
Is handler causing more CPU usage increase ?
AlarmManager starts your app in the future when it is not running. So I think Handler.postDelayed() is a more efficient choice if you will only ping the server when the app is open.
Note: The Alarm Manager is intended for cases where you want to have your application code run at a specific time, even if your application is not currently running. For normal timing operations (ticks, timeouts, etc) it is easier and much more efficient to use Handler.
See AlarmManager.
You should definitely use AlarmManager for this use case. I can think of several reasons right away:
If you use Handler and want to post a "cancellable" Runnable to it, then you'll have to store references to both the Handler and the Runnable in order to be able to cancel the execution (e.g. if user leaves your app). It means that you'll have to either store them in an Application context, or create a Service for this feature. Using Application for this kind of stuff is generally discouraged, and Service is a bit of an overkill.
AlarmManager is the standard API for this kind of stuff. Any other developer reading your source code (or yourself in few months) will have a much easier time understanding the feature.
I don't see how you can have less code using Handler approach - all you need in order to use AlarmManager is a single method that creates PendingIntent, which is being passed to both set and cancel methods in AlarmManager...
As for CPU usage, I'm sure that the scale will be insignificant, therefore it won't matter.
In general, I think that Handler#postDelayed should not be used to control flows that involve user interactions. It just feels wrong and clumsy.
I have a website that sends and receives documents. I was thinking of building an Android app that notifies the user if a new document has been received, and displays document details if the notification is clicked. It doesn't have to be in real time, it could update in interval of five minutes or something.
What is the best way to update the Android app of changes in the website? I'm new to Android and I'm not quite sure where to start. I've heard of Services, BroadcastReceivers and Alarms, but I don't know if those are the right ideas.
Update: How do I update my Android db from my web db within an AsyncTask in my BroadcastReceiver? I'm worried I might have a "leak error" which sometimes comes up with my AsyncTask.
You can try to implement GCM or as the above-mentioned, work with an AlarmManager or the more efficient JobScheduler (requires API level 21!). Avoid doing heavy work on a BroadcastReceiver. Instead use the Broadcastreceiver to receive Alarms and start a Service in background. You may also have a look to WakefulBroadcastReceiver which holds a WakeLock for you. The Service could GET data from your webservice by using a REST architecture and update it's local database. Retrofit is a powerful open source library for a REST architecture. If there are new database records, you can inform the user by a Notification. Don't forget to check basic things like not starting the Service if the device hasn't got a network connection or to stop the Service after the work has been finished. I personally recommend to learn the basics first and then go to advanced topics. Good luck and pleasure.
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
im wondering if it would be a bad idea to create a Singleton that is used between some Android Activities and a Android Service. As far as I know the static fields, in my case the Singleton, is available as long as the whole Process is alive.
My plan is to use a singleton instead of Parcelable to share data between my activities and a Background service. So my Activity1 will add some data by calling MySingleton.getInstance().addData(foo); then I would sent an Intent to inform my Service that new Data has been added to the singleton. Next my BackgroundService would handle the intent and call MySingleton.getInstance().getLatestData(); then it would process the data (takes some time). The result of the service would next be "post" back by using the singleton and fire a broadcast intent, which are handled by the Activity1 (if alive) and the Activity1 will retrieve the result from the singleton.
Do you guys think thats a bad idea?
EDIT:
What I want to implement is an peace of software that downloads data from a web server parse it and return the result. So my Activity would create DownloadJob Object. The DownloadJob-Object would be put into the DownloadScheduler (Singleton) which queues and manage all DownloadJobs. The DownloadScheduler would allow to run 5 DownloadJobs at the same time and use a queue to store the waiting. The effective Download would be done by the DownloadService (IntentService), which gets informed over an Intent that the a new DownloadJob should now be executed (downloaded) right now. The DowanlodService would retrieve the next job from the DownloadSchedulers queue (PriorityBlockingQueue) and return the Result by setting DownloadJob.setResult(...) and fires up an broadcast intent, that the Result is ready, which will be received by the DownloadScheduler which would remve the job from the queue and inform the Activity that the download is complete etc.
So in my scenario I would use the singleton to access the DownloadJobs from the DownloadService instead of making a DownloadJob Parcelable and pass it with the Intent. So i would avoid the problem, that I have two DownloadJobs in memory (one on the "Activity Site" and one on "Service site").
Any suggestions how to solve this better?
Is it true that static instances, like DownloadScheduler(Singleton), would be used by freed by the android system on low memory? So would subclassing the Application and hold there the reference (non static) avoid this problem?
If you are using the singleton just as shared memory between a background service which I assume is performing operations on a different thread, you may run into synchronization issues and or read inconsistent data.
If the data in the singleton is not synchronized, you have to be careful because you are relying on your "protocol" to be sure that nobody is reading while your background thread is writing (which may lead to errors).
On the other hand, if it is synchronized, you are risking to face anr error because the activity which reads the data may be blocked waiting the service to finish to write the data in the singleton.
As the other said, you also have to keep in mind that your singleton may be freed if the os needs resources, and that your data may not be there anymore.
I'd rather use an event bus such as otto or eventbus
EDIT:
Using a singleton as the entry point of background (intent) service is the approach suggested in 2010 Virgil Dobjanschi talk about building rest client applications for android.
The suggested approach is having a singleton that performs as controller of ongoing requests. Please consider also that request to intent service are already queued by the os, so you can throw several intents that will be processed sequentially by the intent service.
Some time ago I also tried take that as a starting point for a library, which still remains unfinished. YOu can find the sources here
What I would certainly not do is to store your data in the singleton. The approach I would prefer is to store the data in some persistent storage (such as sql / preferences / file / content provider) and let the client know of the change through a broadcast message (or, if you are using a content provider, through an observer).
Finally, to some extent this is the approach followed by the robospice library, which looks quite mature and ships a lot of interesting features such as caching.
A better idea is to subclass Application and put any long living objects in there. By subclassing Application you can properly handle startup and shutdown of the application something you can't easily do with a singleton. Also by using an Application Activites and Services can share access to the models within your program without resorting to parcelables. And you can avoid all of the problems Singletons bring to your program.
You also don't have to resort to storing everything in a database which requires lots of boiler plate code just to shove a bunch of data in there. It doesn't do anything for sharing behavior between parts of your application and doesn't do anything to facilitate communication and centralization of activities. If you really need to persist state between shutdowns great use it, but if not you can save yourself a lot of work.
You could also look into using something like Roboguice which makes injecting shared models into your Activities and services.
You might find this helpful:
what's design pattern principle in the Android development?
Using a singleton like this is not necessarily a bad idea, but you will lose it's state if Android decides to stop your process. You may want to consider storing your state instead in a SQLite database or a persistent queue (take a look at tape for a good example).
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.