text: package com.mantz_it.rfanalyzer;
  
  import android.content.ContentResolver;
  import android.content.ContentUris;
  import android.content.Context;
  import android.content.Intent;
  import android.database.Cursor;
  import android.database.DatabaseUtils;
  import android.graphics.Bitmap;
  import android.net.Uri;
  import android.os.Build;
  import android.os.Environment;
  import android.provider.DocumentsContract;
  import android.provider.MediaStore;
  import android.util.Log;
  import android.webkit.MimeTypeMap;
  import java.io.File;
  import java.io.FileFilter;
  import java.text.DecimalFormat;
  import java.util.Comparator;
  
  /**
   * This Class is copied from the Open Source project "aFileChooser"
   * (https://github.com/iPaulPro/aFileChooser). All credit goes
   * to the original author Paul Burke!
   *
   * Copyright (C) 2007-2008 OpenIntents.org
   *
   * Licensed under the Apache License, Version 2.0 (the "License");
   * you may not use this file except in compliance with the License.
   * You may obtain a copy of the License at
   *
   *      http://www.apache.org/licenses/LICENSE-2.0
   *
   * Unless required by applicable law or agreed to in writing, software
   * distributed under the License is distributed on an "AS IS" BASIS,
   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   * See the License for the specific language governing permissions and
   * limitations under the License.
   */
  
  
  /**
   * @version 2009-07-03
   * @author Peli
   * @version 2013-12-11
   * @author paulburke (ipaulpro)
   */
  public class FileUtils {
  	private FileUtils() {} //private constructor to enforce Singleton pattern
  
  	/** TAG for log messages. */
  	static final String TAG = "FileUtils";
  	private static final boolean DEBUG = false; // Set to true to enable logging
  
  	public static final String MIME_TYPE_AUDIO = "audio/*";
  	public static final String MIME_TYPE_TEXT = "text/*";
  	public static final String MIME_TYPE_IMAGE = "image/*";
  	public static final String MIME_TYPE_VIDEO = "video/*";
  	public static final String MIME_TYPE_APP = "application/*";
  
  	public static final String HIDDEN_PREFIX = ".";
  
  	/**
  	 * Gets the extension of a file name, like ".png" or ".jpg".
  	 *
  	 * @param uri
  	 * @return Extension including the dot("."); "" if there is no extension;
  	 *         null if uri was null.
  	 */
  	public static String getExtension(String uri) {
  		if (uri == null) {
  			return null;
  		}
  
  		int dot = uri.lastIndexOf(".");
  		if (dot >= 0) {
  			return uri.substring(dot);
  		} else {
  			// No extension.
  			return "";
  		}
  	}
  
  	/**
  	 * @return Whether the URI is a local one.
  	 */
  	public static boolean isLocal(String url) {
  		if (url != null && !url.startsWith("http://") && !url.startsWith("https://")) {
  			return true;
  		}
  		return false;
  	}
  
  	/**
  	 * @return True if Uri is a MediaStore Uri.
  	 * @author paulburke
  	 */
  	public static boolean isMediaUri(Uri uri) {
  		return "media".equalsIgnoreCase(uri.getAuthority());
  	}
  
  	/**
  	 * Convert File into Uri.
  	 *
  	 * @param file
  	 * @return uri
  	 */
  	public static Uri getUri(File file) {
  		if (file != null) {
  			return Uri.fromFile(file);
  		}
  		return null;
  	}
  
  	/**
  	 * Returns the path only (without file name).
  	 *
  	 * @param file
  	 * @return
  	 */
  	public static File getPathWithoutFilename(File file) {
  		if (file != null) {
  			if (file.isDirectory()) {
  				// no file to be split off. Return everything
  				return file;
  			} else {
  				String filename = file.getName();
  				String filepath = file.getAbsolutePath();
  
  				// Construct path without file name.
  				String pathwithoutname = filepath.substring(0,
  						filepath.length() - filename.length());
  				if (pathwithoutname.endsWith("/")) {
  					pathwithoutname = pathwithoutname.substring(0, pathwithoutname.length() - 1);
  				}
  				return new File(pathwithoutname);
  			}
  		}
  		return null;
  	}
  
  	/**
  	 * @return The MIME type for the given file.
  	 */
  	public static String getMimeType(File file) {
  
  		String extension = getExtension(file.getName());
  
  		if (extension.length() > 0)
  			return MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension.substring(1));
  
  		return "application/octet-stream";
  	}
  
  	/**
  	 * @return The MIME type for the give Uri.
  	 */
  	public static String getMimeType(Context context, Uri uri) {
  		File file = new File(getPath(context, uri));
  		return getMimeType(file);
  	}
  
  	/**
  	 * @param uri The Uri to check.
  	 * @return Whether the Uri authority is ExternalStorageProvider.
  	 * @author paulburke
  	 */
  	public static boolean isExternalStorageDocument(Uri uri) {
  		return "com.android.externalstorage.documents".equals(uri.getAuthority());
  	}
  
  	/**
  	 * @param uri The Uri to check.
  	 * @return Whether the Uri authority is DownloadsProvider.
  	 * @author paulburke
  	 */
  	public static boolean isDownloadsDocument(Uri uri) {
  		return "com.android.providers.downloads.documents".equals(uri.getAuthority());
  	}
  
  	/**
  	 * @param uri The Uri to check.
  	 * @return Whether the Uri authority is MediaProvider.
  	 * @author paulburke
  	 */
  	public static boolean isMediaDocument(Uri uri) {
  		return "com.android.providers.media.documents".equals(uri.getAuthority());
  	}
  
  	/**
  	 * @param uri The Uri to check.
  	 * @return Whether the Uri authority is Google Photos.
  	 */
  	public static boolean isGooglePhotosUri(Uri uri) {
  		return "com.google.android.apps.photos.content".equals(uri.getAuthority());
  	}
  
  	/**
  	 * Get the value of the data column for this Uri. This is useful for
  	 * MediaStore Uris, and other file-based ContentProviders.
  	 *
  	 * @param context The context.
  	 * @param uri The Uri to query.
  	 * @param selection (Optional) Filter used in the query.
  	 * @param selectionArgs (Optional) Selection arguments used in the query.
  	 * @return The value of the _data column, which is typically a file path.
  	 * @author paulburke
  	 */
  	public static String getDataColumn(Context context, Uri uri, String selection,
  									   String[] selectionArgs) {
  
  		Cursor cursor = null;
  		final String column = "_data";
  		final String[] projection = {
  				column
  		};
  
  		try {
  			cursor = context.getContentResolver().query(uri, projection, selection, selectionArgs,
  					null);
  			if (cursor != null && cursor.moveToFirst()) {
  				if (DEBUG)
  					DatabaseUtils.dumpCursor(cursor);
  
  				final int column_index = cursor.getColumnIndexOrThrow(column);
  				return cursor.getString(column_index);
  			}
  		} finally {
  			if (cursor != null)
  				cursor.close();
  		}
  		return null;
  	}
  
  	/**
  	 * Get a file path from a Uri. This will get the the path for Storage Access
  	 * Framework Documents, as well as the _data field for the MediaStore and
  	 * other file-based ContentProviders.<br>
  	 * <br>
  	 * Callers should check whether the path is local before assuming it
  	 * represents a local file.
  	 *
  	 * @param context The context.
  	 * @param uri The Uri to query.
  	 * @see #isLocal(String)
  	 * @see #getFile(Context, Uri)
  	 * @author paulburke
  	 */
  	public static String getPath(final Context context, final Uri uri) {
  
  		if (DEBUG)
  			Log.d(TAG + " File -",
  					"Authority: " + uri.getAuthority() +
  							", Fragment: " + uri.getFragment() +
  							", Port: " + uri.getPort() +
  							", Query: " + uri.getQuery() +
  							", Scheme: " + uri.getScheme() +
  							", Host: " + uri.getHost() +
  							", Segments: " + uri.getPathSegments().toString()
  			);
  
  		final boolean isKitKat = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT;
  
  		// DocumentProvider
  		if (isKitKat && DocumentsContract.isDocumentUri(context, uri)) {
  			// ExternalStorageProvider
  			if (isExternalStorageDocument(uri)) {
  				final String docId = DocumentsContract.getDocumentId(uri);
  				final String[] split = docId.split(":");
  				final String type = split[0];
  
  				if ("primary".equalsIgnoreCase(type)) {
  					return Environment.getExternalStorageDirectory() + "/" + split[1];
  				}
  
  				// TODO handle non-primary volumes
  			}
  			// DownloadsProvider
  			else if (isDownloadsDocument(uri)) {
  
  				final String id = DocumentsContract.getDocumentId(uri);
  				final Uri contentUri = ContentUris.withAppendedId(
  						Uri.parse("content://downloads/public_downloads"), Long.valueOf(id));
  
  				return getDataColumn(context, contentUri, null, null);
  			}
  			// MediaProvider
  			else if (isMediaDocument(uri)) {
  				final String docId = DocumentsContract.getDocumentId(uri);
  				final String[] split = docId.split(":");
  				final String type = split[0];
  
  				Uri contentUri = null;
  				if ("image".equals(type)) {
  					contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
  				} else if ("video".equals(type)) {
  					contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
  				} else if ("audio".equals(type)) {
  					contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
  				}
  
  				final String selection = "_id=?";
  				final String[] selectionArgs = new String[] {
  						split[1]
  				};
  
  				return getDataColumn(context, contentUri, selection, selectionArgs);
  			}
  		}
  		// MediaStore (and general)
  		else if ("content".equalsIgnoreCase(uri.getScheme())) {
  
  			// Return the remote address
  			if (isGooglePhotosUri(uri))
  				return uri.getLastPathSegment();
  
  			return getDataColumn(context, uri, null, null);
  		}
  		// File
  		else if ("file".equalsIgnoreCase(uri.getScheme())) {
  			return uri.getPath();
  		}
  
  		return null;
  	}
  
  	/**
  	 * Convert Uri into File, if possible.
  	 *
  	 * @return file A local file that the Uri was pointing to, or null if the
  	 *         Uri is unsupported or pointed to a remote resource.
  	 * @see #getPath(Context, Uri)
  	 * @author paulburke
  	 */
  	public static File getFile(Context context, Uri uri) {
  		if (uri != null) {
  			String path = getPath(context, uri);
  			if (path != null && isLocal(path)) {
  				return new File(path);
  			}
  		}
  		return null;
  	}
  
  	/**
  	 * Get the file size in a human-readable string.
  	 *
  	 * @param size
  	 * @return
  	 * @author paulburke
  	 */
  	public static String getReadableFileSize(int size) {
  		final int BYTES_IN_KILOBYTES = 1024;
  		final DecimalFormat dec = new DecimalFormat("###.#");
  		final String KILOBYTES = " KB";
  		final String MEGABYTES = " MB";
  		final String GIGABYTES = " GB";
  		float fileSize = 0;
  		String suffix = KILOBYTES;
  
  		if (size > BYTES_IN_KILOBYTES) {
  			fileSize = size / BYTES_IN_KILOBYTES;
  			if (fileSize > BYTES_IN_KILOBYTES) {
  				fileSize = fileSize / BYTES_IN_KILOBYTES;
  				if (fileSize > BYTES_IN_KILOBYTES) {
  					fileSize = fileSize / BYTES_IN_KILOBYTES;
  					suffix = GIGABYTES;
  				} else {
  					suffix = MEGABYTES;
  				}
  			}
  		}
  		return String.valueOf(dec.format(fileSize) + suffix);
  	}
  
  	/**
  	 * Attempt to retrieve the thumbnail of given File from the MediaStore. This
  	 * should not be called on the UI thread.
  	 *
  	 * @param context
  	 * @param file
  	 * @return
  	 * @author paulburke
  	 */
  	public static Bitmap getThumbnail(Context context, File file) {
  		return getThumbnail(context, getUri(file), getMimeType(file));
  	}
  
  	/**
  	 * Attempt to retrieve the thumbnail of given Uri from the MediaStore. This
  	 * should not be called on the UI thread.
  	 *
  	 * @param context
  	 * @param uri
  	 * @return
  	 * @author paulburke
  	 */
  	public static Bitmap getThumbnail(Context context, Uri uri) {
  		return getThumbnail(context, uri, getMimeType(context, uri));
  	}
  
  	/**
  	 * Attempt to retrieve the thumbnail of given Uri from the MediaStore. This
  	 * should not be called on the UI thread.
  	 *
  	 * @param context
  	 * @param uri
  	 * @param mimeType
  	 * @return
  	 * @author paulburke
  	 */
  	public static Bitmap getThumbnail(Context context, Uri uri, String mimeType) {
  		if (DEBUG)
  			Log.d(TAG, "Attempting to get thumbnail");
  
  		if (!isMediaUri(uri)) {
  			Log.e(TAG, "You can only retrieve thumbnails for images and videos.");
  			return null;
  		}
  
  		Bitmap bm = null;
  		if (uri != null) {
  			final ContentResolver resolver = context.getContentResolver();
  			Cursor cursor = null;
  			try {
  				cursor = resolver.query(uri, null, null, null, null);
  				if (cursor.moveToFirst()) {
  					final int id = cursor.getInt(0);
  					if (DEBUG)
  						Log.d(TAG, "Got thumb ID: " + id);
  
  					if (mimeType.contains("video")) {
  						bm = MediaStore.Video.Thumbnails.getThumbnail(
  								resolver,
  								id,
  								MediaStore.Video.Thumbnails.MINI_KIND,
  								null);
  					}
  					else if (mimeType.contains(FileUtils.MIME_TYPE_IMAGE)) {
  						bm = MediaStore.Images.Thumbnails.getThumbnail(
  								resolver,
  								id,
  								MediaStore.Images.Thumbnails.MINI_KIND,
  								null);
  					}
  				}
  			} catch (Exception e) {
  				if (DEBUG)
  					Log.e(TAG, "getThumbnail", e);
  			} finally {
  				if (cursor != null)
  					cursor.close();
  			}
  		}
  		return bm;
  	}
  
  	/**
  	 * File and folder comparator. TODO Expose sorting option method
  	 *
  	 * @author paulburke
  	 */
  	public static Comparator<File> sComparator = new Comparator<File>() {
  		@Override
  		public int compare(File f1, File f2) {
  			// Sort alphabetically by lower case, which is much cleaner
  			return f1.getName().toLowerCase().compareTo(
  					f2.getName().toLowerCase());
  		}
  	};
  
  	/**
  	 * File (not directories) filter.
  	 *
  	 * @author paulburke
  	 */
  	public static FileFilter sFileFilter = new FileFilter() {
  		@Override
  		public boolean accept(File file) {
  			final String fileName = file.getName();
  			// Return files only (not directories) and skip hidden files
  			return file.isFile() && !fileName.startsWith(HIDDEN_PREFIX);
  		}
  	};
  
  	/**
  	 * Folder (directories) filter.
  	 *
  	 * @author paulburke
  	 */
  	public static FileFilter sDirFilter = new FileFilter() {
  		@Override
  		public boolean accept(File file) {
  			final String fileName = file.getName();
  			// Return directories only and skip hidden directories
  			return file.isDirectory() && !fileName.startsWith(HIDDEN_PREFIX);
  		}
  	};
  
  	/**
  	 * Get the Intent for selecting content to be used in an Intent Chooser.
  	 *
  	 * @return The intent for opening a file with Intent.createChooser()
  	 * @author paulburke
  	 */
  	public static Intent createGetContentIntent() {
  		// Implicitly allow the user to select a particular kind of data
  		final Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
  		// The MIME data type filter
  		intent.setType("*/*");
  		// Only return URIs that can be opened with ContentResolver
  		intent.addCategory(Intent.CATEGORY_OPENABLE);
  		return intent;
  	}
  }