Is there any method to get /storage/ directory. I tried with Environment.getExternalStorageDirectory() but it returns /storage/emulated/0 i know i can use file.getParent() but for some reason i cant use that. I just want a straight path to /storage/ directory using some function... Thanks in advance.
You can't and should not access that directory normally. But it seems you need more control on storage locations are available to your device.
For that you can use this,
public List<String> getStorageDirectories() {
// Final set of paths
final ArrayList<String> finalPaths = new ArrayList<String>();
// Must add the ROOT directory
finalPaths.add("/");
// Primary physical SD-CARD (not emulated)
final String rawExternalStorage = System.getenv("EXTERNAL_STORAGE");
// All Secondary SD-CARDs (all exclude primary) separated by ":"
final String rawSecondaryStoragesStr = System.getenv("SECONDARY_STORAGE");
// Primary emulated SD-CARD
final String rawEmulatedStorageTarget = System.getenv("EMULATED_STORAGE_TARGET");
if (TextUtils.isEmpty(rawEmulatedStorageTarget)) {
// Device has physical external storage; use plain paths.
if (TextUtils.isEmpty(rawExternalStorage)) {
// EXTERNAL_STORAGE undefined; falling back to default.
finalPaths.add("/storage/sdcard0");
} else {
finalPaths.add(rawExternalStorage);
}
} else {
// Device has emulated storage; external storage paths should have
// userId burned into them.
final String rawUserId;
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR1) {
rawUserId = "";
} else {
final String path = Environment.getExternalStorageDirectory().getAbsolutePath();
final String[] folders = DIR_SEPARATOR.split(path);
final String lastFolder = folders[folders.length - 1];
boolean isDigit = false;
try {
Integer.valueOf(lastFolder);
isDigit = true;
} catch (NumberFormatException ignored) {
}
rawUserId = isDigit ? lastFolder : "";
}
// /storage/emulated/0[1,2,...]
if (TextUtils.isEmpty(rawUserId)) {
finalPaths.add(rawEmulatedStorageTarget);
} else {
finalPaths.add(rawEmulatedStorageTarget + File.separator + rawUserId);
}
}
// Add all secondary storages
if (!TextUtils.isEmpty(rawSecondaryStoragesStr)) {
// All Secondary SD-CARDs splited into array
final String[] rawSecondaryStorages = rawSecondaryStoragesStr.split(File.pathSeparator);
Collections.addAll(finalPaths, rawSecondaryStorages);
}
File usb = getUsbDrive();
if (usb != null && !finalPaths.contains(usb.getPath()))
finalPaths.add(usb.getPath());
return finalPaths;
}
And here is the method to get the USB drive attached to your device,
public File getUsbDrive() {
File parent;
parent = new File("/storage");
try {
for (File f : parent.listFiles()) {
if (f.exists() && f.getName().toLowerCase().contains("usb") && f.canExecute()) {
return f;
}
}
} catch (Exception e) {
}
parent = new File("/mnt/sdcard/usbStorage");
if (parent.exists() && parent.canExecute())
return (parent);
parent = new File("/mnt/sdcard/usb_storage");
if (parent.exists() && parent.canExecute())
return parent;
return null;
}
But remember that this is not an official way but a hack, so use it at your own risk.
Related
File[] fs = this.getExternalFilesDirs(null);
String extPath = "";
if (fs != null && fs.length >= 2)
{
extPath = fs[1].getAbsolutePath();
Toast.makeText(this, ""+extPath, Toast.LENGTH_SHORT).show();
Log.e("SD Path",fs[1].getAbsolutePath());
}
I use this piece of code but I'm not getting the answer.
I found the solution for this over here https://stackoverflow.com/a/13648873/842607
The code is -
public static HashSet<String> getExternalMounts() {
final HashSet<String> out = new HashSet<String>();
String reg = "(?i).*vold.*(vfat|ntfs|exfat|fat32|ext3|ext4).*rw.*";
String s = "";
try {
final Process process = new ProcessBuilder().command("mount")
.redirectErrorStream(true).start();
process.waitFor();
final InputStream is = process.getInputStream();
final byte[] buffer = new byte[1024];
while (is.read(buffer) != -1) {
s = s + new String(buffer);
}
is.close();
} catch (final Exception e) {
e.printStackTrace();
}
// parse output
final String[] lines = s.split("\n");
for (String line : lines) {
if (!line.toLowerCase(Locale.US).contains("asec")) {
if (line.matches(reg)) {
String[] parts = line.split(" ");
for (String part : parts) {
if (part.startsWith("/"))
if (!part.toLowerCase(Locale.US).contains("vold"))
out.add(part);
}
}
}
}
return out;
}
The other one is the hack which I found from the same page -
private static final Pattern DIR_SEPORATOR = Pattern.compile("/");
/**
* Raturns all available SD-Cards in the system (include emulated)
*
* Warning: Hack! Based on Android source code of version 4.3 (API 18)
* Because there is no standart way to get it.
* TODO: Test on future Android versions 4.4+
*
* #return paths to all available SD-Cards in the system (include emulated)
*/
public static String[] getStorageDirectories()
{
// Final set of paths
final Set<String> rv = new HashSet<String>();
// Primary physical SD-CARD (not emulated)
final String rawExternalStorage = System.getenv("EXTERNAL_STORAGE");
// All Secondary SD-CARDs (all exclude primary) separated by ":"
final String rawSecondaryStoragesStr = System.getenv("SECONDARY_STORAGE");
// Primary emulated SD-CARD
final String rawEmulatedStorageTarget = System.getenv("EMULATED_STORAGE_TARGET");
if(TextUtils.isEmpty(rawEmulatedStorageTarget))
{
// Device has physical external storage; use plain paths.
if(TextUtils.isEmpty(rawExternalStorage))
{
// EXTERNAL_STORAGE undefined; falling back to default.
rv.add("/storage/sdcard0");
}
else
{
rv.add(rawExternalStorage);
}
}
else
{
// Device has emulated storage; external storage paths should have
// userId burned into them.
final String rawUserId;
if(Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR1)
{
rawUserId = "";
}
else
{
final String path = Environment.getExternalStorageDirectory().getAbsolutePath();
final String[] folders = DIR_SEPORATOR.split(path);
final String lastFolder = folders[folders.length - 1];
boolean isDigit = false;
try
{
Integer.valueOf(lastFolder);
isDigit = true;
}
catch(NumberFormatException ignored)
{
}
rawUserId = isDigit ? lastFolder : "";
}
// /storage/emulated/0[1,2,...]
if(TextUtils.isEmpty(rawUserId))
{
rv.add(rawEmulatedStorageTarget);
}
else
{
rv.add(rawEmulatedStorageTarget + File.separator + rawUserId);
}
}
// Add all secondary storages
if(!TextUtils.isEmpty(rawSecondaryStoragesStr))
{
// All Secondary SD-CARDs splited into array
final String[] rawSecondaryStorages = rawSecondaryStoragesStr.split(File.pathSeparator);
Collections.addAll(rv, rawSecondaryStorages);
}
return rv.toArray(new String[rv.size()]);
}
I've been trying to get access to Internal and External SD Card in android. I've tried many codes available in StackOverFlow but doesn't work on most or all Android versions. Then, I found two solutions. One which works on Kitkat & above, another one which works on lower than Kitkat. I tried to merge both of them and it works!
If anyone has better solution than this, please share.
These two answers are what I merged to get it working.
How to get SD_Card path in android6.0 programmatically
Find an external SD card location
Here's the solution,
Add this line of code in AndroidManifest.xml to get permission from Android to read external storages.
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
Now, add this class to your project.
public class StoragePath {
File[] getExternalFilesDirs;
/**
* Constructor for KitKat & above
* #param getExternalFilesDirs
*/
public StoragePath(File[] getExternalFilesDirs) {
this.getExternalFilesDirs = getExternalFilesDirs;
}
/**
* Constructor for lower than Kitkat
*
*/
public StoragePath() {
}
public String[] getDeviceStorages() {
List<String> results = new ArrayList<>();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { //Method 1 for KitKat & above
File[] externalDirs = getExternalFilesDirs;
for (File file : externalDirs) {
String path = file.getPath().split("/Android")[0];
boolean addPath = false;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
addPath = Environment.isExternalStorageRemovable(file);
} else {
addPath = Environment.MEDIA_MOUNTED.equals(EnvironmentCompat.getStorageState(file));
}
if (addPath) {
results.add(path);
}
}
}
if (results.isEmpty()) { //Method 2 for all versions
final List<String> out = new ArrayList<>();
String reg = "(?i).*vold.*(vfat|ntfs|exfat|fat32|ext3|ext4).*rw.*";
String s = "";
try {
final Process process = new ProcessBuilder().command("mount")
.redirectErrorStream(true).start();
process.waitFor();
final InputStream is = process.getInputStream();
final byte[] buffer = new byte[1024];
while (is.read(buffer) != -1) {
s = s + new String(buffer);
}
is.close();
} catch (final Exception e) {
e.printStackTrace();
}
// parse output
final String[] lines = s.split("\n");
for (String line : lines) {
if (!line.toLowerCase(Locale.US).contains("asec")) {
if (line.matches(reg)) {
String[] parts = line.split(" ");
for (String part : parts) {
if (part.startsWith("/"))
if (!part.toLowerCase(Locale.US).contains("vold"))
out.add(part);
}
}
}
}
results.addAll(out);
}
//Below few lines is to remove paths which may not be external memory card, like OTG (feel free to comment them out)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
for (int i = 0; i < results.size(); i++) {
if (!results.get(i).toLowerCase().matches(".*[0-9a-f]{4}[-][0-9a-f]{4}")) {
Log.d("Tag", results.get(i) + " might not be extSDcard");
results.remove(i--);
}
}
} else {
for (int i = 0; i < results.size(); i++) {
if (!results.get(i).toLowerCase().contains("ext") && !results.get(i).toLowerCase().contains("sdcard")) {
Log.d("Tag", results.get(i) + " might not be extSDcard");
results.remove(i--);
}
}
}
//Get path to the Internal Storage aka ExternalStorageDirectory
final String internalStoragePath = Environment.getExternalStorageDirectory().getAbsolutePath();
results.add(0, internalStoragePath);
String[] storageDirectories = new String[results.size()];
for (int i = 0; i < results.size(); ++i) storageDirectories[i] = results.get(i);
return storageDirectories;
}
}
Now to use this class,
StoragePath storagePath;
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.KITKAT) {
storagePath = new StoragePath(getExternalFilesDirs(null));
}else {
storagePath = new StoragePath();
}
String[] storages;
storages = storagePath.getDeviceStorages();
String array storages now contains the path of the storages.
I used to get all the files in USB/SD Card from "/storage/external_storage" like so
File = new File("/storage/external_storage");
file.listFiles()
and show the files and folders in my own Fragment and it worked great until API 23. Where now I am unable to get the file list from the path.
I know in Android Marshmallow (23) there were permission changes and some USB Connection behavior changes.
If your app supports user interactions with the device over a USB port, take into consideration that the interaction must be explicitly enabled.
Does not explain how or when user can enable interactions explicitly.
My question is whether or not it is possible to Access USB files and Folders list.
If there is how can we achieve this?
EDIT : I opened Android Device Monitor and I couldn't find external_storage in /storage/external_storage.
It is true the doc is not very clear about that....but it seems you have to ask the system to mount the media device for you. Can you try to use
Environment.getExternalStorageState() to see what it returns you?
Otherwise, you can also try to access the SD/External USB by using this class:
public class ExternalStorage {
public static final String SD_CARD = "sdCard";
public static final String EXTERNAL_SD_CARD = "externalSdCard";
/**
* #return True if the external storage is available. False otherwise.
*/
public static boolean isAvailable() {
String state = Environment.getExternalStorageState();
if (Environment.MEDIA_MOUNTED.equals(state) || Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)) {
return true;
}
return false;
}
public static String getSdCardPath() {
return Environment.getExternalStorageDirectory().getPath() + "/";
}
/**
* #return True if the external storage is writable. False otherwise.
*/
public static boolean isWritable() {
String state = Environment.getExternalStorageState();
if (Environment.MEDIA_MOUNTED.equals(state)) {
return true;
}
return false;
}
/**
* #return A map of all storage locations available
*/
public static Map<String, File> getAllStorageLocations() {
Map<String, File> map = new HashMap<String, File>(10);
List<String> mMounts = new ArrayList<String>(10);
List<String> mVold = new ArrayList<String>(10);
mMounts.add("/mnt/sdcard");
mVold.add("/mnt/sdcard");
try {
File mountFile = new File("/proc/mounts");
if(mountFile.exists()){
Scanner scanner = new Scanner(mountFile);
while (scanner.hasNext()) {
String line = scanner.nextLine();
if (line.startsWith("/dev/block/vold/")) {
String[] lineElements = line.split(" ");
String element = lineElements[1];
// don't add the default mount path
// it's already in the list.
if (!element.equals("/mnt/sdcard"))
mMounts.add(element);
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
try {
File voldFile = new File("/system/etc/vold.fstab");
if(voldFile.exists()){
Scanner scanner = new Scanner(voldFile);
while (scanner.hasNext()) {
String line = scanner.nextLine();
if (line.startsWith("dev_mount")) {
String[] lineElements = line.split(" ");
String element = lineElements[2];
if (element.contains(":"))
element = element.substring(0, element.indexOf(":"));
if (!element.equals("/mnt/sdcard"))
mVold.add(element);
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
for (int i = 0; i < mMounts.size(); i++) {
String mount = mMounts.get(i);
if (!mVold.contains(mount))
mMounts.remove(i--);
}
mVold.clear();
List<String> mountHash = new ArrayList<String>(10);
for(String mount : mMounts){
File root = new File(mount);
if (root.exists() && root.isDirectory() && root.canWrite()) {
File[] list = root.listFiles();
String hash = "[";
if(list!=null){
for(File f : list){
hash += f.getName().hashCode()+":"+f.length()+", ";
}
}
hash += "]";
if(!mountHash.contains(hash)){
String key = SD_CARD + "_" + map.size();
if (map.size() == 0) {
key = SD_CARD;
} else if (map.size() == 1) {
key = EXTERNAL_SD_CARD;
}
mountHash.add(hash);
map.put(key, root);
}
}
}
mMounts.clear();
if(map.isEmpty()){
map.put(SD_CARD, Environment.getExternalStorageDirectory());
}
return map;
}
}
The use is like this:
Map<String, File> externalLocations = ExternalStorage.getAllStorageLocations();
File sdCard = externalLocations.get(ExternalStorage.SD_CARD);
File externalSdCard = externalLocations.get(ExternalStorage.EXTERNAL_SD_CARD);
Source here: Find an external SD card location
Have a look at getExternalFilesDirs().
If a micro SD card is inserted the second entry will point to the card.
If you then attach a USB OTG drive the third entry will point to the drive.
With Intent.ACTION_OPEN_DOCUMENT_TREE you can let the user choose from all drives and then use Storage Access Framework.
I am trying to check whether device having external storage or not by using external storage path like this given below
if (new File("/ext_card/").exists()) {
specialPath = "/ext_card/";
} else if (new File("/mnt/sdcard/external_sd/").exists()) {
specialPath = "/mnt/sdcard/external_sd/";
} else if (new File("/storage/extSdCard/").exists()) {
specialPath = "/storage/extSdCard/";
} else if (new File("/mnt/extSdCard/").exists()) {
specialPath = "/mnt/extSdCard/";
} else if (new File("/mnt/sdcard/external_sd/").exists()) {
specialPath = "/mnt/sdcard/external_sd/";
} else if (new File("storage/sdcard1/").exists()) {
specialPath = "storage/sdcard1/";
}
But in marshmallow I con't find this path and while checking using ES FILEMANAGER, they give like storage/3263-3131 in Moto G 3rd generation. While check in other marshmallow devices that numbers getting differ. Please help me to check that marshmallow device have external storage or not? and if storage found means how to get the path of that external storage?
Note:- I gave permission for storage in my application and also enabled storage permission in settings for my app.
Thanks in advance and did you find any mistake in my question please crt it. thank you again.
Here's my solution, which is guaranteed to work till Android 7.0 Nougat:
/* returns external storage paths (directory of external memory card) as array of Strings */
public String[] getExternalStorageDirectories() {
List<String> results = new ArrayList<>();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { //Method 1 for KitKat & above
File[] externalDirs = getExternalFilesDirs(null);
String internalRoot = Environment.getExternalStorageDirectory().getAbsolutePath().toLowerCase();
for (File file : externalDirs) {
if(file==null) //solved NPE on some Lollipop devices
continue;
String path = file.getPath().split("/Android")[0];
if(path.toLowerCase().startsWith(internalRoot))
continue;
boolean addPath = false;
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
addPath = Environment.isExternalStorageRemovable(file);
}
else{
addPath = Environment.MEDIA_MOUNTED.equals(EnvironmentCompat.getStorageState(file));
}
if(addPath){
results.add(path);
}
}
}
if(results.isEmpty()) { //Method 2 for all versions
// better variation of: http://stackoverflow.com/a/40123073/5002496
String output = "";
try {
final Process process = new ProcessBuilder().command("mount | grep /dev/block/vold")
.redirectErrorStream(true).start();
process.waitFor();
final InputStream is = process.getInputStream();
final byte[] buffer = new byte[1024];
while (is.read(buffer) != -1) {
output = output + new String(buffer);
}
is.close();
} catch (final Exception e) {
e.printStackTrace();
}
if(!output.trim().isEmpty()) {
String devicePoints[] = output.split("\n");
for(String voldPoint: devicePoints) {
results.add(voldPoint.split(" ")[2]);
}
}
}
//Below few lines is to remove paths which may not be external memory card, like OTG (feel free to comment them out)
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
for (int i = 0; i < results.size(); i++) {
if (!results.get(i).toLowerCase().matches(".*[0-9a-f]{4}[-][0-9a-f]{4}")) {
Log.d(LOG_TAG, results.get(i) + " might not be extSDcard");
results.remove(i--);
}
}
} else {
for (int i = 0; i < results.size(); i++) {
if (!results.get(i).toLowerCase().contains("ext") && !results.get(i).toLowerCase().contains("sdcard")) {
Log.d(LOG_TAG, results.get(i)+" might not be extSDcard");
results.remove(i--);
}
}
}
String[] storageDirectories = new String[results.size()];
for(int i=0; i<results.size(); ++i) storageDirectories[i] = results.get(i);
return storageDirectories;
}
I found the solution for this over here https://stackoverflow.com/a/13648873/842607
The code is -
public static HashSet<String> getExternalMounts() {
final HashSet<String> out = new HashSet<String>();
String reg = "(?i).*vold.*(vfat|ntfs|exfat|fat32|ext3|ext4).*rw.*";
String s = "";
try {
final Process process = new ProcessBuilder().command("mount")
.redirectErrorStream(true).start();
process.waitFor();
final InputStream is = process.getInputStream();
final byte[] buffer = new byte[1024];
while (is.read(buffer) != -1) {
s = s + new String(buffer);
}
is.close();
} catch (final Exception e) {
e.printStackTrace();
}
// parse output
final String[] lines = s.split("\n");
for (String line : lines) {
if (!line.toLowerCase(Locale.US).contains("asec")) {
if (line.matches(reg)) {
String[] parts = line.split(" ");
for (String part : parts) {
if (part.startsWith("/"))
if (!part.toLowerCase(Locale.US).contains("vold"))
out.add(part);
}
}
}
}
return out;
}
The other one is the hack which I found from the same page -
private static final Pattern DIR_SEPORATOR = Pattern.compile("/");
/**
* Raturns all available SD-Cards in the system (include emulated)
*
* Warning: Hack! Based on Android source code of version 4.3 (API 18)
* Because there is no standart way to get it.
* TODO: Test on future Android versions 4.4+
*
* #return paths to all available SD-Cards in the system (include emulated)
*/
public static String[] getStorageDirectories()
{
// Final set of paths
final Set<String> rv = new HashSet<String>();
// Primary physical SD-CARD (not emulated)
final String rawExternalStorage = System.getenv("EXTERNAL_STORAGE");
// All Secondary SD-CARDs (all exclude primary) separated by ":"
final String rawSecondaryStoragesStr = System.getenv("SECONDARY_STORAGE");
// Primary emulated SD-CARD
final String rawEmulatedStorageTarget = System.getenv("EMULATED_STORAGE_TARGET");
if(TextUtils.isEmpty(rawEmulatedStorageTarget))
{
// Device has physical external storage; use plain paths.
if(TextUtils.isEmpty(rawExternalStorage))
{
// EXTERNAL_STORAGE undefined; falling back to default.
rv.add("/storage/sdcard0");
}
else
{
rv.add(rawExternalStorage);
}
}
else
{
// Device has emulated storage; external storage paths should have
// userId burned into them.
final String rawUserId;
if(Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR1)
{
rawUserId = "";
}
else
{
final String path = Environment.getExternalStorageDirectory().getAbsolutePath();
final String[] folders = DIR_SEPORATOR.split(path);
final String lastFolder = folders[folders.length - 1];
boolean isDigit = false;
try
{
Integer.valueOf(lastFolder);
isDigit = true;
}
catch(NumberFormatException ignored)
{
}
rawUserId = isDigit ? lastFolder : "";
}
// /storage/emulated/0[1,2,...]
if(TextUtils.isEmpty(rawUserId))
{
rv.add(rawEmulatedStorageTarget);
}
else
{
rv.add(rawEmulatedStorageTarget + File.separator + rawUserId);
}
}
// Add all secondary storages
if(!TextUtils.isEmpty(rawSecondaryStoragesStr))
{
// All Secondary SD-CARDs splited into array
final String[] rawSecondaryStorages = rawSecondaryStoragesStr.split(File.pathSeparator);
Collections.addAll(rv, rawSecondaryStorages);
}
return rv.toArray(new String[rv.size()]);
}
This library solve my problem.
https://github.com/hendrawd/StorageUtil
What i did is:
private File directory;
String[] allPath;
allPath = StorageUtil.getStorageDirectories(this);
for (String path: allPath){
directory = new File(path);
Methods.update_Directory_Files(directory);
}
Methods.update_Directory_Files()
// Retrieving files from memory
public static void update_Directory_Files(File directory) {
//Get all file in storage
File[] fileList = directory.listFiles();
//check storage is empty or not
if(fileList != null && fileList.length > 0)
{
for (int i=0; i<fileList.length; i++)
{
boolean restricted_directory = false;
//check file is directory or other file
if(fileList[i].isDirectory())
{
for (String path : Constant.removePath){
if (path.equals(fileList[i].getPath())) {
restricted_directory = true;
break;
}
}
if (!restricted_directory)
update_Directory_Files(fileList[i]);
}
else
{
String name = fileList[i].getName().toLowerCase();
for (String ext : Constant.videoExtensions){
//Check the type of file
if(name.endsWith(ext))
{
//first getVideoDuration
String videoDuration = Methods.getVideoDuration(fileList[i]);
long playbackPosition;
long percentage = C.TIME_UNSET;
FilesInfo.fileState state;
/*First check video already played or not. If not then state is NEW
* else load playback position and calculate percentage of it and assign it*/
//check it if already exist or not if yes then start from there else start from start position
int existIndex = -1;
for (int j = 0; j < Constant.filesPlaybackHistory.size(); j++) {
String fListName = fileList[i].getName();
String fPlaybackHisName = Constant.filesPlaybackHistory.get(j).getFileName();
if (fListName.equals(fPlaybackHisName)) {
existIndex = j;
break;
}
}
try {
if (existIndex != -1) {
//if true that means file is not new
state = FilesInfo.fileState.NOT_NEW;
//set playbackPercentage not playbackPosition
MediaMetadataRetriever retriever = new MediaMetadataRetriever();
retriever.setDataSource(fileList[i].getPath());
String time = retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION);
retriever.release();
int duration = Integer.parseInt(time);
playbackPosition = Constant.filesPlaybackHistory.get(existIndex).getPlaybackPosition();
if (duration > 0)
percentage = 1000L * playbackPosition / duration;
else
percentage = C.TIME_UNSET;
}
else
state = FilesInfo.fileState.NEW;
//playbackPosition have value in percentage
Constant.allMemoryVideoList.add(new FilesInfo(fileList[i],
directory,videoDuration, state, percentage));
//directory portion
currentDirectory = directory.getPath();
unique_directory = true;
for(int j=0; j<directoryList.size(); j++)
{
if((directoryList.get(j).toString()).equals(currentDirectory)){
unique_directory = false;
}
}
if(unique_directory){
directoryList.add(directory);
}
//When we found extension from videoExtension array we will break it.
break;
}catch (Exception e){
e.printStackTrace();
Constant.allMemoryVideoList.add(new FilesInfo(fileList[i],
directory,videoDuration, FilesInfo.fileState.NOT_NEW, C.TIME_UNSET));
}
}
}
}
}
}
Constant.directoryList = directoryList;
}
in this i have redmi note prime 2.and i have no memory card.so when i found path and File[] externalDirs = getExternalFilesDirs(null); give null second postion value of file[].
}
Is it true that the file path to external SDCard on Android devices are always "/storage/extSdCard"? If not, how many variations are there?
I need it for my App to test the availability of external SDCard.
I am using Titanium, it has a method Titanium.Filesystem.isExternalStoragePresent( )
but it always return true even external SDCard is not mounted.
I think it detect SDCard at local storage thus return true. But what I really want is detect whether physical SDCard is mounted or not.
Can I do this by detecting the existence of file "/storage/extSdCard" alone?
Thanks.
Is it true that the file path to external SDCard on Android devices are always "/storage/extSdCard"? If not, how many variations are there?
Sadly the path to the external storage is not always the same according to manufacturer. Using Environment.getExternalStorageDirectory() will return you the normal path for SD card which is mnt/sdcard/. But for Samsung devices for example, the SD card path is either under mnt/extSdCard/ or under mnt/external_sd/.
So one way to proceed would be to check the existence of external directory according to the path used by each manufacturer. With something like this:
mExternalDirectory = Environment.getExternalStorageDirectory()
.getAbsolutePath();
if (android.os.Build.DEVICE.contains("samsung")
|| android.os.Build.MANUFACTURER.contains("samsung")) {
File f = new File(Environment.getExternalStorageDirectory()
.getParent() + "/extSdCard" + "/myDirectory");
if (f.exists() && f.isDirectory()) {
mExternalDirectory = Environment.getExternalStorageDirectory()
.getParent() + "/extSdCard";
} else {
f = new File(Environment.getExternalStorageDirectory()
.getAbsolutePath() + "/external_sd" + "/myDirectory");
if (f.exists() && f.isDirectory()) {
mExternalDirectory = Environment
.getExternalStorageDirectory().getAbsolutePath()
+ "/external_sd";
}
}
}
But what I really want is detect whether physical SDCard is mounted or not.
I didn't try the code yet, but the approach of Dmitriy Lozenko in this answer is much more interesting. His method returns the path of all mounted SD cards on sytem regardless of the manufacturer.
This is how I finally got sdcard path using :
public String getExternalStoragePath() {
String internalPath = Environment.getExternalStorageDirectory().getAbsolutePath();
String[] paths = internalPath.split("/");
String parentPath = "/";
for (String s : paths) {
if (s.trim().length() > 0) {
parentPath = parentPath.concat(s);
break;
}
}
File parent = new File(parentPath);
if (parent.exists()) {
File[] files = parent.listFiles();
for (File file : files) {
String filePath = file.getAbsolutePath();
Log.d(TAG, filePath);
if (filePath.equals(internalPath)) {
continue;
} else if (filePath.toLowerCase().contains("sdcard")) {
return filePath;
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
try {
if (Environment.isExternalStorageRemovable(file)) {
return filePath;
}
} catch (RuntimeException e) {
Log.e(TAG, "RuntimeException: " + e);
}
}
}
}
return null;
}
I hope it will be useful for you :)
import android.os.Environment;
import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Scanner;
public class MemoryStorage {
private MemoryStorage() {}
public static final String SD_CARD = "sdCard";
public static final String EXTERNAL_SD_CARD = "externalSdCard";
/**
* #return True if the external storage is available. False otherwise.
*/
public static boolean isAvailable() {
String state = Environment.getExternalStorageState();
if (Environment.MEDIA_MOUNTED.equals(state) || Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)) {
return true;
}
return false;
}
public static String getSdCardPath() {
return Environment.getExternalStorageDirectory().getPath() + "/";
}
/**
* #return True if the external storage is writable. False otherwise.
*/
public static boolean isWritable() {
String state = Environment.getExternalStorageState();
if (Environment.MEDIA_MOUNTED.equals(state)) {
return true;
}
return false;
}
/**
* #return A map of all storage locations available
*/
public static Map<String, File> getAllStorageLocations() {
Map<String, File> map = new HashMap<String, File>(10);
List<String> mMounts = new ArrayList<String>(10);
List<String> mVold = new ArrayList<String>(10);
mMounts.add("/mnt/sdcard");
mVold.add("/mnt/sdcard");
try {
File mountFile = new File("/proc/mounts");
if (mountFile.exists()) {
Scanner scanner = new Scanner(mountFile);
while (scanner.hasNext()) {
String line = scanner.nextLine();
if (line.startsWith("/dev/block/vold/")) {
String[] lineElements = line.split(" ");
String element = lineElements[1];
// don't add the default mount path
// it's already in the list.
if (!element.equals("/mnt/sdcard"))
mMounts.add(element);
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
try {
File voldFile = new File("/system/etc/vold.fstab");
if (voldFile.exists()) {
Scanner scanner = new Scanner(voldFile);
while (scanner.hasNext()) {
String line = scanner.nextLine();
if (line.startsWith("dev_mount")) {
String[] lineElements = line.split(" ");
String element = lineElements[2];
if (element.contains(":"))
element = element.substring(0, element.indexOf(":"));
if (!element.equals("/mnt/sdcard"))
mVold.add(element);
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
for (int i = 0; i < mMounts.size(); i++) {
String mount = mMounts.get(i);
if (!mVold.contains(mount))
mMounts.remove(i--);
}
mVold.clear();
List<String> mountHash = new ArrayList<String>(10);
for (String mount : mMounts) {
File root = new File(mount);
if (root.exists() && root.isDirectory() && root.canWrite()) {
File[] list = root.listFiles();
String hash = "[";
if (list != null) {
for (File f : list) {
hash += f.getName().hashCode() + ":" + f.length() + ", ";
}
}
hash += "]";
if (!mountHash.contains(hash)) {
String key = SD_CARD + "_" + map.size();
if (map.size() == 0) {
key = SD_CARD;
} else if (map.size() == 1) {
key = EXTERNAL_SD_CARD;
}
mountHash.add(hash);
map.put(key, root);
}
}
}
mMounts.clear();
if (map.isEmpty()) {
map.put(SD_CARD, Environment.getExternalStorageDirectory());
}
return map;
}
}
I just figured out something. At least for my Android Emulator, I had the SD Card Path like ' /storage/????-???? ' where every ? is a capital letter or a digit.
So, if /storage/ directory has a directory which is readable and that is not the internal storage directory, it must be the SD Card.
My code worked on my android emulator!
String removableStoragePath;
File fileList[] = new File("/storage/").listFiles();
for (File file : fileList)
{ if(!file.getAbsolutePath().equalsIgnoreCase(Environment.getExternalStorageDirectory().getAbsolutePath()) && file.isDirectory() && file.canRead())
removableStoragePath = file.getAbsolutePath(); }
//If there is an SD Card, removableStoragePath will have it's path. If there isn't it will be an empty string.
If there is an SD Card, removableStoragePath will have it's path. If there isn't it will be an empty string.
I have got solution on this after 4 days, Please note following points while giving path to File class in Android(Java):
Use path for internal storage String
path="/storage/sdcard0/myfile.txt";
use path for external storage
path="/storage/sdcard1/myfile.txt";
mention permissions in Manifest file.
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
First check file length for confirmation.
Check paths in ES File Explorer regarding sdcard0 & sdcard1 is
this same or else...
e.g.:
File file = new File(path);
long = file.length();//in Bytes