Android: Cache XML File from RSS Feed - android

I just started doing my first Android app which happens to be an RSS Reader. I did a bit of googling about this but haven't seen a clear reference though. What I want to do is cache my xml file (the feed file) to the sdcard so when the phone is offline, the user can still view the feed by automatically telling the application to look for it when no network is detected. What I have now is the mechanism to cache the image but I wonder how to use this for other files since it was specified only for images that converts it to Bitmap using the HashMap().

I think the preferred way is (just as Umakant Patil commented on your question) to store data in an SQLite database. You would typically write a background service which every now and then refreshes your database with the server side data. Your application will always read only from your SQLite database. Note that the service and the application will typically live their own lives, independently from each other (your application will never communicate directly with your service).
This procedure is also somewhat safer from an architectural perspective. Your application will never depend on network connectivity or timing issues due to network traffic. It will only rely on data and database access on your local device.
TIP #1:
You could pass an entry to the AlarmManager which will wake up your service at a given interval. Your service will synchronize your database with the RSS source and then kill itself (saving resources is always good :-)
There is a good example of Services in Android here: http://developer.android.com/reference/android/app/Service.html
And about Content Providers here:
http://developer.android.com/guide/topics/providers/content-providers.html
TIP #2:
Note that you don't necessarily need a content provider to communicate with your database. The content provider is good to have if you wish to "standardize" your database communication. Perhaps several components of your application need to access it or even several applications, then it's good to use an already defined "de facto standard" way of accessing the database.

Related

Is SQLite appropriate for off-line storage before replication to a server?

I am planning on writing an application that saves a fair amount of data. Historically, I have simply written data directly to a server, and only used some simple key/value storage with shared preferences for local storage.
I am considering this time, instead, using SQLite to save the information at first, and sync the data to the server in the background later. This will benefit the user in a few ways: 1) can use the app offline 2) don't have to worry about data being saved right away, it happens when ever it can 3) more reliability.
My approach will be to get/set data from SQLite during UI usage, and use a background process to find new rows and put them on the server, flagging them as synced when it happens.
Does this sound reasonable?
You can use SQLIte for your scenario. But, while implementing, you can follow any one of this approach.
Approach #1: Use an Abstract Factory to Instantiate the SQLiteOpenHelper.
Approach #2: Wrap the SQLiteDatabase in a ContentProvider
Refer to this link for how to implement these 2 approaches. http://www.androiddesignpatterns.com/2012/05/correctly-managing-your-sqlite-database.html
Key points to be noted while using SQLite
Sqlite takes care of the file level locking.
Many threads can read,one can write. The locks prevent more than one
writing.
Android implements some java locking in SQLiteDatabase to help keep
things straight.
If we handle the database incorrectly from many threads and mess up the code, your
database will not be corrupted. Only few updates will be lost.
How "Multiple Threads - DB access" can be used for your scenario
The SqliteOpenHelper object holds on to one database connection.
If you try to write to the database from actual distinct connections (multiple threads) at the same time, one will fail. It will not wait till the first is done and then write. It will simply not write your change. Worse, if you don’t call the right version of insert/update on the SQLiteDatabase, you won’t get an exception. You’ll just get a message in your LogCat, and that will be it.
So recommended to write using single thread and read from multiple threads if necessary for faster access.
Does this sound reasonable?
Yes. Note that the synchronization process can get tricky (e.g., what happens if the server hiccups halfway through?), but that has mostly to do with synchronization and little to do with SQLite.
We implemented a solution that used a SQLite db on the device to sync data via a web service to the master database. We did this for a couple reasons: offline, poor connection, manual sync.
For our solution we had a flag on the table that determined if the data was pushed to the web service. Our web service also provided data back to our application to let us know if the data was received and processed correctly. This allowed us to clean up the data on the device, send notifications if there were failures, and resubmit the data if there were previous failures.
You can use push notifications as well if you have fixed the issues on the backend and have the device resend the data to the web service. This worked really well for us.

Android Apps to asynchronously read some kind of buffer

