/** Takes a screenshot of the current display and shows an animation. */
  void takeScreenshot(Runnable finisher, boolean statusBarVisible, boolean navBarVisible) {
    // We need to orient the screenshot correctly (and the Surface api seems to take screenshots
    // only in the natural orientation of the device :!)
    mDisplay.getRealMetrics(mDisplayMetrics);
    float[] dims = {mDisplayMetrics.widthPixels, mDisplayMetrics.heightPixels};
    // float degrees = getDegreesForRotation(mDisplay.getRotation());
    int value = mDisplay.getRotation();
    String hwRotation = SystemProperties.get("ro.sf.hwrotation", "0");
    if (hwRotation.equals("270") || hwRotation.equals("90")) {
      value = (value + 3) % 4;
    }
    float degrees = getDegreesForRotation(value);
    boolean requiresRotation = (degrees > 0);
    if (requiresRotation) {
      // Get the dimensions of the device in its native orientation
      mDisplayMatrix.reset();
      mDisplayMatrix.preRotate(-degrees);
      mDisplayMatrix.mapPoints(dims);
      dims[0] = Math.abs(dims[0]);
      dims[1] = Math.abs(dims[1]);
    }

    // Take the screenshot
    mScreenBitmap = Surface.screenshot((int) dims[0], (int) dims[1]);
    if (mScreenBitmap == null) {
      notifyScreenshotError(mContext, mNotificationManager);
      finisher.run();
      return;
    }

    if (requiresRotation) {
      // Rotate the screenshot to the current orientation
      Bitmap ss =
          Bitmap.createBitmap(
              mDisplayMetrics.widthPixels, mDisplayMetrics.heightPixels, Bitmap.Config.ARGB_8888);
      Canvas c = new Canvas(ss);
      c.translate(ss.getWidth() / 2, ss.getHeight() / 2);
      c.rotate(degrees);
      c.translate(-dims[0] / 2, -dims[1] / 2);
      c.drawBitmap(mScreenBitmap, 0, 0, null);
      c.setBitmap(null);
      mScreenBitmap = ss;
    }

    // Optimizations
    mScreenBitmap.setHasAlpha(false);
    mScreenBitmap.prepareToDraw();

    // Start the post-screenshot animation
    startAnimation(
        finisher,
        mDisplayMetrics.widthPixels,
        mDisplayMetrics.heightPixels,
        statusBarVisible,
        navBarVisible);
  }
示例#2
0
  /** Returns a screenshot of the current display contents. */
  Bitmap createScreenshot() {
    // We need to orient the screenshot correctly (and the Surface api seems to
    // take screenshots only in the natural orientation of the device :!)

    mDisplay.getRealMetrics(mDisplayMetrics);
    boolean hasNavBar =
        mContext.getResources().getBoolean(com.android.internal.R.bool.config_showNavigationBar);

    float[] dims = {mDisplayMetrics.widthPixels, mDisplayMetrics.heightPixels};
    float degrees = getDegreesForRotation(mDisplay.getRotation());
    final int statusBarHeight =
        mContext
            .getResources()
            .getDimensionPixelSize(com.android.internal.R.dimen.status_bar_height);

    // Navbar has different sizes, depending on orientation
    final int navBarHeight =
        hasNavBar
            ? mContext
                .getResources()
                .getDimensionPixelSize(com.android.internal.R.dimen.navigation_bar_height)
            : 0;
    final int navBarWidth =
        hasNavBar
            ? mContext
                .getResources()
                .getDimensionPixelSize(com.android.internal.R.dimen.navigation_bar_width)
            : 0;

    boolean requiresRotation = (degrees > 0);
    if (requiresRotation) {
      // Get the dimensions of the device in its native orientation
      mDisplayMatrix.reset();
      mDisplayMatrix.preRotate(-degrees);
      mDisplayMatrix.mapPoints(dims);
      dims[0] = Math.abs(dims[0]);
      dims[1] = Math.abs(dims[1]);
    }

    Bitmap bitmap = Surface.screenshot((int) dims[0], (int) dims[1]);
    // Bail if we couldn't take the screenshot
    if (bitmap == null) {
      return null;
    }

    if (requiresRotation) {
      // Rotate the screenshot to the current orientation
      Bitmap ss =
          Bitmap.createBitmap(
              mDisplayMetrics.widthPixels, mDisplayMetrics.heightPixels, Bitmap.Config.ARGB_8888);
      Canvas c = new Canvas(ss);
      c.translate(ss.getWidth() / 2, ss.getHeight() / 2);
      c.rotate(360f - degrees);
      c.translate(-dims[0] / 2, -dims[1] / 2);
      c.drawBitmap(bitmap, 0, 0, null);

      bitmap = ss;
    }

    // TODO this is somewhat device-specific; need generic solution.
    // Crop off the status bar and the nav bar
    // Portrait: 0, statusBarHeight, width, height - status - nav
    // Landscape: 0, statusBarHeight, width - navBar, height - status
    int newLeft = 0;
    int newTop = statusBarHeight;
    int newWidth = bitmap.getWidth();
    int newHeight = bitmap.getHeight();
    if (bitmap.getWidth() < bitmap.getHeight()) {
      // Portrait mode: status bar is at the top, navbar bottom, width unchanged
      newHeight = bitmap.getHeight() - statusBarHeight - navBarHeight;
    } else {
      // Landscape mode: status bar is at the top, navbar right
      newHeight = bitmap.getHeight() - statusBarHeight;
      newWidth = bitmap.getWidth() - navBarWidth;
    }
    bitmap = Bitmap.createBitmap(bitmap, newLeft, newTop, newWidth, newHeight);

    return bitmap;
  }