Monday, January 28, 2013

72 Create a simple File Explorer in Android


Many android apps need a File browser to help users work with files in their device. In this tutorial we going to create a simple File Explorer.

Here is a result of this tutorial:
Simple File Explorer Android

This project is developed in Eclipse 4.2.0.

1. Make application interface: The main layout of this app demo is very simple layout. It have one text view, one edit text and one button.


<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/textview"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="Get File Name From SDCard" 
        android:textSize="18dp"
        android:gravity="center"
        android:layout_marginTop="10dp"     
    />   
    <RelativeLayout android:id="@+id/relativeLayout1"
        android:layout_height="wrap_content"
        android:layout_width="wrap_content"> 
        <EditText
            android:layout_alignParentLeft="true"
            android:hint="EditText"
            android:id="@+id/editText"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:layout_marginLeft="5dp"
            android:layout_marginRight="5dp"
            android:layout_marginTop="15dp"
            android:ems="10"
            android:inputType="textPersonName"
            android:layout_toLeftOf="@+id/skipButton" >
        </EditText>
   
        <Button android:text="Browser"
                 android:id="@+id/skipButton"
                 android:textSize="18dp"
                 android:layout_marginTop="10dp"
                 android:layout_alignParentRight="true"
                 android:layout_height="wrap_content"
                 android:layout_width="wrap_content"
                 android:onClick="getfile" >
         </Button>
    </RelativeLayout>
</LinearLayout>
We show all items(folder and file) on File-explorer under a custom list view and here is the code xml layout for each row in list:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
  xmlns:android="http://schemas.android.com/apk/res/android"
  android:layout_height="wrap_content" android:orientation="vertical" android:layout_width="fill_parent">
<ImageView
    android:id="@+id/fd_Icon1"
    android:layout_width="50dip"
    android:layout_height="50dip" >
</ImageView>
               
<TextView android:text="@+id/TextView01"
    android:id="@+id/TextView01"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:singleLine="true"
    android:textStyle="bold"
    android:layout_toRightOf="@+id/fd_Icon1"
    android:layout_marginTop="5dip" 
    android:layout_marginLeft="5dip">
</TextView>
<TextView android:text="@+id/TextView02"
    android:id="@+id/TextView02"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_toRightOf="@+id/fd_Icon1"
    android:layout_below="@+id/TextView01"
    android:layout_marginLeft="10dip">
   
</TextView>
<TextView android:text="@+id/TextViewDate"
    android:id="@+id/TextViewDate"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_below="@+id/TextView01"
    android:layout_alignParentRight="true"
    android:layout_marginLeft="5dip">
</TextView>
</RelativeLayout>
Each row have three text views, the first one shows the name of item, the second text view shows the number of item if that row contains a folder and show the capacity if it is a file, the last one shows the last modifying date of this item. The result is:

Simple File Explorer Android - Figure 2


2. Java Code
2.1. Code for Main Activity, when we click on the button, we will open a new activity:
package com.example.fileexplorer;
 
import android.os.Bundle;
import android.app.Activity;
import android.content.Intent;
import android.view.View;
import android.widget.EditText;

public class FileexplorerActivity extends Activity {

        private static final int REQUEST_PATH = 1;
        String curFileName;    
        EditText edittext;
        @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_fileexplorer);
        edittext = (EditText)findViewById(R.id.editText);
    }

    public void getfile(View view){
        Intent intent1 = new Intent(this, FileChooser.class);
        startActivityForResult(intent1,REQUEST_PATH);
    }
 // Listen for results.
    protected void onActivityResult(int requestCode, int resultCode, Intent data){
        // See which child activity is calling us back.
        if (requestCode == REQUEST_PATH){
                if (resultCode == RESULT_OK) {
                        curFileName = data.getStringExtra("GetFileName");
                        edittext.setText(curFileName);
                }
         }
    }
}
The result from FileChoose is a name of file.
2.2. The new activity is FileChoose extends ListActivity, here is all codes of FileChoose Activity:
package com.example.fileexplorer;

