Android Open Source - vanilindy File System Adapter






From Project

Back to project page vanilindy.

License

The source code is released under:

Apache License

If you think the Android project vanilindy listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.

Java Source Code

/*
 * Copyright (C) 2010, 2011 Christopher Eby <kreed@kreed.org>
 */* w w  w  . j  av  a  2s .  c  om*/
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */

package ch.blinkenlights.android.vanilla;

import android.content.Context;
import android.content.Intent;
import android.graphics.drawable.Drawable;
import android.os.Environment;
import android.os.FileObserver;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.TextView;
import java.io.File;
import java.io.FilenameFilter;
import java.io.IOException;
import java.util.Arrays;
import java.util.Comparator;
import java.util.regex.Pattern;

/**
 * A list adapter that provides a view of the filesystem. The active directory
 * is set through a {@link Limiter} and rows are displayed using MediaViews.
 */
public class FileSystemAdapter
  extends BaseAdapter
  implements LibraryAdapter
           , View.OnClickListener
{
  private static final Pattern SPACE_SPLIT = Pattern.compile("\\s+");
  private static final Pattern FILE_SEPARATOR = Pattern.compile(File.separator);

  /**
   * The owner LibraryActivity.
   */
  final LibraryActivity mActivity;
  /**
   * A LayoutInflater to use.
   */
  private final LayoutInflater mInflater;
  /**
   * The currently active limiter, set by a row expander being clicked.
   */
  private Limiter mLimiter;
  /**
   * The files and folders in the current directory.
   */
  private File[] mFiles;
  /**
   * The folder icon shown for folder rows.
   */
  private final Drawable mFolderIcon;
  /**
   * The currently active filter, entered by the user from the search box.
   */
  String[] mFilter;
  /**
   * Excludes dot files and files not matching mFilter.
   */
  private final FilenameFilter mFileFilter = new FilenameFilter() {
    @Override
    public boolean accept(File dir, String filename)
    {
      if (filename.charAt(0) == '.')
        return false;
      if (mFilter != null) {
        filename = filename.toLowerCase();
        for (String term : mFilter) {
          if (!filename.contains(term))
            return false;
        }
      }
      return true;
    }
  };
  /**
   * Sorts folders before files first, then sorts alphabetically by name.
   */
  private final Comparator<File> mFileComparator = new Comparator<File>() {
    @Override
    public int compare(File a, File b)
    {
      boolean aIsFolder = a.isDirectory();
      boolean bIsFolder = b.isDirectory();
      if (bIsFolder == aIsFolder) {
        return a.getName().compareToIgnoreCase(b.getName());
      } else if (bIsFolder) {
        return 1;
      }
      return -1;
    }
  };
  /**
   * The Observer instance for the current directory.
   */
  private Observer mFileObserver;

  /**
   * Create a FileSystemAdapter.
   *
   * @param activity The LibraryActivity that will contain this adapter.
   * Called on to requery this adapter when the contents of the directory
   * change.
   * @param limiter An initial limiter to set. If none is given, will be set
   * to the external storage directory.
   */
  public FileSystemAdapter(LibraryActivity activity, Limiter limiter)
  {
    mActivity = activity;
    mLimiter = limiter;
    mFolderIcon = activity.getResources().getDrawable(R.drawable.folder);
    mInflater = (LayoutInflater)activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    if (limiter == null) {
      limiter = buildLimiter( activity.getFilesystemBrowseStart() );
    }
    setLimiter(limiter);
  }

  @Override
  public Object query()
  {
    File file = mLimiter == null ? new File("/") : (File)mLimiter.data;

    if (mFileObserver == null) {
      mFileObserver = new Observer(file.getPath());
    }

    File[] files = file.listFiles(mFileFilter);
    if (files != null)
      Arrays.sort(files, mFileComparator);
    return files;
  }

  @Override
  public void commitQuery(Object data)
  {
    mFiles = (File[])data;
    notifyDataSetInvalidated();
  }

  @Override
  public void clear()
  {
    mFiles = null;
    notifyDataSetInvalidated();
  }

  @Override
  public int getCount()
  {
    if (mFiles == null)
      return 0;
    return mFiles.length;
  }

  @Override
  public Object getItem(int pos)
  {
    return mFiles[pos];
  }

  @Override
  public long getItemId(int pos)
  {
    return pos;
  }

  private static class ViewHolder {
    public int id;
    public TextView text;
    public View divider;
    public ImageView arrow;
  }

  @Override
  public View getView(int pos, View convertView, ViewGroup parent)
  {
    View view;
    ViewHolder holder;

    if (convertView == null) {
      view = mInflater.inflate(R.layout.library_row_expandable, null);
      holder = new ViewHolder();
      holder.text = (TextView)view.findViewById(R.id.text);
      holder.divider = view.findViewById(R.id.divider);
      holder.arrow = (ImageView)view.findViewById(R.id.arrow);
      holder.text.setOnClickListener(this);
      holder.arrow.setOnClickListener(this);
      view.setTag(holder);
    } else {
      view = convertView;
      holder = (ViewHolder)view.getTag();
    }

    File file = mFiles[pos];
    boolean isDirectory = file.isDirectory();
    holder.id = pos;
    holder.text.setText(file.getName());
    holder.divider.setVisibility(isDirectory ? View.VISIBLE : View.GONE);
    holder.arrow.setVisibility(isDirectory ? View.VISIBLE : View.GONE);
    holder.text.setCompoundDrawablesWithIntrinsicBounds(isDirectory ? mFolderIcon : null, null, null, null);
    return view;
  }

  @Override
  public void setFilter(String filter)
  {
    if (filter == null)
      mFilter = null;
    else
      mFilter = SPACE_SPLIT.split(filter.toLowerCase());
  }

  @Override
  public void setLimiter(Limiter limiter)
  {
    if (mFileObserver != null)
      mFileObserver.stopWatching();
    mFileObserver = null;
    mLimiter = limiter;
  }

  @Override
  public Limiter getLimiter()
  {
    return mLimiter;
  }

  /**
   * Builds a limiter from the given folder. Only files contained in the
   * given folder will be shown if the limiter is set on this adapter.
   *
   * @param file A File pointing to a folder.
   * @return A limiter describing the given folder.
   */
  public static Limiter buildLimiter(File file)
  {
    String[] fields = FILE_SEPARATOR.split(file.getPath().substring(1));
    return new Limiter(MediaUtils.TYPE_FILE, fields, file);
  }

  @Override
  public Limiter buildLimiter(long id)
  {
    return buildLimiter(mFiles[(int)id]);
  }

  @Override
  public int getMediaType()
  {
    return MediaUtils.TYPE_FILE;
  }

  /**
   * FileObserver that reloads the files in this adapter.
   */
  private class Observer extends FileObserver {
    public Observer(String path)
    {
      super(path, FileObserver.CREATE | FileObserver.DELETE | FileObserver.MOVED_TO | FileObserver.MOVED_FROM);
      startWatching();
    }

    @Override
    public void onEvent(int event, String path)
    {
      mActivity.mPagerAdapter.postRequestRequery(FileSystemAdapter.this);
    }
  }

  @Override
  public Intent createData(View view)
  {
    ViewHolder holder = (ViewHolder)view.getTag();
    File file = mFiles[holder.id];

    Intent intent = new Intent();
    intent.putExtra(LibraryAdapter.DATA_TYPE, MediaUtils.TYPE_FILE);
    intent.putExtra(LibraryAdapter.DATA_ID, (long)holder.id);
    intent.putExtra(LibraryAdapter.DATA_TITLE, holder.text.getText().toString());
    intent.putExtra(LibraryAdapter.DATA_EXPANDABLE, file.isDirectory());

    String path;
    try {
      path = file.getCanonicalPath();
    } catch (IOException e) {
      path = file.getAbsolutePath();
      Log.e("VanillaMusic", "Failed to canonicalize path", e);
    }
    intent.putExtra(LibraryAdapter.DATA_FILE, path);
    return intent;
  }

  @Override
  public void onClick(View view)
  {
    Intent intent = createData((View)view.getParent());
    boolean isFolder = intent.getBooleanExtra(LibraryAdapter.DATA_EXPANDABLE, false);
    if (isFolder) {
      mActivity.onItemExpanded(intent);
    } else {
      mActivity.onItemClicked(intent);
    }
  }
}




