How exactly does one go about such a simple thing in this beautifully over-complicated framework?
Yes I've read the documentation on Data Storage for Android, about 54.5 times. But I can not find anyplace where the documentation describes how you should go about placing files on the external storage at compile time.
Here's what I want to do: I want to include a couple of (big) (10-20mb) audio files in my application. Naturally, I do not want these to be stored on the internal storage, because they're just too big. So placing them in res/raw is not an option (because, if I understand correctly, things in res/raw will be placed in the internal storage of the phone, correct?)
The documentation only states that "if you want to store static files at compile time, use res/raw". Now if Android is smart enough to place those files on the external storage all by itself then I'm forever greatful.. But somehow I doubt that. All help is appreciated :)
(Sorry if it seems like I have an attitude, I've just spent way too much time on something so simple)
Thanks again :)
UPDATE: I ended up downloading the files from the application instead of including them at install-time. Thanks for the help guys!
I hit a problem while trying to download through a url, spent a lot of time trying to get it to work, and in the end the problem was because I hadn't declared the correct permission in the android manifest file! So to anyone who's looking to download stuff in their apps, do not forget to set the permissions in the android manifest, here are the permissions I needed:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"></uses-permission>
<uses-permission android:name="android.permission.INTERNET"></uses-permission>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"></uses-permission>
<uses-permission android:name="android.permission.READ_PHONE_STATE"></uses-permission>
Place these above the start of the tag
If your large files are in the APK, they'll be stored wherever the APK gets stored - this can be internal or external, and it seems that this is not what you want. The most likely option for you seems to be to place the files on a web site and during the first run of your application, it must notice that the files do not exist and retrieve them post-installation.
how you should go about placing files on the external storage at compile time.
I'm assuming the above is a typo and you mean at install time.
As for your requirement - it's not possible to instruct the Android Application Manager to unpack different parts of an APK to different places during the installation.
Further to this, there's no guarantee that an APK download will go to the internal or external memory storage (where it will stay unless otherwise deleted).
And even further to this, there's no guarantee that even if a device has external storage, it will be available at installation time or have enough free space.
At this point I wonder about audio files which are 10-20MB in size - either they're very long (in duration) or they're encoded at a high bit-rate. If it's the latter then this doesn't make too much sense as most mobile devices have fairly poor audio reproduction (in relative terms)....just some thoughts to mull over.
I personally think mah's suggestion of downloading post-installation may be a better approach but my comments about availability of external storage still hold true.
Proper approach to solving your problem on Android is "don't put them with your application". Just download them on first start from your web server (using HTTP client API) or, if these files will be upgraded independently of the application itself, prepare them as a separate "application" for the user to download via Market.
Related
Well hello, im working on a app that take a picture and then save it into the external storage, the problem that i get is when i use a external app, to clean up the cell phone memory, this kind of apps get into the folder where the pictures located, then deleted everything on it, i realy don't have any idea to protect them.
sorry for the problems with my English is not my native tongue
I think the problem is not yours. The problem is your cleaner's. Modify the cleaner's settings. Android cleaner like Clean Master is just weird. I don't know what kind of cleaning they do! Once they deleted my 150+ apps from my SD Card. So, if you are tensed about protecting your files from being deleted then it is worthless. You can't. Ok, think, a user is not using any cleaner to keep his/her phone tidy. But what will you do or how you will protect your files when the user is going to delete those files himself/herself?
The one thing you can do is - by achieving SuperUser permission from a user, you can just modify the SD Card's W/O or R/O system. But it has also some disadvantages. If you do something lile this, then you app may be introduced as a malicious program by your user. So, afterall, the answer is it isn't possible...
You should use:
getFilesDir()
This folder is located inside Android/data/data/your_package/ so no app except yours has access to it (unless it has root permission).
Can someone explain the permission of the app specific folder /Android/data/< package_name>/files/ as described here http://developer.android.com/guide/topics/data/data-storage.html#filesExternal
It is not clear when it is truly private to the app and when it is world-readable. Is it the case that when the USB mass storage is enabled the files in the external storage, including the app specific folder, are world readable?
I tried using a file manager app (ASTRO file manager) and I am able to see/open files in the app specific folders on the sdcard and this is irrespective of the setting Protect USB storage in the developer options under Settings. I am using Google Nexus 4 running 4.3 version of android.
So it's confusing when this folder /Android/data/appname/files/ is really private to the app.
thanks.
Let's talk some Android security, shall we?
You can not access an application's home directory, on an unrooted device. This would have been a MAJOR security hole.
Creating WORLD_READABLE files is deprecated, and judging by the text in the API, this is one of those cases where "decperacted" means "deprecated".
So - you wanna pass data between applications?
a. You can leave a file in a set place for the 2nd app to fetch. This is a bad idea though. It litters the user's storage space, there is NO SECURITY at all, the 2nd app is not notified about pending updates and you can not easily determine the state of affairs. I suggest you stear away from this approach. Even though, I've included some elaboration in the UPDATE section below.
b. For simple, small chunks of data, I suggest you go the Intent/BroadcastReceiver approach.
c. You can go the ContentProvider approach is you wanna do things the right way.
d. You can go the Intent/Service approach.
e. For true IPC - use AIDL.
UPDATE:
I suggest you begin by reading Google's article throughly. This article clearly deals with the case of transfering large files between apps. Also, as you can clearly witness, the terminology is quite confusing.
So let's review your question in light of Google's article on the subject.
Internal storage is private to your application and can not be accessed by other apps. You can access its directory structure via Context.html#getFilesDir().
Please mind that:
Files written here are deleted when the user uninstalls the app.
External storage can be physically internal (built in storage) or external (removable SD card). There is no security model here, files are visible and accessible to the world. You can access the external directory structure via Context.html#getExternalFilesDir(). Please mind that:
This direcory might become unaccessible (when the user connects the device to a computer or when he removes the SD card).
There might be a seperate directory per device user.
Files remain even when the user uninstalls the app.
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
Indra's point is correct. for reading EXTERNAL_STORAGE you need to put this uses-permission
try this permission
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
As far as I knew, the files on the external storage are public, but as Indra points out you do need the permission if you want your app to read them:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
I think it is only the internal storage files that are private, requiring ROOT access to be read from outside your app (or an app signed with the same key as your app).
i'm writing an application that needs to store some data,and picture. For example place's information. this information don't need to change very often. and
I have seen that databases are
stored under /data/data/package_name/databases
I decided to store my data under /data/data/package_name/files.
With the emulator i can see all these files (databases)
under the proposed directories but moving the application on a real
device and installing a file system browser i cannot see any file
under /data. i know that there are some security constrain in (not-rooted) device. However, are there any suggestion about the solution.. where can i store these data and how? because i'm quite new to android. Thanks so much for your help.
The reason you can't see it on the device is basically just as you said; the device isn't rooted, so other apps don't have access to the /data folder.
This is okay though, because you can still store your files there. Your app has access to anything under /data/data/package_name/, you just won't be able to see it in a file browser unless you root. This is normally a good thing, to keep average users from mucking around with your databases/files.
Read up more on storage methods here.
My app has several image and media files, which are around 1MB each or so. So if i follow the normal way, the app size is crossing over 40MB, which is huge. Is there anyway to avoid this?
I have heard of external storage, but i really don't get any clue of how to work on them!
Do i need to ask all those who instal this to save the images and media files in the external disk and then the app uses those? This makes my files public..isn't it?
I actually don't own a android device. So is it like, whenever people install an app from the market, does it ask if it has to install in the phone memory or the external memory?
I really need your help.
If there is a way, i'd be thankful if you can provide me the step by step details of how this can be done!
Thanks a lot..
Regards
Nithin
There is, from the little I know of this, a slight security risk from putting files onto the SD card. I don't think I personally would worry too much about that since most people that would want access to the files in your apk (Which does not include your source code) could get it regardless without too much trouble.
As of Android 2.2 the user has the option to move an app to their SD card, but only if the developer explicitly tells the app to allow it. I'm fairly sure this only applies to 2.2+ devices though, so being that you are likely going for a larger audience than that it isn't an end-all solution. I am only really pointing this out in case you do end up putting one large file on the market. If so, be sure to allow the transfer to SD card, your app will stay on devices much longer.
Downloading the files online from within the app and saving them out to the SD card would be a good solution, though I am not sure how end users feel about downloading a small app then having to download a very large package before using it. In the end they will have to download it either way, so it is up to you whether you want to ask them to do it up front in the market or afterwards via the app. If you do want to try to download all the content then maybe the code example in this link will help you figure it out :
http://androidsnips.blogspot.com/2010/08/download-from-internet-and-save-to-sd.html
You might consider streaming the files or downloading them inside the application to the sdcard. Speaking from experience my users have had problems downloading apps as big as 30MB. Some phones also have a severely limited internal memory, which is where the applications are downloaded to.
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.