import java.io.File;
import java.sql.Date;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.text.DateFormat;
import android.os.Bundle;
import android.app.ListActivity;
import android.content.Intent;
import android.view.View;
import android.widget.ListView;

public class FileChooser extends ListActivity {

    private File currentDir;
    private FileArrayAdapter adapter;
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        currentDir = new File("/sdcard/");
        fill(currentDir);
    }
    private void fill(File f)
    {
        File[]dirs = f.listFiles();
                 this.setTitle("Current Dir: "+f.getName());
                 List<Item>dir = new ArrayList<Item>();
                 List<Item>fls = new ArrayList<Item>();
                 try{
                         for(File ff: dirs)
                         {
                                Date lastModDate = new Date(ff.lastModified());
                                DateFormat formater = DateFormat.getDateTimeInstance();
                                String date_modify = formater.format(lastModDate);
                                if(ff.isDirectory()){
                                       
                                       
                                        File[] fbuf = ff.listFiles();
                                        int buf = 0;
                                        if(fbuf != null){
                                                buf = fbuf.length;
                                        }
                                        else buf = 0;
                                        String num_item = String.valueOf(buf);
                                        if(buf == 0) num_item = num_item + " item";
                                        else num_item = num_item + " items";
                                       
                                        //String formated = lastModDate.toString();
                                        dir.add(new Item(ff.getName(),num_item,date_modify,ff.getAbsolutePath(),"directory_icon"));
                                }
                                else
                                {
                                        fls.add(new Item(ff.getName(),ff.length() + " Byte", date_modify, ff.getAbsolutePath(),"file_icon"));
                                }
                         }
                 }catch(Exception e)
                 {   
                         
                 }
                 Collections.sort(dir);
                 Collections.sort(fls);
                 dir.addAll(fls);
                 if(!f.getName().equalsIgnoreCase("sdcard"))
                         dir.add(0,new Item("..","Parent Directory","",f.getParent(),"directory_up"));
                 adapter = new FileArrayAdapter(FileChooser.this,R.layout.file_view,dir);
                 this.setListAdapter(adapter);
    }
    @Override
        protected void onListItemClick(ListView l, View v, int position, long id) {
                // TODO Auto-generated method stub
                super.onListItemClick(l, v, position, id);
                Item o = adapter.getItem(position);
                if(o.getImage().equalsIgnoreCase("directory_icon")||o.getImage().equalsIgnoreCase("directory_up")){
                                currentDir = new File(o.getPath());
                                fill(currentDir);
                }
                else
                {
                        onFileClick(o);
                }
        }
    private void onFileClick(Item o)
    {
        //Toast.makeText(this, "Folder Clicked: "+ currentDir, Toast.LENGTH_SHORT).show();
        Intent intent = new Intent();
        intent.putExtra("GetPath",currentDir.toString());
        intent.putExtra("GetFileName",o.getName());
        setResult(RESULT_OK, intent);
        finish();
    }
}
2.3. Create FileArrayAdapter for Listview above:
package com.example.fileexplorer;

import java.util.List; 
import android.content.Context;
import android.graphics.drawable.Drawable;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.TextView;

public class FileArrayAdapter extends ArrayAdapter<Item>{

        private Context c;
        private int id;
        private List<Item>items;
       
