package com.mcxiaoke.next.utils; import android.annotation.SuppressLint; import android.annotation.TargetApi; import android.app.Activity; import android.content.ContentResolver; import android.content.ContentUris; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.content.pm.ActivityInfo; import android.content.pm.PackageInfo; import android.content.pm.PackageManager; import android.content.pm.Signature; import android.content.res.Configuration; import android.database.Cursor; import android.media.MediaScannerConnection; import android.net.Uri; import android.os.AsyncTask; import android.os.BatteryManager; import android.os.Build; import android.os.Build.VERSION_CODES; import android.os.Environment; import android.os.StatFs; import android.os.StrictMode; import android.provider.DocumentsContract; import android.provider.MediaStore; import android.view.View; import android.view.WindowManager; import android.view.inputmethod.InputMethodManager; import android.widget.EditText; import android.widget.Toast; import com.mcxiaoke.next.core.BuildConfig; import java.io.ByteArrayInputStream; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.security.cert.CertificateFactory; import java.security.cert.X509Certificate; import java.util.regex.Pattern; /** * User: mcxiaoke * Date: 13-5-3 * Time: 上午10:06 */ public final class AndroidUtils { public static final boolean DEBUG = BuildConfig.DEBUG; public static final String TAG = AndroidUtils.class.getSimpleName(); public static final String FILENAME_NOMEDIA = ".nomedia"; public static final int HEAP_SIZE_LARGE = 48 * 1024 * 1024; private static final Pattern SAFE_FILENAME_PATTERN = Pattern.compile("[\\w%+,./=_-]+"); private AndroidUtils() { } /** * Check if a filename is "safe" (no metacharacters or spaces). * * @param file The file to check */ public static boolean isFilenameSafe(File file) { // Note, we check whether it matches what's known to be safe, // rather than what's known to be unsafe. Non-ASCII, control // characters, etc. are all unsafe by default. return SAFE_FILENAME_PATTERN.matcher(file.getPath()).matches(); } public static File getCacheDir(Context context) { if (Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())) { File cacheDir = context.getExternalCacheDir(); File noMedia = new File(cacheDir, FILENAME_NOMEDIA); if (!noMedia.exists()) { try { noMedia.createNewFile(); } catch (IOException e) { e.printStackTrace(); } } return cacheDir; } else { return context.getCacheDir(); } } /** * 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. * * @param context The context. * @param uri The Uri to query. * @author paulburke */ @SuppressLint("NewApi") public static String getPath(final Context context, final Uri uri) { final boolean isKitKat = Build.VERSION.SDK_INT >= VERSION_CODES.KITKAT; if (DEBUG) { LogUtils.v(TAG, "getRealPath() uri=" + uri + " isKitKat=" + isKitKat); } // 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]; } } // 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 (ContentResolver.SCHEME_CONTENT.equalsIgnoreCase(uri.getScheme())) { // Return the remote address if (isGooglePhotosUri(uri)) return uri.getLastPathSegment(); return getDataColumn(context, uri, null, null); } // File else if (ContentResolver.SCHEME_FILE.equalsIgnoreCase(uri.getScheme())) { return uri.getPath(); } return uri.getPath(); } /** * 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. */ private static String getDataColumn(Context context, Uri uri, String selection, String[] selectionArgs) { Cursor cursor = null; final String column = MediaStore.MediaColumns.DATA; final String[] projection = {column}; try { cursor = context.getContentResolver().query(uri, projection, selection, selectionArgs, null); if (cursor != null && cursor.moveToFirst()) { final int index = cursor.getColumnIndexOrThrow(column); return cursor.getString(index); } } finally { if (cursor != null) cursor.close(); } return null; } /** * @param uri The Uri to check. * @return Whether the Uri authority is ExternalStorageProvider. */ 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. */ 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. */ 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()); } public static boolean isLargeHeap() { return Runtime.getRuntime().maxMemory() > HEAP_SIZE_LARGE; } public static boolean noSdcard() { return !Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState()); } /** * check if free size of SDCARD and CACHE dir is OK * * @param needSize how much space should release at least * @return true if has enough space */ public static boolean noFreeSpace(long needSize) { long freeSpace = getFreeSpace(); return freeSpace < needSize * 3; } @SuppressWarnings("deprecation") public static long getFreeSpace() { StatFs stat = new StatFs(Environment.getExternalStorageDirectory() .getPath()); long blockSize = stat.getBlockSize(); long availableBlocks = stat.getAvailableBlocks(); return availableBlocks * blockSize; } public static void hideSoftKeyboard(Context context, EditText editText) { InputMethodManager imm = (InputMethodManager) context.getSystemService( Context.INPUT_METHOD_SERVICE); imm.hideSoftInputFromWindow(editText.getWindowToken(), 0); } public static void showSoftKeyboard(Context context, EditText editText) { if (editText.requestFocus()) { InputMethodManager imm = (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE); imm.showSoftInput(editText, InputMethodManager.SHOW_IMPLICIT); } } public static void toggleSoftInput(Context context, View view) { if (view.requestFocus()) { InputMethodManager imm = (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE); imm.toggleSoftInput(0, 0); } } public static void showToast(Context context, int resId) { Toast.makeText(context, resId, Toast.LENGTH_SHORT).show(); } public static void showToast(Context context, CharSequence text) { Toast.makeText(context, text, Toast.LENGTH_SHORT).show(); } public static void showLongToast(Context context, int resId) { Toast.makeText(context, resId, Toast.LENGTH_LONG).show(); } public static void showLongToast(Context context, CharSequence text) { Toast.makeText(context, text, Toast.LENGTH_LONG).show(); } /** * Execute an {@link AsyncTask} on a thread pool. * * @param task Task to add. * @param args Optional arguments to pass to {@link AsyncTask#execute(Object[])}. * @param <T> Task argument type. */ @SuppressWarnings("unchecked") @TargetApi(VERSION_CODES.HONEYCOMB) public static <T> void execute(AsyncTask<T, ?, ?> task, T... args) { if (Build.VERSION.SDK_INT < VERSION_CODES.HONEYCOMB) { task.execute(args); } else { task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, args); } } public static boolean hasCamera(Context context) { PackageManager pm = context.getPackageManager(); return pm.hasSystemFeature(PackageManager.FEATURE_CAMERA) || pm.hasSystemFeature(PackageManager.FEATURE_CAMERA_FRONT); } public static void mediaScan(Context context, Uri uri) { Intent intent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE); intent.setData(uri); context.sendBroadcast(intent); } // another media scan way public static void addToMediaStore(Context context, File file) { String[] path = new String[]{file.getPath()}; MediaScannerConnection.scanFile(context, path, null, null); } public static boolean isMediaMounted() { return Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState()); } public static void setFullScreen(final Activity activity, final boolean fullscreen) { if (fullscreen) { activity.getWindow().addFlags( WindowManager.LayoutParams.FLAG_FULLSCREEN); activity.getWindow().clearFlags( WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN); } else { activity.getWindow().addFlags( WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN); activity.getWindow().clearFlags( WindowManager.LayoutParams.FLAG_FULLSCREEN); } } public static void setPortraitOrientation(final Activity activity, final boolean portrait) { if (portrait) { activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); } else { activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED); } } public static void lockScreenOrientation(final Activity context, final boolean portrait) { if (portrait) { context.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); } else { if (context.getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) { context.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE); } if (context.getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) { context.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); } } } public static void unlockScreenOrientation(final Activity context) { context.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED); } public static boolean hasIceCreamSandwich() { return Build.VERSION.SDK_INT >= VERSION_CODES.ICE_CREAM_SANDWICH; } public static boolean isPreIceCreamSandwich() { return Build.VERSION.SDK_INT < VERSION_CODES.ICE_CREAM_SANDWICH; } public static boolean hasJellyBean() { return Build.VERSION.SDK_INT >= VERSION_CODES.JELLY_BEAN; } public static boolean hasKitkat() { return Build.VERSION.SDK_INT >= VERSION_CODES.KITKAT; } public static boolean isPreLollipop() { return Build.VERSION.SDK_INT < VERSION_CODES.LOLLIPOP; } public static boolean hasLollipop() { return Build.VERSION.SDK_INT >= VERSION_CODES.LOLLIPOP; } @SuppressWarnings({"ResourceType", "unchecked"}) public <T> T getSystemService(final Context context, final String name) { return (T) context.getSystemService(name); } @TargetApi(11) public static void setStrictMode(boolean enable) { if (!enable) { return; } StrictMode.ThreadPolicy.Builder threadPolicyBuilder = new StrictMode.ThreadPolicy.Builder() .detectAll() .penaltyLog(); StrictMode.VmPolicy.Builder vmPolicyBuilder = new StrictMode.VmPolicy.Builder() .detectAll() .penaltyLog(); StrictMode.setThreadPolicy(threadPolicyBuilder.build()); StrictMode.setVmPolicy(vmPolicyBuilder.build()); } /** * 重启一个Activity * * @param activity Activity */ public static void restartActivity(final Activity activity) { Intent intent = activity.getIntent(); activity.overridePendingTransition(0, 0); intent.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION); activity.finish(); activity.overridePendingTransition(0, 0); activity.startActivity(intent); } public static Intent getBatteryStatus(Context context) { Context appContext = context.getApplicationContext(); return appContext.registerReceiver(null, new IntentFilter(Intent.ACTION_BATTERY_CHANGED)); } public static float getBatteryLevel(Intent batteryIntent) { int level = batteryIntent.getIntExtra(BatteryManager.EXTRA_LEVEL, -1); int scale = batteryIntent.getIntExtra(BatteryManager.EXTRA_SCALE, -1); return level / (float) scale; } public static String getBatteryInfo(Intent batteryIntent) { int status = batteryIntent.getIntExtra(BatteryManager.EXTRA_STATUS, -1); boolean isCharging = status == BatteryManager.BATTERY_STATUS_CHARGING || status == BatteryManager.BATTERY_STATUS_FULL; int chargePlug = batteryIntent.getIntExtra(BatteryManager.EXTRA_PLUGGED, -1); boolean usbCharge = chargePlug == BatteryManager.BATTERY_PLUGGED_USB; boolean acCharge = chargePlug == BatteryManager.BATTERY_PLUGGED_AC; int level = batteryIntent.getIntExtra(BatteryManager.EXTRA_LEVEL, -1); int scale = batteryIntent.getIntExtra(BatteryManager.EXTRA_SCALE, -1); float batteryPct = level / (float) scale; return "Battery Info: isCharging=" + isCharging + " usbCharge=" + usbCharge + " acCharge=" + acCharge + " batteryPct=" + batteryPct; } @SuppressLint("PackageManagerGetSignatures") private static Signature getPackageSignature(Context context) { final PackageManager pm = context.getPackageManager(); PackageInfo info = null; try { info = pm.getPackageInfo(context.getPackageName(), PackageManager.GET_SIGNATURES); } catch (Exception ignored) { } Signature signature = null; if (info != null) { Signature[] signatures = info.signatures; if (signatures != null && signatures.length > 0) { signature = signatures[0]; } } if (DEBUG) { LogUtils.v(TAG, "getSignature() " + signature); } return signature; } public static String getSignature(Context context) { final Signature signature = getPackageSignature(context); if (signature != null) { try { return CryptoUtils.HASH.sha1(signature.toByteArray()); } catch (Exception e) { LogUtils.e(TAG, "getSignature() ex=" + e); } } return ""; } public static String getSignatureInfo(Context context) { final Signature signature = getPackageSignature(context); if (signature == null) { return ""; } final StringBuilder builder = new StringBuilder(); try { final byte[] signatureBytes = signature.toByteArray(); CertificateFactory certFactory = CertificateFactory.getInstance("X.509"); final InputStream is = new ByteArrayInputStream(signatureBytes); X509Certificate cert = (X509Certificate) certFactory.generateCertificate(is); final String chars = signature.toCharsString(); final String hex = CryptoUtils.HEX.encodeHex(signatureBytes, false); final String md5 = CryptoUtils.HASH.md5(signatureBytes); final String sha1 = CryptoUtils.HASH.sha1(signatureBytes); builder.append("SignName:").append(cert.getSigAlgName()).append("\n"); builder.append("Chars:").append(chars).append("\n"); builder.append("Hex:").append(hex).append("\n"); builder.append("MD5:").append(md5).append("\n"); builder.append("SHA1:").append(sha1).append("\n"); builder.append("SignNumber:").append(cert.getSerialNumber()).append("\n"); builder.append("SubjectDN:").append(cert.getSubjectDN().getName()).append("\n"); builder.append("IssuerDN:").append(cert.getIssuerDN().getName()).append("\n"); } catch (Exception e) { LogUtils.e(TAG, "parseSignature() ex=" + e); } final String text = builder.toString(); if (DEBUG) { LogUtils.v(TAG, text); } return text; } }