Copying Assets to internal storage slows down my application and takes a lot of time to load. Since, I want my application to run offline, I need those asset files to be copied.
But, do I have to copy every file each time I run my application ? Can I just copy the files that I have made changes to ? Might be a noob question. Any advice is appreciated. Thank you
No, you don't. You only have to copy it in 2 circumstances:
1)This is the first time your app is running.
2)The app was just upgraded and you need to copy over the new asset. There's several ways to check this. An easy way is to write the version of assets you've copied over to shared preference, then check if it matches the version number of your app. If they match, you don't need to rewrite the assets.
So the combined pseudocode is
if(sharedPreference.get(VersionNumber, -1) != App version number){
copyFromAssets();
}
Related
I'm looking to packing a large sqlite database with an android app, about 200-300MB. From what I've read, my options are putting it in the assets folder, and coping it out at runtime, resulting in duplicate data, or downloading the database from the web at runtime. I don't want to create a webserver for this app, so I was thinking of creating a seperate app that just installs the database to get around the data duplication problem.
All of those are pretty crummy, and I was wondering if there is a better solution?
First, I don't think you are allowed to put a 200-300MB database in your assets folder and distribute it as a single apk, since the hard limit for an apk file size is (as per google's documentation) 50 MB and I doubt that your db will compress that far.. Google introduced the "APK expansion files" for packaging large files with your apk. You can read all about those here: http://developer.android.com/google/play/expansion-files.html
I think (but I have no experience with expansion files myself) that this will not fix the issue you mentioned about having to deal with duplicate data because of the requirement to copy out your database file, but at least this will help you in the sense that you won't have to host your database file on your own webserver. I quickly scanned the documentation on the link I gave above and it clearly states that you should NOT throw away the expansion files when you are done with them, so no help on that part.
Of course, for the "setting up your own webserver part": I wouldn't even bother setting up my own webserver. There are plenty of parties out there that provide you some file hosting service. Probably you will have to pay for the bandwidth, but hey.. if people download your db file a lot, that also means that your app is doing well ;-)
I test of apk expansion files. I created a test app with a 100 MB sqlite database, uploaded the apk and database to the play store. I then downloaded the app onto the phone, the database was downloaded at the same time. The database was automatically renamed and placed in the publicly accessible directory:
/storage/sdcard0/Android/obb/com.example.app/main.1.com.example.app.obb
The app was able to open the database without any problems, but required external read and write permissions. The new and original database are bit for bit, the same. This appears to be the best solution for my use case.
A few issues, the new android developer console does not support uploading expansion files, so the old one needs to be used. Google only allows 2 expansion files, so that may be an issue for some use cases. Google say that you must not rename or delete the file, and that your app must be able to download the file from Google itself if it wasn't automatically installed.
I making an application with phonegap/cordova where I need to keep a lot of files up to date. Some files (mainly images) will need to be erased in time, and some new ones will get downloaded. The thing is, in Android, to manipulate those files, it seems I need to have them on the sdcard; so I copy the files the app starts with from my assets folder to the sdcard. It just seems like a waste of memory space.
Do you know if is there anyway I can start with the app having those files the app starts with already inside the sdcard? or at least somewhere I can delete them later?
Thank you.
Files that are delivered to the device as part of your APK will be stored in a form that cannot be modified by your application (other than by updating to a new version of the apk).
If you copy the files out of the APK into the private internal storage area or the external storage area, those copies can be modified, but the originals inside the apk will remain.
The most efficient solution may be to not put these files in your apk, but have your app instead download them separately on the first run, using whatever mechanism you wanted to use to change them in the future.
(Some people object to this feeling that such files are less secure against unauthorized use, but as the contents of an .apk are trivial to extract this is not a strong argument. Needing to maintain a server to download from is a slightly more substantial objection.)
You do not need to store the files on the SD Card. Each app has its own internal storage that is not accessible by any other apps. For more information see the official docs: http://developer.android.com/guide/topics/data/data-storage.html
I have been gathering information in this site and others about the best way to include a pre-populated sqlite database in Android. I just would like to confirm that I understood the reasons of why something that should be trivial… it is not.
So could someone please tell me if my following conclusions are correct or wrong?:
the main reason many people suggest copying a pre-populated database file from the assets folder to "/data/data/YOUR_PACKAGE/databases/" is because there is no way to access a database file in the assets folder or doing that would be overly complex (?). (Could someone clarify which of these two answers is the right one ?)
another important reason database files in the assets folder must be copied somewhere else is because files in that location cannot be updated. Then even if a database in the assets folder could be open, this would be useful only if such database does not have to be modified.
UPDATE: I launched a new thread focussing only on this issue: Opening a read only database directly in the assets folder.
files in the assets folder can be only 1 Mb size (unless they have certain file extensions such as mp3). Note that this restriction is not relevant if: your database is smaller that 1 Mb, or you do not mind dividing your database in 1 Mb chunks and putting them together at runtime, or you do not mind distributing a database file with a mp3 extension.
If the database file is copied from the assets folder to "/data/data/YOUR_PACKAGE/databases/", there is no way to delete the original database file at the assets folder to avoid having a duplicated file. This is also because files in the assets folder cannot be modified.
Making the puzzle a bit more complex: I found in the comments to the accepted answer of this question: Ship an application with a database
that copying the database from the assets folder to another location in fact does not work on some devices running 2.3+. Is that accurate ? If that is true, then the best alternative would be to download the database file from the web at first run ?
Thanks for any clarification.
You're essentially confusing apks with actual folders on your device.
Think of an apk as an install package - not unlike the msi of the Windows world. The whole goal of this install package is to securely authenticate and deliver code and resources to your device. In a naive implementation, you would then unpack said code to a read-only location, the resources somewhere read-writeable and be on your merry way.
To save space, Android is a bit smarter - the code and resources never leave the signed archive, so you always know it's the ones you put in and you don't waste space by storing the code twice. There's some real magic going on in the class loader that also allows it to unzip classes on the fly but that's besides the point.
So, essentially, everything in this compressed install package is read-only (by virtue of also being signed). It's your job to be the "installer" and move whatever resources you need to a read-writeable location. Of course, you can't touch the apk once it's in place since that would allow for malware and defeat the whole purpose of the signing.
Hope this clears the confusion.
My android application needs another NATIVE application executable to run before the android one, so that they can communicate through sockets. Android application has a JNI layer for handling the client-side communication.
Now i need to bundle up the native executable along with the apk file, so that when it is installed on a device it gets unzipped into either the phone memory or the memory card.
How do i do this?
I tried keeping the native executable in res/asset and in res/raw folders, but they still don't get unzipped in /data/data/ folder.
One way I could find is to use AssetManager and then with help of InputStream and OutputStream, i can write this file onto the device the first time it is run and then use it. But there is no point to write it manually on phone memory as it might eat up the memory. ( the case where if memory card is not present. )
Can anyone help me on how can i achieve this? It would be great if there is an option to unzip the necessary files automatically at the time of installation.
How do i do this?
You don't. You unpack it yourself on first run of your application.
One way I could find is to use AssetManager and then with help of InputStream and OutputStream, i can write this file onto the device the first time it is run and then use it.
Correct.
But there is no point to write it manually on phone memory as it might eat up the memory.
Then why did you want it automatically unpacked there in the first place?
It would be great if there is an option to unzip the necessary files automatically at the time of installation.
No, sorry, this is not possible.
We have the same issue ... the direction we are exploring is to have two separate installs - the first one is the app and the second one is the data-app. When the data-app installs it copies the binary files to the SD card. When we uninstall the data-app it frees up the internal storage.
We don't have this one completely licked yet, and would love to hear other input and maybe find someone to help us by writing a couple of skeletal sample applications for us.
There are so many people who are in this boat (based on my googling) that if this approach doesn't work I suggest we (or someone) set up a generic file delivery web server and generic file delivery Android service and make it available to developers for a very low cost.
This isn't a typical use of OBBs but why not use one? It would then be a file separate to your apk installed in a pre-determined location. It doesn't have to be compressed.
I have 2 binary files that i would like to package with my apk. (/res/raw)
i need to copy these 2 files to /sdcard when the application is run
how can i do this?
We have the same issue ... the direction we are exploring is to have two separate installs - the first one is the app and the second one is the data-app. When the data-app installs it copies the binary files to the SD card. When we uninstall the data-app it frees up the internal storage.
We don't have this one completely licked yet, and would love to hear other input and maybe find someone to help us by writing a couple of skeletal sample applications for us.
There are so many people who are in this boat (based on my googling) that if this approach doesn't work I suggest we (or someone) set up a generic file delivery web server and generic file delivery Android service and make it available to developers for a very low cost.
You need to use the AssetManager.
That will give you can InputStream that you can copy to a FileOutputStream.
It all depends on what your goal is by doing this.
Are you trying to be nice to the user and conserve disk space on the device by moving files to the sdcard? Or do you merely want to ensure that these files are on the sd card?
If you just want to put the files on the sdcard then you should use the AssetManager as CaseyB mentioned
If you are trying to conserve phone memory then consider distributing the apk file without the 2 raw files, and then on first run download the files from a server that you have set up. This may cause a bit of a problem due to the time needed to download the files, but some users on devices with limited memory available on the device itself will be appreciative of it.