Saturday, January 2, 2010

Implement a simple File Explorer in Android

It's a simple File Explorer in Android.



The files information can be read using java.io.File, using the code:
File f = new File(dirPath);
File[] files = f.listFiles();

The name of the files/folders will be added in a ArrayList. If it's not the root, two more elements (the root and the parent) will be added in the front of the ArrayList.

Then, the ArrayList will be adapted to a ArrayAdapter, and also set to be displayed on screen.

In case any item is clicked; if it's a file, the name will be display in a dialog; if it's a directory (isDirectory) and can be read (canRead), will open the selected directory; if it's a directory and CANNOT be read, a message will be prompt.




Create a layout file /res/layout/row.xml, which is the layout of each row the the list.
<?xml version="1.0" encoding="utf-8"?>

<TextView 

  xmlns:android="http://schemas.android.com/apk/res/android"

  android:id="@+id/rowtext"

  android:layout_width="fill_parent"

     android:layout_height="25px"

     android:textSize="23sp" />


Modify /res/layout/main.xml to have a List:
<?xml version="1.0" encoding="utf-8"?>

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

    android:orientation="vertical"

    android:layout_width="fill_parent"

    android:layout_height="fill_parent"

    >

<TextView

 android:id="@+id/path"

    android:layout_width="fill_parent" 

    android:layout_height="wrap_content" 

    />

<ListView

 android:id="@android:id/list"

 android:layout_width="fill_parent" 

    android:layout_height="wrap_content" 

 />

<TextView

 android:id="@android:id/empty"

 android:layout_width="fill_parent" 

    android:layout_height="wrap_content" 

    android:text="No Data"

 />

</LinearLayout>


remark: TextView with id empty will be display IF the list is empty.

Modify the code, AndroidExplorer.java
package com.AndroidExplorer;



import java.io.File;

import java.util.ArrayList;

import java.util.List;

import android.app.AlertDialog;

import android.app.ListActivity;

import android.content.DialogInterface;

import android.os.Bundle;

import android.view.View;

import android.widget.ArrayAdapter;

import android.widget.ListView;

import android.widget.TextView;



public class AndroidExplorer extends ListActivity {

 

 private List<String> item = null;

 private List<String> path = null;

 private String root="/";

 private TextView myPath;

 

    /** Called when the activity is first created. */

    @Override

    public void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        setContentView(R.layout.main);

        myPath = (TextView)findViewById(R.id.path);

        getDir(root);

    }

    

    private void getDir(String dirPath)

    {

     myPath.setText("Location: " + dirPath);

     

     item = new ArrayList<String>();

     path = new ArrayList<String>();

     

     File f = new File(dirPath);

     File[] files = f.listFiles();

     

     if(!dirPath.equals(root))

     {



      item.add(root);

      path.add(root);

      

      item.add("../");

      path.add(f.getParent());

            

     }

     

     for(int i=0; i < files.length; i++)

     {

       File file = files[i];

       path.add(file.getPath());

       if(file.isDirectory())

        item.add(file.getName() + "/");

       else

        item.add(file.getName());

     }



     ArrayAdapter<String> fileList =

      new ArrayAdapter<String>(this, R.layout.row, item);

     setListAdapter(fileList);

    }



 @Override

 protected void onListItemClick(ListView l, View v, int position, long id) {

  

  File file = new File(path.get(position));

  

  if (file.isDirectory())

  {

   if(file.canRead())

    getDir(path.get(position));

   else

   {

    new AlertDialog.Builder(this)

    .setIcon(R.drawable.icon)

    .setTitle("[" + file.getName() + "] folder can't be read!")

    .setPositiveButton("OK", 

      new DialogInterface.OnClickListener() {

       

       @Override

       public void onClick(DialogInterface dialog, int which) {

        // TODO Auto-generated method stub

       }

      }).show();

   }

  }

  else

  {

   new AlertDialog.Builder(this)

    .setIcon(R.drawable.icon)

    .setTitle("[" + file.getName() + "]")

    .setPositiveButton("OK", 

      new DialogInterface.OnClickListener() {

       

       @Override

       public void onClick(DialogInterface dialog, int which) {

        // TODO Auto-generated method stub

       }

      }).show();

  }

 }

}


- Updated: Example of File Explorer in Android.

49 comments:

Unknown said...

Thank you, this is very helpful!!

Grey said...

I'm a noob (idiot) and I can't get this to run. I get the error:

Still no compatible AVDs with target 'Google APIs': Aborting launch.

Is there some reason this will not run in a 2.2 emmulator?

Grey said...

More details..

All I did was create a new Android project called AndroidExplorer. selected the 2.2 Google API and used your com.AndroidProject name. The I pasted your files in the right place:

/src/com.AndroidExplorer/AndroidExplorer.java
/res/layout/main.xml
/res/layout/row.xml

But when I run it, it says no compatible targets found, even though I have a 2.2 emulator running.

Grey said...

Never mind...it works great. I was selecting the target as Google API instead of Android 2.2.

Erik said...

hello Grey,

Yes, I think you already solved the problem.

If you select target with Google API, you have to create a AVD with Google API support.

:)

Grey said...

What if I wanted to rename one of the files that I clicked on? Any suggestions (for a total noob to java) as to where that code would go and what th4e code should say?

Unknown said...

Hey, great stuff very helpful, How would i direct people towards a certain folder, for example go to the gallery to select a photo

