My app downloads image files for offline use. Using the DownloadManager, the files are saved to the app's /data/ folder (retrieved with Environment.getDataDirectory().getAbsolutePath()). When displaying the images, the function File.exists for the path /data/filename returns false. When I provide the full path (kinda harcoded with the following function) everything works.
private static String getImageUri(Context c, String name) {
return Environment.getExternalStorageDirectory().getPath() + File.separator +
"Android" + File.separator + "data" + File.separator +
c.getPackageName() + File.separator +
"files" + File.separator + name;
}
It seems the File api requires the full path but I couldn't find a more elegant way of getting the full path.
Is there a better way of doing this? Another api that allows r/w and treats paths the same way the DownloadManager does? Or a better way of retrieving the full path?
The code returns the path storage/emulated/0/android/data/com.package.app/files/data.
I assume that your lowercase android is a typo, as that location should be Android.
You can obtain that location more simply via getExternalFilesDir() (method on Context), though you will need to append the trailing data segment yourself.
The line request.setDestinationInExternalFilesDir(context, Environment.getDataDirectory().getAbsolutePath(), name); works
It would be simpler — and far more compliant with the documentation — to just use request.setDestnationInExternalFilesDir(context, null, name). Then, your downloaded file would be in the location new File(getExternalFilesDir(null), name).
Related
I am working on getting my application over to scoped storage. One feature of the app is that it contains document templates stored as application assets. At run time, they are copied to local storage, here: (code is Java)
String path = Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_DOWNLOADS)
.getAbsolutePath() +
File.separator + "Templates";
Since these files are private to the app, I am happy to put them in
String path = context.getFilesDir()
.getAbsolutePath() +
File.separator + "Templates";
But I'm also planning to do this (or something like it) for the user to browse for files:
Intent newIntent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
newIntent.addCategory(Intent.CATEGORY_OPENABLE);
newIntent.setType("*/*");
startActivityForResult(newIntent, 0);
My question is, how can I get ACTION_OPEN_DOCUMENT to include as browsable the place where I've put my templates?
The only way to expose private files from your app in the system file picker is to create a custom DocumentsProvider. This would add your app as a source of files that the user can pick from.
Note that with this approach, there is no requirement to copy files to local storage at all - your code for opening a document can use AssetManager's openFd() method along with getParcelFileDescriptor() to directly pass that through to the calling app without going through the File APIs at all.
Which is correct,
String filePath = Environment.getExternalStorageDirectory()
+ "/data/com.packagename";
or
String filePath = Environment.getExternalStorageDirectory()
+ "/Android/data/com.packagename";
if I want to store data in external storage? I see many apps are using the second option, but some use the first path.
You should rely on the API to figure out the directory for you:
File externalDir = Context.getExternalFilesDir(null);
Context.getExternalFilesDir will return your 2nd path. Programs that return the 1st path probably hardcoded the path and got it wrong as a result.
It's been two days now I'm stucked on a veeery common and simple problem I don't seem to be able to solve (while other people are):
creating a folder on a SD card on Android!!! YES!!!
I red many many posts here, many tutorials that seems to say the same thing:
create a string with the external folder path + /yourFolderName
create a new file passing the path as argument
call mkdir() (or mkdirs()) on it
done!
alongside you can check if the SD card is MOUNTED, READABLE, WRITABLE,
and of course don't forget to put in your Manifest.xml the permission to WRITE_EXTERNAL_STORAGE, but be careful, it must be set as direct child of the manifest and not of the application!!!
Well nothing of that seems to work for me.
The folder_creation code is inside onCreate() and I'm trying to call a MediaScannerConnection to test if the file exists but it return null on OnScanCompleteListener - but I'm not sure I'm using this in the correct way-.
The application runs fine (launch the default camera activity then returns to the main one), but the folder is not created! (by now I just want to create the folder with nothing inside)
Maybe is an issue related to the package name containing the word "example" included in my package name? (I red something related somewhere...)
What could be wrong? Please give me an hint, advice, something...
I'm building on a Mac 1.7.5 with Eclipse using minSdkVersion = 8 and testing on a HTC Wildfire S with 2.3.5 (sdkVersion = 10). Checking with ES File Manager 1.6.1.6 on a non rooted device
Here's the main part of the code driving me crazy...
I would be very glad to know there's something I can do...
Thank you in advance!
myPath = Environment.getExternalStorageDirectory().getAbsolutePath() + File.separator
+ "myFolder";
File newDirectory = new File(myPath);
Log.v("judy says", newDirectory.toString());
newDirectory.mkdir(); // this doesn't work because "no directory" is displayed in the logCat window
if (!newDirectory.exists()) {
newDirectory.mkdir();
Log.v("no, no, no", "no directory");
}
MediaScannerConnection.scanFile(this,
new String[] { newDirectory.toString() }, null,
new MediaScannerConnection.OnScanCompletedListener() {
public void onScanCompleted(String path, Uri uri) {
Log.i("ExternalStorage", "Scanned " + path + ":");
Log.i("ExternalStorage", "-> uri=" + uri);
}
});
This works, if you want to create a directory "/mnt/sdcard/somedir/newdir"
File temp = new File (Environment.getExternalStorageDirectory (),
"somedir" + File.separator + "newdir");
if (!temp.exists ())
temp.mkdirs ();
ok, I solved: Simply using "uses permission" instead of "permission", the problem was that I was hard writing it in the manifest.xml, instead of using the graphical interface, this way I could use the built in list to choose a permission...
Really sorry if I bored...
I hope this could be useful for someone.
I have an app that downloads files using Android's DownloadManager to a folder on the external file storage (SD card). This normally works fine, but there are some sources that cause the DownloadManager to trash the file when it finishes downloading it. A good example of a source file is:
http://traffic.libsyn.com/hdtvpodcast/HDTV-2012-06-01.mp3
It looks like maybe the problem is only with files from libsyn.com, but I'm not positive. I've looked around for ways to change how DownloadManager handles saving files, but can't find any options in the class.
This is where I enqueue the URL for download:
request = new Request(Uri.parse(currUrl));
external = Uri.fromFile(externalFile);
request.setDestinationUri(external);
request.setVisibleInDownloadsUi(false);
request.setNotificationVisibility(
DownloadManager.Request.VISIBILITY_HIDDEN);
currDownloadId = dm.enqueue(request);
The file locations are created using this:
Environment.getExternalStorageDirectory().getAbsolutePath() +
File.separator + "Podcatcher" + File.separator + "Feeds" + File.separator +
[int] + File.separator + [int] + [string extension];
Which turns out to be something like this when I query DownloadManager.COLUMN_LOCAL_FILENAME column from DownloadManager:
/mnt/sdcard/Podcatcher/Feeds/19/225.mp3
Most of the files are fine and persist after download, but not in this case. Any ideas about how I can force DownloadManager to leave the file after it is downloaded?
EDIT: I neglected to mention that when I use the standalone Download Manager when downloading this file from a browser that it reports failed at the end of the download. Perhaps my only solution is to download it from scratch, without DownloadManager?
try please followed code - worked for me:
request.setMimeType(application/octet-stream);
I want to save some data in the user's external directory (ie. SD card), but there seems to be a weird problem. I'm using Environment.getExternalStorageDirectory() which returns "mnt/sdcard/" (which is fine). I want to create two folders on in this directory so I do:
File main = new File(getExternalStorageDirectory() + "/my_app/some_data");
if(!main.isDirectory())
main.mkdirs();
Now I thought this would make the directory "mnt/sdcard/my_app/some_data", but after using a file manager to look at the SD card, it turns out that this folder is created at "mnt/sdcard/my_app/mnt/sdcard/my_app/some_data", which is quite bizarre. Can anyone tell me how to fix this?
Try the following and see what you get...
String packageName = this.getPackageName();
File myFilesDir = new File(Environment.getExternalStorageDirectory().getAbsolutePath() + File.separator + "Android" + File.separator + "data" + File.separator + packageName + File.separator + "files");
myFilesDir.mkdirs();
It's exacly what I use to create a working directory on an SD card. For me it creates...
/mnt/sdcard/Android/data/com.mycompany.myApp/files
...where 'com.mycompany.myApp' is the actual package name of my app.