I am working on an android project and I am trying to get a list of files and directories from the SD Card. It seems to be more a less working except the file name is outputting a load of nonsense and I can't see why.
Below is the code I am using to get the file listing.
public ArrayList getFileDirectoryListing()
{
ArrayList fileAndDirectories = new ArrayList();
final String state = Environment.getExternalStorageState();
if (Environment.MEDIA_MOUNTED.equals(state))
{
File[] files = Environment.getExternalStorageDirectory().listFiles();
for (int i = 0; i < files.length; i++)
{
FileDirectoryDetails fileDirectoryDetails = new FileDirectoryDetails();
fileDirectoryDetails.path = files[i].getName();
if (files[i].isDirectory())
{
fileDirectoryDetails.fileOrDirectory = FileOrDirectory.Directory;
}
else
{
fileDirectoryDetails.fileOrDirectory = FileOrDirectory.File;
}
fileAndDirectories.add(fileDirectoryDetails);
}
}
return fileAndDirectories;
}
Below is the code I am using to set the list adapter
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
listView = getListView();
ArrayList<FileDirectoryDetails> filesAndDirectories = getFileDirectoryListing();
fileDirectoryDetailsArrayAdapter = new
ArrayAdapter<FileDirectoryDetails>(this, android.R.layout.simple_list_item_1, filesAndDirectories);
setListAdapter(fileDirectoryDetailsArrayAdapter);
}
Below is a screenshot of what I am getting back in the list view instead of the actual file names.
Make sure you override toString() in your FileDirectoryDetails returning meaningful details. Currently you're using the default toString()
Or just fill your array with paths strings instead of the whole FileDirectoryDetails
Alternatively, override getView() of the adapter setting the text of the TextView to details.path
Related
I'm trying to get files from a folder and populate recyclerview based on the name of files using a custom adapter.
This is how I'm doing it:
In onBindViewHolder:
Product m = dataList.get(position);
//title
holder.title.setText(m.getTitle());
And :
void popList() {
Product product = new Product();
File dir = new File(mainFolder);//path of files
File[] filelist = dir.listFiles();
String[] nameOfFiles = new String[filelist.length];
for (int i = 0; i < nameOfFiles.length; i++) {
nameOfFiles[i] = filelist[i].getName();
product.setTitle(nameOfFiles[i]);
}
songList.add(product);
}
But the problem is, it just adds the first item.
I can't figure it out where should I loop to add it all.
You need to create separate product objects for items in loop and add it to list instead of creating a single Product object in list which will hold the last set data
void popList() {
Product product ;
File dir = new File(mainFolder);//path of files
File[] filelist = dir.listFiles();
String[] nameOfFiles = new String[filelist.length];
for (int i = 0; i < nameOfFiles.length; i++) {
// create product
product = new Product();
nameOfFiles[i] = filelist[i].getName();
product.setTitle(nameOfFiles[i]);
// add it to list
songList.add(product);
}
}
Your code walk through
void popList() {
Product product = new Product(); // one object
// ..code
for (int i = 0; i < nameOfFiles.length; i++) {
nameOfFiles[i] = filelist[i].getName();
product.setTitle(nameOfFiles[i]); // at the end of loop set last file name to object
}
songList.add(product); // one object in the list , end of story
}
I saved some file in my app now I want to show the ones which are ended by .txt on my listview not all of them. Could you please help me?
Here is how I generated my listview:
void ShowSavedFiles(){
SavedFiles = fileList();
ArrayAdapter adapter = new ArrayAdapter<String>(this,
android.R.layout.simple_list_item_1,
SavedFiles);
listSavedFiles.setAdapter(adapter);
}
You need to modify your fileList method to filter out other files, since it looks like the only data your adapter gets.
You have to create a list with only filenames that ends with .txt, if you use Java 8 you can do it like this:
SavedFiles = fileList().stream() // Convert list to stream
.filter(fileName -> fileName.endsWith(".txt")) // Filters filename to only keep ones that ends with ".txt"
.collect(Collectors.toList()); // Then collect to a list
try this:
search for specific values and add them
public void search(){
List <String> listClone = new ArrayList<String>();
for (String string : SavedFiles) {
if(string.matches(".txt")){
listClone.add(string);
}
}
}
update the listview using: updatedData(listClone)
public void updatedData(List itemsArrayList) {
adapter .clear();
if (itemsArrayList != null){
for (Object object : itemsArrayList) {
adapter .insert(object, mAdapter.getCount());
}
}
adapter .notifyDataSetChanged();
}
Here is the solution:
void ShowSavedFiles(){ArrayList<String> filteredList = new ArrayList<String>();
SavedFiles = fileList();
for(String str: SavedFiles) {
if (str.trim().contains("_cred.txt")) {
filteredList.add(str.trim());}
}
ArrayAdapter adapter
= new ArrayAdapter<String>(this,
android.R.layout.simple_list_item_1,
filteredList);
listSavedFiles.setAdapter(adapter);}
Listing all the Specific type of Documents files in android from external storage to ListView widget.
ArrayList<String> filenames;
ArrayAdapter<String> adapter;
// onCreate method
filelist = findViewById(R.id.fileList); //filelist is ListView widget
filenames = new ArrayList<>();
getFiles(); // files funtions
adapter=new ArrayAdapter<>(YourActivity.this, android.R.layout.simple_list_item_1, filenames);
filelist.setAdapter(adapter);
// getFiles() is method for getting and filtering all doccuments files from external storage
private void getFiles() {
File path = Environment.getExternalStorageDirectory();
String filename ;
Queue<File> files = new LinkedList<>(); //Linklist
files.addAll(Arrays.asList(path.listFiles())); //adding all files of path in linklist
while (!files.isEmpty()){
File file = files.remove();
if (file.isDirectory()){
files.addAll(Arrays.asList(file.listFiles()));
}
else if (file.getName().endsWith(".doc")||file.getName().endsWith(".xls")||file.getName().endsWith(".ppt")){ //filtering files
filename = file.getName(); // according to their extension
filenames.add(filename); //filenames is string ListArray
}
}
}
Just change string values like .doc or .xls to .your_file_extension
I am trying to fetch all songs from a specific folder. Currently, I am fetching all songs and then on basis of path I am looping and getting songs in the specific path.Any better way to do this?
for (int i = 0; i < totalSongList.size(); i++) {
String path = totalSongList.get(i).getPathId();
int index = path.lastIndexOf("/");
String folderPath1 = path.substring(0, index);
if (folderPath.equals(folderPath1))
songList.add(totalSongList.get(i));
}
I can't use below code also as it will fetch sub folder songs also.
musicResolver.query(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, null,MediaStore.Audio.Media.DATA + " like ? ",
new String[] {"%SPECIFIC_FOLDER_NAME%"}, null);
Here is java code without using mediaStore for retrieving all songs from the specific folder which may or maynot contain any subfolder.
public String File path = new File("your folder path here");
public void Search(File dir)
{
if(dir.isFile())
{
//get necessary songName over here
String songName = dir.getName();
//if you need path
String songPath = dir.getAbsolutePath();
//if your folder consists of other files other than audio you have to filer it
if(songName.endsWith(".mp3") || songName.endsWith(".MP3")
{
//this is the required mp3 files
//do what you want to do with it
}
}else if(dir.isDirectory())
{
File[] list = dir.listFiles();
for(int i=0;i<list.length();i++)
{
search(list[i]);
}
}
else
{
//handle exceptions here
}
}
I am trying to create a simple Mediaplayer application. It works actually, but I want to do is to show mp3 files on a Textview. I got the list like this way below (I think so). How can I set these filenames to a Textview
List<String>ListOfMusic=new ArrayList<String>();
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Field[]fields=R.raw.class.getFields();
for (int i = 0; i < fields.length; i++) {
ListOfMusic.add(fields[i].getName());
}
initComp();
textShown.setText(ListOfMusic[0]);
Loop through the ListOfMusic and add the items to the TextView (preceding every song name with the "newline" character if you want do display the song names on separate lines).
Something like this:
String songs="";
for(String songName: ListOfMusic){
songs+=songName+"\n";
}
textShown.setText(songs);
try this
String text = "";
for(String s : ListOfMusic) {
text+=s+"\n";
}
textShown.setText(text);
I am attempting to create a music player app for a Nexus 7 tablet. I am able to retrieve music files from a specific directory as well as information that is associated with them such as title, artist, etc. I have loaded the files's titles into a clickable list view. When the user clicks on a title, it takes them to an activity that plays the associated song. I was attempting to sort the titles alphabetically and ran into a snag. When I sort just the titles, they no longer match with the correct songs. This is to be expected since I only ordered the titles and not the actual files. I attempted to modify the sorting algorithm by doing this:
//will probably only work for Nexus 7
private final static File fileList = new File("/storage/emulated/0/Music/");
private final static File fileNames[] = fileList.listFiles(); //get list of files
public static void sortFiles()
{
int j;
boolean flag = true;
File temp;
MediaMetadataRetriever titleMMR = new MediaMetadataRetriever();
MediaMetadataRetriever titleMMR2 = new MediaMetadataRetriever();
while(flag)
{
flag = false;
for(j = 0; j < fileNames.length - 1; j++)
{
titleMMR.setDataSource(fileNames[j].toString());
titleMMR2.setDataSource(fileNames[j+1].toString());
if(titleMMR.extractMetadata(MediaMetadataRetriever.METADATA_KEY_TITLE).compareToIgnoreCase(titleMMR2.extractMetadata(MediaMetadataRetriever.METADATA_KEY_TITLE)) > 0)
{
temp = fileNames[j];
fileNames[j] = fileNames[j+1]; // swapping
fileNames[j+1] = temp;
flag = true;
}//end if
}//end for
}//end while
}
This is supposed to retrieve the song titles from two files, compare them, and swap the files in the File array if the first comes after the second alphabetically. For some reason, when I run the activity that calls this method, the app crashes. If I remove the + 1 from titleMMR2's data source
titleMMR2.setDataSource(fileNames[j].toString());
the app no longer crashes but the list is not in order. Again this is understandable since it compares the song titles to themselves. I don't know why the + 1 would make the program crash. It is not an array out of bounds error. There are a total of 6 .mp3 files in the directory and they are the only files in that directory. I have also tried using Arrays.sort(fileNames) but that only orders them by their file name and not song title. I also tried this:
Arrays.sort(fileNames, new Comparator<File>(){
public int compare(File f1, File f2)
{
titleMMR.setDataSource(f1.toString());
titleMMR2.setDataSource(f2.toString());
return titleMMR.extractMetadata(MediaMetadataRetriever.METADATA_KEY_TITLE).compareToIgnoreCase(titleMMR2.extractMetadata(MediaMetadataRetriever.METADATA_KEY_TITLE));
} });
That snippet also resulted in a crash. There are no errors in the java code and all appropriate classes have been imported. I'm really at a loss as to what is wrong. Any help will be appreciated and if any new info is needed I will gladly provide it. Thanks in advance.
FIXED
The correct code snip is this:
public static void sortFiles()
{
int j;
boolean flag = true;
File temp;
MediaMetadataRetriever titleMMR = new MediaMetadataRetriever();
MediaMetadataRetriever titleMMR2 = new MediaMetadataRetriever();
while(flag)
{
flag = false;
for(j = 0; j < fileNames.length - 1; j++)
{
titleMMR.setDataSource(fileNames[j].toString());
titleMMR2.setDataSource(fileNames[j+1].toString());
String title1;
String title2;
if(titleMMR.extractMetadata(MediaMetadataRetriever.METADATA_KEY_TITLE) == null)
title1 = fileNames[j].getName();
else
title1 = titleMMR.extractMetadata(MediaMetadataRetriever.METADATA_KEY_TITLE);
if(titleMMR2.extractMetadata(MediaMetadataRetriever.METADATA_KEY_TITLE) == null)
title2 = fileNames[j+1].getName();
else
title2= titleMMR2.extractMetadata(MediaMetadataRetriever.METADATA_KEY_TITLE);
if(title1.compareToIgnoreCase(title2) > 0)
{
temp = fileNames[j];
fileNames[j] = fileNames[j+1]; // swapping
fileNames[j+1] = temp;
flag = true;
}//end if
}//end for
}//end while
}