Java Source Code List

android.support.v4.view.PagerAdapter.java
android.support.v4.view.ViewPager.java
ch.blinkenlights.android.vanilla.ActionBarControls.java
ch.blinkenlights.android.vanilla.Action.java
ch.blinkenlights.android.vanilla.BastpUtil.java
ch.blinkenlights.android.vanilla.BuildConfig.java
ch.blinkenlights.android.vanilla.CompatHoneycomb.java
ch.blinkenlights.android.vanilla.CompatIcs.java
ch.blinkenlights.android.vanilla.CoverBitmap.java
ch.blinkenlights.android.vanilla.CoverView.java
ch.blinkenlights.android.vanilla.DragListView.java
ch.blinkenlights.android.vanilla.DragTextView.java
ch.blinkenlights.android.vanilla.FileSystemAdapter.java
ch.blinkenlights.android.vanilla.FilebrowserStartActivity.java
ch.blinkenlights.android.vanilla.FilebrowserStartAdapter.java
ch.blinkenlights.android.vanilla.FourLongWidget.java
ch.blinkenlights.android.vanilla.FourSquareWidget.java
ch.blinkenlights.android.vanilla.FourWhiteWidget.java
ch.blinkenlights.android.vanilla.FullPlaybackActivity.java
ch.blinkenlights.android.vanilla.IdlePreference.java
ch.blinkenlights.android.vanilla.LibraryActivity.java
ch.blinkenlights.android.vanilla.LibraryAdapter.java
ch.blinkenlights.android.vanilla.LibraryPagerAdapter.java
ch.blinkenlights.android.vanilla.Limiter.java
ch.blinkenlights.android.vanilla.ListPreferenceSummary.java
ch.blinkenlights.android.vanilla.MediaAdapter.java
ch.blinkenlights.android.vanilla.MediaButtonReceiver.java
ch.blinkenlights.android.vanilla.MediaUtils.java
ch.blinkenlights.android.vanilla.MiniPlaybackActivity.java
ch.blinkenlights.android.vanilla.MusicAlphabetIndexer.java
ch.blinkenlights.android.vanilla.NewPlaylistDialog.java
ch.blinkenlights.android.vanilla.OneCellWidget.java
ch.blinkenlights.android.vanilla.PlayCountsHelper.java
ch.blinkenlights.android.vanilla.PlaybackActivity.java
ch.blinkenlights.android.vanilla.PlaybackService.java
ch.blinkenlights.android.vanilla.PlaylistActivity.java
ch.blinkenlights.android.vanilla.PlaylistAdapter.java
ch.blinkenlights.android.vanilla.Playlist.java
ch.blinkenlights.android.vanilla.PrefKeys.java
ch.blinkenlights.android.vanilla.PreferencesActivity.java
ch.blinkenlights.android.vanilla.PreferencesBackupAgent.java
ch.blinkenlights.android.vanilla.QueryTask.java
ch.blinkenlights.android.vanilla.ReadaheadThread.java
ch.blinkenlights.android.vanilla.SeekBarPreference.java
ch.blinkenlights.android.vanilla.ShowQueueActivity.java
ch.blinkenlights.android.vanilla.ShowQueueAdapter.java
ch.blinkenlights.android.vanilla.SongTimeline.java
ch.blinkenlights.android.vanilla.Song.java
ch.blinkenlights.android.vanilla.TabOrderActivity.java
ch.blinkenlights.android.vanilla.TabOrderAdapter.java
ch.blinkenlights.android.vanilla.WidgetD.java
ch.blinkenlights.android.vanilla.WidgetE.java
ch.blinkenlights.bastp.Bastp.java
ch.blinkenlights.bastp.Common.java
ch.blinkenlights.bastp.FlacFile.java
ch.blinkenlights.bastp.ID3v2File.java
ch.blinkenlights.bastp.LameHeader.java
ch.blinkenlights.bastp.OggFile.java
com.viewpagerindicator.TabPageIndicator.java