package de.meonwax.soundboard.util; import android.content.Context; import android.os.storage.StorageManager; import android.os.storage.StorageVolume; import android.util.Log; import android.widget.Toast; import java.io.File; import java.io.FileFilter; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.lang.reflect.Method; import java.nio.channels.FileChannel; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.HashSet; import java.util.List; import java.util.Locale; import java.util.Set; import de.meonwax.soundboard.R; public class FileUtils { private static final String LOG_TAG = FileUtils.class.getSimpleName(); private final static String[] EXTENSION_WHITELIST = new String[]{"wav", "mp3", "ogg"}; private final static String TYPE_SOUND = "Sound"; private static Set<File> storageDirectories; /** * Converts the bytes value into a human readable string */ public static String getSize(long bytes) { if (bytes < 1024) { return bytes + " B"; } if (bytes < 1024 * 1024) { return Math.round(bytes / 1024f) + " KB"; } if (bytes < 1024 * 1024 * 1024) { return Math.round(bytes / 1024f / 1024f) + " MB"; } return Math.round(bytes / 1024f / 1024f / 1024f) + " GB"; } public static boolean isWhitelisted(File file) { return EXTENSION_WHITELIST != null && Arrays.asList(EXTENSION_WHITELIST).contains(getExtension(file).toLowerCase(Locale.US)); } private static String getExtension(File file) { int i = file.getName().lastIndexOf('.'); int k = file.getName().lastIndexOf(File.separator); if (i > k) { return file.getName().substring(i + 1); } return ""; } public static String getInternalPath(Context context, File file) { return getInternalPath(context, file.getName()); } private static String getInternalPath(Context context, String fileName) { File dir = context.getExternalFilesDir(TYPE_SOUND); if (dir == null) { Toast.makeText(context, context.getString(R.string.error_no_storage), Toast.LENGTH_LONG).show(); return null; } return dir + File.separator + fileName; } public static List<File> getInternalFiles(Context context) { List<File> files = new ArrayList<>(); File dir = context.getExternalFilesDir(TYPE_SOUND); if (dir != null) { Collections.addAll(files, new File(dir.getAbsolutePath()).listFiles(new FileFilter() { @Override public boolean accept(File file) { return isWhitelisted(file); } })); } else { Toast.makeText(context, context.getString(R.string.error_no_storage), Toast.LENGTH_LONG).show(); } return files; } public static boolean existsInternalFile(Context context, String fileName) { String internalPath = FileUtils.getInternalPath(context, fileName); return (internalPath != null && new File(internalPath).exists()); } public static void copyToInternal(Context context, File file) { FileChannel inChannel = null; FileChannel outChannel = null; String internalPath = getInternalPath(context, file); if (internalPath != null) { try { File outputFile = new File(internalPath); inChannel = new FileInputStream(file).getChannel(); outChannel = new FileOutputStream(outputFile).getChannel(); inChannel.transferTo(0, inChannel.size(), outChannel); Log.d(LOG_TAG, String.format("Copied %s to %s", file.getAbsolutePath(), outputFile.getAbsolutePath())); } catch (IOException e) { Log.e(LOG_TAG, e.getMessage()); try { if (inChannel != null && inChannel.isOpen()) { inChannel.close(); } if (outChannel != null && outChannel.isOpen()) { outChannel.close(); } } catch (IOException ignored) { } } } } /** * Get all available storage directories. * Inspired by CyanogenMod File Manager: * https://github.com/CyanogenMod/android_packages_apps_CMFileManager */ public static Set<File> getStorageDirectories(Context context) { if (storageDirectories == null) { try { // Use reflection to retrieve storage volumes because required classes and methods are hidden in AOSP. StorageManager storageManager = (StorageManager) context.getSystemService(Context.STORAGE_SERVICE); Method method = storageManager.getClass().getMethod("getVolumeList"); StorageVolume[] storageVolumes = (StorageVolume[]) method.invoke(storageManager); if (storageVolumes != null && storageVolumes.length > 0) { storageDirectories = new HashSet<>(); for (StorageVolume volume : storageVolumes) { storageDirectories.add(new File(volume.getPath())); } } } catch (Exception e) { Log.e(LOG_TAG, e.getMessage()); } } return storageDirectories; } }