Android save downloaded data to SD - android

I've developed an app which
- download some data ( .png and .wav files )
- insert the path where each files is downloaded into a database (SQLite)
So far so good, everything works.
Some users asked me if there was a way to move the the downloaded data in the sd card in order to save some internal space.
By now i create the directory with this line of code
File directory = getApplicationContext().getDir("folderName", Context.MODE_PRIVATE);
Then the app will fill it with all the stuff I downloaded.
I tried using this piece of code:
try {
File newFolder = new File(Environment.getExternalStorageDirectory(), "TestFolder");
if (!newFolder.exists()) {
newFolder.mkdir();
}
try {
File file = new File(newFolder, "MyTest" + ".txt");
file.createNewFile();
System.out.println("Path: " + file.getPath());
} catch (Exception ex) {
System.out.println("ex: " + ex);
}
} catch (Exception e) {
System.out.println("e: " + e);
}
And this create a folder and a text file into: /storage/emulated/0/TestFolder/MyTest.txt
Which is not my sdcard directory, it should be:
/storage/sdcard1/TestFolder/MyTest.txt
So my question is:
- where and how I saved my app's private data (.png and .wav files) in the SD card?

The getExternalFilesDir, getExternalStorageDirectory or relatives, does not always return a folder on a SD card. On my Samsung for example, it returns an emulated, internal SD card.
You can get all external storage devices (also the removable) using ContextCompat.getExternalFilesDirs.
My next step, is to use the folder on the device with the largest free space. To get that, I enumerate the getExternalFilesDirs, and call getUsableSpace on every folder.
I use this code to store (cache) bitmaps in a folder named "bmp" on the device.
#SuppressWarnings("ResultOfMethodCallIgnored")
private static File[] allCacheFolders(Context context) {
File local = context.getCacheDir();
File[] extern = ContextCompat.getExternalCacheDirs(context);
List<File> result = new ArrayList<>(extern.length + 1);
File localFile = new File(local, "bmp");
localFile.mkdirs();
result.add(localFile);
for (File anExtern : extern) {
if (anExtern == null) {
continue;
}
try {
File externFile = new File(anExtern, "bmp");
externFile.mkdirs();
result.add(externFile);
} catch (Exception e) {
e.printStackTrace();
// Probably read-only device, not good for cache -> ignore
}
}
return result.toArray(new File[result.size()]);
}
private static File _cachedCacheFolderWithMaxFreeSpace;
private static File getCacheFolderWithMaxFreeSpace(Context context) {
if (_cachedCacheFolderWithMaxFreeSpace != null) {
return _cachedCacheFolderWithMaxFreeSpace;
}
File result = null;
long free = 0;
for (File folder : allCacheFolders(context)) {
if (!folder.canWrite()) {
continue;
}
long currentFree = folder.getUsableSpace();
if (currentFree < free) {
continue;
}
free = currentFree;
result = folder;
}
_cachedCacheFolderWithMaxFreeSpace = result;
return result;
}

try this
File sdCard = Environment.getExternalStorageDirectory();
File dir = new File (sdCard.getAbsolutePath() + "/newfolder");
dir.mkdirs();
add permission in Manifest file
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

Related

How to create directories in /storage/extSdCard path in android java?

