How to list files in an android directory? - android
Here's my code so far:
String path = Environment.getExternalStorageDirectory().toString()+"/Pictures";
AssetManager mgr = getAssets();
try {
String list[] = mgr.list(path);
Log.e("FILES", String.valueOf(list.length));
if (list != null)
for (int i=0; i<list.length; ++i)
{
Log.e("FILE:", path +"/"+ list[i]);
}
} catch (IOException e) {
Log.v("List error:", "can't list" + path);
}
Yet while I do have files in that dir, it returns me list.length = 0... any ideas?
In order to access the files, the permissions must be given in the manifest file.
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
Try this:
String path = Environment.getExternalStorageDirectory().toString()+"/Pictures";
Log.d("Files", "Path: " + path);
File directory = new File(path);
File[] files = directory.listFiles();
Log.d("Files", "Size: "+ files.length);
for (int i = 0; i < files.length; i++)
{
Log.d("Files", "FileName:" + files[i].getName());
}
I just discovered that:
new File("/sdcard/").listFiles()
returns null if you do not have:
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
set in your AndroidManifest.xml file.
Well, the AssetManager lists files within the assets folder that is inside of your APK file. So what you're trying to list in your example above is [apk]/assets/sdcard/Pictures.
If you put some pictures within the assets folder inside of your application, and they were in the Pictures directory, you would do mgr.list("/Pictures/").
On the other hand, if you have files on the sdcard that are outside of your APK file, in the Pictures folder, then you would use File as so:
File file = new File(Environment.getExternalStorageDirectory(), "Pictures");
File[] pictures = file.listFiles();
...
for (...)
{
log.e("FILE:", pictures[i].getAbsolutePath());
}
And relevant links from the docs:
File
Asset Manager
In addition to all the answers above:
If you are on Android 6.0+ (API Level 23+) you have to explicitly ask for permission to access external storage. Simply having
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
in your manifest won't be enough. You also have actively request the permission in your activity:
//check for permission
if(ContextCompat.checkSelfPermission(this,
Manifest.permission.READ_EXTERNAL_STORAGE) == PackageManager.PERMISSION_DENIED){
//ask for permission
requestPermissions(new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, READ_EXTERNAL_STORAGE_PERMISSION_CODE);
}
I recommend reading this:
http://developer.android.com/training/permissions/requesting.html#perm-request
Updated working method
My minSdkversion is 21, so I'm using ContextCompat.checkSelfPermission() method to grant permissions apart from also adding the <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/> in manifest. Thus, to get rid of the NullPointerException in spite of having files in your targeted directory, grant permissions as follows:-
MainActivity.java
public class MainActivity extends AppCompatActivity {
/*Other variables & constants here*/
private final int READ_EXTERNAL_STORAGE=100;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// ignore the button code
Button btn = (Button) findViewById(R.id.button);
btn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
openWebView();
}
});
/*---------------------------- GRANT PERMISSIONS START-------------------------*/
// Main part to grant permission. Handle other cases of permission denied
// yourself.
if(ContextCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED)
ActivityCompat.requestPermissions(this,new String[] {Manifest.permission.READ_EXTERNAL_STORAGE},READ_EXTERNAL_STORAGE);
/*---------------------------- GRANT PERMISSIONS OVER-------------------------*/
}
And the function that list all the files (in MainActivity.java), thanks to #Yury:-
public void getDownloadedFile() {
String path = Environment.getExternalStorageDirectory().toString()+"/Download/";
Log.d("Files", "Path: " + path);
File directory = new File(path);
File[] files = directory.listFiles();
if(directory.canRead() && files!=null) {
Log.d("Files", "Size: " + files.length);
for(File file: files)
Log.d("FILE",file.getName());
}
else
Log.d("Null?", "it is null");
}
Your path is not within the assets folder. Either you enumerate files within the assets folder by means of AssetManager.list() or you enumerate files on your SD card by means of File.list()
Yury's answer needs some elaboration for newer versions of Android.
First, make sure to defined READ_EXTERNAL_STORAGE permission in manifest file.
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
Include the below, for SDK greater than or equals to Android 10(Q).
<application android:requestLegacyExternalStorage="true"...</application>
Now you can list files in a directory.
String path = Environment.getExternalStorageDirectory().toString()+"/Pictures";
Log.d("Files", "Path: " + path);
File directory = new File(path);
File[] files = directory.listFiles();
Log.d("Files", "Size: "+ files.length);
for (int i = 0; i < files.length; i++)
{
Log.d("Files", "FileName:" + files[i].getName());
}
String[] listOfFiles = getActivity().getFilesDir().list();
or
String[] listOfFiles = Environment.getExternalStoragePublicDirectory (Environment.DIRECTORY_DOWNLOADS).list();
Try this:
public class GetAllFilesInDirectory {
public static void main(String[] args) throws IOException {
File dir = new File("dir");
System.out.println("Getting all files in " + dir.getCanonicalPath() + " including those in subdirectories");
List<File> files = (List<File>) FileUtils.listFiles(dir, TrueFileFilter.INSTANCE, TrueFileFilter.INSTANCE);
for (File file : files) {
System.out.println("file: " + file.getCanonicalPath());
}
}
}
There are two things that could be happening:
You are not adding READ_EXTERNAL_STORAGE permission to your AndroidManifest.xml
You are targeting Android 23 and you're not asking for that permission to the user. Go down to Android 22 or ask the user for that permission.
Try these
String appDirectoryName = getResources().getString(R.string.app_name);
File directory = new File(Environment.getExternalStorageDirectory().getAbsolutePath() + "/" + getResources().getString(R.string.app_name));
directory.mkdirs();
File[] fList = directory.listFiles();
int a = 1;
for (int x = 0; x < fList.length; x++) {
//txt.setText("You Have Capture " + String.valueOf(a) + " Photos");
a++;
}
//get all the files from a directory
for (File file : fList) {
if (file.isFile()) {
list.add(new ModelClass(file.getName(), file.getAbsolutePath()));
}
}
If you are on Android 10/Q and you did all of the correct things to request access permissions to read external storage and it still doesn't work, it's worth reading this answer:
Android Q (10) ask permission to get access all storage. Scoped storage
I had working code, but me device took it upon itself to update when it was on a network connection (it was usually without a connection.) Once in Android 10, the file access no longer worked. The only easy way to fix it without rewriting the code was to add that extra attribute to the manifest as described. The file access now works as in Android 9 again. YMMV, it probably won't continue to work in future versions.
For the people are still getting NullPointerException when they try to get file list, if you using Android API 29+ then you need to add
<application android:requestLegacyExternalStorage="true"...
in your AndroidManifest.xml file.
Then request for storage permission again.
Simple way to list files in android device in a specific folder
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
IN Kotlin
val fileRoot = Environment.getExternalStorageDirectory()
val yourDir = File(fileRoot, "FOLDER_NAME")
for (f in yourDir.listFiles()!!) {
if (f.isFile){
print(f.name)
}
}
All the file name will be printed with the file extension
Related
Android: can write but can't read file from Environment.DIRECTORY_PICTURES
I'm trying to save pictures on my Android phone and then restore them when it's needed. So I use RxJava to save and read this files to Environment.DITECTORY_PICTURES folder. My problem is that I can write an image (my rx method calls onNext, but not onError, debug shows the correct path, settings testify that app data size grows), but can't read from there. When I use my reading code with the correct path its throws FileNotFoundException. When I use this test code try { String path = Environment.DIRECTORY_PICTURES; Log.d("Files", "Path: " + path); File directory = new File(path); File[] files = directory.listFiles(); Log.d("Files", "Size: "+ files.length); for (int i = 0; i < files.length; i++) { Log.d("Files", "FileName:" + files[i].getName()); } } catch (Exception e) { e.printStackTrace(); } it throws NPE saying that files array is null. I have Read/Write external storage permissions granted. Tested on Android 5 and 6, so I guess there is nothing about Runtime permissions as well. Is there something special about reading from Environment folders I don't know? Thanks in advance for your help!
Environment.DIRECTORY_PICTURES is not a fulll qualified path to the file system directory, the one you looking for is get trough the class and using this as argument. File directory = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES); Theres more kind of storages described at: https://developer.android.com/reference/android/os/Environment.html
Saving a file on external memory
I'm trying to create a directory and save a file into the directory, my program returns that the directory was created, but I can not find the directory using either the USB port to explore from a PC, or using ES file Explorer. The program also returns true (that the directory was created) every time I run the program, if it did create it, it should return true only the first time. Additionally when I try to create a file within the directory it returns that the file does not exist. In the manifest I am setting user permissions for write to both external and internal storage. Please advise what I'm doing wrong, why does my program not actually create a folder (or file) (note that the tager folder path is storage/emulated/0/Documents/Saved_Receipts), which I assume will end up being /My Documents/Saved_Receipts) <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> <uses-permission android:name="android.permission.WRITE_INTERNAL_STORAGE"/> boolean success = false; String root = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOCUMENTS).toString(); File myDir = new File(root + "/Saved_Receipts"); if (!myDir.exists()) { success = myDir.mkdir(); textIncoming.append("creating folder"); } if (success) { textIncoming.append("created folder"); } else { textIncoming.append("folder existed"); } Random generator = new Random(); int n = 10000; n = generator.nextInt(n); String fname = "DRcpt_.xml"; File file = new File (myDir, fname); if (file.exists ()) { textIncoming.append("file exists"); } else{ textIncoming.append("file does not exist"); }
You are probably using SDK (API) 23 or higher. If that's the case, declaring permissions in the manifest is no longer enough. You should be able to fix that issue by adding the following block in your code: if (Build.VERSION.SDK_INT >= 23) { if (checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) { } else { ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 1); } } See: Storage permission error in Marshmallow
Can't delete File with the File class
Im trying to delete a music file through my App but can't achieve that. Ive checked with boolean exists = temp.exists(); boolean isFile = temp.isFile(); if there true and yes they are. These methods returns me true. But when I come to the delete method : boolean deleted = temp.delete(); It returns me False and the file is not getting deleted. There are no Exception throws just a false return to my deleted variable. Im also using these permissons : <uses-permission android:name="android.permission.MEDIA_CONTENT_CONTROL" /> <uses-permission android:name="android.permission.WAKE_LOCK" /> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/> <uses-permission android:name="android.permission.ACTION_HEADSET_PLUG"/> Someone got an Idea for a solution ? (Or other classes I can use ?) Edit: Thats my full code File temp = new File(str_path); boolean exists = temp.exists(); boolean isFile = temp.isFile(); if (exists)) { boolean deleted = temp.delete(); if (deleted) { Toast.makeText(context, "Successful deleted " + Title_Artist, Toast.LENGTH_SHORT).show(); } else { Toast.makeText(context, "Not able to delete file " + Title_Artist, Toast.LENGTH_SHORT).show(); } } (And I checked while debuging if the object has his path in it and it have it)
Delete file music you must do two task: Delete file in Storage. public static boolean delete(File path) { boolean result = true; if (path.exists()) { if (path.isDirectory()) { for (File child : path.listFiles()) { result &= delete(child); } result &= path.delete(); // Delete empty directory. } if (path.isFile()) { result &= path.delete(); } if (!result) { Log.e("Delete", "Delete failed;"); } return result; } else { Log.e("Delete", "File does not exist."); return false; } } Delete file from MediaStore: public static void deleteFileFromMediaStore(final ContentResolver contentResolver, final File file) { int sdk = android.os.Build.VERSION.SDK_INT; if (sdk >= android.os.Build.VERSION_CODES.HONEYCOMB) { String canonicalPath; try { canonicalPath = file.getCanonicalPath(); } catch (IOException e) { canonicalPath = file.getAbsolutePath(); } final Uri uri = MediaStore.Files.getContentUri("external"); final int result = contentResolver.delete(uri, MediaStore.Files.FileColumns.DATA + "=?", new String[]{canonicalPath}); if (result == 0) { final String absolutePath = file.getAbsolutePath(); if (!absolutePath.equals(canonicalPath)) { contentResolver.delete(uri, MediaStore.Files.FileColumns.DATA + "=?", new String[]{absolutePath}); } } } } You can reset/rescan MediaStore instead of do some code above. Note: If you delete from SD card and android 4.4 + Change for Android 4.4+ : Apps are not allowed to write (delete, modify ...) to external storage except to their package-specific directories.
The path from your comment looks like the file is on a removable SD card. You need special permissions on Android 4.4+ to manage or delete files on an SD card. You will need to use DocumentFile#delete(). For help accessing files on a removable SD card using DocumentFile see the following StackOverflow post: How to use the new SD card access API presented for Android 5.0 (Lollipop)? There is also a hack that might work without using DocumentFile as explained by the developer of FX file manager here: http://forum.xda-developers.com/showpost.php?p=52151865
Since you are checking that the file exists, there can only be one reason you can not delete the file: you don't have permissions to do it. An app can not delete system files, or files of other apps.
Suppose your file path is Environment.getExternalStorageDirectory().getPath() + "/Music" + "/" + "song.mp3" delete it like this File dir = new File(Environment.getExternalStorageDirectory() .getPath() + "/Music"); if (dir.isDirectory()) {new File(dir, song.mp3).delete();} if you want to delete all the files in music folder do this if (dir.isDirectory()) { String[] children = dir.list(); for (int i = 0; i < children.length; i++) { new File(dir, children[i]).delete(); } }
Delete files from application directory folder in Android?
I created folder inside application directory. File dir = new File(getActivity().getFilesDir().getParent() + File.separator + "Image directory"); in that again i created folder for specify contents File dir1 = new File(getActivity().getFilesDir().getParent() + File.separator + "Image directory" + File.separator+ "Image 1"); Inside that I am going to storage images. Images are stored and accessed. I want to delete all images which are stored at dir1 location. I tried if(dir1.isDirectory()) { for (int j = 0; j < dir1.length; j++) { File file = new File(dir1, dir1[j]); //file.canExecute(); file.delete(); } } file.delete(); returns false each time. I added permissions in manifest <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>
In your file.delete method you have used bundle don't know where did that came from. Below code will delete all files in your Image Directory File dir1 = new File(getActivity().getFilesDir().getParent() + File.separator + "Image directory" + File.separator+ "Image 1"); if (dir1 .isDirectory()) { String[] children = dir1 .list(); for (int i = 0; i < children.length; i++) { new File(dir1 , children[i]).delete(); } } Make sure you have permission for writing in external memory, which you already have uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"
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); }