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
Related
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.
I have an application that uses a webservice to get information and save the changes made by the user.
currently I have one service that runs while the application is open, and it has public methods for each operation. the trouble is that service is growing considerably and I'm thinking refactor, but the question is what is the best way?
I can think of the following options:
Deferred services the current service and that all are initialized at boot time application
Create small services and that these are initialized by local broadcast
although I have doubts about performance. Can give me some clue or example about which method is better, do not really care that changes are instantly synchronized, these are stored locally and can be synchronized when possible. Data sent are not many, so the synchronization is relatively fast
Synchronization processes are something like
Check if there is new data (I have several types of data, these are the ones that are growing)
Synchronize user preferences
Most likely there's no point of having Service running all the time. Instead, I'd go for IntentService. If possible, I'd also condifer using push notification (like GCM) so the server could let my app know that there's new data to fetch (or maybe even send it to me if you'd fit in the GCM payload limit).
I am getting started on Android & iOS development and hence links to relevant resources will also be appreciated, just that I couldn't find anything much relevant.
Case Detail: I have to build an app that holds some critical information in a variable that is created, sent over a ssl-encrypted connection and destroyed. This variable shouldn't be read by any other process on the device. So far, I know of two cases that can happen:
[1] a service or program monitors the foreground app(which here would be my app) and then if it can inject some code(getting the foreground to bind to the rogue service for example) to read off the variable contents in question. I know OS safeguards exist, but are there any proofs out in the wild that demonstrate this ability of injecting code?
[2] a service or program monitors the network connections and logs the data being sent over the wire. Is there a possibility of apps reading network data like this? I know apps exist which can log the amount of data exchanged per app, but I have no clue as to whether they read system log files or actually monitor the connection.
It will be appreciated if details could be provided for both the platforms.
I work only with android, so this is valid for android only:
No, a service cannot inject code in foreground up, due to (at least) 2 reasons:
Each installed application gets it's own user id, and each process, and their data is protected by the user id. So one process cannot access the memory of another process. So no process can modify the memory either (by inserting code)
The java bytecode is converted to dalvik code, and stored in a place where only the system process can write. So no other process can inject code by changing the compiled dex files.
That is the protection provided by the system. Of course hackers might find an exploit in a certain library, and using buffer overflow might be able to run some snippet of code, but that's a different story. Also note that the data files of the process are private by default (no other process can see it), but processes could have read access to the code. Which means storing private keys in the code is probably not safe.
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.
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.