/* * Copyright 2008-2013, ETH Zürich, Samuel Welten, Michael Kuhn, Tobias Langner, * Sandro Affentranger, Lukas Bossard, Michael Grob, Rahul Jain, * Dominic Langenegger, Sonia Mayor Alonso, Roger Odermatt, Tobias Schlueter, * Yannick Stucki, Sebastian Wendland, Samuel Zehnder, Samuel Zihlmann, * Samuel Zweifel * * This file is part of Jukefox. * * Jukefox 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 any later version. Jukefox 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 * Jukefox. If not, see <http://www.gnu.org/licenses/>. */ package ch.ethz.dcg.pancho3.commons.utils; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.util.Collection; import android.content.ComponentName; import android.content.ContentResolver; import android.content.Context; import android.content.pm.PackageInfo; import android.content.res.Resources; import android.database.Cursor; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.net.ConnectivityManager; import android.net.NetworkInfo; import android.net.Uri; import android.os.Environment; import android.os.StatFs; import android.provider.MediaStore; import ch.ethz.dcg.jukefox.commons.utils.Log; import ch.ethz.dcg.jukefox.commons.utils.PatchInputStream; import ch.ethz.dcg.jukefox.model.collection.BaseAlbum; import ch.ethz.dcg.jukefox.model.collection.BaseArtist; import ch.ethz.dcg.jukefox.model.collection.BaseSong; import ch.ethz.dcg.pancho3.model.JukefoxApplication; public class AndroidUtils { private final static String TAG = AndroidUtils.class.getSimpleName(); private static Boolean isSensorProblemDevice = null; public static String getVersionName() { try { Context context = JukefoxApplication.getAppContext(); ComponentName comp = new ComponentName(context, JukefoxApplication.class); PackageInfo pinfo = context.getPackageManager().getPackageInfo(comp.getPackageName(), 0); return pinfo.versionName; } catch (android.content.pm.PackageManager.NameNotFoundException e) { return ""; } } public static int getVersionCode() { try { Context context = JukefoxApplication.getAppContext(); ComponentName comp = new ComponentName(context, JukefoxApplication.class); PackageInfo pinfo = context.getPackageManager().getPackageInfo(comp.getPackageName(), 0); return pinfo.versionCode; } catch (android.content.pm.PackageManager.NameNotFoundException e) { return -1; } } public static String getModel() { return android.os.Build.MODEL; } public static String getAndroidVersionName() { return android.os.Build.VERSION.RELEASE; } public static long getAvailableInternalMemorySize() { File path = Environment.getDataDirectory(); StatFs stat = new StatFs(path.getPath()); long blockSize = stat.getBlockSize(); long availableBlocks = stat.getAvailableBlocks(); return availableBlocks * blockSize; } public static long getAvailableExternalMemorySize() { File path = Environment.getExternalStorageDirectory(); StatFs stat = new StatFs(path.getPath()); long blockSize = stat.getBlockSize(); long availableBlocks = stat.getAvailableBlocks(); return availableBlocks * blockSize; } // public static boolean isSdCardOk() { // try { // Log.d(TAG, "1"); // File f = new File(Constants.SDCARD_PATH); // boolean b = f.exists() && f.isDirectory() && f.canWrite() // && f.canRead(); // if (!b) { // return false; // } // Log.d(TAG, "2"); // String[] files = f.list(); // Log.d(TAG, "3"); // if (files.length > 0) { // return true; // } else { // return false; // } // } catch (Exception e) { // Log.w(TAG, e); // return false; // } // } public static boolean isSdCardOk() { String state = Environment.getExternalStorageState(); if (Environment.MEDIA_MOUNTED.equals(state)) { return true; } else if (Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)) { Log.w(TAG, "Access to sd-card is read only"); return false; } else { return false; } } public static boolean fileExists(String filename) throws IOException { File f = new File(filename); return f.exists(); } public static boolean deleteFile(String filename) throws IOException { Log.v(TAG, "Delete file: " + filename); File f = new File(filename); return f.delete(); } public static boolean isMultiTouchOs() { Log.v("Version String", android.os.Build.VERSION.RELEASE); // double osVersion = // Double.parseDouble(android.os.Build.VERSION.RELEASE); // return osVersion >= version; try { if (android.os.Build.VERSION.RELEASE.length() < 1) { return false; } String firstLetter = android.os.Build.VERSION.RELEASE.substring(0, 1); Integer v = Integer.parseInt(firstLetter); return v >= 2; } catch (Exception e) { Log.w("PersHelper", e); return android.os.Build.VERSION.RELEASE.startsWith("2"); } } /** * return true if the current os version has a problem with reading the * duration of certain media files. * * @param version * @return */ public static boolean isDurationProblemOs() { Log.v(TAG, "Version String: " + android.os.Build.VERSION.RELEASE); try { if (android.os.Build.VERSION.RELEASE.length() < 1) { return false; } return android.os.Build.VERSION.RELEASE.startsWith("2.3"); } catch (Exception e) { Log.w(TAG, e); return false; } } public static boolean isMediaScannerScanning(Context context) { boolean result = false; Cursor cursor = query(context, MediaStore.getMediaScannerUri(), new String[] { MediaStore.MEDIA_SCANNER_VOLUME }, null, null, null); if (cursor != null) { if (cursor.getCount() == 1) { cursor.moveToFirst(); result = "external".equals(cursor.getString(0)); } cursor.close(); } return result; } public static Cursor query(Context context, Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) { return query(context, uri, projection, selection, selectionArgs, sortOrder, 0); } public static Cursor query(Context context, Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder, int limit) { try { ContentResolver resolver = context.getContentResolver(); if (resolver == null) { return null; } if (limit > 0) { uri = uri.buildUpon().appendQueryParameter("limit", "" + limit).build(); } return resolver.query(uri, projection, selection, selectionArgs, sortOrder); } catch (UnsupportedOperationException ex) { return null; } } public static Bitmap getBitmapFromResource(Resources res, int resourceId, int maxSize) { Bitmap bitmap = null; int dummySize = maxSize * maxSize / 4; // KB while (bitmap == null && dummySize <= maxSize * maxSize * 4) { try { int sampleFactor = getSampleFactor(res, resourceId, maxSize); BitmapFactory.Options resample = new BitmapFactory.Options(); resample.inSampleSize = sampleFactor; bitmap = BitmapFactory.decodeResource(res, resourceId, resample); } catch (Throwable e) { System.gc(); // Avoid that heap has to be grown for the BitmapFactory, // as this would lead to an out of memory error int[] dummyArray = new int[dummySize * 1024]; // Avoid being eliminated by optimization of compiler if (dummyArray != null) { dummyArray = null; System.gc(); } Log.w(TAG, e); dummySize *= 2; } } return bitmap; } public static Bitmap getBitmapFromInputStream(InputStream is, int maxSize) { byte[] inputBytes; try { // TODO: Check if PatchInputStream is still necessary. see // http://code.google.com/p/android/issues/detail?id=6066 inputBytes = getByteArrayFromInputStream(new PatchInputStream(is)); } catch (IOException e3) { Log.w(TAG, e3); return null; } return getBitmapFromByteArray(inputBytes, maxSize); } private static byte[] getByteArrayFromInputStream(InputStream is) throws IOException { // byte[] byteArray = null; // // byteArray = new byte[is.available()]; // is.read(byteArray); // return byteArray; ByteArrayOutputStream buffer = new ByteArrayOutputStream(); int nRead; byte[] data = new byte[16384]; while ((nRead = is.read(data, 0, data.length)) != -1) { buffer.write(data, 0, nRead); } buffer.flush(); return buffer.toByteArray(); } public static Bitmap getBitmapFromByteArray(byte[] byteArray, int maxSize) { Bitmap bitmap = null; try { try { int sampleFactor = getSampleFactor(byteArray, maxSize); BitmapFactory.Options resample = new BitmapFactory.Options(); resample.inSampleSize = sampleFactor; bitmap = BitmapFactory.decodeByteArray(byteArray, 0, byteArray.length, resample); } catch (Error e) { // Avoid that heap has to be grown for the BitmapFactory, // as this would lead to an out of memory error int[] dummyArray = new int[byteArray.length]; // Avoid being eliminated by optimization of compiler if (dummyArray != null) { dummyArray = null; System.gc(); } Log.w("BitmapFactory", e); } if (bitmap == null) { try { int sampleFactor = getSampleFactor(byteArray, maxSize); BitmapFactory.Options resample = new BitmapFactory.Options(); resample.inSampleSize = sampleFactor; bitmap = BitmapFactory.decodeByteArray(byteArray, 0, byteArray.length, resample); } catch (Error e) { System.gc(); Log.w("BitmapFactory", e); } } } catch (Throwable e) { Log.w("Bitmap", e); } return bitmap; } public static Bitmap getBitmapFromFile(String path, int maxSize) { Bitmap bitmap = null; int dummySize = maxSize * maxSize / 4; // KB while (bitmap == null && dummySize <= maxSize * maxSize * 4) { try { int sampleFactor = getSampleFactor(path, maxSize); BitmapFactory.Options resample = new BitmapFactory.Options(); resample.inSampleSize = sampleFactor; bitmap = BitmapFactory.decodeFile(path, resample); } catch (Throwable e) { // Avoid that heap has to be grown for the BitmapFactory, // as this would lead to an out of memory error int[] dummyArray = new int[dummySize * 1024]; // Avoid being eliminated by optimization of compiler if (dummyArray != null) { dummyArray = null; System.gc(); } Log.w(TAG, e); dummySize *= 2; } } return bitmap; } private static int getSampleFactor(String path, int maxSize) { BitmapFactory.Options bounds = getBounds(path); return getSampleFactor(maxSize, bounds); } private static int getSampleFactor(byte[] byteArray, int maxSize) { BitmapFactory.Options bounds = getBounds(byteArray); return getSampleFactor(maxSize, bounds); } private static int getSampleFactor(Resources res, int resrouceId, int maxSize) { BitmapFactory.Options bounds = getBounds(res, resrouceId); return getSampleFactor(maxSize, bounds); } private static int getSampleFactor(int maxSize, BitmapFactory.Options bounds) { int width = bounds.outWidth; int height = bounds.outHeight; if (width > height) { if (width > maxSize) { return width / maxSize + 1; } else { return 1; } } else { if (height > maxSize) { return height / maxSize + 1; } else { return 1; } } } public static BitmapFactory.Options getBounds(byte[] byteArray) { BitmapFactory.Options bounds = new BitmapFactory.Options(); bounds.inJustDecodeBounds = true; BitmapFactory.decodeByteArray(byteArray, 0, byteArray.length, bounds); return bounds; } public static BitmapFactory.Options getBounds(Resources res, int resourceId) { BitmapFactory.Options bounds = new BitmapFactory.Options(); bounds.inJustDecodeBounds = true; BitmapFactory.decodeResource(res, resourceId, bounds); return bounds; } public static BitmapFactory.Options getBounds(String path) { BitmapFactory.Options bounds = new BitmapFactory.Options(); bounds.inJustDecodeBounds = true; BitmapFactory.decodeFile(path, bounds); return bounds; } public static boolean hasInternetConnection(Context context) { ConnectivityManager connectivity = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); if (connectivity == null) { Log.w(TAG, "couldn't get connectivity manager"); } else { NetworkInfo[] info = connectivity.getAllNetworkInfo(); if (info != null) { for (int i = 0; i < info.length; i++) { if (info[i].getState() == NetworkInfo.State.CONNECTED) { return true; } } } } return false; } /** * On the Motorola Atrix, activating the sensors results in a buzzing sound. * On Android 2.3.x devices activating the sensors leads to a huge battery * consumption * * @return */ public static boolean isSensorProblemDevice() { if (isSensorProblemDevice == null) { // Compare it to the model name of the motorola atrix if (android.os.Build.MODEL.equals("MB860")) { Log.v(TAG, "SensorProblemDevice - MB860"); isSensorProblemDevice = true; } else if (android.os.Build.VERSION.RELEASE.startsWith("2.3")) { Log.v(TAG, "SensorProblemDevice - 2.3.x"); isSensorProblemDevice = true; } else { isSensorProblemDevice = false; } } Log.v(TAG, "isSensorProblemDevice: " + isSensorProblemDevice); return isSensorProblemDevice; } public static void printSongCollection(String label, Collection<? extends BaseSong<? extends BaseArtist, ? extends BaseAlbum>> songs) { Log.v(TAG, label); for (BaseSong<? extends BaseArtist, ? extends BaseAlbum> s : songs) { Log.v(TAG, "id: " + s.getId() + ", " + s.getArtist() + " - " + s.getTitle()); } } public static void printCollection(String label, Collection<? extends Object> collection) { Log.v(TAG, label); for (Object o : collection) { Log.v(TAG, o.toString()); } } }