I can see sdcard folder contents by using this
File f = new File("/storage/extSdCard");
if (f.exists()) {
File[] files = f.listFiles();
if (files != null) {
for (File filz : files) {
Toast.makeText(this, filz.getName() + "", Toast.LENGTH_SHORT).show();
}
}
}
But when i try to create directories
File dir = new File("/storage/extSdCard/Android/Mayor");
try {
if (!dir.exists()) {
if (dir.mkdirs()) {
Toast.makeText(this, "Folder Created", Toast.LENGTH_LONG).show();
} else {
Toast.makeText(this, "Folder Not Created", Toast.LENGTH_LONG).show();
}
}
} catch (Exception e) {
e.printStackTrace();
Toast.makeText(this, "WTF", Toast.LENGTH_LONG).show();
}
Its doesnt create at all. Any idea?
// create a File object for the parent directory
File myDirectory = new File("/sdcard/Wallpaper/");
// have the object build the directory structure, if needed.
myDirectory.mkdirs();
// create a File object for the output file
File outputFile = new File(myDirectory, filename);
// now attach the OutputStream to the file object, instead of a String representation
FileOutputStream fos = new FileOutputStream(outputFile);
Note:
It might be wise to use Environment.getExternalStorageDirectory() for getting the "SD Card" directory as this might change if a phone comes along which has something other than an SD Card (such as built-in flash, a'la the iPhone). Either way you should keep in mind that you need to check to make sure it's actually there as the SD Card may be removed.
UPDATE:
Since API Level 4 (1.6) you'll also have to request the permission. Something like this (in the manifest) should work:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
You need to use DocumentFile.createDirectory(displayName) to create a directory on a removable SD card. See https://stackoverflow.com/a/35175460/1048340
File mnt = new File("/storage");
if (!mnt.exists())
mnt = new File("/mnt");
File[] roots = mnt.listFiles();
For read external sdcard, you need to mount sdcard path first then after you can able to use external sdcard path.

Where to store images within Internal Memory?

I have a custom camera Android application that saves captured images, according to the Google tutorials, into the external memory, then Media Scanner triggers Gallery to detect them.
But I have a new client with LG G2 that has no SD card slot, not external memory -- only internal.
I explained to him that I can only make my app store the images in internal Cache of the app, and he would access them through Root Explorer of some kind.
But he asserts that other purchased camera apps store their images so that Gallery can detect them. HOW? Please help -- I need to make my app able to do that as well.
Thanks!
UPD: Following is my code that works for other devices and deals primarily with external memory:
public static File getBaseFolder() {
File f;
f = null;
try {
f = Environment
.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);
} catch (Exception e) {
Utils.toasterLong("Error accessing storage: " + e.getMessage());
}
return f;
}
public static File getImageFolder() {
File f;
f = null;
try {
f = new File(getBaseFolder(), "Magic");
} catch (Exception e) {
Utils.toasterLong("Error accessing storage: " + e.getMessage());
}
return f;
}
/** Create a file Uri for saving an image or video */
private static Uri getOutputMediaFileUri(int type) {
return Uri.fromFile(getOutputMediaFile(type));
}
/** Create a File for saving an image or video */
private static File getOutputMediaFile(int type) {
// To be safe, you should check that the SDCard is mounted
// using Environment.getExternalStorageState() before doing this.
File mediaStorageDir = getImageFolder();
// This location works best if you want the created images to be shared
// between applications and persist after your app has been uninstalled.
// Create the storage directory if it does not exist
if (!mediaStorageDir.exists()) {
if (!mediaStorageDir.mkdirs()) {
Log.d(TAG, "failed to create directory");
return null;
}
}
// Create a media file name
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss")
.format(new Date());
File mediaFile;
if (type == MEDIA_TYPE_IMAGE) {
mediaFile = new File(mediaStorageDir.getPath() + File.separator
+ "IMG_" + timeStamp + ".jpg");
} else if (type == MEDIA_TYPE_VIDEO) {
mediaFile = new File(mediaStorageDir.getPath() + File.separator
+ "VID_" + timeStamp + ".mp4");
} else {
return null;
}
return mediaFile;
}
and the part of code that writes the image to external memory and triggers the scanner:
{
pictureFile = getOutputMediaFile(MEDIA_TYPE_IMAGE);
if (pictureFile == null) {
writeErrorDirty = true;
if (MyDebug.LOG)
Log.d(TAG,
"Error creating media file, check storage permissions");
} else if (MyDebug.LOG)
Log.d(TAG, "Valid path=" + pictureFile.getAbsolutePath());
FileOutputStream out = null;
try {
out = new FileOutputStream(pictureFile);
picTaken_mod.compress(Bitmap.CompressFormat.JPEG, 90, out);
} catch (Exception e) {
e.printStackTrace();
writeErrorDirty = true;
} finally {
try {
if (out != null) {
out.close();
}
} catch (IOException e) {
e.printStackTrace();
writeErrorDirty = true;
if (MyDebug.LOG)
Log.d(TAG,
"Error writing media file, check storage permissions");
}
} // end try
try {
MediaScannerConnection.scanFile(grandContext,
new String[] { pictureFile.getAbsolutePath() }, null,
new MediaScannerConnection.OnScanCompletedListener() {
public void onScanCompleted(String path, Uri uri) {
// now visible in gallery
}
});
} catch (Exception e) {
if (MyDebug.LOG)
Log.d(TAG,
"Error broadcasting the image: " + e.getMessage());
// writeErrorDirty = true;
}
}
But I have a new client with LG G2 that has no SD card slot, not external memory -- only internal.
You have both internal storage and external storage on that device. You may not have removable storage, but removable storage is not internal storage and it is not external storage.
Please understand that what the Android SDK refers to as internal storage and external storage is tied to the Android SDK as does not necessarily line up with what information is shown to the user (e.g., in Settings).
But he asserts that other purchased camera apps store their images so that Gallery can detect them. HOW?
They wrote the images to external storage, then used MediaScannerConnection to inform the Gallery and other apps that use the MediaStore ContentProvider that the files are there.