Erik said...

hello james,
you can change the code getDir(root) in onCreate() to point to your default default folder.

Unknown said...

thanks for this snippet. it really helped me out

Erol said...

Hi,
I couldn't get to run the application. I think i have done everything right but i just get this error message "The application AndroidExplorer has stoped unexpectedly. Please try again."
I don't get the error in the source code. When i run the application, i get that message.
Also i select target with google api 2.2 also avd has google api support.

Thanks..

kmk1018 said...

This is awesome! Thanks!

JS said...

Hey there,

Nice snippet but unfortunately I've stuck in an error. I have my app Class, in order to use yours, I've created a new class with the code of you snippet and placed the layout files in layout folder, so each time I call the getDir() method from my app's 'main' class, it keeps returning me an error which is: "system services not available to Activities before onCreate()". Can you enlighten me regarding this error? thanks a lot, Regards.

GoGreen said...

I am also getting the same problem what Erol is facing. Any idea ? Please help

DayDreamer said...

If you are adding this class to your main app, chances are you already have a main.xml. Make sure you are inflating the correct layout.

This works really great, if I want to include this in some app I am building, what is the license for this piece of code? :) Public domain? ;-)

DanM said...

Great tutorial. To put things in alphabetical order, just add Arrays.sort:

File f = new File(dirPath);
File[] files = f.listFiles();

Arrays.sort(files);

Konar said...
This comment has been removed by the author.
Konar said...

import java.io.File;
import java.util.ArrayList;

public class FileFinder {
static void fileDir(ArrayList fileList,File file,String filter){
if(file.isDirectory()){
File[] files = file.listFiles();
for(File nfile : files){
fileDir(fileList,nfile,filter);
}
}else{
String fileName = file.getName();
if(fileName.substring(fileName.length()-filter.length()).endsWith(filter))
fileList.add(file);
}
}
public static ArrayList getFileList(String filter){
ArrayList fileList = new ArrayList();

File file = new File("/sdcard");
fileDir(fileList, file, filter);

return fileList;
}

}

Parthraj said...

Hello, I am getting error on this app, "Application has stopped unexpectedly please try again"
Are there any permissions to be added in manifest file??
Please help me, I'm new to android and java.

Erik said...

You can try the project:
Download the project

Tested on Nexus One

Parthraj said...

Thank you very much.
This will help me a lot :)

all about work said...

thanks, this tutorial works..
but how I open the file through this file browser, for example after I click OK button?
thanks for your answer.. :)

all about work said...
This comment has been removed by the author.
Nitash said...

Hey ,
Plz help , i am new to android development.
1.It says the method setListAdapter is undefined for the activity
2.icon is not a field or cannot be resolved

Nitash

AAKASH said...

pls........help me out with this.

"icon is not a field or cannot be resolved"

EVERY THING IS NOW FINE EXCEPT FOR THIS ABOVE PROBLEM.
help me pls..

androprog said...

It's a great example!
Could you tell me how I can add folder icon to folder file?

thx for your answer.

Vivek Kumar Bajpai said...

thnk you ... :)

Abhijat said...

Great work, and amazingly explained. It helped us greatly with our project.
Thanks a lot

dillistreet said...

how to come one level up directory ,
if I click back button it close the application

Erik said...

hello ankit,

If it't not the root, it should be a item "/" and "../" on top of the list.

To one level up, click "../" item.

To go to the root level, click "/".

Erik said...

Please read the updated: Example of File Explorer in Android.

Anonymous said...

Thank you for this tutorial. But I have a question.

How can I modify this code to be able to open my '/data/data' folder using the emulator?

Anonymous said...
This comment has been removed by the author.
Erik said...

Hello Taurus,

YOu can simple replace the statement
private String root="/"

to
private String root="/data/data"

But, as I remember, "/data/data" is unreadable by user apps.

Please also read the updated post.

Anonymous said...

Awesome !!! It helps me a lot

Anonymous said...

Thanks , This is a good article

Anonymous said...

This was an excellent example. Very clear and devoid of unnecessary code. Thanks for this as it is very helpful.

Anonymous said...

Thank you very much!!, it's very helpful for me.

Anonymous said...

thank u very much for such a explanatory Post

Anonymous said...

Hello.
Do you have the link of that example for download? I see the link for the new one that you did, but I need this older.

Erik said...

Sorry, I have no copy!

Anonymous said...

awesome thanks a lot

Unknown said...

How do you get around special characters in filenames?

My app breaks when calling file.listFiles() when there are files that contain special characters in their filenames. Characters like (hoping this displays correctly) ë

Unknown said...

Thanks:)

Eduardo Maia said...

Thanks, very helpful!

Guys, maybe you'd like to add this line on AndroidManifest.xml file to avoid messages reporting that some directory could not be read:



Best regards for you all.

Erik said...

hello Eduardo Maia,

May be some character missed! please don't include < and >.

Hank said...

Thanks for this. It was very easy to implement, works like a charm.

Easy enough to follow to make the custom changes I need for inclusion in my apps.

Good work

Unknown said...

Great tutorial & thanks ... I just wish it was complete AND accurate. I don't understand why anyone would publish something like this (for beginners) without actually checking that it at least works properly.

Unknown said...

No Datathat's what in the display when I use this codes

Unknown said...

its not working for me
am using api:19 (kit kat)