I am trying to read an image file from /mnt/sdcard/image.jpg into my ImageView. Here is my code:
Bitmap bmp = BitmapFactory.decodeFile("/mnt/sdcard/image.jpg");
webImage.setImageBitmap(bmp);
I have write external storage permission.
My code says bmp is null, even though the image resides in the root directory (I go to I Drive and image.jpg is there.)
What am I doing incorrectly?
There could be two cases:
1) If you image is in the root folder of sdcard then it is possible to to access it through
Environment.getExternalStorageDirectory().toString + File.separator + "yourimage.jpg"
2) But i guess in your case it is in the /mnt/sdcard/external_sd which your memory card of the device in that case try this:
Environment.getExternalStorageDirectory().toString + File.separator + "external_sd" + File.separator + "yourimage.jpg"
Replace the above two paths with yours in BitmapFactory.decodeFile("Replace Here...")
I suspect the card with the image isn't mounted under /mnt/sdcard/.
Since you are using a Motorola device, chances are that you have two mass storage devices (see this list, if your device is in there, this is the case). In this situation you have to use the Motorola "External" Storage API to get the path to your second mass storage.
Also in general: You can't rely on hardcoding paths to the SD-Card like this. The mountpoint differs across devices. Or might be named differently, some devices might have a flash storage instead of a card, and so on. In short: What works on your phone breaks on others. You can read a reliable path to the primary external storage by calling Environment.getExternalStorageDirectory() instead.
Thanks, I managed to resolve it. Here is what I found:
I went to project > clean
I disconnected the phone from the computer. When it is connected, the SD is mounted and you can't view data.
The image name can't start with numbers. I am using SDK 7.
I viewed LogCat and I didn't get any errors, however, saving to other system areas (like /Android/Data/) caused a FileNotFoundException - permissions error.
File destination = new File(Environment.getExternalStorageDirectory(), "image" +
DateHelper.getTodaysDate() + "_" + DateHelper.getCurrentTime() + ".jpg");
private View.OnClickListener listener = new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
// Add extra to save full-image somewhere
intent.putExtra(MediaStore.EXTRA_OUTPUT,
Uri.fromFile(destination));
startActivityForResult(intent, REQUEST_IMAGE);
}
};
Please check you LogCat for more information.
My guess is you have a Samsung device. Samsung tends to have an external_sd folder, so you might have added it to the wrong sdcard because Samsung often has an internal and an external one.
Your code is perfectly okay. Just check whether you are writing proper sd card path or not. May be for that reason you are getting null bitmap.
And "write external storage permission" is for writing to your sd card not for reading from sd card. Make this concept clear.
Related
I'm using react-native-document-picker in order to pick files and send them to the server. After picking the file, I use RNFetchBlob.fs.stat(uri) from rn-fetch-blob package to get the real path from the URI that the picker gives me. It works fine with internal storage files but when I choose an image from "SD card" section the stat function throws an exception which says something like this:
failed to stat path null for it doesn't exist or it's not a folder
Surprisingly, when I choose "Images" section and go to the SD card folder and choose the very same image it works just fine!!
I have the same problem with "Downloads" section, too.
The URI that the picker returns is this when I choose the image from "Images" section:
content://com.android.providers.media.documents/document/image%3A76431
and when I choose from "SD card" section:
content://com.android.externalstorage.documents/document/F673-1818%3Abbb.png
Right now I'm using this code but it's not the right solution because it's somehow dirty and it doesn't work on all devices.
if(uri.substr(0,57) === "content://com.android.externalstorage.documents/document/"){
let filePath = decodeURIComponent(uri.substr(57));
let subUri = filePath.replace(/:\s*/g, "/");
filePath = "/storage/" + subUri;
return `file://${filePath}`
}
Is there a nicer way to get the real path of a file in SD card from it's URI?
I appreciate any idea.
OS: Android
I have write a code to find if SD card path if available which is like this
File[] paths = ContextCompat.getExternalFilesDirs(context, null);
if (paths.length > 1) {
if (paths[1] != null) {
root = paths[1].getAbsolutePath();
// for sd card
} else {
root = Environment.getExternalStorageDirectory().toString();
}
} else {
root = paths[0].getAbsolutePath();
}
I am saving my data in path "/storage/4130-1912/Android/data/com.enable/files" but I wanted to save data outside Android folder.
I have also tried to make an directory outside the Android folder.But unable to make it.I am testing in Lave phone with version Marhmallow
As you are using Marshmallow, you should be requesting runtime permissions (more details here). Despite that, you may add the WRITE_EXTERNAL_STORAGE and READ_EXTERNAL_STORAGE for external storage access. You can find more information on how to here.
You can access the external storage path like this: Environment.getExternalStorageDirectory().getAbsoluteFile(). If you are getting FileNotFoundException, it's probably because you didn't add an additional "/" before your file. Example:
File file = new File(Environment.getExternalStorageDirectory().getAbsoluteFile() +
"/your_file.txt");
I am saving my data in path "/storage/4130-1912/Android/data/com.enable/files"
Ok. Go ahead. You will succeed.
but I wanted to save data outside Android folder.
Well that is not possible anymore on modern Android systems.
Even inside the Android folder you can only write to mentioned private directory for your app.
If you want to write to the whole micro SD card then use the storage access framework.
This will help you
As miguelarc said:
As you are using Marshmallow, you should be requesting runtime
permissions (more details here). Despite that, you may add the
WRITE_EXTERNAL_STORAGE and READ_EXTERNAL_STORAGE for external
storage access.
File f = new File(Environment.getExternalStorageDirectory().getAbsolutePath() + "/" + getPackageName() + "/yourdir");
if (f.mkdirs() || f.isDirectory())
Log.e("path",f.getPath());
//do what you want
}
In my application I am capturing photos and storing into the SD card.
The location of my file is:
photoPath = getExternalFilesDir(Environment.DIRECTORY_PICTURES) + "/"
+ "MyFolder" + "/"+"ImageName";
But when I give clear data using the "device's clear data option" the file is not getting deleted.When I used the Samsung devices, it is getting deleted. But I am facing this problem when I trying with Lenovo devices.
Any one could you please share your suggestions?
I think that option is meant to clear just the data associated with the app internally.
You have chosen to store extra data on the SD card, and I don't think the system is meant to delete it. You should be managing that yourself.
Which brings up the question of why Samsung is able to delete that file? I do not know why.
May be it depends upon the device.
If you want to delete the entire content in a folder, try this code.
void DeleteRecursive(File fileOrDirectory) {
if (fileOrDirectory.isDirectory())
for (File child : fileOrDirectory.listFiles())
DeleteRecursive(child);
fileOrDirectory.delete();
}
Toast.makeText(this, Environment.getExternalStorageDirectory(),
Toast.LENGTH_LONG).show();
File file = new File(Environment.getExternalStorageDirectory() +
"/whatsupv2/abc.jpg");
Bitmap mybitmap = BitmapFactory.decodeFile(file.getAbsolutePath());
imageView.setImageURI(Uri.fromFile(file));
the above code is working for android 3.3 but not in 4.1.2 where we have two storage directories... i have checked abc.jpg is there in dir .. and path given is correct.. but imageview just show a white screen..
but not in 4.1.2 where we have two storage directoies
There is only one external storage directory in all Android devices, at least through Android 4.3.
First, make sure the image is in the official external storage location.
Second, use new File(Environment.getExternalStorageDirectory(), "/whatsupv2/abc.jpg") rather than string concatenation.
Third, either use decodeFile() or setImageURI(), not both.
Fourth, examine LogCat for any messages.
i have given required permission :
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
hard-coded the path as "/sdcard/filename".
I guess Nexus don't have external SD support but S2 has, that I think might cause a problem in getting the path. How should I handle such a case gracefully?
On each Android Device you can get the path to the external storage like this
Environment.getExternalStorageDirectory()
I've a Nexus device and it works - also on my old milestone
Here is an example usage to create your own apps directory:
You should always check to see if the SDcard is available first because it could be mounted/teathered to a computer or be removed from the device.
private void SetDirectory() {
if (android.os.Environment.getExternalStorageState().equals(android.os.Environment.MEDIA_MOUNTED)) {
extStorageDirectory = Environment.getExternalStorageDirectory().toString();
File dbDirectory = new File(extStorageDirectory + "/yourAppName/whatever/");
myDirectory.mkdirs();// Have the object build the directory
} else if (android.os.Environment.getExternalStorageState().equals(android.os.Environment.MEDIA_MOUNTED_READ_ONLY)) {
//TODO Make some kind of allert or Toast to warn/notify the user that the SDcard is needed.
}
}
You can use the android.os.Environment.getExternalStorageState().equals(android.os.Environment.MEDIA_MOUNTED) method to check if the card is available anywhere within your application.