Back to project page android_device.
The source code is released under:
[Apache License](http://www.apache.org/licenses/): Version 2.0, January 2004 =============== ## TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION ## ### 1. Definitions. ### "License" sha...
If you think the Android project android_device listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.
/* * ================================================================================================= * Copyright (C) 2012 - 2014 Martin Albedinsky [Wolf-ITechnologies] * ================================================================================================= * Licensed under the Apache License, Version 2.0 or later (further "License" only). * ------------------------------------------------------------------------------------------------- * You may use this file only in compliance with the License. More details and copy of this License * you may obtain at/*ww w .j a va2 s .co m*/ * * http://www.apache.org/licenses/LICENSE-2.0 * * You can redistribute, modify or publish any part of the code written within this file but as it * is described in the License, the software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES or CONDITIONS OF ANY KIND. * * See the License for the specific language governing permissions and limitations under the License. * ================================================================================================= */ package com.wit.android.device; import android.app.Activity; import android.content.Context; import android.content.res.Configuration; import android.os.PowerManager; import android.provider.Settings.SettingNotFoundException; import android.provider.Settings.System; import android.support.annotation.NonNull; import android.util.DisplayMetrics; import android.util.Log; import android.view.Display; import android.view.Window; import android.view.WindowManager; /** * <h3>Class Overview</h3> * Implementation of {@link com.wit.android.device.Screen} wrapper for {@link com.wit.android.device.AndroidDevice AndroidDevice}. * * @author Martin Albedinsky */ final class ScreenImpl implements Screen { /** * Interface =================================================================================== */ /** * Constants =================================================================================== */ /** * Log TAG. */ private static final String TAG = "ScreenImpl"; /** * Flag indicating whether the debug output trough log-cat is enabled or not. */ private static final boolean DEBUG_ENABLED = DeviceConfig.LIBRARY_DEBUG_LOG_ENABLED; /** * Flag indicating whether the output trough log-cat is enabled or not. */ private static final boolean LOG_ENABLED = DeviceConfig.LIBRARY_LOG_ENABLED; /** * Static members ============================================================================== */ /** * Members ===================================================================================== */ /** * Display metrics. */ private final DisplayMetrics METRICS = new DisplayMetrics(); /** * Application context obtained from the context passed during initialization of this wrapper. */ private final Context mContext; /** * "Default" width of the current Android device's screen. */ private final int mWidth; /** * "Default" height of the current Android device's screen. */ private final int mHeight; /** * Window manager service. */ private final WindowManager mWindowManager; /** * Default orientation of the current Android device's screen. */ private final ScreenOrientation mDefaultOrientation; /** * Type of the current Android device's screen. */ private ScreenType mType = ScreenType.UNKNOWN; /** * Density of the current Android device's screen. */ private ScreenDensity mDensity = ScreenDensity.UNKNOWN; /** * Raw density of the current Android device's screen. */ private int mRawDensity = -1; /** * Actual orientation of the current Android device's screen. */ private ScreenOrientation mCurrentOrientation = ScreenOrientation.UNSPECIFIED; /** * Actual rotation of the current Android device's screen. */ private ScreenRotation mCurrentRotation = ScreenRotation.UNKNOWN; /** * Actual width of the current Android device's screen. Depends on the actual screen orientation. */ private int mCurrentWidth = 0; /** * Actual height of the current Android device's screen. Depends on the actual screen orientation. */ private int mCurrentHeight = 0; /** * Flag indicating whether the current Android device's screen orientation is currently locked or * not. */ private boolean mOrientationLocked; /** * Constructors ================================================================================ */ /** * Creates a new instance of ScreenImpl wrapper with already prepared screen data to access. * * @param context Application context or activity context. */ ScreenImpl(Context context) { this.mContext = context.getApplicationContext(); // Initialize window manager. this.mWindowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE); // Initialize data to new ones. this.refresh(); // Initialize screen default orientation. this.mDefaultOrientation = this.resolveDefaultOrientation(mCurrentOrientation, mCurrentRotation); // Initialize screen density. this.mDensity = ScreenDensity.resolve(mRawDensity = METRICS.densityDpi); // Initialize screen type. this.mType = resolveScreenType(mCurrentOrientation); // Resolve actual screen metrics. boolean reverse = false; switch (mDefaultOrientation) { case PORTRAIT: reverse = mCurrentOrientation != ScreenOrientation.PORTRAIT && mCurrentOrientation != ScreenOrientation.REVERSE_PORTRAIT; break; case LANDSCAPE: reverse = mCurrentOrientation != ScreenOrientation.LANDSCAPE && mCurrentOrientation != ScreenOrientation.REVERSE_LANDSCAPE; break; } // Initialize display actual width and height. this.mCurrentWidth = METRICS.widthPixels; this.mCurrentHeight = METRICS.heightPixels; this.mWidth = reverse ? mCurrentHeight : mCurrentWidth; this.mHeight = reverse ? mCurrentWidth : mCurrentHeight; } /** * Public -------------------------------------------------------------------------------------- */ /** */ @Override public boolean isOn() { final PowerManager power = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE); return power != null && power.isScreenOn(); } /** */ @Override public boolean lockOrientation(@NonNull Activity activity) { return requestOrientation(ScreenOrientation.CURRENT, activity); } /** */ @Override public void unlockOrientation(@NonNull Activity activity) { requestOrientation(ScreenOrientation.USER, activity); } /** */ @Override public boolean requestOrientation(@NonNull ScreenOrientation requestedOrientation, @NonNull Activity activity) { if (DEBUG_ENABLED) { Log.d(TAG, "requestOrientation(requestedOrientation = " + requestedOrientation + ", " + activity + ")"); } // Request for screen orientation. this.requestOrientationInner( requestedOrientation != ScreenOrientation.CURRENT ? requestedOrientation : (requestedOrientation = getCurrentOrientation()), activity ); return mOrientationLocked = (requestedOrientation != ScreenOrientation.USER); } /** * Getters + Setters --------------------------------------------------------------------------- */ /** */ @Override public Display getDisplay() { return mWindowManager.getDefaultDisplay(); } /** */ @Override public int getWidth() { return mWidth; } /** */ @Override public int getHeight() { return mHeight; } /** */ @Override public int getCurrentWidth() { refresh(); return mCurrentWidth; } /** */ @Override public int getCurrentHeight() { refresh(); return mCurrentHeight; } /** */ @NonNull @Override public DisplayMetrics getMetrics() { refresh(); return METRICS; } /** */ @NonNull @Override public ScreenDensity getDensity() { return mDensity; } /** */ @Override public int getRawDensity() { return mRawDensity; } /** */ @NonNull @Override public ScreenType getType() { return mType; } /** */ @NonNull @Override public ScreenOrientation getCurrentOrientation() { refresh(); return mCurrentOrientation; } /** */ @NonNull @Override public ScreenOrientation getDefaultOrientation() { return mDefaultOrientation; } /** */ @NonNull @Override public ScreenRotation getCurrentRotation() { refresh(); return mCurrentRotation; } /** */ @Override public float getDiagonalDistance(boolean inInches) { refresh(); return inInches ? /** * Calculation in inches will depends on the exact pixel per inch in each axis (x and y) of the device display. */ (float) Math.sqrt(Math.pow((mWidth / METRICS.xdpi), 2) + Math.pow((mHeight / METRICS.ydpi), 2)) : /** * Calculation in raw pixels. */ (float) Math.sqrt(Math.pow(mWidth, 2) + Math.pow(mHeight, 2)); } /** */ @Override public float getRefreshRate() { return getDisplay().getRefreshRate(); } /** */ @Override public int getBrightness(@NonNull Activity activity) { if (activity != null) { final Window window = activity.getWindow(); if (window != null) { // Get the brightness from the current application window settings. return Math.round(window.getAttributes().screenBrightness * 100); } else { if (LOG_ENABLED) Log.v(TAG, "Passed activity window is invalid. Can't obtain its brightness."); } } return -100; } /** */ @Override public void setBrightness(int brightness, @NonNull Activity activity) { if (brightness < 0 || brightness > 100) { throw new IllegalArgumentException("Brightness value(" + brightness + ") out of the range [0, 100]."); } // Create new window parameters. final Window window = activity.getWindow(); WindowManager.LayoutParams layoutParams = window.getAttributes(); layoutParams.screenBrightness = ((brightness == 0) ? ++brightness : brightness) / 100f; // Set new brightness to the current application window. window.setAttributes(layoutParams); } /** */ @Override public int getSystemBrightness() { float brightness = 0; try { brightness = System.getInt(mContext.getContentResolver(), System.SCREEN_BRIGHTNESS); } catch (SettingNotFoundException e) { e.printStackTrace(); } return Math.round(brightness / 255 * 100); } /** */ @Override public boolean isOrientationLocked() { return mOrientationLocked; } /** */ @Override public float pixelToDP(int pixel) { // From the Android developers documentation: // px = dp * (dpi / 160) // So modified equation is: // dp = px / (dpi / 160) return (pixel / (mDensity.value / 160)); } /** */ @Override public float dpToPixel(int dp) { // From the Android developers documentation: // px = dp * (dpi / 160) return (dp * (mDensity.value / 160)); } /** */ @Override public float getScreenDP() { // From the Android developers documentation: // The density-independent pixel is equivalent to one physical pixel on // a 160 dpi screen, which is the baseline density assumed by the system // for a "medium" density screen. // px = dp * (dpi / 160) // So modified equation is: // dp = px / (dpi / 160) // and finally to determine for 1 px: return (mDensity.value / 160); } /** * Protected ----------------------------------------------------------------------------------- */ /** * Private ------------------------------------------------------------------------------------- */ /** * Called to refresh the current data of this screen wrapper instance. This should be called whenever * the current data are requested. */ private void refresh() { // Reinitialize display metrics to new ones. this.initNewMetrics(); // Refresh when: // 1) screen orientation change occurred if (mCurrentWidth != METRICS.widthPixels || mCurrentHeight != METRICS.heightPixels) { onRefresh(); } } /** * Invoked to refresh/update the current data. This is invoked only in case, that the current * Android device's screen orientation was changed. */ private void onRefresh() { // Update orientation to the actual. // This call also updates the screen rotation. updateOrientation(); if (DEBUG_ENABLED) { Log.d(TAG, "onRefresh() orientation(" + mCurrentOrientation + ")"); Log.d(TAG, "onRefresh() rotation(" + mCurrentRotation + ")"); Log.d(TAG, "onRefresh() actualWidth(" + METRICS.widthPixels + ") actualHeight(" + METRICS.heightPixels + ")"); } // Get screen metrics to handle actual ones. this.mCurrentWidth = METRICS.widthPixels; this.mCurrentHeight = METRICS.heightPixels; } /** * Requests for the given screen <var>orientation</var>. * * @param orientation Requested orientation. * @param activity The actual (visible) activity context. */ private void requestOrientationInner(ScreenOrientation orientation, Activity activity) { // Resolve request. switch (orientation) { case SQUARE: case UNSPECIFIED: // In case of SQUARE and UNKNOWN oriented screen we can't do nothing useful :). break; case CURRENT: default: // Request for screen orientation. activity.setRequestedOrientation(orientation.systemConstant); break; } } /** * Initializes new display metrics to obtain actual ones. */ private void initNewMetrics() { // Initialize new display metrics to get the useful data about device display. getDisplay().getMetrics(METRICS); } /** * Resolves the current Android device's screen type. * * @param orientation Actual screen orientation. * @return Resolved type of the screen. */ private ScreenType resolveScreenType(ScreenOrientation orientation) { // Get display width and height in dp units depends on actual orientation. float defaultWidthDP, defaultHeightDP; switch (orientation) { case LANDSCAPE: case REVERSE_LANDSCAPE: defaultWidthDP = pixelToDP(METRICS.heightPixels); defaultHeightDP = pixelToDP(METRICS.widthPixels); break; case PORTRAIT: case REVERSE_PORTRAIT: defaultWidthDP = pixelToDP(METRICS.widthPixels); defaultHeightDP = pixelToDP(METRICS.heightPixels); break; case SQUARE: case UNSPECIFIED: default: defaultWidthDP = pixelToDP(METRICS.widthPixels); defaultHeightDP = pixelToDP(METRICS.heightPixels); break; } if (DEBUG_ENABLED) { Log.d(TAG, "resolveScreenType() defaultWidthDP = " + defaultWidthDP + "; defaultHeightDP = " + defaultHeightDP); } return ScreenType.resolve(defaultWidthDP, defaultHeightDP); } /** * Resolves the current Android device's screen default orientation. * * @param currentOrientation The current screen orientation. * @param currentRotation The current screen rotation. * @return Default screen orientation depends on the given parameters. */ private ScreenOrientation resolveDefaultOrientation(ScreenOrientation currentOrientation, ScreenRotation currentRotation) { ScreenOrientation orientation = ScreenOrientation.UNSPECIFIED; switch (currentRotation) { case ROTATION_0: case ROTATION_180: switch (currentOrientation) { case LANDSCAPE: case REVERSE_LANDSCAPE: orientation = ScreenOrientation.LANDSCAPE; break; case PORTRAIT: case REVERSE_PORTRAIT: orientation = ScreenOrientation.PORTRAIT; break; default: } break; case ROTATION_90: case ROTATION_270: switch (currentOrientation) { case LANDSCAPE: case REVERSE_LANDSCAPE: orientation = ScreenOrientation.PORTRAIT; break; case PORTRAIT: case REVERSE_PORTRAIT: orientation = ScreenOrientation.LANDSCAPE; break; default: } break; default: } return orientation; } /** * Updates the current screen orientation to the actual one. This make difference between phone * and tablet screen rotation in degrees so we can find out reversed orientations. Also updates * the screen rotation to the actual one. * * @return Updated screen orientation. */ private ScreenOrientation updateOrientation() { // Default initialization. ScreenOrientation orientation = ScreenOrientation.UNSPECIFIED; // Get actual screen rotation to resolve difference between phone and // tablet device. final ScreenRotation rotation = updateRotation(); // Resolve actual screen orientation from configuration. switch (mContext.getResources().getConfiguration().orientation) { case Configuration.ORIENTATION_LANDSCAPE: // Check screen rotation. switch (rotation) { case ROTATION_0: // Tablet in landscape mode. case ROTATION_90: // Phone in landscape mode. orientation = ScreenOrientation.LANDSCAPE; break; case ROTATION_180: // Tablet in reverse landscape mode. case ROTATION_270: // Phone in reverse landscape mode. orientation = ScreenOrientation.REVERSE_LANDSCAPE; break; } break; case Configuration.ORIENTATION_PORTRAIT: // Check screen rotation. switch (rotation) { case ROTATION_0: // Phone in portrait mode. case ROTATION_270: // Tablet in portrait mode. orientation = ScreenOrientation.PORTRAIT; break; case ROTATION_90: // Tablet in reverse portrait mode. case ROTATION_180: // Phone in reverse portrait mode. orientation = ScreenOrientation.REVERSE_PORTRAIT; break; } break; case Configuration.ORIENTATION_UNDEFINED: default: break; } return this.mCurrentOrientation = orientation; } /** * Updates the current screen rotation to the actual one. * * @return Updated screen rotation. */ private ScreenRotation updateRotation() { // Resolve by rotation obtained from display. return mCurrentRotation = ScreenRotation.resolve(getDisplay().getRotation()); } /** * Inner classes =============================================================================== */ }