Android Open Source - filemanager File Utils






From Project

Back to project page filemanager.

License

The source code is released under:

MIT License

If you think the Android project filemanager 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) 2014 Michal Dabski/*from   w  ww .  j a v  a2  s  .co m*/
 * 
 * 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 com.michaldabski.utils;

import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.media.MediaMetadataRetriever;
import android.media.ThumbnailUtils;
import android.os.Build;
import android.os.Environment;
import android.provider.MediaStore;
import android.webkit.MimeTypeMap;

import com.michaldabski.filemanager.R;

import java.io.File;
import java.io.FileFilter;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Comparator;
import java.util.List;
import java.util.Locale;

public class FileUtils
{

  public static class DirectoryNotEmptyException extends IOException
  {
    private static final long serialVersionUID = 1L;

    public DirectoryNotEmptyException(File file)
    {
      super("Directory "+file.getName()+" is not empty");
    }
  }
  
  public static class FileAlreadyExistsException extends IOException
  {
    private static final long serialVersionUID = 1L;

    public FileAlreadyExistsException(File file)
    {
      super("File "+file.getName()+" already exists in destination");
    }
  }
  
  @SuppressLint("SdCardPath")
  private static final String SDCARD_DISPLAY_PATH = "/sdcard";
  private static final double FILE_APP_ICON_SCALE = 0.2;
  private static final int NUM_FOLDER_PREVIEWS = 6;
  private static final int THUMBNAIL_SIZE = 256;
  private static final int PREVIEW_WIDTH = (int) (THUMBNAIL_SIZE * 1.3),
      PREVIEW_HEIGHT = THUMBNAIL_SIZE;
  
  // user-friendly names for predefined folders
  public static final String 
    DISPLAY_NAME_ROOT = "Root",
    DISPLAY_NAME_SD_CARD = "SD Card";
  
  public final static int 
    KILOBYTE = 1024,
    MEGABYTE = KILOBYTE * 1024,
    GIGABYTE = MEGABYTE * 1024,
    MAX_BYTE_SIZE = KILOBYTE / 2,
    MAX_KILOBYTE_SIZE = MEGABYTE / 2,
    MAX_MEGABYTE_SIZE = GIGABYTE / 2;
  
  public static final String MIME_TYPE_ANY = "*/*";
  
  public static final FileFilter DEFAULT_FILE_FILTER = new FileFilter()
  {
    
    @Override
    public boolean accept(File pathname)
    {
      return pathname.isHidden() == false;
    }
  };
  
  /**
   * Compares files by name, where directories come always first
   */
  public static class FileNameComparator implements Comparator<File>
  {
    protected final static int 
      FIRST = -1,
      SECOND = 1;
    @Override
    public int compare(File lhs, File rhs)
    {
      if (lhs.isDirectory() || rhs.isDirectory())
      {
        if (lhs.isDirectory() == rhs.isDirectory())
          return lhs.getName().compareToIgnoreCase(rhs.getName());
        else if (lhs.isDirectory()) return FIRST;
        else return SECOND;
      }
      return lhs.getName().compareToIgnoreCase(rhs.getName());
    }    
  }
  
  /**
   * Compares files by extension. 
   * Falls back to sort by name if extensions are the same or one of the objects is a Directory
   * @author Michal
   *
   */
  public static class FileExtensionComparator extends FileNameComparator
  {
    @Override
    public int compare(File lhs, File rhs)
    {
      if (lhs.isDirectory() || rhs.isDirectory())
        return super.compare(lhs, rhs);

      String ext1 = getFileExtension(lhs),
          ext2 = getFileExtension(rhs);

      if (ext1.equals(ext2))
        return super.compare(lhs, rhs);
      else
        return ext1.compareToIgnoreCase(ext2);
    }
  }
  
  public static class FileSizeComparator extends FileNameComparator
  {
    private final boolean ascending = false;
    
    @Override
    public int compare(File lhs, File rhs)
    {
      if (lhs.isDirectory() || rhs.isDirectory())
        return super.compare(lhs, rhs);

      if (lhs.length() > rhs.length())
        return ascending ? SECOND : FIRST;
      else if (lhs.length() < rhs.length())
        return ascending ? FIRST : SECOND;
      else return super.compare(lhs, rhs);
    }
  }
  
  public static String formatFileSize(File file)
  {
    return formatFileSize(file.length());    
  }
  
  public static String formatFileSize(long size)
  {
    if (size < MAX_BYTE_SIZE)
      return String.format(Locale.ENGLISH, "%d bytes", size);
    else if (size < MAX_KILOBYTE_SIZE)
      return String.format(Locale.ENGLISH, "%.2f kb", (float)size / KILOBYTE);
    else if (size < MAX_MEGABYTE_SIZE)
      return String.format(Locale.ENGLISH, "%.2f mb", (float)size / MEGABYTE);
    else 
      return String.format(Locale.ENGLISH, "%.2f gb", (float)size / GIGABYTE);
  }
  