I am currently assigned the task to research and implement two Apps that do the following:
App A writes some content to a buffer/register of some sort
App A terminates
App B starts and reads the Buffer
The Apps are not supposed to run at the same time.
First of all I don't know which possibilities I have.
I came up with the following:
Write to a File
Write to some shared memory range
Are those two options possible and do i have to grant App B the right to access the file or memory range?
Furthermore i am supposed to check network sockets for usage as "buffer".
I know that would go against everything that is supposed to be done but this is expected!
I was trying to use a DatagramSocket because i can open up that kind of socket, send packets over it, close the socket and terminate the App.
I thought there would be some system buffer holding the packets until someone calls receive on a DatagramSocket with the same port.
Would that even be possible or will the system throw all packets away when nobody is receiving them immediately?
There is a class in the android API that was created specifically to allow you sharing data between different applications - the ContentProvider.
You should create a ContentProvider that will be in charge of the data (I recommend using the SQLite database to store the data), and both apps can use that same ContentProvider to access and/or modify the data.
It does not matter in which of the apps the ContentProvider resides, but probably best it is in App A since it is the one creating and modifying the data.
See this great guide on how to create a ContentProvider:
http://developer.android.com/guide/topics/providers/content-providers.html

Synchronizing partial database model from server to client

This is more of a conceptual question not necessarily bound to any specific technologies.
Lets say you got some database on a server, some REST/JSON API to access content in that database and some mobile client displaying data retrieved through the API.
It would be nice to have some caching mechanism on the client and also to be able to enable offline access to the data as long as the client is only reading (In my case it's fine to deny write access to offline clients to avoid having to manage all those nasty conflicts that might happen).
It appears that a nice way to solve that would be to have a subset of the servers database model present on the client and synchronizing data from the server to the client.
Access to the local database might then immediately return results but also trigger update requests to the server. In case the server returns modified data the client model then synchronizes it's local database and notifies the display of data changes.
The goal in the end is of course is that the user may browse the information regardless of the stability of his internet connection and is not annoyed by connection dialogs or similar as long as he doesn't modify any data.
Now from an implementation perspective... on one hand it seems like a bad idea to couple the server database directly to the client database as they may be from different vendors. I guess at least there would need to be a vendor independent model above both database implementations. On the other hand, transforming the data from the server database into some transport format and than putting it back into the client database seems like a lot of overhead.
Any suggestions how to solve that in an elegant and maintainable way?
I am working on an app that syncs small portions of a large database locally onto the handset. There is an initial preload that has to occur on the handset but after that the updates happen asynchronously in the background.
First of all, decoupling the server and handset using JSON or XML is highly advised. Locking into one technology always causes issues as you are forced to use the same technology regardless of the platform. That is, if you plan on expanding into other platforms (Web,iOS,etc..) you are forced to use the format dictated by the server. Choosing a generic format will make that simpler in the long run. In reality with the amount of public libraries reading/writing JSON is a trivial matter.
There are two ways that we use to sync the data;
1. AlarmManager
We schedule the AlarmManager to trigger a service to wakeup on a regular schedule (lets say every 6 hours). The wakeup starts a background service that contacts the server, downloads the changes in JSON and updates a local SQLite DB. If there is no connection, the update is skipped and scheduled for the next wakeup. We add a ConnectivityChanged receiver to automatically restart the sync when the connection is restored.
2. GCM
It's a little more work but saves a lot of battery and data usage if you only update the local database when there are changes. Google Cloud Messaging can send a wakeup message to the device and tell it to start the sync service. The sync service runs the same as the AlarmManager method above.
We do a combination of both of the methods above depending on how "fresh" you need the data and how often it changes. Something like an RSS feed should probably be updated every 30min whereas weather data may not need to be updated more than every 4 hours.
So to run the database sync we use;
Receivers -> listen for system events and trigger Service
Services -> connect to the server, download the JSON and update the SQLite providers
Providers -> insert the records into the database and broadcast content changes to ContentObservers
ContentObservers -> when the app is running, the ContentObservers update the UI with the new data
There is a lot of technical details in each of the components above but that should provide you with a very robust architecture for syncing server data with a local db.
I'm working on a project that has similar requirements. We want to have a big, available database on a server somewhere and then mobile devices that get data from it. If the devices go offline it's ok because they have saved their own copies of the data locally.
We've decided to use BigCouch (fork of Apache CouchDb that supports clustering) as the server technology and then Couchbase Mobile on the mobile devices. (As a note TouchDB for Android will replace Couchbase Mobile, but it's not stable yet.)
The reason we went with Couch* technologies is that Couch has good replication over HTTP. You can programmatically initiate a sync event on the mobile device and it will replicate all inserts, updates and deletes for you. It stores the information on it's own embedded CouchDb on the mobile device, so it can be read offline.
If you didn't want to go down the Couch road, you could simply use something like SQLlite to store the results of your REST/API calls. Then you would have to write your own replication logic for when a mobile device goes offline and then comes back. There are creative ways to do this, so maybe it's an option.

How to transfer files between Android applications running on the same device?

