I have been sufferring in one problem for several days.
Currently I'm running in the source code of "Settings" on Android2.2.
In AdroidMenifest.xml, we can see:
android:sharedUserId="android.uid.system"
With this, many permissions can be accessed for the activities in Settings.
But with this statement, the sd card can't be accessed for Read/Write, I have tried to read files in directory
File f = new File("/mnt/sdcard/"+filename);
or
File f = new File("/sdcard/"+filename);
But all of them don't work, I got an exception telling me that the file didn't exist (I have already put the file there).
If I delete android:sharedUserId="android.uid.system", then I can access the file successfully . However, I need the android:sharedUserId="android.uid.system"
to make the other activities run well.
Does anybody happened to meet the same problem, and have you solved it? Thanks!
The system user can not access the SD card, because if the SD card gets unmounted it may need to kill any processes that have files open on it and we don't want system processes being killed like that. If you want to access the SD card, you need to not use the system shared user ID.
Related
Trying to make some sense of this complete mess of scoped storage.
So I'm storing some files (logs) generated by App A inside the Download folder.
I'm using Mediastore/ContentResolver and no problems with that either for read or write access as long as it's from App A.
But then App B needs to read these files and here comes the problem.
Same way using Mediastore/ContentResolver but the files seem invisible for queries.
Download is supposed to be a Shared Storage, but files are indeed generated as -rw-rw--- which means no permission for others which could explaind why App B does not sees files from App A if they are not in the same group.
Would the Storage Access Framework method work around this?
Thi not tried it yet because poping system window's is definitely not something I wanted as a user experience for my App.
Thanks.
If the second app has 'all files access' with MANAGE_EXTERNAL_STORAGE it can also list the files of the first app.
Otherwise you can let the user of the second app pick those files with ACTION_OPEN_DOCUMENT of Storage Access Framework.
You better store your files in a sub directory as then second app can pick complete directory with ACTION_OPEN_DOCUMENT_TREE and list all the files.
I'm trying to create an android application that writes to a text file that can later be accessed once a button is pushed.
The past week i've tried a bunch of methods that people suggest to write to the internal storage, and sometimes it appears to work (using an outputwriter, and also a File class?), but i'm never able to locate the file on the Android device I test-run it on.
I'm rather new to development for Android, so all this is confusing to me.
Thanks
If by "internal storage" you mean what the Android SDK refers to as internal storage, this is not possible. Files that you create there are only accessible to your app, not by file managers on or off the device.
If by "internal storage", you mean what the Android SDK refers to as external storage, you need to:
Get a File pointing to a directory on external storage, such as calling getExternalFilesDir() on some Context, like your Activity
Create that directory if it does not exist
Create a File object pointing to the file you want to create, off of that directory
Use standard Java file I/O to write to the location identified by that File
Use MediaScannerConnection and its scanFile() method to tell Android "hey, I just put a file on external storage, please index it so it shows up in file managers"
Also:
Ideally, you do the disk I/O on a background thread, so you do not freeze the UI while that work is going on.
Depending on your minSdkVersion and where you choose to write the file, you may need the WRITE_EXTERNAL_STORAGE permission
Depending on your targetSdkVersion, you may need to ask for WRITE_EXTERNAL_STORAGE at runtime
You CAN access internal storage sometimes, but this depends on your phone.
You always can get data from internal memory for rooted phones (need root).
Files are in the folder /Android/data/
Some vendors allows you to run root shell on non-rooted phone through adb
(I saw this behaviour on Explay tabet) just run adb shell su to
test. Then you can copy your file from internal storage to public
with shell commands.
adb pull may also work in this case. (Again
vendor dependent)
I am aware about changes in Access to SD card introduced by Google with Android 4.4. However in my application I need to be able to store data on some removable /secondary sd card.
When I create the application folder (app.xyz.com) on the secondary using default file manager then I am able to create dirs and files inside. But by default such dir dosen't exist on secondary sd card.
So, I would like to create the application specific dir programmatically inside my application…
Do you have any idea how to do this??? Simple file.mkdirs(), even with the correct application related path, doesn’t work. Permission error…
I have spend already two days trying to find a way, without any success
THANKS FOR YOUR HELP!!!
Do you have any idea how to do this?
Use getExternalFilesDirs() (note the plural). If that returns more than one entry, the second and subsequent ones are on removable media. Those directories you can read and write to without any permissions on Android 4.4.
From my android app, I'm downloading an apk from the web, storing it in application's private storage (openFileOutput(FILENAME, Context.MODE_PRIVATE))
and trying to call the android package installer for this downloaded apk by,
intent.setDataAndType(Uri.fromFile(f), "application/vnd.android.package-archive");
startActivity(intent);
but I'm getting an error which says
Unable to open zip: /data/data/com.test/files/abc.apk : Permission denied
in the LogCat
and,
Parse Error: There is a problem parsing the package
on the phone screen.
Is it happening because the apk file is in application's private storage so the Android package installer can't access it? If yes, is it somehow possible to still get the apk installed (with user's permission of course.) or Am I doing something wrong?
PS: Please don't assume the phone to be rooted.
In addition to Mark Allisons comment, my GUESS is that since you have the file saved to private storage with mode_private, only your application has read/write permission. But you are trying to have the package installer read it which means that the file must be accessed by an External application and therefore should either be MODE_WORLD_READABLE or MODE_WORLD_WRITEABLE.
Or you could save it to external storage where it is world readable by default.
Ok, for now I've figured out a workaround (and which helped me confirming the exact problem also- the problem was that installer couldn't access the apk file). Now, I'm using MODE_WORLD_READABLE instead of MODE_PRIVATE while saving the file in internal storage, and the android installer is able to access the apk and can install it without any error.
Actually, for me the main purpose of using internal storage was that users shouldn't be able to copy the apk file directly (assuming a simple threat model in which a user doesn't have rooted phone, but can browse through the SD card to find the apk and copy it). Though I'm still not sure whether the file is visible to a user now or not? I mean I'm (almost) fine if the downloaded apk can be accessed from an app in the phone, but can't be copied directly by the user.
Would be helpful if someone knowing the exact scope of MODE_WORLD_READABLE could elaborate on the same, specifically whether a file saved in this mode can be browsed in the (unrooted) phone. Also, is it possible to have a better strategy to safeguard the apk while still allowing the installer to access it?
MODE_WORLD_READABLE does say that it can be accessed by whole "world on the phone" so other apps can get it including file explorers. Some programs like es-file manager let you see contents on device private storage even if you are not rooted but don't let you change those files. Why don't you just delete apk file immediately after installation ? Also since you are downloading apk file in your application I am guessing you don't want to use play store but if that is not an issue see Licensing options for your app on: http://developer.android.com/google/play/licensing/overview.html since there is probably use case that covers your requirements.
It'd be convenient if an application I'm writing stored some files to external storage permanently (so they persist after the application has been exited[destroyed]), but on an uninstall I'd like to do the decent thing and have these files removed to free up the storage.
Is there any way I can have these files removed on an uninstall?
If there isn't (and I'm skeptical), then I'll have to create these files each time. I'm trying to save start-up time and also occupy required space by having them exist permanently.
Note: I need to use external storage, so both internal storage or a DB would be inappropriate.
actually it is possible .
android will automatically remove files of the app in the external storage , but the files must be inside a specific path of the app :
"...../Android/data/APP_PACKAGE_NAME/"
where APP_PACKAGE_NAME is the application's package name.
another path that is automatically being emptied is :
"...../Android/obb/APP_PACKAGE_NAME/"
where APP_PACKAGE_NAME is the application's package name.
the data is for anything you wish.
the obb folder is for huge files that are downloaded using the play-store and the apk extension library . you are not supposed to create files there .
No, I don't believe so. Only files that you write to internal storage will be removed when your application is uninstalled (or if the user presses the 'clear data' button in the Application settings app).
Your app can't receive its own PACKAGE_REMOVED broadcast intent either, so you essentially have no notification that you're being uninstalled.
Yes, this is possible. Simply write your files to the external files directory:
File dir = getExternalFilesDir(null);
This will create a folder at /Android/data/your.package/. Note that this is not External as in sdcard, but it is publicly accessible. If a user uninstalls your app, this directory will also be removed, along with all of its contents.
Quoting from the blog post of CommonsWare
Internal storage: your file is deleted
External storage: if you wrote your file to a location rooted at getExternalFilesDir() or getExternalCacheDir(), your file is deleted. If you wrote your file elsewhere (e.g., Environment.getExternalStoragePublicDirectory()), your file is not deleted
Removable storage, prior to Android 4.4: removable storage is not officially accessible; if your file winds up out there, it should not be deleted when your app is uninstalled
Removable storage, Android 4.4+: AFAIK, if you write to a supported location (getExternalFilesDirs() or getExternalCacheDirs()), your file is deleted if that particular bit of removable storage is in the device at the time of uninstall