This one has me stumped (Android 4.3)
I have the right permission:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
... I'm explicitly creating a path to /storage/sdcard0/path/to/data.csv and the FileOutputStream doesn't throw any exceptions.
I tried reading the path via Environment.getExternalStorageDirectory() but that has some "emulated" path.
In either case, I can't see the files on the filesystem ...
What's more confusing is that MEDIA_MOUNTED_READ_ONLYis mounted_ro ... but this isn't the case .
It looks like another app us using /mnt/extSdCard... I tried hard coding that in my app but that doesn't work either. Even the directory is missing. This is very confusing.
I'm calling mkdirs() on this of course and the FileOutputStream is created....
What am I doing wrong?
Try the following code, and see where it fails?
try {
File mPath = new File(android.os.Environment.getExternalStorageDirectory(),"path/to");
if (!mPath.exists()) {
if(!mPath.mkdirs()) {
Log.e(getClass().getName(), "Can't Create Folder: "+mPath.getName());
}
}
File mLogFile = new File(mPath, "data.csv");
FileWriter mFileWriter = null;
if(mPath.canWrite()) {
mFileWriter = new FileWriter(mLogFile, true);
mBufferedWriter = new BufferedWriter(mFileWriter);
}
else {
Log.e(getClass().getName(), "Can't write under Folder: "+mPath.getName());
}
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
Related
I want to achieve that after I click the BACKUP button, the mydb.db file from my app database folder will be copied to device internal memory, where a New folder should be created and the file put inside it.
My code what I tried:
backupbtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
try {
File data = Environment.getDataDirectory();
File extdata = Environment.getExternalStorageDirectory();
String backupDBPath = "/Newfolder/mydb.db";
File ddir = new File(Environment.getExternalStorageDirectory()
+ "/Newfolder/");
DirectoryExist(ddir);
String currentDBPath ="/data/mypackage/databases/mydb.db";
File currentDB = new File(data, currentDBPath);
File backupDB = new File(extdata, backupDBPath);
if (currentDB.exists()) {
FileChannel src = new FileInputStream(currentDB).getChannel();
FileChannel dst = new FileOutputStream(backupDB).getChannel();
dst.transferFrom(src, 0, src.size());
src.close();
dst.close();
Toast.makeText(getApplicationContext(), "Backup is successful ", Toast.LENGTH_SHORT).show();
}
} catch (IOException e) {
e.printStackTrace();
}
}
});
private void DirectoryExist(File destination) {
if (!destination.isDirectory()) {
if (destination.mkdirs()) {
Log.d("Carpeta creada", "....");
} else {
Log.d("Carpeta no creada", "....");
}
}
}
However I have this error: java.io.FileNotFoundException: /storage/emulated/0/Newfolder/mydb.db (No such file or directory)
UPDATE: After investigation I found out, it is a storage permission issue.
If I set permissions manually in app settings, it is working. But when I try to set permissions in the app, it still says, permission denied:
if(!checkPermissionForReadExtertalStorage())
{
try {
requestPermissionForReadExtertalStorage();
} catch (Exception e) {
e.printStackTrace();
}
}
public boolean checkPermissionForReadExtertalStorage() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
int result = this.checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE);
return result == PackageManager.PERMISSION_GRANTED;
}
return false;
}
public void requestPermissionForReadExtertalStorage() throws Exception {
try {
ActivityCompat.requestPermissions((Activity) this, new String[]{Manifest.permission.READ_EXTERNAL_STORAGE},
READ_STORAGE_PERMISSION_REQUEST_CODE);
} catch (Exception e) {
e.printStackTrace();
throw e;
}
}
The popup with permissions comes up, but still, seems it doesn't allows permissions.
In manifest I have:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
However the WRITE_EXTERNAL_STORAGE is not used anymore for android 10+, so not sure if I need to keep it there.
And I have also <application android:requestLegacyExternalStorage="true"
But as I read: Starting in Android 11, apps that use the scoped storage model can access only their own app-specific cache files.
So it seems, there is no option to create any folder in local storage to backup files anymore except the app folder. One option seems to be via MediaStore API, but using this for backup one small db file seems to be an overkill.
I'm trying to save an image on the public storage directory using the below code. However, when this is saving to storage/emulated/0 and not to the public Pictures folder. I have used basically this exact code in another app and it's worked fine. Does anyone know why .getExternalStoragePublic directory is not returning the accessible /Pictures/ and instead returning storage/emulated/0 ?
I have "uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" in my Manifest file
File backupFile;
File appFolder;
String path= Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES).getAbsolutePath() + "/CustomFolder";
appFolder = new File(path);
if (!appFolder.exists())
appFolder.mkdir();
String fileName = "picture.jpg"
backupFile = new File(appFolder, fileName);
FileOutputStream output = null;
try {
output = new FileOutputStream(backupFile);
output.write(bytes);
} catch (IOException e) {
e.printStackTrace();
} finally {
mImage.close();
if (null != output) {
try {
output.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
Nevermind, I figured it out. It turns out just having "uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" in the Manifest file is insufficient, and I had to put the following code before it to make it work:
int CAMERA_PERMISSION_REQUEST_CODE = 2;
int result = ContextCompat.checkSelfPermission(getActivity().getApplicationContext(), Manifest.permission.WRITE_EXTERNAL_STORAGE);
if (result != PackageManager.PERMISSION_GRANTED){
if (ActivityCompat.shouldShowRequestPermissionRationale(getActivity(), Manifest.permission.WRITE_EXTERNAL_STORAGE)){
Toast.makeText(getActivity().getApplicationContext(), "External Storage permission needed. Please allow in App Settings for additional functionality.", Toast.LENGTH_LONG).show();
} else {
ActivityCompat.requestPermissions(getActivity(),new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},CAMERA_PERMISSION_REQUEST_CODE);
}
}
I used a lot of examples trying to understand why it doesnt create my file but i didn't and i need some help.
File myFile = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS), "FFFFFFFFF.bin");
try {
myFile.createNewFile();
setOutputStream(new FileOutputStream(myFile));
for (short i = 1; i <= this.array.length; i++) {
this.array[i-1] = new myobject(i);
}
get_objOutputStream().writeObject(this.array);
getOutputStream().close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
the getters/setters are regular, it worked when i wrote it to internal file before i changed it a little so the problem is not an error or related to the array of my objects
thanks for any help
updates:
i got no errors, it just run and then i cant find the file when im looking for it when i plug my phone to my pc after installing and running.
and yes i did wrote the premition, that is not the problem
Did you add permission in manifest file?
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
I know how to delete a file, it's:
File file = new File(path);
file.delete();
Can I test that the file is currenlty in use without rooting my device?
For exmple I want to check if the file is open before i can delete it.
I want to be able to catch errors with a try catch sentence.
You can use a try/catch clause.
try {
Files.delete(path);
} catch (NoSuchFileException x) {
System.err.format("%s: no such" + " file or directory%n", path);
} catch (DirectoryNotEmptyException x) {
System.err.format("%s not empty%n", path);
} catch (IOException x) {
// File permission problems are caught here.
System.err.println(x);
}
You can find more information here.
I have a problem with creating a folder and a file on the sdcard.
Here's the code:
File folder = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).toString() + "/folder");
boolean success;
if (!folder.exists()) {
success = folder.mkdirs();
}
File obdt = new File(folder, "file.txt");
try {
success = obdt.createNewFile();
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
With this code I expect to create the folderfolder in the Download folder of the sdcard and in this the file file. I want that the user can access the file. So I want to put it in a shared folder.
The success variable is true and when I run the code again the folder already exists and doesnt come in the if-block.
But I can't see the created folder and file on the sdcard in file explorer.
Info:getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).toString() returns storage/sdcard/Download
I work with a Galaxy Nexus.
Damn! :)
Now I solved my problem...I was misunderstanding the operation of creating files in the file system.
When I spoke of file explorer I meant the file explorer of the operating system and NOT the file explorer in the DDMS :).
I thought when I create a file I will see it in the file explorer of the operating system but when the device is connected to the PC the files can only be seen in the DDMS file explorer.
Sorry I'm new to Android ;)
When the App is running standalone without PC connection and afterwards I connect with the PC I see the created files and folders of course :)
Thanks for help
Any errors from logcat?
Else: try something like Log.I("PATHNAME",folder.absolutePath()); and then look in your logcat to make sure where you are creating the folder where you think it is.
If you haven't done so already, you will need to give your app the correct permission to write to the SD Card by adding the line below to your Manifest:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
If you have already done that see if :
File obdt = new File(/sdcard/folder/file.txt)
try {
success = obdt.createNewFile();
} catch (IOException e1) {
e1.printStackTrace();
}
works.
You cannot see the folder/file in explorer? Maybe it is because the MediaScanner is active, but not adding your files. You can do this in your program or switch the Media Scanner of somewhere in your phone settings.
MediaScanner
Trigger MediaScanner
Try this out.
File dir = new File(Environment.getExternalStorageDirectory()
+ "/XXX/Wallpapers/");
File[] files = dir.listFiles();
if (files == null)
{
int numberOfImages = 0;
BitmapDrawable drawable = (BitmapDrawable) imageView
.getDrawable();
Bitmap bitmap = drawable.getBitmap();
File sdCardDirectory = Environment
.getExternalStorageDirectory();
new File(sdCardDirectory + "/XXX/Wallpapers/").mkdirs();
File image = new File(sdCardDirectory
+ "/XXX/Wallpapers/Sample" + numberOfImages + ".JPG");
boolean success = false;
FileOutputStream outStream;
try {
outStream = new FileOutputStream(image);
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, outStream);
outStream.flush();
outStream.close();
success = true;
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
if (success) {
Toast.makeText(
getApplicationContext(),
"Image saved successfully in Sdcard/XXX/Wallpapers",
Toast.LENGTH_LONG).show();
} else {
Toast.makeText(getApplicationContext(),
"Error during image saving", Toast.LENGTH_LONG)
.show();
}
Dont forget to add permission in manifest
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
Apparently there is a known bug in MTP.
Issue 195362
All phones using MTP instead of USB Mass storage do not properly show the list of files when that phone is connected to a computer using a USB cable. Android apps running on the device also cannot see these files.
It is actually as old as 2012
I've encountered the same problem: created files and folders don't show immediately after being written to sdcard, despite the file being flushed and closed !!
They don't show on your computer over USB or a file explorer on the phone.
I observed three things:
if the absolute path of the file starts with /storage/emulated/0/ it doesn't mean it'll be on your sdcard - it could be on your main storage instead.
if you wait around 5 minutes, the files do begin to show over USB (i.e. Windows explorer and built-in file explorer)
if you use adb shell ls /sdcard from terminal, then the file does show! you could use adb pull ... to get the file immediately. You could probably use DDMS too.
Code I used was:
Gson gson = new GsonBuilder().setPrettyPrinting().create();
String json = gson.toJson(myArrayList);
try {
File externalDir = getExternalStorageDirectory();
File newFile = new File(externalDir, "myfile.txt");
FileOutputStream os = new FileOutputStream(newFile);
os.write(json.getBytes());
os.flush();
os.close();
Timber.i("saved file to %s",newFile.getAbsoluteFile().toString());
}catch (Exception ex)
{
Toast.makeText(getApplicationContext(), "Save to private external storage failed. Error message is " + ex.getMessage(), Toast.LENGTH_LONG).show();
}
and
Gson gson = new GsonBuilder().setPrettyPrinting().create();
String json = gson.toJson(myArrayList);
try {
File externalDir = getExternalStorageDirectory();
File newFile = new File(externalDir, "myfile.txt");
FileWriter fw = new FileWriter(newFile);
fw.write(json);
fw.flush();
fw.close();
Timber.i("saved file to %s",newFile.getAbsoluteFile().toString());
}catch (Exception ex)
{
Toast.makeText(getApplicationContext(), "Save to private external storage failed. Error message is " + ex.getMessage(), Toast.LENGTH_LONG).show();
}
why is it like this? Seems like another one of those "Android-isms" that you have to suffer through the first time you experience it.