  public static String formatFileSize(Collection<File> files)
  {
    return formatFileSize(getFileSize(files));
  }
  
  public static long getFileSize(File... files)
  {
    if (files == null) return 0l;
    long size=0;
    for (File file : files)
    {
      if (file.isDirectory())
        size += getFileSize(file.listFiles());
      else size += file.length();
    }
    return size;
  }
  
  public static long getFileSize(Collection<File> files)
  {
    return getFileSize(files.toArray(new File[files.size()]));
  }
  
  public static String getFileExtension(File file)
  {
    return getFileExtension(file.getName());
  }
  
  /**
   * Gets extension of the file name excluding the . character
   */
  public static String getFileExtension(String fileName)
  {
    if (fileName.contains("."))
      return fileName.substring(fileName.lastIndexOf('.')+1);
    else 
      return "";
  }
  
  public static String getFileMimeType(File file)
  {
    String type = MimeTypeMap.getSingleton().getMimeTypeFromExtension(getFileExtension(file));
    if (type == null) return "*/*";
    return type;
  }
  
  public static int getNumFilesInFolder(File folder)
  {
    if (folder.isDirectory() == false) return 0;
    File [] files = folder.listFiles(DEFAULT_FILE_FILTER);
    if (files == null) return 0;
    return files.length;
  }
  
  /**
   * Attempts to get common mime type for a collection of assorted files
   */
  public static String getCollectiveMimeType(Collection<File> files)
  {
    String typeStart=null;
    String type=null;
    for (File file : files) if (file.isDirectory() == false)
    {
      String thisType = getFileMimeType(file);
      if (thisType == null) continue;
      if (type == null)
      {
        type = thisType;
        try
        {
          typeStart = thisType.substring(0, thisType.indexOf('/'));
        }
        catch(Exception e)
        {
          return MIME_TYPE_ANY;
        }
      }
      else if (type.equalsIgnoreCase(thisType))
        continue;
      else if (thisType.startsWith(typeStart))
        type = typeStart + "*";
      else return MIME_TYPE_ANY;
    }
    if (type == null) return MIME_TYPE_ANY;
    return type;
  }
  
  public static StringBuilder combineFileNames(Collection<File> files)
  {
    StringBuilder fileNamesStringBuilder = new StringBuilder();
    boolean first=true;
    for (File file : files)
    {
      if (first == false) fileNamesStringBuilder.append(", ");
      fileNamesStringBuilder.append(file.getName());
      first=false;
    }
    return fileNamesStringBuilder;
  }
  
  
  public static void flattenDirectory(File directory, List<File> result)
  {
    if (directory.isDirectory())
    {
      for (File file : directory.listFiles(DEFAULT_FILE_FILTER))
      {
        if (file.isDirectory())
          flattenDirectory(file, result);
        else result.add(file);
      }
    }
    else result.add(directory);
  }
  
  public static void validateCopyMoveDirectory(File file, File toFolder) throws IOException
  {
    if (toFolder.equals(file))
      throw new IOException("Folder cannot be copied to itself");
    else if (toFolder.equals(file.getParentFile()))
      throw new IOException("Source and target directory are the same");
    else if (toFolder.getAbsolutePath().startsWith(file.getAbsolutePath()))
      throw new IOException("Folder cannot be copied to its child folder");
  }
  
  public static void copyFile(File src, File dst) throws IOException 
  {
    if (src.isDirectory())
      throw new IOException("Source is a directory");
      InputStream in = new FileInputStream(src);
      OutputStream out = new FileOutputStream(dst);

      // Transfer bytes from in to out
      byte[] buf = new byte[1024];
      int len;
      while ((len = in.read(buf)) > 0) {
          out.write(buf, 0, len);
      }
      in.close();
      out.close();
  }
  
  public static void deleteEmptyFolders(Collection<File> directories) throws DirectoryNotEmptyException
  {
    for (File file : directories) if (file.isDirectory())
    {      
      deleteFiles(Arrays.asList(file.listFiles()));
      file.delete();
    }
    else throw new DirectoryNotEmptyException(file);
  }
  
  public static int deleteFiles(Collection<File> files)
  {
    int n=0;
    for (File file : files)
    {
      if (file.isDirectory())
      {
        n += deleteFiles(Arrays.asList(file.listFiles()));
      }
      if (file.delete()) n++;
    }
    return n;
  }
  