how to create a folder in android External Storage Directory?

I cannot create a folder in android External Storage Directory.
I have added permissing on manifest,
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
Here is my code:
String Path = Environment.getExternalStorageDirectory().getPath().toString()+ "/Shidhin/ShidhiImages";
System.out.println("Path : " +Path );
File FPath = new File(Path);
if (!FPath.exists()) {
if (!FPath.mkdir()) {
System.out.println("***Problem creating Image folder " +Path );
}
}
Do it like this :
String folder_main = "NewFolder";
File f = new File(Environment.getExternalStorageDirectory(), folder_main);
if (!f.exists()) {
f.mkdirs();
}
If you wanna create another folder into that :
File f1 = new File(Environment.getExternalStorageDirectory() + "/" + folder_main, "product1");
if (!f1.exists()) {
f1.mkdirs();
}
The difference between mkdir and mkdirs is that mkdir does not create nonexistent parent directory, while mkdirs does, so if Shidhin does not exist, mkdir will fail. Also, mkdir and mkdirs returns true only if the directory was created. If the directory already exists they return false
getexternalstoragedirectory() is already deprecated. I got the solution it might be helpful for you. (it's a June 2021 solution)
Corresponding To incliding Api 30, Android 11 :
Now, use this commonDocumentDirPath for saving files.
Step: 1
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
Step: 2
public static File commonDocumentDirPath(String FolderName){
File dir = null ;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
dir = new File (Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOCUMENTS)+ "/"+FolderName );
} else {
dir = new File(Environment.getExternalStorageDirectory() + "/"+FolderName);
}
return dir ;
}
The use of Environment.getExternalStorageDirectory() now is deprecated since API level 29, the option is using:
Context.getExternalFilesDir().
Example:
void createExternalStoragePrivateFile() {
// Create a path where we will place our private file on external
// storage.
File file = new File(getExternalFilesDir(null), "DemoFile.jpg");
try {
// Very simple code to copy a picture from the application's
// resource into the external file. Note that this code does
// no error checking, and assumes the picture is small (does not
// try to copy it in chunks). Note that if external storage is
// not currently mounted this will silently fail.
InputStream is = getResources().openRawResource(R.drawable.balloons);
OutputStream os = new FileOutputStream(file);
byte[] data = new byte[is.available()];
is.read(data);
os.write(data);
is.close();
os.close();
} catch (IOException e) {
// Unable to create file, likely because external storage is
// not currently mounted.
Log.w("ExternalStorage", "Error writing " + file, e);
}
}
void deleteExternalStoragePrivateFile() {
// Get path for the file on external storage. If external
// storage is not currently mounted this will fail.
File file = new File(getExternalFilesDir(null), "DemoFile.jpg");
file.delete();
}
boolean hasExternalStoragePrivateFile() {
// Get path for the file on external storage. If external
// storage is not currently mounted this will fail.
File file = new File(getExternalFilesDir(null), "DemoFile.jpg");
return file.exists();
}
I can create a folder in android External Storage Directory.
I have added permissing on manifest,
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
Here is my code:
String folder_main = "Images";
File outerFolder = new File(Environment.getExternalStorageDirectory(), folder_main);
File inerDire = new File(outerFolder.getAbsoluteFile(), System.currentTimeMillis() + ".jpg");
if (!outerFolder.exists()) {
outerFolder.mkdirs();
}
if (!outerFolder.exists()) {
inerDire.createNewFile();
}
outerFolder.mkdirs(); // This will create a Folder
inerDire.createNewFile(); // This will create File (For E.g .jpg
file)
we can Create Folder or Directory on External storage as :
String myfolder=Environment.getExternalStorageDirectory()+"/"+fname;
File f=new File(myfolder);
if(!f.exists())
if(!f.mkdir()){
Toast.makeText(this, myfolder+" can't be created.", Toast.LENGTH_SHORT).show();
}
else
Toast.makeText(this, myfolder+" can be created.", Toast.LENGTH_SHORT).show();
}
and if we want to create Directory or folder on Internal Memory then we will do :
File folder = getFilesDir();
File f= new File(folder, "doc_download");
f.mkdir();
But make Sure you have given Write External Storage Permission.
And Remember that if you have no external drive then it choose by default to internal parent directory.
I'm Sure it will work .....enjoy code
If you are trying to create a folder inside your app directory in your storage.
Step 1 : Add Permission
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
Step 2 : Add the following
private String createFolder(Context context, String folderName) {
//getting app directory
final File externalFileDir = context.getExternalFilesDir(null);
//creating new folder instance
File createdDir = new File(externalFileDir.getAbsoluteFile(),folderName);
if(!createdDir.exists()){
//making new directory if it doesn't exist already
createdDir.mkdir();
}
return finalDir.getAbsolutePath() + "/" + System.currentTimeMillis() + ".txt";
}
This is raw but should be enough to get you going
// create folder external located in Data/comexampl your app file
File folder = getExternalFilesDir("yourfolder");
//create folder Internal
File file = new File(Environment.getExternalStorageDirectory().getPath( ) + "/RICKYH");
if (!file.exists()) {
file.mkdirs();
Toast.makeText(MainActivity.this, "Make Dir", Toast.LENGTH_SHORT).show();
}
Try adding
FPath.mkdirs();
(See http://developer.android.com/reference/java/io/File.html)
and then just save the file as needed to that path, Android OS will create all the directories needed.
You don't need to do the exists checks, just set that flag and save.
(Also see : How to create directory automatically on SD card
I found some another thing too :
I had the same problem recently, and i tryed abow solutions and they did not work...
i did this to solve my problem :
I added this permission to my project manifests file :
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE"/>
(plus READ and WRITE permissions) and my app just worked correctly.
try {
String filename = "SampleFile.txt";
String filepath = "MyFileStorage";
FileInputStream fis = new FileInputStream(myExternalFile);
DataInputStream in = new DataInputStream(fis);
BufferedReader br =
new BufferedReader(new InputStreamReader(in));
String strLine;
while ((strLine = br.readLine()) != null) {
myData = myData + strLine;
}
in.close();
} catch (IOException e) {
e.printStackTrace();
}
inputText.setText(myData);
response.setText("SampleFile.txt data retrieved from External Storage...");
}
});
if (!isExternalStorageAvailable() || isExternalStorageReadOnly()) {
saveButton.setEnabled(false);
}
else {
myExternalFile = new File(getExternalFilesDir(filepath), filename);
}

