@TargetApi(Build.VERSION_CODES.HONEYCOMB) public static <A, B, C> void executeTask(AsyncTask<A, B, C> task, A... params ) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) { task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, params); } else { task.execute(params); } }
@TargetApi(19) private static boolean checkOp(Context context, int op) { final int version = Build.VERSION.SDK_INT; if (version >= Build.VERSION_CODES.KITKAT) { AppOpsManager manager = (AppOpsManager) context.getSystemService(Context.APP_OPS_SERVICE); try { Method method = manager.getClass().getDeclaredMethod("checkOp", int.class, int.class, String.class); int property = (Integer) method.invoke(manager, op, Binder.getCallingUid(), context.getPackageName()); return AppOpsManager.MODE_ALLOWED == property; } catch (Exception e) { e.printStackTrace(); } } return false; }
/** * Get the size in bytes of a bitmap in a BitmapDrawable. Note that from Android 4.4 (KitKat) * onward this returns the allocated memory size of the bitmap which can be larger than the * actual bitmap data byte count (in the case it was re-used). * * @param value * @return size in bytes */ @TargetApi(VERSION_CODES.KITKAT) public static int getBitmapSize(BitmapDrawable value) { Bitmap bitmap = value.getBitmap(); // From KitKat onward use getAllocationByteCount() as allocated bytes can potentially be // larger than bitmap byte count. if (Utils.hasKitKat()) { return bitmap.getAllocationByteCount(); } if (Utils.hasHoneycombMR1()) { return bitmap.getByteCount(); } // Pre HC-MR1 return bitmap.getRowBytes() * bitmap.getHeight(); }
@TargetApi(VERSION_CODES.JELLY_BEAN) @Override public void onItemClick(AdapterView<?> parent, View v, int position, long id) { final Intent i = new Intent(getActivity(), ImageDetailActivity.class); i.putExtra(ImageDetailActivity.EXTRA_IMAGE, (int) id); if (Utils.hasJellyBean()) { // makeThumbnailScaleUpAnimation() looks kind of ugly here as the loading spinner may // show plus the thumbnail image in GridView is cropped. so using // makeScaleUpAnimation() instead. ActivityOptions options = ActivityOptions.makeScaleUpAnimation(v, 0, 0, v.getWidth(), v.getHeight()); getActivity().startActivity(i, options.toBundle()); } else { startActivity(i); } }
@TargetApi(Build.VERSION_CODES.HONEYCOMB) @Override public void onClick(View view) { switch (view.getId()) { case R.id.tv_setting: Intent intent = new Intent(this, SettingActivity.class); startActivityForResult(intent, SETTING_REQUEST_CODE); tv_setting.setVisibility(View.GONE); break; case R.id.rel_main: localWakeLock.isHeld(); switchMode(MODE_SETTING_OTHER); break; case R.id.tv_time: switchMode(MODE_SETTING_OTHER); break; } }
/** 打开通知栏消息 */ @TargetApi(Build.VERSION_CODES.JELLY_BEAN) private void openNotify(AccessibilityEvent event) { if (event.getParcelableData() == null || !(event.getParcelableData() instanceof Notification)) { return; } // 将微信的通知栏消息打开 Notification notification = (Notification) event.getParcelableData(); PendingIntent pendingIntent = notification.contentIntent; try { pendingIntent.send(); } catch (PendingIntent.CanceledException e) { e.printStackTrace(); } }
/** * 获取SD卡信息 * * @return SDCardInfo */ @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR2) public static String getSDCardInfo() { if (!isSDCardEnable()) return null; SDCardInfo sd = new SDCardInfo(); sd.isExist = true; StatFs sf = new StatFs(Environment.getExternalStorageDirectory().getPath()); sd.totalBlocks = sf.getBlockCountLong(); sd.blockByteSize = sf.getBlockSizeLong(); sd.availableBlocks = sf.getAvailableBlocksLong(); sd.availableBytes = sf.getAvailableBytes(); sd.freeBlocks = sf.getFreeBlocksLong(); sd.freeBytes = sf.getFreeBytes(); sd.totalBytes = sf.getTotalBytes(); return sd.toString(); }
@TargetApi(Build.VERSION_CODES.HONEYCOMB) private void manageLayer(View v, boolean enableHardware) { if (!API_11) return; int layerType = enableHardware ? View.LAYER_TYPE_HARDWARE : View.LAYER_TYPE_NONE; if (layerType != v.getLayerType()) v.setLayerType(layerType, null); }
/** * 检查单个权限是否被允许,(当应用第一次安装的时候,不会有rational的值,此时返回均是denied) * * @param permission The name of the permission being checked. * @return PermissionUtil.PERMISSION_GRANTED / PERMISSION_DENIED / PERMISSION_RATIONAL or {@code null} * if context is not instanceof Activity. */ @TargetApi(Build.VERSION_CODES.M) public int checkSinglePermission(String permission) { if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) { return PERMISSION_GRANTED; } if (mActivity == null) { mActivity = getTopActivity(); } if (mActivity != null) { if (mActivity.checkSelfPermission(permission) == PackageManager.PERMISSION_GRANTED) { return PERMISSION_GRANTED; } else { if (mActivity.shouldShowRequestPermissionRationale(permission)) { return PERMISSION_RATIONAL; } else { return PERMISSION_DENIED; } } } else { Log.e(TAG, "TopActivity not find"); return -1; } }
@TargetApi(14) private boolean hasNavBar(Context context) { Resources res = context.getResources(); int resourceId = res.getIdentifier(SHOW_NAV_BAR_RES_NAME, "bool", "android"); if (resourceId != 0) { boolean hasNav = res.getBoolean(resourceId); // check override flag (see static block) if ("1".equals(sNavBarOverride)) { hasNav = false; } else if ("0".equals(sNavBarOverride)) { hasNav = true; } return hasNav; } else { // fallback return !ViewConfiguration.get(context).hasPermanentMenuKey(); } }
@SuppressLint("ObsoleteSdkInt") @TargetApi(Build.VERSION_CODES.HONEYCOMB_MR2) @SuppressWarnings("deprecation") private synchronized Point getDisplayDimens() { if (mDisplayDimens != null) { return mDisplayDimens; } Point displayDimens; WindowManager windowManager = (WindowManager) getSystemService(Context.WINDOW_SERVICE); assert windowManager != null; Display display = windowManager.getDefaultDisplay(); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB_MR2) { displayDimens = new Point(); display.getSize(displayDimens); } else { displayDimens = new Point(display.getWidth(), display.getHeight()); } // In this we can only get 85% width and 60% height //displayDimens.y = (int) (displayDimens.y * 0.60f); //displayDimens.x = (int) (displayDimens.x * 0.85f); mDisplayDimens = displayDimens; return mDisplayDimens; }
@TargetApi(24) @Override public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) { Log.d(TAG, "shouldOverrideUrlLoading() called with: request = [" + request.getUrl() + "]"); if (pager.webviewClient != null) { if (pager.webviewClient.shouldOverrideUrlLoading(view, request)) { return true; } } if (handleUrlLoading(view, request.getUrl().toString())) { return true; } return super.shouldOverrideUrlLoading(view, request); }
/** * * @param context * @param title * @param message * @param isCritical */ @TargetApi(Build.VERSION_CODES.JELLY_BEAN) public static void sendNotification(Context context, String title, String message, boolean isCritical) { Intent broadCastIntent = new Intent(context, DashboardActivity.class); PendingIntent pIntent = PendingIntent.getActivity(context, (int) System.currentTimeMillis(), broadCastIntent, 0); NotificationManager mNotificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE); NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(context) .setSmallIcon(R.drawable.app_icon) .setContentIntent(pIntent) .setAutoCancel(true).setContentTitle("" + title); if (!TextUtils.isEmpty(message)) { mBuilder.setContentText(message); } if (isCritical) { mBuilder.setVibrate(new long[]{100, 250}).setDefaults(Notification.DEFAULT_SOUND); mBuilder.setColor(Color.RED); } else { mBuilder.setColor(Color.GREEN); } mBuilder.setContentIntent(pIntent); mNotificationManager.notify(0, mBuilder.build()); }
@TargetApi(Build.VERSION_CODES.LOLLIPOP) private SaiyVoice getEngineDefaultSaiyVoice() { final Voice voice = getDefaultVoice(); if (voice != null) { final SaiyVoice saiyVoice = new SaiyVoice(voice); saiyVoice.setEngine(getInitialisedEngine()); saiyVoice.setGender(saiyVoice.getName()); if (DEBUG) { MyLog.i(CLS_NAME, "getEngineDefaultSaiyVoice: setting Gender: " + saiyVoice.getGender().name()); } return saiyVoice; } else { if (DEBUG) { MyLog.i(CLS_NAME, "getEngineDefaultSaiyVoice: voice null"); } return null; } }
@TargetApi(21) @Override public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) { super.onInitializeAccessibilityNodeInfo(info); info.setClassName(com.google.android.exoplayer2.ui.DefaultTimeBar.class.getCanonicalName()); info.setContentDescription(getProgressText()); if (duration <= 0) { return; } if (Util.SDK_INT >= 21) { info.addAction(AccessibilityNodeInfo.AccessibilityAction.ACTION_SCROLL_FORWARD); info.addAction(AccessibilityNodeInfo.AccessibilityAction.ACTION_SCROLL_BACKWARD); } else if (Util.SDK_INT >= 16) { info.addAction(AccessibilityNodeInfo.ACTION_SCROLL_FORWARD); info.addAction(AccessibilityNodeInfo.ACTION_SCROLL_BACKWARD); } }
/** * Sets the shadow color and radius to mimic the native elevation. * * <p><b>API 21+</b>: Sets the native elevation of this view, in pixels. Updates margins to * make the view hold its position in layout across different platform versions.</p> */ @TargetApi(Build.VERSION_CODES.LOLLIPOP) public void setElevationCompat(float elevation) { mShadowColor = 0x26000000; mShadowRadius = Math.round(elevation / 2); mShadowXOffset = 0; mShadowYOffset = Math.round(mFabSize == SIZE_NORMAL ? elevation : elevation / 2); if (Util.hasLollipop()) { super.setElevation(elevation); mUsingElevationCompat = true; mShowShadow = false; updateBackground(); ViewGroup.LayoutParams layoutParams = getLayoutParams(); if (layoutParams != null) { setLayoutParams(layoutParams); } } else { mShowShadow = true; updateBackground(); } }
/** * Set the reference of seconds picker, its digit format and register value change listener. * * @param pickerVisible if false, removes the spinner widget. */ @TargetApi(11) protected void setupSecondPicker(boolean pickerVisible) { mSecondPicker = (NumberPicker) findViewById(R.id.seconds); if (pickerVisible) { mSecondPicker.setMinValue(0); mSecondPicker.setMaxValue(59); mSecondPicker.setFormatter(TWO_DIGIT_FORMATTER); mSecondPicker.setOnValueChangedListener(new NumberPicker.OnValueChangeListener() { @Override public void onValueChange(NumberPicker picker, int oldVal, int newVal) { mCurrentSecond = newVal; } }); } else { mHourPicker.setVisibility(View.GONE); } }
/** * @param candidate - Bitmap to check * @param targetOptions - Options that have the out* value populated * @return true if <code>candidate</code> can be used for inBitmap re-use with * <code>targetOptions</code> */ @TargetApi(VERSION_CODES.KITKAT) private static boolean canUseForInBitmap( Bitmap candidate, BitmapFactory.Options targetOptions) { //BEGIN_INCLUDE(can_use_for_inbitmap) if (!Utils.hasKitKat()) { // On earlier versions, the dimensions must match exactly and the inSampleSize must be 1 return candidate.getWidth() == targetOptions.outWidth && candidate.getHeight() == targetOptions.outHeight && targetOptions.inSampleSize == 1; } // From Android 4.4 (KitKat) onward we can re-use if the byte size of the new bitmap // is smaller than the reusable bitmap candidate allocation byte count. int width = targetOptions.outWidth / targetOptions.inSampleSize; int height = targetOptions.outHeight / targetOptions.inSampleSize; int byteCount = width * height * getBytesPerPixel(candidate.getConfig()); return byteCount <= candidate.getAllocationByteCount(); //END_INCLUDE(can_use_for_inbitmap) }
@TargetApi(Build.VERSION_CODES.LOLLIPOP) public Drawable getIcon(Context context, IconCache cache) { if (isCustomWidget) { return cache.getFullResIcon(provider.getPackageName(), icon); } return super.loadIcon(context, LauncherAppState.getInstance().getInvariantDeviceProfile().fillResIconDpi); }
/** * SoundPool creator with the new constructor available since API 21 */ @TargetApi(Build.VERSION_CODES.LOLLIPOP) private void createNewSoundPool() { Log.d(this.getClass().getSimpleName(), "New soundpool constructor"); AudioAttributes attr = new AudioAttributes.Builder().setUsage(AudioAttributes.USAGE_GAME) .setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION).build(); soundPool = new SoundPool.Builder().setMaxStreams(1).setAudioAttributes(attr).build(); correctSound = soundPool.load(this, R.raw.correct_sound, 1); wrongSound = soundPool.load(this, R.raw.wrong_sound, 1); }
@TargetApi(Build.VERSION_CODES.LOLLIPOP) public TextInputTimePickerView(Context context, AttributeSet attrs, int defStyle, int defStyleRes) { super(context, attrs, defStyle, defStyleRes); attrHandler(context, attrs, defStyle, defStyleRes); }
@TargetApi(Build.VERSION_CODES.JELLY_BEAN) public static boolean checkPermission(final Context context) { int currentAPIVersion = Build.VERSION.SDK_INT; if(currentAPIVersion>=android.os.Build.VERSION_CODES.M) { if (ContextCompat.checkSelfPermission(context, Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) { if (ActivityCompat.shouldShowRequestPermissionRationale((Activity) context, Manifest.permission.READ_EXTERNAL_STORAGE)) { AlertDialog.Builder alertBuilder = new AlertDialog.Builder(context); alertBuilder.setCancelable(true); alertBuilder.setTitle("Permission necessary"); alertBuilder.setMessage("External storage permission is necessary"); alertBuilder.setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() { @TargetApi(Build.VERSION_CODES.JELLY_BEAN) public void onClick(DialogInterface dialog, int which) { ActivityCompat.requestPermissions((Activity) context, new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, MY_PERMISSIONS_REQUEST_READ_EXTERNAL_STORAGE); } }); AlertDialog alert = alertBuilder.create(); alert.show(); } else { ActivityCompat.requestPermissions((Activity) context, new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, MY_PERMISSIONS_REQUEST_READ_EXTERNAL_STORAGE); } return false; } else { return true; } } else { return true; } }
@TargetApi(Build.VERSION_CODES.LOLLIPOP) public X5CookieManager(WebView webview) { webView = webview; cookieManager = CookieManager.getInstance(); //REALLY? Nobody has seen this UNTIL NOW? // cookieManager.setAcceptFileSchemeCookies(true); cookieManager.setAcceptCookie(true); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { cookieManager.setAcceptThirdPartyCookies(webView, true); } }
@TargetApi(18) public static AudioRecord getAudioRecord() { int frequency = Options.getInstance().audio.frequency; int audioEncoding = Options.getInstance().audio.encoding; int channelConfiguration = AudioFormat.CHANNEL_CONFIGURATION_MONO; if(Options.getInstance().audio.channelCount == 2) { channelConfiguration = AudioFormat.CHANNEL_CONFIGURATION_STEREO; } int audioSource = MediaRecorder.AudioSource.MIC; if(Options.getInstance().audio.aec) { audioSource = MediaRecorder.AudioSource.VOICE_COMMUNICATION; } return new AudioRecord(audioSource, frequency, channelConfiguration, audioEncoding, getRecordBufferSize()); }
@TargetApi(Build.VERSION_CODES.JELLY_BEAN) Choreographer.FrameCallback getFrameCallback() { if (mFrameCallback == null) { mFrameCallback = new Choreographer.FrameCallback() { @Override public void doFrame(long frameTimeNanos) { FrameCallback.this.doFrame(frameTimeNanos); } }; } return mFrameCallback; }
/** * Create a {@link DocumentFileCompat} representing the document tree rooted at * the given {@link Uri}. This is only useful on devices running * {@link android.os.Build.VERSION_CODES#LOLLIPOP} or later, and will return * {@code null} when called on earlier platform versions. * * @param treeUri the {@link Intent#getData()} from a successful * {@link Intent#ACTION_OPEN_DOCUMENT_TREE} request. */ @TargetApi(Build.VERSION_CODES.LOLLIPOP) public static DocumentFileCompat fromTreeUri(Context context, Uri treeUri) { final int version = Build.VERSION.SDK_INT; if (version >= 21) { return new TreeDocumentFile(null, context, DocumentsContractApi21.prepareTreeUri(treeUri)); } else { return null; } }
/** * Apply the specified alpha to the system navigation bar. * * @param alpha The alpha to use */ @TargetApi(11) public void setNavigationBarAlpha(float alpha) { if (mNavBarAvailable && Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) { mNavBarTintView.setAlpha(alpha); } }
@TargetApi(23) @Override public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) { switch (requestCode) { case REQUEST_CODE_ASK_MULTIPLE_PERMISSIONS: boolean permissionGranted; if (mediaType == RongCallCommon.CallMediaType.AUDIO) { permissionGranted = PermissionCheckUtil.checkPermissions(this, AUDIO_CALL_PERMISSIONS); } else { permissionGranted = PermissionCheckUtil.checkPermissions(this, VIDEO_CALL_PERMISSIONS); } if (permissionGranted) { if (startForCheckPermissions) { startForCheckPermissions = false; RongCallClient.getInstance().onPermissionGranted(); } else { setupIntent(); } } else { if (startForCheckPermissions) { startForCheckPermissions = false; RongCallClient.getInstance().onPermissionDenied(); } else { finish(); } } break; default: super.onRequestPermissionsResult(requestCode, permissions, grantResults); } }
@RequiresApi(21) @TargetApi(21) public ThrowsThrowable( final Context context, final AttributeSet attrs, final int defStyleAttr, final int defStyleRes) { super(context, attrs, defStyleAttr, defStyleRes); init(attrs, defStyleAttr, defStyleRes); }
@TargetApi(Build.VERSION_CODES.KITKAT) private static String getExtSdCardFolder(final File file) { String[] extSdPaths = getExtSdCardPaths(); try { for (String extSdPath : extSdPaths) { if (file.getCanonicalPath().startsWith(extSdPath)) { return extSdPath; } } } catch (IOException e) { return null; } return null; }
@TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1) private void setAnimationEnabled() { int currentApiVersion = Build.VERSION.SDK_INT; float animationValue; if (currentApiVersion >= Build.VERSION_CODES.JELLY_BEAN_MR1) { animationValue = Settings.Global.getFloat(getContext().getContentResolver(), Settings.Global.ANIMATOR_DURATION_SCALE, 1); } else { animationValue = Settings.System.getFloat(getContext().getContentResolver(), Settings.System.ANIMATOR_DURATION_SCALE, 1); } shouldAnimate = animationValue != 0; }
@TargetApi(Build.VERSION_CODES.KITKAT) public void scrollListBy(int deltaY) { if (SdkVerUtils.isAbove19()) { super.scrollListBy(deltaY); } else { ReflectUtil.invokeMethod(this, "trackMotionScroll", new Object[]{-deltaY, -deltaY}, new Class[]{int.class, int.class}); } }
@TargetApi(23) private boolean checkPermissions() { if (C.SDK < 23 || checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) { return true; } requestPermissions(new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 0); return false; }
@RequiresApi(19) @TargetApi(19) public LayoutParams(LayoutParams source) { // The copy constructor used here is only supported on API 19+. this((FrameLayout.LayoutParams) source); mPercentLayoutInfo = source.mPercentLayoutInfo; }
/** */ @Override @TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH) public void onInitializeAccessibilityNodeInfo(@NonNull AccessibilityNodeInfo info) { super.onInitializeAccessibilityNodeInfo(info); info.setClassName(CircularNumberPicker.class.getName()); }
/** * Automatically select the user's default voice. * * @param language the {@link Locale} language * @param region the {@link Locale} region * @param conditions the {@link SelfAwareConditions} * @param params the {@link SelfAwareParameters} */ @TargetApi(Build.VERSION_CODES.LOLLIPOP) private void setDefaultVoice(@NonNull final String language, @NonNull final String region, @NonNull final SelfAwareConditions conditions, @NonNull final SelfAwareParameters params) { if (DEBUG) { MyLog.i(CLS_NAME, "setDefaultVoice"); } final Pair<SaiyVoice, Locale> voicePair = new TTSVoice(language, region, conditions, params, null) .buildVoice(); if (voicePair.first != null) { if (DEBUG) { MyLog.i(CLS_NAME, "setDefaultVoice: Setting Voice: " + voicePair.first.toString()); } final SaiyVoice saiyVoice = new SaiyVoice(voicePair.first); saiyVoice.setEngine(getInitialisedEngine()); saiyVoice.setGender(saiyVoice.getName()); final String gsonString = new GsonBuilder().disableHtmlEscaping().create().toJson(saiyVoice); if (DEBUG) { MyLog.i(CLS_NAME, "setDefaultVoice: gsonString: " + gsonString); } SPH.setDefaultTTSVoice(mContext, gsonString); } else { if (DEBUG) { MyLog.w(CLS_NAME, "setDefaultVoice: Unable to establish a default voice"); } } }
@TargetApi(Build.VERSION_CODES.LOLLIPOP) private SoundPool createSoundPoolLollipop() { final AudioAttributes audioAttributes = new AudioAttributes.Builder() .setUsage(AudioAttributes.USAGE_GAME) .setContentType(AudioAttributes.CONTENT_TYPE_MUSIC) .build(); return new SoundPool.Builder() .setAudioAttributes(audioAttributes) .setMaxStreams(4) .build(); }
@TargetApi(Build.VERSION_CODES.LOLLIPOP) @Override public void startLeScan() { List<ScanFilter> filters = new ArrayList<ScanFilter>(); ScanFilter filter = new ScanFilter.Builder().build(); filters.add(filter); ScanSettings settings = new ScanSettings.Builder().setScanMode(SCAN_MODE_LOW_LATENCY) .build(); mBluetoothLeScanner.startScan(filters, settings, mLeScanCallback); }
/** */ @Override @TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH) public void onInitializeAccessibilityEvent(@NonNull AccessibilityEvent event) { super.onInitializeAccessibilityEvent(event); event.setClassName(WebViewWidget.class.getName()); }
/** */ @Override @TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH) public void onInitializeAccessibilityNodeInfo(@NonNull AccessibilityNodeInfo info) { super.onInitializeAccessibilityNodeInfo(info); info.setClassName(FrameLayoutWidget.class.getName()); }