  /**
   * gets icon for this file type
   */
  @SuppressLint("NewApi")
  public static int getFileIconResource(File file)
  {
    if (file.isDirectory())
    {
      if (file.equals(Environment.getExternalStorageDirectory()) || SDCARD_DISPLAY_PATH.equals(file.getAbsolutePath()))
        return R.drawable.icon_sdcard;
      else if (file.equals(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM)))
        return R.drawable.icon_pictures;
      else if (file.equals(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS)))
        return R.drawable.icon_downloads;
      else if (file.equals(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_MOVIES)))
        return R.drawable.icon_movies;
      else if (file.equals(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_MUSIC)))
        return R.drawable.icon_music;
      else if (file.equals(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES)))
        return R.drawable.icon_pictures;
      else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT && file.equals(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOCUMENTS)))
        return R.drawable.icon_documents;
      return R.drawable.icon_folder;
    }
    else
    {
      return R.drawable.icon_file;
    }
  }
  
  public static Bitmap createFileIcon(File file, Context context, boolean homescreen)
  {
    final Bitmap bitmap;
    final Canvas canvas;
    if (file.isDirectory())
    {
      // load Folder bitmap
      Bitmap folderBitmap = BitmapFactory.decodeResource(context.getResources(), R.drawable.icon_home_folder);
      
      bitmap = Bitmap.createBitmap(folderBitmap.getWidth(), folderBitmap.getHeight(), Bitmap.Config.ARGB_8888);
      canvas = new Canvas(bitmap);
      canvas.drawBitmap(folderBitmap, 0, 0, null);
    }
    else
    {
      Bitmap folderBitmap = BitmapFactory.decodeResource(context.getResources(), homescreen?R.drawable.icon_home_file:R.drawable.icon_file);
      
      bitmap = Bitmap.createBitmap(folderBitmap.getWidth(), folderBitmap.getHeight(), Bitmap.Config.ARGB_8888);
      canvas = new Canvas(bitmap);
      canvas.drawBitmap(folderBitmap, 0, 0, null);
      
      Drawable appIcon = IntentUtils.getAppIconForFile(file, context);
      if (appIcon != null)
      {
        Rect bounds = canvas.getClipBounds();
        int shrinkage = (int)(bounds.width() * FILE_APP_ICON_SCALE);
        bounds.left += shrinkage;
        bounds.right -= shrinkage;
        bounds.top += shrinkage * 1.5;
        bounds.bottom -= shrinkage * 0.5;
        appIcon.setBounds(bounds);
        appIcon.draw(canvas);
      }
    }
    
    // add shortcut symbol
    if (homescreen)
      canvas.drawBitmap(BitmapFactory.decodeResource(context.getResources(), R.drawable.icon_home_shortcut), 0, 0, null);
    
    return  bitmap;
  }
  
  public static int countFilesIn(Collection<File> roots)
  {
    int result=0;
    for (File file : roots)
      result += countFilesIn(file);
    return result;
  }
  
  public static int countFilesIn(File root)
  {
    if (root.isDirectory() == false) return 1;
    File[] files = root.listFiles();
    if (files == null) return 0;
    
    int n = 0;
    
    for (File file : files)
    {
      if (file.isDirectory())
        n += countFilesIn(file);
      else
        n ++;
    }
    return n;
  }
  
  public static String getUserFriendlySdcardPath(File file)
  {
    String path;
    try
    {
      path = file.getCanonicalPath();
    } catch (IOException e)
    {
      path = file.getAbsolutePath();
    }
    return path
        .replace(Environment.getExternalStorageDirectory().getAbsolutePath(), SDCARD_DISPLAY_PATH);
  }
  
  public static String getFolderDisplayName(File folder)
  {
    if (Environment.getExternalStorageDirectory().equals(folder))
      return DISPLAY_NAME_SD_CARD;
    else if ("/".equals(folder.getAbsolutePath()))
      return DISPLAY_NAME_ROOT;
    else return folder.getName();
  }
  
  public static void getBitmapsInFolder(File folder, List<Bitmap>previews)
  {
    File [] files = folder.listFiles(FileUtils.DEFAULT_FILE_FILTER);
    Arrays.sort(files, new Comparator<File>()
    {

      @Override
      public int compare(File lhs, File rhs)
      {
        if (lhs.lastModified() > rhs.lastModified()) return -1;
        else if (lhs.lastModified() < rhs.lastModified()) return 1;
        else return 0;
      }
      
    });
    for (File file : files) 
      if (file.isDirectory() == false)
    {
      Bitmap bitmap = getPreview(file);
      if (bitmap != null)
      {
        previews.add(bitmap);
        if (previews.size() == NUM_FOLDER_PREVIEWS)
          break;
      }
    }
  }
  
  public static Bitmap buildFolderPreview(File folder)
  {
    List<Bitmap> previews = new ArrayList<Bitmap>(NUM_FOLDER_PREVIEWS);
    getBitmapsInFolder(folder, previews);
    if (previews.isEmpty()) return null;
    
    Bitmap folderPreview = Bitmap.createBitmap(PREVIEW_WIDTH, PREVIEW_HEIGHT, Bitmap.Config.ARGB_8888);
    Rect[] destRect = BitmapUtils.layoutImagesInGrid(folderPreview, 3, 2);
    Canvas canvas = new Canvas(folderPreview);
    Paint paint = new Paint();
    Rect srcRect = new Rect();
    int i=0;
    for (Bitmap bitmap : previews)
    {
      srcRect = BitmapUtils.getBestFitRect(bitmap, destRect[i]);
      canvas.drawBitmap(bitmap, srcRect, destRect[i++], paint);
      bitmap.recycle();
    }
    return folderPreview;
  }
  
  public static Bitmap getPreview(File image) 
  {
    if (image.isDirectory()) return buildFolderPreview(image);
    String type = getFileMimeType(image);
    if (type.startsWith("video/"))
    {
      return ThumbnailUtils.createVideoThumbnail(image.getAbsolutePath(), MediaStore.Video.Thumbnails.MINI_KIND);
    }
    else if (type.startsWith("image/"))
    {
      BitmapFactory.Options bounds = new BitmapFactory.Options();
        bounds.inJustDecodeBounds = true;
        BitmapFactory.decodeFile(image.getPath(), bounds);
        if ((bounds.outWidth == -1) || (bounds.outHeight == -1))
            return null;

        int originalSize = (bounds.outHeight > bounds.outWidth) ? bounds.outHeight
                : bounds.outWidth;

        BitmapFactory.Options opts = new BitmapFactory.Options();
        opts.inSampleSize = originalSize / THUMBNAIL_SIZE;
        return BitmapFactory.decodeFile(image.getPath(), opts);    
    }
        else if (type.startsWith("audio/"))
        {
            MediaMetadataRetriever metadataRetriever;
            metadataRetriever = new MediaMetadataRetriever();
            metadataRetriever.setDataSource(image.getAbsolutePath());
            byte[] picture = metadataRetriever.getEmbeddedPicture();
            if (picture == null) return null;
            metadataRetriever.release();
            return BitmapFactory.decodeByteArray(picture, 0, picture.length);
        }
    else return null;
  }
  
  public static boolean isMediaDirectory(File file)
  {
    try
    {
      String path = file.getCanonicalPath();
      for (String directory : new String[]{Environment.DIRECTORY_DCIM,
                    Environment.DIRECTORY_MUSIC,
          Environment.DIRECTORY_PICTURES})
      {
        if (path.startsWith(Environment.getExternalStoragePublicDirectory(directory)
            .getAbsolutePath()))
          return true;
      }
      return false;
    } catch (IOException e)
    {
      e.printStackTrace();
      return false;
    }
  }
}