        public FileArrayAdapter(Context context, int textViewResourceId,
                        List<Item> objects) {
                super(context, textViewResourceId, objects);
                c = context;
                id = textViewResourceId;
                items = objects;
        }
        public Item getItem(int i)
         {
                 return items.get(i);
         }
         @Override
       public View getView(int position, View convertView, ViewGroup parent) {
               View v = convertView;
               if (v == null) {
                   LayoutInflater vi = (LayoutInflater)c.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
                   v = vi.inflate(id, null);
               }
              
               /* create a new view of my layout and inflate it in the row */
                //convertView = ( RelativeLayout ) inflater.inflate( resource, null );
               
               final Item o = items.get(position);
               if (o != null) {
                       TextView t1 = (TextView) v.findViewById(R.id.TextView01);
                       TextView t2 = (TextView) v.findViewById(R.id.TextView02);
                       TextView t3 = (TextView) v.findViewById(R.id.TextViewDate);
                       /* Take the ImageView from layout and set the city's image */
                                ImageView imageCity = (ImageView) v.findViewById(R.id.fd_Icon1);
                                String uri = "drawable/" + o.getImage();
                           int imageResource = c.getResources().getIdentifier(uri, null, c.getPackageName());
                           Drawable image = c.getResources().getDrawable(imageResource);
                           imageCity.setImageDrawable(image);
                      
                       if(t1!=null)
                       t1.setText(o.getName());
                       if(t2!=null)
                                t2.setText(o.getData());
                       if(t3!=null)
                                t3.setText(o.getDate());
               }
               return v;
       }
}
2.4. Finally we create file item.java for item object:
package com.example.fileexplorer;

public class Item implements Comparable<Item>{
        private String name;
        private String data;
        private String date;
        private String path;
        private String image;
       
        public Item(String n,String d, String dt, String p, String img)
        {
                name = n;
                data = d;
                date = dt;
                path = p;
                image = img;           
        }
        public String getName()
        {
                return name;
        }
        public String getData()
        {
                return data;
        }
        public String getDate()
        {
                return date;
        }
        public String getPath()
        {
                return path;
        }
        public String getImage() {
                return image;
        }
        public int compareTo(Item o) {
                if(this.name != null)
                        return this.name.toLowerCase().compareTo(o.getName().toLowerCase());
                else
                        throw new IllegalArgumentException();
        }
}

3.DEMO
3.1. Run application
Simple File Explorer Android - Figure 3


3.2. Click on a button


3.3. After click on a file in File-explorer, show this file name on edit text on Main activity


You can download all source codes of this tutorial from here.  

