/* * Copyright (C) 2012 The CyanogenMod Project * * 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. */ package com.cyanogenmod.filemanager.util; import android.content.Context; import android.os.Environment; import android.os.storage.StorageManager; import android.os.storage.StorageVolume; import com.cyanogenmod.filemanager.FileManagerApplication; import com.cyanogenmod.filemanager.R; import java.io.File; import java.lang.reflect.Constructor; import java.lang.reflect.Method; /** * A helper class with useful methods for deal with storages. */ public final class StorageHelper { private static StorageVolume[] sStorageVolumes; /** * Method that returns the storage volumes defined in the system. This method uses * reflection to retrieve the method because CM10 has a {@link Context} * as first parameter, that AOSP hasn't. * * @param ctx The current context * @return StorageVolume[] The storage volumes defined in the system */ @SuppressWarnings("boxing") public static synchronized StorageVolume[] getStorageVolumes(Context ctx) { if (sStorageVolumes == null) { //IMP!! Android SDK doesn't have a "getVolumeList" but is supported by CM10. //Use reflect to get this value (if possible) try { StorageManager sm = (StorageManager) ctx.getSystemService(Context.STORAGE_SERVICE); Method method = sm.getClass().getMethod("getVolumeList"); //$NON-NLS-1$ sStorageVolumes = (StorageVolume[])method.invoke(sm); } catch (Exception ex) { //Ignore. Android SDK StorageManager class doesn't have this method //Use default android information from environment try { File externalStorage = Environment.getExternalStorageDirectory(); String path = externalStorage.getCanonicalPath(); String description = null; if (path.toLowerCase().indexOf("usb") != -1) { //$NON-NLS-1$ description = ctx.getString(R.string.usb_storage); } else { description = ctx.getString(R.string.external_storage); } // Android SDK has a different constructor for StorageVolume. In CM10 the // description is a resource id. Create the object by reflection Constructor<StorageVolume> constructor = StorageVolume.class. getConstructor( String.class, String.class, boolean.class, boolean.class, int.class, boolean.class, long.class); StorageVolume sv = constructor.newInstance(path, description, false, false, 0, false, 0); sStorageVolumes = new StorageVolume[]{sv}; } catch (Exception ex2) { /**NON BLOCK**/ } } if (sStorageVolumes == null) { sStorageVolumes = new StorageVolume[]{}; } } return sStorageVolumes; } /** * Method that returns the storage volume description. This method uses * reflection to retrieve the description because CM10 has a {@link Context} * as first parameter, that AOSP hasn't. * * @param ctx The current context * @param volume The storage volume * @return String The description of the storage volume */ public static String getStorageVolumeDescription(Context ctx, StorageVolume volume) { try { Method method = volume.getClass().getMethod( "getDescription", //$NON-NLS-1$ new Class[]{Context.class}); if (method == null) { // AOSP method = volume.getClass().getMethod("getDescription"); //$NON-NLS-1$ return (String)method.invoke(volume); } // CM10 return (String)method.invoke(volume, ctx); } catch (Throwable _throw) { // Returns the volume storage path return volume.getPath(); } } /** * Method that returns if the path is in a volume storage * * @param path The path * @return boolean If the path is in a volume storage */ public static boolean isPathInStorageVolume(String path) { StorageVolume[] volumes = getStorageVolumes(FileManagerApplication.getInstance().getApplicationContext()); int cc = volumes.length; for (int i = 0; i < cc; i++) { StorageVolume vol = volumes[i]; if (path.startsWith(vol.getPath())) { return true; } } return false; } /** * Method that returns if the path is a storage volume * * @param path The path * @return boolean If the path is a storage volume */ public static boolean isStorageVolume(String path) { StorageVolume[] volumes = getStorageVolumes(FileManagerApplication.getInstance().getApplicationContext()); int cc = volumes.length; for (int i = 0; i < cc; i++) { StorageVolume vol = volumes[i]; String p = new File(path).getAbsolutePath(); String v = new File(vol.getPath()).getAbsolutePath(); if (p.compareTo(v) == 0) { return true; } } return false; } /** * Method that return the chrooted path of an absolute path. xe: /storage/sdcard0 --> sdcard0. * * @param path The path * @return String The chrooted path */ public static String getChrootedPath(String path) { StorageVolume[] volumes = getStorageVolumes(FileManagerApplication.getInstance().getApplicationContext()); int cc = volumes.length; for (int i = 0; i < cc; i++) { StorageVolume vol = volumes[i]; File p = new File(path); File v = new File(vol.getPath()); if (p.getAbsolutePath().startsWith(v.getAbsolutePath())) { return v.getName() + path.substring(v.getAbsolutePath().length()); } } return null; } }