Java Source Code List

com.michaldabski.filemanager.AppPreferences.java
com.michaldabski.filemanager.BaseFileAdapter.java
com.michaldabski.filemanager.FileManagerApplication.java
com.michaldabski.filemanager.RobotoAdapter.java
com.michaldabski.filemanager.about.AboutActivity.java
com.michaldabski.filemanager.clipboard.ClipboardFileAdapter.java
com.michaldabski.filemanager.clipboard.Clipboard.java
com.michaldabski.filemanager.clipboard.FileOperationListener.java
com.michaldabski.filemanager.favourites.FavouriteFolder.java
com.michaldabski.filemanager.favourites.FavouritesManager.java
com.michaldabski.filemanager.folders.CardPreviewer.java
com.michaldabski.filemanager.folders.FileAdapter.java
com.michaldabski.filemanager.folders.FileCardAdapter.java
com.michaldabski.filemanager.folders.FolderActivity.java
com.michaldabski.filemanager.folders.FolderFragment.java
com.michaldabski.filemanager.nav_drawer.NavDrawerAdapter.java
com.michaldabski.filemanager.nav_drawer.NavDrawerDivider.java
com.michaldabski.filemanager.nav_drawer.NavDrawerShortcut.java
com.michaldabski.filemanager.sqlite.SQLiteHelper.java
com.michaldabski.utils.AsyncResult.java
com.michaldabski.utils.BitmapUtils.java
com.michaldabski.utils.FileIconResolver.java
com.michaldabski.utils.FilePreviewCache.java
com.michaldabski.utils.FileUtils.java
com.michaldabski.utils.FontApplicator.java
com.michaldabski.utils.IntentUtils.java
com.michaldabski.utils.ListViewUtils.java
com.michaldabski.utils.OnResultListener.java
com.michaldabski.utils.ViewHolder.java
com.michaldabski.utils.ViewTraverser.java