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:

  1. Thank you, this is very helpful!!

    ReplyDelete
  2. 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?

    ReplyDelete
  3. 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.

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

    ReplyDelete
  5. 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.

    :)

    ReplyDelete
  6. 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?

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

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

    ReplyDelete
  9. thanks for this snippet. it really helped me out

    ReplyDelete
  10. 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..

    ReplyDelete
  11. 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.

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

    ReplyDelete
  13. 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? ;-)

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

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

    Arrays.sort(files);

    ReplyDelete
  15. This comment has been removed by the author.

    ReplyDelete
  16. 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;
    }

    }

    ReplyDelete
  17. 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.

    ReplyDelete
  18. You can try the project:
    Download the project

    Tested on Nexus One

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

    ReplyDelete
  20. 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.. :)

    ReplyDelete
  21. This comment has been removed by the author.

    ReplyDelete
  22. 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

    ReplyDelete
  23. 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..

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

    thx for your answer.

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

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

    ReplyDelete
  27. 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 "/".

    ReplyDelete
  28. 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?

    ReplyDelete
  29. This comment has been removed by the author.

    ReplyDelete
  30. 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.

    ReplyDelete
  31. Awesome !!! It helps me a lot

    ReplyDelete
  32. Thanks , This is a good article

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

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

    ReplyDelete
  35. thank u very much for such a explanatory Post

    ReplyDelete
  36. 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.

    ReplyDelete
  37. awesome thanks a lot

    ReplyDelete
  38. 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) ë

    ReplyDelete
  39. 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.

    ReplyDelete
  40. hello Eduardo Maia,

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

    ReplyDelete
  41. 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

    ReplyDelete
  42. 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.

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

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

    ReplyDelete