I am writing an Android application that interfaces with a RESTful service. This web service essentially fronts a file system, and provides metadata as well CRUD access to the files. My application retrieves the metadata, and exposes it to 3rd party apps through a ContentProvider.
I need to add the ability for 3rd party applications, running on the same device as my app, to CRUD the actual files by making requests to/from my app (not directly with the server). This means they need to either send or receive the contents of the files (which are typically XML or images) through my app.
I have thought of two approaches for implementing this:
Option 1 - Using ContentProvider.openFile
This seems like an obvious choice for giving 3rd party applications the ability to read files from my ContentProvider. I think it starts getting tricky when those applications need to create or update files through my `ContentProvider'. I'll need a callback when they are finished in order to know when to send the new/changed file back to the server. I believe I could use a FileObserver for that purpose though.
Option 2 - Using a Messenger through a Service
With this approach, I can send the files between my application and client applications through the Messenger. The files would have to be passed through a Bundle, so I am not sure what the best format is for transmitting them (File, FileDescriptor, byte array, something else??). I don't have a good handle on whether or not this would cause problems if the files get to be large.
Option 3 - a hybrid approach
Use folder(s) on external storage as a drop box
Communicate CRUD requests, and drop box contents, through a Messenger/Service
Use the ContentProvider to store the status of requests
3rd party app receives status updates through a ContentObserver
Summary
I think using ContentProvider would be the ideal solution, but it seems that the API does not fully support my use case. I am concerned that trying to go down that path might result in a kludgy implementation. If I go with a Messenger and Service approach, I am uncertain of the most robust way to transfer the files through a Bundle.
The hybrid approach seems pretty robust, but the most complex to implement. Files aren't actually being passed around, so performance should be good. However, I fear this is over-architecting the solution.
What is the best approach for transferring files between applications running on the same Android device? Of course, I am open to other options which I have not outlined in my question.
Content provider is definitely the way to go. If you consider that google uses this approach for almost everything then it becomes appaentr that this is the intended design method.
I'm not extolling the virtues of them, but in the land of the blind, the one eyed content provider is king.
Update
There is an example of how to do this in CommonsWare book, see the link provided.
Source of Content Provider/Files
Use the synch framework for content providers. Simply maintain a list of requests and then schedule the sync to download those file. You can also do this on network tickles etc. you can use broadcast intents or contentobserver to notify clients that the file is downloaded.
In essence this is probably similar to your 3rd option but importantly it uses the Android supplied tools rather than rolling your own.
Ad Endum
Best place to start is the android SDK sample in: android-sdk\samples\android-8\SampleSyncAdapter but be warned that there's a load of contacts related stuff that masks the juicy bits. It took me a while to figure out that I could delete almost all of it except the syncadapter
http://developer.android.com/reference/android/os/ParcelFileDescriptor.html can be sent between processes. I believe that there is a subtly where these are explicitly blacklisted from being allowed to be put in intents. They can be sent through AIDL though.
Also, do NOT use the sdcard for this. This is just asking for trouble. One sdcard is world readable, so anyone can see it. Also, you do not always have access to write to the sdcard (it is removed or put in UMS).
Using the SD card is definitely the recommended way to go to share files on Android.
However, I would go with a modified hybrid solution which makes use of startActivityForResult() and onActivityResult() (docs here) on the client side to communicate CRUD requests (and getting the Uri to the file(s) on the SD card if needed) if you don't mind creating a dummy activity as a front end to your service. Clients, once finished with the file(s), can call startActivityForResult() again to alert your app to changes.
Of course this can be done with startService()/bindService() however it doesn't provide an easy way for clients to obtain a status result especially if you need IPC.
Although content providers/resolvers feel like the correct way to go about things, I do feel it is more for single direction requests specific to providing/consuming content.

Difference between Android Service and Content Provider

I am developing an app and get confused about the idea of Service and Content Provider in Android. In practice, what will be the difference between them?
Content Provider
is a facade and it defines a way to share data among applications. You many attach a local database to your app or create Content Provider mapped to a universal database so that all the application on the same device can share it.
Service
is long running processes that need to be decoupled from main activity. It has local and remote service. local service is like the local database, and remote service is like Content Provider sharing the database info.
What My App is doing?
downloads info. from multiple internet resource in the background (I suppose this will be Service) and store the info. into database, and multiple applications will need to retrieve the data, format them and output them to user (I guess it will be a Content Provider).
What will be the fine line between Service and Content Provider? Newbie in Android, and any suggestion is welcome.
Lily
Your understanding of the difference between a Service and ContentProvider is pretty spot on. The key thing is that a ContentProvider simply acts as a conduit for retrieving data, while a Service is meant to do something in the background without user interaction.

Categories

Resources