Monday, January 28, 2013

26 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.