I am trying to simply create a subdirectory in the external storage pictures directory, however, I always end up in the lower if condition. (The directory does not exist and mkdir fails creating it).
...
File storageDir = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES), "foto_test_app");
if(!Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState()))
{
Log.e(LOG_TAG, "External Storage not mounted.");
return null;
}
if(!storageDir.exists() && !storageDir.mkdir())
{
Log.e(LOG_TAG, "Directory not created.");
}
...
I do have the the line in the Manifest file that reads:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
I tested it on two different devices. Both do not have an SDCard installed, but that should not be a concern, right? What am I missing?
Probably you are using Android Marshmallow or above.
You need to make sure that you have granted run-time permission for storage.
This can be done either by setting it explicitly in the settings of your android device or asking for the permission during run time.
You can check below link how run time permission works
https://developer.android.com/training/permissions/requesting.html
Related
I am failing to get the Android 6 write permission to the memory extension SD card. I am getting the exception "Permission denied”. I am using Android 6, targetSdkVersion 24, with both manifest uses-permission request and run time permission request for WRITE_EXTERNAL_STORAGE. I am getting granted ok permission replay on the onRequestPermissionsResult().
I am able to read from this SD card but I am failing to write to it. I am using a Samsung note 4, 6.0.1. I am trying to write to the file: “/storage/3530-3464/my_file.txt”, I can read this file with the same path. I am getting exception on this line:
File file = new File(SD1_StoragefilePath);
FileOutputStream fop = new FileOutputStream(file); // get permission exception here.
Manifest:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
Runtime permission:
ActivityCompat.requestPermissions(this,
new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},
PERMISSION_REQ_REPLAY_WRITE_EXTERNAL_STORAGE);
thanks for your help greenapps.
using the SAF as implemented:
Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT_TREE);
startActivityForResult(intent, REQUEST_CODE_STORAGE_ACCESS);
I can have write access to the entire SD card.
There are two issue:
When implementing the intent command a funny card selection activity spears, is there a way to get read of this selection activity, and by default select the SD root.
Intent.ACTION_OPEN_DOCUMENT_TREE activity
On every Application start this activity spears.
Is there a way to remember this permission granted ?
Using Android 6.0.1 (API23) on a Nexus 5X,
The different Android versions and how to access an external storage (i.e. USB-Stick in my case) can be very confusing. From what I understood, you need to give permissions in your manifest, as follows:
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
After that you should be able to access external storage..
Here is my approach on how to get the external-storage path, using "getExternalFilesDirs()" method. But it turns out, only the internal SD card is recognized (i.e. first array-element returned by the method).
From what I read, there should be more array-elements returned with the "getExternalFilesDirs()"-method if more external memory devices are connected to the phone. But in my case, none of them is available.
Here is my code :
String strInfo = "";
File folders[] = getExternalFilesDirs(null);
// File folders[] = ContextCompat.getExternalFilesDirs(this,null);
strInfo += "\ngetExternalFilesDirs(null):\n";
for(File f : folders){
strInfo += f.getAbsolutePath() + "\n";
}
if (folders.length > 1) {
Toast.makeText(this, "nr of folders = " + folders.length + "/ info = " + strInfo, Toast.LENGTH_SHORT).show();
File myFile = new File(folders[1], "testfile.txt");
} else {
// !!!!!!!!!!!!! Keep ending up in this case, even tough a USB-stick is
// connected to the phone (...also tried with a second SD-card
// connected...but same thing, keeeping up ending here...
// any idea WHY ???????????????
Toast.makeText(this, "No external storage device found / info = " + strInfo, Toast.LENGTH_SHORT).show();
}
Eventually, I would like to create files and folders on an externally connected USB-stick. Can anybody tell me a reliable method on how to create new files and folders on an USB-stick connected to an Android-6.0.1 phone ??
I appreciate it.
To close this off: USB-sticks do not seem to work as SECONDARY STORAGE (= external storage) for Android-mobile phones, unfortunately.
I just found this link, saying:
External storage devices returned here are considered a permanent part
of the device, including both emulated external storage and physical
media slots, such as SD cards in a battery compartment. The returned
paths do not include transient devices, such as USB flash drives.
And similar, the official Android documentation about getExternalFilesDirs() sais:
The returned paths do not include transient devices, such as USB flash drives
connected to handheld devices.
If anybody knows a C-Type USB-stick that does fulfill the requirements of a SECONDARY STORAGE, please let me know ! The same, if anybody knows USB-C-type SDcard-Adapters that work as SECONDARY STORAGE, please let me know...
Too bad, I am not able to write files & folders from my java android app to an external USB-stick :(
Android 4.4.4
Writing a simple app to learn basics of Android programming.
Running a debug build (on my device not in emulator), both in USB debug from Android Studio, and also on the device after disconnecting from USB.
I simply want to write text data to a text file on external storage. Don't care at this stage if it is internal storage or SD card (there is an SD card installed).
I HAVE got WRITE_EXTERNAL_STORAGE permission set in my manifest.
I AM checking that external storage is mounted - it is.
I have tried the code I found here:
File file = new File(myContext.getExternalFilesDir(null), "state.txt");
try {
FileOutputStream os = new FileOutputStream(file, true);
OutputStreamWriter out = new OutputStreamWriter(os);
out.write(data);
out.close();
}
I log filename to LOGCAT and it appears as
/storage/emulated/0/Android/data/com.amazed.matthew.brunel/files/file.csv
which looks reasonable. There is no exception thrown, code runs fine, just no file created!! So, is a file being created somewhere else because I'm in debug, or what? Am I missing something?
Thanks.
Following this example from Android Documentation you can do:
void write() {
File file = new File(getExternalFilesDir(null), "state.txt");
try {
OutputStream os = new FileOutputStream(file);
os.write(data);
} catch (IOException e) {
Log.w("ExternalStorage", "Error writing " + file, e);
} finally {
os.close();
}
}
Without using OutputStreamWriter, also keep in mind that according to documentation:
Starting in KITKAT, no permissions are required to read or write to
the returned path; it's always accessible to the calling app. This
only applies to paths generated for package name of the calling
application. To access paths belonging to other packages,
WRITE_EXTERNAL_STORAGE and/or READ_EXTERNAL_STORAGE are required.
Ok, I don't fully understand why behaviour is as described below, but basic issue is solved.
I powered down the device and rebooted - next time I connected the USB cable and looked in Windows Explorer on my host debug machine....there were my files. So I don't know why I can't see them without power cycling the device, but they are there. Weird!!
I want to access the picture files in public folder in external storage. Here is my code:
if (Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())) {
java.io.File pictureDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);
///storage/sdcard0/Pictures
boolean canRead = pictureDir.canRead();
//Above gives false
java.io.File[] picFiles = pictureDir.listFiles();
//null is returned for the file though I've atleast three picture files at this location
}
It gives me correct pointer to public folder, but canRead() method returns false. When I try listing the files under Picture directory, it gives me null.
Let me know if you need more details.
[UPDATE]
Permission in AndroidManifest.xml
<uses-permission android:name="android.permission.WRITE_INTERNAL_STORAGE" />
[UPDATE 2]
This looks like a device specific issue since it works fine on emulator.
I'm just chiming in with another point of "device specific" troubles.. I have a ZTE Valet that I'm trying to get access to an external directory for reading, but having the same problem where the following permission results in getExternalFilesDir() to return null:
<uses-permission
android:name="android.permission.READ_EXTERNAL_STORAGE"
android:maxSdkVersion="18"
/>
The trick mentioned above (use the WRITE_EXTERNAL_STORAGE permission) indeed results in a File being returned by getExternalFilesDir()... odd.. so odd...
You declare wrong permission in you AndroidManifest.xml. You are actually using external storage. From API 16 there is new permission that is required if you are using external storage:
http://developer.android.com/reference/android/Manifest.permission.html#READ_EXTERNAL_STORAGE
You can test your app with the permission enforced by either running
your app on the Android Emulator when running Android 4.1 or higher,
or enabling Protect USB storage under Developer options in the
Settings app on a device running Android 4.1 or higher.
Probably in your device is set Protect USB storage in such case you need to use READ_EXTERNAL_STORAGE permission. By the way WRITE_EXTERNAL_STORAGE will cover READ_EXTERNAL_STORAGE.
Sorry for the ambiguous title but I'm doing the following to write a simple string to a file:
try {
File root = Environment.getExternalStorageDirectory();
if (root.canWrite()){
System.out.println("Can write.");
File def_file = new File(root, "default.txt");
FileWriter fw = new FileWriter(def_file);
BufferedWriter out = new BufferedWriter(fw);
String defbuf = "default";
out.write(defbuf);
out.flush();
out.close();
}
else
System.out.println("Can't write.");
}catch (IOException e) {
e.printStackTrace();
}
But root.canWrite() seems to be returning false everytime. I am not running this off of an emulator, I have my android Eris plugged into my computer via USB and running the app off of my phone via Eclipse. Is there a way of giving my app permission so this doesn't happen?
Also, this code seems to be create the file default.txt but what if it already exists, will it ignore the creation and just open it to write or do I have to catch something like FileAlreadyExists(if such an exception exists) which then just opens it and writes?
Thanks for any help guys.
Is there a way of giving my app
permission so this doesn't happen?
You need the WRITE_EXTERNAL_STORAGE permission.
You also need to not have the SD card mounted on your development machine -- either the computer or the phone can access the SD card, but not both at the same time.
add WRITE_EXTERNAL_STORAGE permission to your manifest file
and if it is necessary do the following
plug the droid into your computer
pull down the manager (the bar on top with the time, sorry don't know the name, can't recall right now)
hit "usb connected"
window pops up on your computer showing you the contents of the SD card
hit "turn off usb storage" when you're done
disconnect usb cable (if you want) and then your Droid can read the SD card again