android - file.exists() returns false for existing file (for anything different than pdf)

Both files are present on the sdcard, but for whatever reason exists() returns false the the png file.
//String path = "/mnt/sdcard/Android/data/com.gemoro.toffer/cache/1551619351/0/foto/-921042926.png";
String path = "/mnt/sdcard/Android/data/com.gemoro.toffer/cache/1551619351/0/foto/-1200240592.pdf";
File file2 = new File(path);
if (null != file2)
{
if(file2.exists())
{
LOG.x("file exist");
}
else
{
LOG.x("file does not exist");
}
}
Now, I've look at what's under the hood, what the method file.exists() does actually and this is what it does:
public boolean exists()
{
return doAccess(F_OK);
}
private boolean doAccess(int mode)
{
try
{
return Libcore.os.access(path, mode);
}
catch (ErrnoException errnoException)
{
return false;
}
}
May it be that the method finishes by throwing the exception and returning false?
If so,
how can I make this work
what other options to check if a file exists on the sdcard are available for use?
Thanks.
1 You need get the permission of device
Add this to AndroidManifest.xml
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
2 Get the external storage directory
File sdDir = Environment.getExternalStorageDirectory();
3 At last, check the file
File file = new File(sdDir + filename /* what you want to load in SD card */);
if (!file.canRead()) {
return false;
}
return true;
Note: filename is the path in the sdcard, not in root.
For example: you want find
/mnt/sdcard/Android/data/com.gemoro.toffer/cache/1551619351/0/foto/-921042926.png
then filename is
./Android/data/com.gemoro.toffer/cache/1551619351/0/foto/-921042926.png
.
Please try this code. Hope it should helpful for you. I am using this code only. Its working fine for me to find the file is exists or not. Please try and let me know.
File file = new File(path);
if (!file.isFile()) {
Log.e("uploadFile", "Source File not exist :" + filePath);
}else{
Log.e("uploadFile","file exist");
}
Check that USB Storage is not connected to the PC. Since Android device is connected to the PC as storage the files are not available for the application and you get FALSE to File.Exists().
Check file exist in internal storage
Example : /storage/emulated/0/FOLDER_NAME/FILE_NAME.EXTENTION
check permission (write storage)
and check file exist or not
public static boolean isFilePresent(String fileName) {
return getFilePath(fileName).isFile();
}
get File from the file name
public static File getFilePath(String fileName){
String extStorageDirectory = Environment.getExternalStorageDirectory().toString();
File folder = new File(extStorageDirectory, "FOLDER_NAME");
File filePath = new File(folder + "/" + fileName);
return filePath;
}

