» Программирование Android

Файловый менеджер для Android своими руками

В данной статье для начинающих разработчиков программного обеспечения для операционной системы Android мы попытается пошагово разобраться, как создать свой собственный несложный файловый менеджер. Конечно же, примеры использованного кода будут полезны и в чисто обучающих целях для новичков в Android-программировании.

Для начала, необходимо подготовиться. В первую очередь нам понадобиться IDE, то есть среда программирования. Мы будем использовать IDE Eclipse, однако это не означает, что нельзя использовать любую другу доступную среду разработки. Итак, загружаем Eclipse Classic по ссылке: http://www.eclipse.org/downloads/. Далее загружаем и устанавливаем SDK Starter Package по ссылке: http://developer.android.com/sdk/index.html. Устанавливаем ADT Plugin для Eclipse и настраиваем его.

После установки среды разработки, запускаем её. В случае, если это Eclipse, выбираем пункт меню «Window» -> «Android SDK and AVD Manager», где выбираем все необходимые для установки элементы. Проще всего, конечно, установить все компоненты, но необходимый минимум включает, в любом случае, как минимум Android 2.1/2.2, Android SDK Tools, Android SDK Platform-tools.

Среда для разработки готова. Чтобы проверять созданные приложения, можно воспользоваться удобным эмулятором виртуального Android-устройства. Эмулятор добавляется в окне Android SDK and AVD Manager. Для этого нажимаем «New…» во вкладке «Virtual Devices». Заполняем поле «Name» по желанию, указываем необходимую версию API и добавляем вновь созданный виртуальный Android-девайс.

Отметим лишь, что проверять созданные приложения на реальном физическом устройстве всё-равно крайне желательно, для пущей уверенности в его работоспособности.

Теперь приступим непосредственно к созданию нового проекта. Выбираем «File» -> «New» -> «Project», в появившемся окне выбираем «Android» -> «Android Project» и нажимаем «Next». Появившееся окно заполняем как-то вот так:

Теперь разъясним, что означают введенные данные. Project Name – это имя проекта в среде разработки Eclipse. Application Name – название приложения, которое будет видно пользователю при установке на Android-девайс. Package Name – название пакета, по аналогии с Java-проектом. Данное имя обязательно должно быть уникальным, в том числе среди всех возможных названий на конечном Android-устройстве пользователя. В связи с этим, довольно эффективно в таких целях использовать веб-домен наоборот, после которого – название самого проекта, отделенное точкой. Таким образом можно достичь достаточно высокой степени уникальности. Create Activity – это имя класса, который впоследствии будет являться подклассом класса Activity. Min SDK Version – как понятно из названия, минимальная необходимая версия SDK. Если просмотреть список Build Target нашего приложения, то становится ясно, что подходит только устройство с установленной операционной системой Android версии 2.1 (версия SDK 7) или новее. Это не столь принципиально, если только не задействуются те или иные функции, доступные только в более новых версиях ОС Android. Нажимаем «Finish» и видим свой проект в разделе «Package Explorer». Проект создан.

Итак, перед нами стоит цель – обеспечить минимальный функционал файлового менеджера, как-то – базовая навигация по каталогам, то есть даже без доступа к папкам, на которые имеет права root. Также нужно отображать в верхней части экрана текущее расположение в файловой системе.

Разберем структуру проекта:

/res/drawable-*dpi – каталоги с ресурсами, которые предназначены для устройств с разной разрешающей способностью экрана. На данном этапе здесь содержится одинокий файл icon.png – иконка для приложения.

/res/layout – директория содержит xml-файлы, которые описывают структуру и внешний вид форм и их элементов. Сразу после создания проекта, в данной папке находится файл main.xml, также создаем файл row.xml, который будет описывать внешний вид рядов – элементов списка в файловом дереве нашего файлового менеджера.

/res/values – в данной папке размещены любые константы, которые могут быть применены для работы проекта.

Редактировать .xml-файлы можно в визуальном и текстовом режимах, причем второй предпочтительнее. А поэтому для редактирования кода нажимаем правой кнопкой мышки на необходимом файле .xml в Package Explorer и выбираем пункт «Open with» -> «Text Editor».

Файл FileManager.java содержит основной класс для основной формы приложения. Здесь же будет находится весь написанный нами код.

AndroidManifest.xml – содержит все основные свойства проекта, в том числе заданные при его создании (например, название). Так что при необходимости изменить название проекта в процессе разработки приложения редактировать нужно именно этот файл.

Приступим к написанию кода, по ходу дела разбираясь, за что он отвечает. Файл main.xml:

            <?xml version="1.0" encoding="utf-8"?>

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

  android:orientation="vertical"

  android:layout_width="fill_parent"

  android:layout_height="fill_parent">

  <TableRow>

    <TextView android:id="@+id/titleManager"

          android:layout_width="fill_parent"

          android:layout_height="fill_parent"

          android:padding="5dip"

          />

  </TableRow>

  <TableRow>

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

          android:layout_width="fill_parent"

          android:layout_height="fill_parent"

          android:layout_weight="2"

          android:drawSelectorOnTop="false"/>

  </TableRow>