72 comments:

  1. Awesome and very detailed. Thank you very much.

    ReplyDelete
  2. Nice post.Give it up. Thanks for share this article. For more visit:Web App Development

    ReplyDelete
  3. you put the name in a edittex, i need put a image in a imageview how i can do that... please help :P

    ReplyDelete
    Replies
    1. jose roberto amaro aguilarMay... No entiendo muy bien tu duda, pero podrian ser estas tres posibles soluciones:

      1.-
      Si solo quieres mostrar un ImageView, tienes que rediseñar el layout que representa cada archivo y recodificar el adaptador (el que recibe la lista de items [Archivos y directorios] )

      2.-
      En este blog el usa una variable string para almacenar el nombre de la imagen (Ej: "directory_up"). Lo que podrias hacer, es mejor alamcenar el ID del recurso y evitarte la linea en donde el obtiene el ID en base al nombre

      3.-
      Para asignar una imagen a una ImageView usando la ruta completa del archivo, se puede hacer de la siguiente forma:

      Android.Graphics.Bitmap myBitmap = Android.Graphics.BitmapFactory.DecodeFile(Ruta_Completa_Archivo);

      MiImageView.SetImageBitmap(myBitmap);

      Delete
    2. Hi, I created a simple and light weight file Browser for android
      https://github.com/amitAnvay/Android-File-Browser

      Delete
  4. Gracias!!! Me ha servido bastante. Hubo unas cosas que se me complicaron.. ya que lo hice bajo c#, pero de ahi en fuera.. todo bien.

    ReplyDelete
  5. after select the particulat file how to open the file

    ReplyDelete
  6. Nice guide,can teach how to develope File Explorer that browser file in server

    ReplyDelete
  7. can u please tell me how to open file that is in the edittext

    ReplyDelete
  8. and can u tell me how to open a excel file from sdcard using this example

    ReplyDelete
  9. Really Very Helpfull Post Thnx a lot

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

    ReplyDelete
  11. my apps ganarate error when i clicked on Browser button.

    ReplyDelete
  12. urgent!!!
    hello!
    thank you for this tutorial,
    but I have a small problem with your code, when I press next browse: "could not find a method getfile(View) in the activity class for onClick handler "
    can you help me? please

    ReplyDelete
    Replies
    1. my apps also generate error when i clicked on Browser button.plzzzz can u exlpain how to solve ...

      Delete
    2. try on clickListener

      Delete
    3. Seems your java classes are not defined in AndroidManifest.xml

      Delete
  13. my click the button opens the screen but nothing appears! put him in the cell error could help me?

    ReplyDelete
  14. You rock for this excercise. I finished everything according to the guidelines yet rather than my
    index.html substance, I am getting "Hi World!" message. Under www envelope I have put index.html and a benefits organizer holding css and js indexes.
    Develop Android Apps // Mobile
    Application Development
    // Android Application Development

    ReplyDelete
  15. ủa sao phần khai báo currentDir = new File("/sdcard1/"); của mình chạy bị lỗi nhỉ :(

    ReplyDelete
  16. This file explorer library is awesome, thank you so much.

    ReplyDelete
  17. This code is working explained well but its not working for the android device having internalmemory or having different SDCARD name like "sdcard0" or "ExtSdcard"

    ReplyDelete
  18. Hi thanks for sharing the tutorials!

    But How can we implement the fileexplorer instead of ListActivity ,
    we prefer to implement into the ListView.... ?

    ReplyDelete
  19. Nice tutorial!!
    But there is a problem: when I click on a folder nothing happens. Solutions?

    ReplyDelete
    Replies
    1. Sorry!! I solved the problem. All works perfectly!

      Delete
  20. How can I browse files not in the SD card?

    ReplyDelete
  21. geting error at this code Collections.sort(dir);

    ReplyDelete
  22. Item was a predefined function How can we create a another Item.java

    ReplyDelete
  23. sorry my English
    i have a question i need to show only .txt files and folders how can i do that
    hey thank u so much

    ReplyDelete
    Replies
    1. Hey Ömer whatsapp i want to help you
      this is your code

      int dotposition= file.lastIndexOf(".");
      //String filename_Without_Ext = file.substring(0,dotposition);
      String ext = file.substring(dotposition + 1, file.length());

      i'm glad to help you :) see u

      Delete
  24. Can we really open the chosen file? What I mean is if I have selected a jpg file, can the image be displayed? or this explorer is just to show what is inside the storage? Thanks!

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

    ReplyDelete
  26. Check out my blog. It explains how to create a Directory Chooser. This code can be adapted to create a File Chooser as well, and even integrated into a fully fledged file manager app.

    http://androidprogrammeringcorner.blogspot.com/p/android.html?m=1

    Best regards,

    Philip

    ReplyDelete
  27. Hi, I´m design with a samsung tablet, and I implement this code in an activity, works fine in landscape orientation, but in portrait orientation the application shows the error "android.content.res.Resources$NotFoundException: Resource ID #0x7f040018", in this part:
    LayoutInflater vi = (LayoutInflater)c.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    v = vi.inflate(id, null);
    Thanks in advance.

    ReplyDelete
    Replies
    1. Hi, I found the problem, and no has relation with the code, thanks

      Delete
  28. Thanks for the tutorial.
    First, I should mention that if a blank page is shown after pressing “Browser” button, as some people stated in comments, READ_EXTERNAL_STORAGE permission should be granted to the app by adding

    in the manifest file.

    I have a problem. A "Resources$NotFoundException" exception is thrown when
    Drawable image = c.getResources().getDrawable(imageResource);
    is executed. It is because that imageResource is always 0 after executing
    int imageResource = c.getResources().getIdentifier(uri, null, c.getPackageName());

    Can anyone help me?

    ReplyDelete
    Replies
    1. **correction:
      by adding
      uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"
      in the manifest file.

      Delete
    2. I believe this is no longer sufficient after API 23:

      http://inthecheesefactory.com/blog/things-you-need-to-know-about-android-m-permission-developer-edition/en

      However, these steps seem to pull up a permissions dialog for me, so I'm still not sure how to resolve the blank screen problem.

      Delete
  29. how to execute this project in android studio?

    ReplyDelete
    Replies
    1. 1. Download source code and extract to FileExplorer folder
      2. Open Android Studio
      3. Select menu File -> Close Project
      4. From welcome form -> Select Import Project(Eclipse ADT, Gradle, ect)
      5. Browse FileExplorer folder (source code) -> OK -> NEXT -> FINISH
      6. Waiting process until completed.

      Delete
  30. Thanks....
    You did great job for us...

    ReplyDelete
  31. Thanks....
    You did great job for us...

    ReplyDelete
  32. Thanks!!!!!!!!!!!!
    It saved me a lot of time

    ReplyDelete
  33. as I can explore a folder on my pc with android through code.

    ReplyDelete
  34. It works really well for all my android phone users, except for 2 people with Samsung Galaxy Core Prime (Android v4.4). I get the following Stack Trace message:
    android.view.InflateException: Binary XML file line #20: Error inflating class android.widget.ListView
    ...
    Caused by: android.content.res.Resources$NotFoundException: Resource is not a Drawable (color or path): TypedValue{t=0x2/d=0x7f010080 a=2}
    ...
    Any ideas?

    ReplyDelete
  35. i have used this code but when we click on browse button blank screen i opening.
    i want to know that which permisstions and gradle dependencies will show .

    ReplyDelete
  36. when we click on browse button this error is coming


    android.content.res.Resources$NotFoundException: Resource ID #0x0

    ReplyDelete
    Replies
    1. in resources (drawables) you have to put three icons:
      file_icon
      directory_icon
      directory_up

      Delete
  37. This can't see my external SD card..It works perfectly but I really need to see the external SD. Any help would be incredibly appreciated.

    ReplyDelete
    Replies
    1. Never mind! I achieved this by using the following as the current directory;
      Environment.getExternalStorageDirectory().getPath()
      in place of the string "sdcard".
      Thank you GREATLY for this tutorial, you've spared me a ton of frustration.

      Delete
  38. Im using this kind of code in fragment, when i click on folder, i refresh the adaptor, i have to handle the back press, how will i do that

    ReplyDelete
  39. Thank you. I just wanted to know where to ship it since I know now to keep producing it

    Android Training in Chennai

    ReplyDelete
  40. How can we make the back button go to the upper directory?

    ReplyDelete
  41. Thank you for sharing this article, it is great info provide me. visit best leading
    mobile app developer

    ReplyDelete
  42. Thank you so much for sharing this code. Very useful. I've added the following code to prevent file browsing reset on orientation change:

    @Override
    public void onSaveInstanceState(Bundle savedInstanceState) {
    super.onSaveInstanceState(savedInstanceState);
    // Save UI state changes to the savedInstanceState.
    // This bundle will be passed to onCreate if the process is
    // killed and restarted.
    savedInstanceState.putString("currentDir", currentDir.toString());
    // etc.
    }
    @Override
    public void onRestoreInstanceState(Bundle savedInstanceState) {
    super.onRestoreInstanceState(savedInstanceState);
    // Restore UI state from the savedInstanceState.
    // This bundle has also been passed to onCreate.
    currentDir = new File (savedInstanceState.getString("currentDir"));
    fill(currentDir);
    }

    Thanks. Cheers :)
    Zox
    Piandro

    ReplyDelete
  43. this blog really helpful blog to everyone... thanks for sharing

    android training institute in chennai

    ReplyDelete
  44. You have provided an nice article, Thank you very much for this one. And i hope this will be useful for many people.. and i am waiting for your next post keep on updating these kinds of knowledgeable things...

    Mobile App Development Company
    Android app Development Company
    ios app development Company
    Mobile App Development Companies

    ReplyDelete
  45. "Nice it seems to be good post... It will get readers engagement on the article since readers engagement plays an vital role in every blog.. i am expecting more updated posts from your hands."!!

    android apps development service

    ReplyDelete
  46. what i have to do if user not have sdcard in the device.

    ReplyDelete
  47. there is no File view layout code plz provide

    ReplyDelete