Where is my Excel file on Android saved?

I have this code which makes new Excel file.
The file is blank, it only creates a sheet.
Code goes like this
public void onClick(View v) {
Workbook workbook = new HSSFWorkbook();
Sheet sheet = workbook.createSheet("Havaji");
Cell cell = sheet.createRow(0).createCell(0);
cell.setCellValue("Hi there");
try{
FileOutputStream output = new FileOutputStream("Test2.xls");
workbook.write(output);
output.close();
}
...
Where is that file saved ?
How to manage to save a file on the location on the mobile device that i want?
How to create a directory where all the files are gonna be stored?
Here are a few methods you'll find useful for your purposes:
Creates all the directories along the path provided:
public static boolean createPath(String path) {
File pathFile = new File(path);
if (!pathFile.exists()) {
boolean result = pathFile.mkdirs();
if (!result) {
Log.e(TAG, "Unable to create directory path: " +
path);
return false;
}
}
if (!pathFile.isDirectory()) {
return false;
}
return true;
}
Returns the root of the external storage directory:
public static String extDirectory() {
File file = Environment.getExternalStorageDirectory();
return file.getAbsolutePath();
}
Returns the path to the root of an application's external storage directory:
public static String externalMyAppDataRoot(Context context) {
return externalAppDataRoot() + File.separatorChar
+ context.getPackageName() + File.separatorChar + "data";
}
Returns the path to the root of the Android application data directory:
public static String externalAppDataRoot() {
return extDirectory() + File.separatorChar + "Android/data";
}
I'm guessing that is being stored in /data/app//files/Test2.xls, though i'm not completely sure
I would try to pass in an absolute file path. If you want the file to be in the sdcard, i would use the Context.getExternalFilesDir to get the root path of the sdcard.

Categories

Resources