</TableLayout>

В данном коде задана разметка для основного Layout`а. TableLayout означает, что элементы будут выстроены в виде таблицы. В верхней ячейке этой таблицы находится элемент TextView, то есть текстовое поле, а в нижней – ListView, то есть список. Оба эти элемента имеют id, используя которые, можно изменять их содержимое. К примеру, с использованием R.id.titleManager для текстового поля TextView.

Файл row.xml:

 <?xml version="1.0" encoding="utf-8"?>

<TextView

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

    android:layout_width="fill_parent"

    android:layout_height="40sp"

    android:padding="5dip"

    android:gravity="center_vertical"

/>

В данных строках задана разметка для каждого элемента ListView, то есть для каждой папки и файла. В коде указана ширина элементов, высота, отступы (padding) и выравнивание – центрирование по вертикали (center_vertical).

Файл FileManager.java:

package ru.alwake.filemanager;

    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.content.Intent;

    import android.content.DialogInterface.OnClickListener;

    import android.net.Uri;

    import android.os.Bundle;

    import android.view.View;

    import android.widget.ArrayAdapter;

    import android.widget.ListView;

    import android.widget.TextView;

    public class FileManager extends ListActivity {

      private List<String> directoryEntries = new ArrayList<String>();

      private File currentDirectory = new File("/");

      //when application started

      @Override

      public void onCreate(Bundle icicle) {

        super.onCreate(icicle);

        //set main layout

        setContentView(R.layout.main);

        //browse to root directory

        browseTo(new File("/"));

      }

      //browse to parent directory

      private void upOneLevel(){

        if(this.currentDirectory.getParent() != null) {

          this.browseTo(this.currentDirectory.getParentFile());

        }

      }

      //browse to file or directory

      private void browseTo(final File aDirectory){

        //if we want to browse directory

        if (aDirectory.isDirectory()){

          //fill list with files from this directory

          this.currentDirectory = aDirectory;

          fill(aDirectory.listFiles());

          //set titleManager text

          TextView titleManager = (TextView) findViewById(R.id.titleManager);

          titleManager.setText(aDirectory.getAbsolutePath());

        } else {

          //if we want to open file, show this dialog:

          //listener when YES button clicked

          OnClickListener okButtonListener = new OnClickListener(){

            public void onClick(DialogInterface arg0, int arg1) {

              //intent to navigate file

              Intent i = new Intent(android.content.Intent.ACTION_VIEW, Uri.parse("file://" + aDirectory.getAbsolutePath()));

              //start this activity

              startActivity(i);

            }

          };

          //listener when NO button clicked

          OnClickListener cancelButtonListener = new OnClickListener() {

            public void onClick(DialogInterface arg0, int arg1) {

              //do nothing

              //or add something you want

            }

          };

          //create dialog

          new AlertDialog.Builder(this)

            .setTitle("Подтверждение") //title

            .setMessage("Хотите открыть файл "+ aDirectory.getName() + "?") //message

            .setPositiveButton("Да", okButtonListener) //positive button

            .setNegativeButton("Нет", cancelButtonListener) //negative button

            .show(); //show dialog

        }

      }

      //fill list

      private void fill(File[] files) {

        //clear list

        this.directoryEntries.clear(); 

        if (this.currentDirectory.getParent() != null)

          this.directoryEntries.add("..");

        //add every file into list

        for (File file : files) {

          this.directoryEntries.add(file.getAbsolutePath());

        }

        //create array adapter to show everything

        ArrayAdapter<String> directoryList = new ArrayAdapter<String>(this, R.layout.row, this.directoryEntries);

        this.setListAdapter(directoryList);

      }

      //when you clicked onto item

      @Override

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

        //get selected file name

        int selectionRowID = position;

        String selectedFileString = this.directoryEntries.get(selectionRowID);

        //if we select ".." then go upper

        if(selectedFileString.equals("..")){

          this.upOneLevel();

        } else {

          //browse to clicked file or directory using browseTo()

          File clickedFile = null;

          clickedFile = new File(selectedFileString);

          if (clickedFile != null)

            this.browseTo(clickedFile);

        }

      }

    }

В начале указано имя пакета (Package Name). Строки со 2й по 18ю отвечают за импорт необходимых для работы приложения библиотек. Eclipse умеет производить подгрузку и импорт нужных библиотек автоматически, если встречает что-либо неизвестное. Вообще, в выше изложенном коде всего пять наглядных функций, это и есть скелет приложения, который обеспечивает базовую навигацию по файловой системе Android-девайса. Единственная оговорка – при попытке открыть директорию, для доступа к которой нужны root-права, приложение выдаст ошибку и будет закрыто.