Our application has a large amount of C++ code that creates its own log file as a simple .txt file. It's a circular buffer so it's limited to the size we specify. It's also placed in whatever directory we specify.
The problem is where to place the file so it can be accessed with ADB or a similar tool (without rooting). If we didn't care about the publicly-accessible part, it seems this would be the logical place to locate the file:
packageManager.getApplicationInfo(applicationContext.getPackageName().dataDir
But since we want to be able to pull the file from a customer's phone for post-mortem debugging, I've tried placing it here:
"/mnt/sdcard/Android/data"
This is problematic for several reasons, but I'm not sure if they're all true. (1) It's hard-coded; (2) Not all Android devices have external storage, although I thought they still mapped it to internal storage? (3) The location isn't app-specific so it won't get uninstalled along with the app. And (4) Runtime permission for EXTERNAL_STORAGE is required.
I believe 1-3 can be solved with something like:
android.content.Context.getExternalFilesDir()
Or is there a better choice?
But I don't believe this will get around #4, which is unfortunate as I'd prefer not to "scare" users with more permission requests.
What's the best way to handle this?
Make sure that you have the permissions to read and write the External SD using this code in the Manifest File:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
And then this string will give you the wanted path:
String directory = Environment.getExternalStorageDirectory().getAbsolutePath() + "/Android/data/" + getContext().getPackageName();
/storage/emulated/0/Android/data/com.exemple.yourapp/
Related
Because of apk maximum size 50MB, i decided to make apk expansion file. I know that I can get any file (inputstream) from this package but I am working in LibGDX, and this doesn't have option to load textures/music from inputstream.
So, I must extract files, load texture/music and then I can delete file.
I think that i need max 50MB space and i have two options:
UNZIP TO:
ContextWrapper.getFilesDir() - it returns internal file, but I can't know how many files can I unzip there, because this storage is shared with all apps.
getExternalStorageDirectory() - it returns external file, but according to website (developer.android.com) "This directory may not currently be accessible"
Which directory will be best to unpack and always avaliable?
If, as you tell us, here there are big quantities of data, so in order to improve user experience (not all phones have huge memory and using internal storage may cause your app is uninstalled) you should use external storage.
You have to care about couple of things:
Add permissions to read / write
Check file availability starting app
Adding permissions:
<manifest ...>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
...
</manifest>
Checking file availability
And starting the app, be careful and check if external storage is available, and show message otherwise in order to avoid exceptions:
Caution: External storage can become unavailable if the user mounts the external storage on a computer or removes the media, and there's no security enforced upon files you save to the external storage. All applications can read and write files placed on the external storage and the user can remove them.
Use Context.getCacheDir() to get access to a private directory where you can extract files. This should be considered as a cache directory, so you should check for the file on startup and extract it again if it is missing.
This method doesn't require any additional permissions and is more secure. Also, the directory is guaranteed to exist by the Android APIs.
I am new to android. I am trying to download a file from server and save the file in a particular path. The application is working fine. However I am not able to find the path of the downloaded file. In the code I have given as
File output = new File("/data/data/com.test.firstApp/", fileName);
Where can i find the file on my system?
Don't use hard coded file paths. The framework will give you the base path of the area you want to save files to.
For the SD card, use Environment.getExternalStorageDirectory()
For local files, use Context.getFilesDir() (or Context.openFileOutput(String name, int mode), etc)
For local cache, use Context.getCacheDir()
Adding to Rich's answer, in the likely event you will end up writing to external storage make sure to include this permission in the manifest:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
Check this page http://developer.android.com/guide/topics/data/data-storage.html
You can find there many methods how to save file. What is more you can also read something about good practices.
Cheers
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.
in my application i create a temporary file this way
File tmp = File.createTempFile("TEST_", null, getFilesDir());
this resolves in a file that toURI()zed corrisponds to something like
/data/data/it.lorenzoff.test/files/TEST_XXX.tmp
In certain circumstances, i'd like to move this file permanently on sdcard but this code
dest = new File("/sdcard/permanentFile");
tmp.renameTo(dest);
never works.
I'm already using these permissions
<uses-permission android:name="android.permission.WRITE_INTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
but renameTo continue returning false.
What i'm doing wrong?
Thanks in advance
L.
The explanation can be found in documentation for File:
Many failures are possible. Some of the more likely failures include:
Write permission is required on the directories containing both the source and destination paths.
Search permission is required for all parents of both paths.
Both paths [must] be on the same mount point. On Android, applications are most likely to hit this restriction when attempting to copy between internal storage and an SD card.
In this case source and target file paths point to different mount points (these two mount points even have different file system). You only option is to manually copy the file to sdcard and then delete the file from internal storage.
This seems like a trivial question, so whoever can answer first and provide me with a resource, I'd be happy to provide you with a green tick :)
How can I write files from within native code? I want to perform some processing in C++ which will output a .txt file, so I'd like to save that to the SD card. (I tried and it told me permission denied).
Thanks!
try to add this to your manifest
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
in default, android denies you of writing to external storage unless you specify your desire to..