/*
* Copyright (c) 2010-2011, The MiCode Open Source Community (www.micode.net)
*
* This file is part of FileExplorer.
*
* FileExplorer is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* FileExplorer is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with SwiFTP. If not, see <http://www.gnu.org/licenses/>.
*/
package net.micode.fileexplorer;
import android.content.Context;
import android.database.Cursor;
import android.net.Uri;
import android.provider.MediaStore.Audio;
import android.provider.MediaStore.Files;
import android.provider.MediaStore.Files.FileColumns;
import android.provider.MediaStore.Images;
import android.provider.MediaStore.Video;
import android.util.Log;
import net.micode.fileexplorer.FileSortHelper.SortMethod;
import net.micode.fileexplorer.MediaFile.MediaFileType;
import java.io.FilenameFilter;
import java.util.HashMap;
import java.util.Iterator;
public class FileCategoryHelper {
public static final int COLUMN_ID = 0;
public static final int COLUMN_PATH = 1;
public static final int COLUMN_SIZE = 2;
public static final int COLUMN_DATE = 3;
private static final String LOG_TAG = "FileCategoryHelper";
public enum FileCategory {
All, Music, Video, Picture, Theme, Doc, Zip, Apk, Custom, Other, Favorite
}
private static String APK_EXT = "apk";
private static String THEME_EXT = "mtz";
private static String[] ZIP_EXTS = new String[] {
"zip", "rar"
};
public static HashMap<FileCategory, FilenameExtFilter> filters = new HashMap<FileCategory, FilenameExtFilter>();
public static HashMap<FileCategory, Integer> categoryNames = new HashMap<FileCategory, Integer>();
static {
categoryNames.put(FileCategory.All, R.string.category_all);
categoryNames.put(FileCategory.Music, R.string.category_music);
categoryNames.put(FileCategory.Video, R.string.category_video);
categoryNames.put(FileCategory.Picture, R.string.category_picture);
categoryNames.put(FileCategory.Theme, R.string.category_theme);
categoryNames.put(FileCategory.Doc, R.string.category_document);
categoryNames.put(FileCategory.Zip, R.string.category_zip);
categoryNames.put(FileCategory.Apk, R.string.category_apk);
categoryNames.put(FileCategory.Other, R.string.category_other);
categoryNames.put(FileCategory.Favorite, R.string.category_favorite);
}
public static FileCategory[] sCategories = new FileCategory[] {
FileCategory.Music, FileCategory.Video, FileCategory.Picture, FileCategory.Theme,
FileCategory.Doc, FileCategory.Zip, FileCategory.Apk, FileCategory.Other
};
private FileCategory mCategory;
private Context mContext;
public FileCategoryHelper(Context context) {
mContext = context;
mCategory = FileCategory.All;
}
public FileCategory getCurCategory() {
return mCategory;
}
public void setCurCategory(FileCategory c) {
mCategory = c;
}
public int getCurCategoryNameResId() {
return categoryNames.get(mCategory);
}
public void setCustomCategory(String[] exts) {
mCategory = FileCategory.Custom;
if (filters.containsKey(FileCategory.Custom)) {
filters.remove(FileCategory.Custom);
}
filters.put(FileCategory.Custom, new FilenameExtFilter(exts));
}
public FilenameFilter getFilter() {
return filters.get(mCategory);
}
private HashMap<FileCategory, CategoryInfo> mCategoryInfo = new HashMap<FileCategory, CategoryInfo>();
public HashMap<FileCategory, CategoryInfo> getCategoryInfos() {
return mCategoryInfo;
}
public CategoryInfo getCategoryInfo(FileCategory fc) {
if (mCategoryInfo.containsKey(fc)) {
return mCategoryInfo.get(fc);
} else {
CategoryInfo info = new CategoryInfo();
mCategoryInfo.put(fc, info);
return info;
}
}
public class CategoryInfo {
public long count;
public long size;
}
private void setCategoryInfo(FileCategory fc, long count, long size) {
CategoryInfo info = mCategoryInfo.get(fc);
if (info == null) {
info = new CategoryInfo();
mCategoryInfo.put(fc, info);
}
info.count = count;
info.size = size;
}
private String buildDocSelection() {
StringBuilder selection = new StringBuilder();
Iterator<String> iter = Util.sDocMimeTypesSet.iterator();
while(iter.hasNext()) {
selection.append("(" + FileColumns.MIME_TYPE + "=='" + iter.next() + "') OR ");
}
return selection.substring(0, selection.lastIndexOf(")") + 1);
}
private String buildSelectionByCategory(FileCategory cat) {
String selection = null;
switch (cat) {
case Theme:
selection = FileColumns.DATA + " LIKE '%.mtz'";
break;
case Doc:
selection = buildDocSelection();
break;
case Zip:
selection = "(" + FileColumns.MIME_TYPE + " == '" + Util.sZipFileMimeType + "')";
break;
case Apk:
selection = FileColumns.DATA + " LIKE '%.apk'";
break;
default:
selection = null;
}
return selection;
}
private Uri getContentUriByCategory(FileCategory cat) {
Uri uri;
String volumeName = "external";
switch(cat) {
case Theme:
case Doc:
case Zip:
case Apk:
uri = Files.getContentUri(volumeName);
break;
case Music:
uri = Audio.Media.getContentUri(volumeName);
break;
case Video:
uri = Video.Media.getContentUri(volumeName);
break;
case Picture:
uri = Images.Media.getContentUri(volumeName);
break;
default:
uri = null;
}
return uri;
}
private String buildSortOrder(SortMethod sort) {
String sortOrder = null;
switch (sort) {
case name:
sortOrder = FileColumns.TITLE + " asc";
break;
case size:
sortOrder = FileColumns.SIZE + " asc";
break;
case date:
sortOrder = FileColumns.DATE_MODIFIED + " desc";
break;
case type:
sortOrder = FileColumns.MIME_TYPE + " asc, " + FileColumns.TITLE + " asc";
break;
}
return sortOrder;
}
public Cursor query(FileCategory fc, SortMethod sort) {
Uri uri = getContentUriByCategory(fc);
String selection = buildSelectionByCategory(fc);
String sortOrder = buildSortOrder(sort);
if (uri == null) {
Log.e(LOG_TAG, "invalid uri, category:" + fc.name());
return null;
}
String[] columns = new String[] {
FileColumns._ID, FileColumns.DATA, FileColumns.SIZE, FileColumns.DATE_MODIFIED
};
return mContext.getContentResolver().query(uri, columns, selection, null, sortOrder);
}
public void refreshCategoryInfo() {
// clear
for (FileCategory fc : sCategories) {
setCategoryInfo(fc, 0, 0);
}
// query database
String volumeName = "external";
Uri uri = Audio.Media.getContentUri(volumeName);
refreshMediaCategory(FileCategory.Music, uri);
uri = Video.Media.getContentUri(volumeName);
refreshMediaCategory(FileCategory.Video, uri);
uri = Images.Media.getContentUri(volumeName);
refreshMediaCategory(FileCategory.Picture, uri);
uri = Files.getContentUri(volumeName);
refreshMediaCategory(FileCategory.Theme, uri);
refreshMediaCategory(FileCategory.Doc, uri);
refreshMediaCategory(FileCategory.Zip, uri);
refreshMediaCategory(FileCategory.Apk, uri);
}
private boolean refreshMediaCategory(FileCategory fc, Uri uri) {
String[] columns = new String[] {
"COUNT(*)", "SUM(_size)"
};
Cursor c = mContext.getContentResolver().query(uri, columns, buildSelectionByCategory(fc), null, null);
if (c == null) {
Log.e(LOG_TAG, "fail to query uri:" + uri);
return false;
}
if (c.moveToNext()) {
setCategoryInfo(fc, c.getLong(0), c.getLong(1));
Log.v(LOG_TAG, "Retrieved " + fc.name() + " info >>> count:" + c.getLong(0) + " size:" + c.getLong(1));
c.close();
return true;
}
return false;
}
public static FileCategory getCategoryFromPath(String path) {
MediaFileType type = MediaFile.getFileType(path);
if (type != null) {
if (MediaFile.isAudioFileType(type.fileType)) return FileCategory.Music;
if (MediaFile.isVideoFileType(type.fileType)) return FileCategory.Video;
if (MediaFile.isImageFileType(type.fileType)) return FileCategory.Picture;
if (Util.sDocMimeTypesSet.contains(type.mimeType)) return FileCategory.Doc;
}
int dotPosition = path.lastIndexOf('.');
if (dotPosition < 0) {
return FileCategory.Other;
}
String ext = path.substring(dotPosition + 1);
if (ext.equalsIgnoreCase(APK_EXT)) {
return FileCategory.Apk;
}
if (ext.equalsIgnoreCase(THEME_EXT)) {
return FileCategory.Theme;
}
if (matchExts(ext, ZIP_EXTS)) {
return FileCategory.Zip;
}
return FileCategory.Other;
}
private static boolean matchExts(String ext, String[] exts) {
for (String ex : exts) {
if (ex.equalsIgnoreCase(ext))
return true;
}
return false;
}
}