FileDocCategorySizeDatePackage
PrintHelperKitkat.javaAPI DocAndroid 5.1 API20789Thu Mar 12 22:22:56 GMT 2015android.support.v4.print

PrintHelperKitkat

public class PrintHelperKitkat extends Object
Kitkat specific PrintManager API implementation.

Fields Summary
private static final String
LOG_TAG
private static final int
MAX_PRINT_SIZE
final android.content.Context
mContext
BitmapFactory.Options
mDecodeOptions
private final Object
mLock
public static final int
SCALE_MODE_FIT
image will be scaled but leave white space
public static final int
SCALE_MODE_FILL
image will fill the paper and be cropped (default)
public static final int
ORIENTATION_LANDSCAPE
select landscape (default)
public static final int
ORIENTATION_PORTRAIT
select portrait
public static final int
COLOR_MODE_MONOCHROME
this is a black and white image
public static final int
COLOR_MODE_COLOR
this is a color image (default)
int
mScaleMode
int
mColorMode
int
mOrientation
Constructors Summary
PrintHelperKitkat(android.content.Context context)


      
        mContext = context;
    
Methods Summary
public intgetColorMode()
Gets the color mode with which the image will be printed.

return
The color mode which is one of {@link #COLOR_MODE_COLOR} and {@link #COLOR_MODE_MONOCHROME}.

        return mColorMode;
    
private android.graphics.MatrixgetMatrix(int imageWidth, int imageHeight, android.graphics.RectF content, int fittingMode)
Calculates the transform the print an Image to fill the page

param
imageWidth with of bitmap
param
imageHeight height of bitmap
param
content The output page dimensions
param
fittingMode The mode of fitting {@link #SCALE_MODE_FILL} vs {@link #SCALE_MODE_FIT}
return
Matrix to be used in canvas.drawBitmap(bitmap, matrix, null) call

        Matrix matrix = new Matrix();

        // Compute and apply scale to fill the page.
        float scale = content.width() / imageWidth;
        if (fittingMode == SCALE_MODE_FILL) {
            scale = Math.max(scale, content.height() / imageHeight);
        } else {
            scale = Math.min(scale, content.height() / imageHeight);
        }
        matrix.postScale(scale, scale);

        // Center the content.
        final float translateX = (content.width()
                - imageWidth * scale) / 2;
        final float translateY = (content.height()
                - imageHeight * scale) / 2;
        matrix.postTranslate(translateX, translateY);
        return matrix;
    
public intgetOrientation()
Gets the page orientation with which the image will be printed.

return
The preferred orientation which is one of {@link #ORIENTATION_LANDSCAPE} or {@link #ORIENTATION_PORTRAIT}

        return mOrientation;
    
public intgetScaleMode()
Returns the scale mode with which the image will fill the paper.

return
The scale Mode: {@link #SCALE_MODE_FIT} or {@link #SCALE_MODE_FILL}

        return mScaleMode;
    
private android.graphics.BitmaploadBitmap(android.net.Uri uri, BitmapFactory.Options o)
Returns the bitmap from the given uri loaded using the given options. Returns null on failure.

        if (uri == null || mContext == null) {
            throw new IllegalArgumentException("bad argument to loadBitmap");
        }
        InputStream is = null;
        try {
            is = mContext.getContentResolver().openInputStream(uri);
            return BitmapFactory.decodeStream(is, null, o);
        } finally {
            if (is != null) {
                try {
                    is.close();
                } catch (IOException t) {
                    Log.w(LOG_TAG, "close fail ", t);
                }
            }
        }
    
private android.graphics.BitmaploadConstrainedBitmap(android.net.Uri uri, int maxSideLength)
Loads a bitmap while limiting its size

param
uri location of a valid image
param
maxSideLength the maximum length of a size
return
the Bitmap
throws
FileNotFoundException if the Uri does not point to an image

        if (maxSideLength <= 0 || uri == null || mContext == null) {
            throw new IllegalArgumentException("bad argument to getScaledBitmap");
        }
        // Get width and height of stored bitmap
        BitmapFactory.Options opt = new BitmapFactory.Options();
        opt.inJustDecodeBounds = true;
        loadBitmap(uri, opt);

        int w = opt.outWidth;
        int h = opt.outHeight;

        // If bitmap cannot be decoded, return null
        if (w <= 0 || h <= 0) {
            return null;
        }

        // Find best downsampling size
        int imageSide = Math.max(w, h);

        int sampleSize = 1;
        while (imageSide > maxSideLength) {
            imageSide >>>= 1;
            sampleSize <<= 1;
        }

        // Make sure sample size is reasonable
        if (sampleSize <= 0 || 0 >= (int) (Math.min(w, h) / sampleSize)) {
            return null;
        }
        BitmapFactory.Options decodeOptions = null;
        synchronized (mLock) { // prevent race with set null below
            mDecodeOptions = new BitmapFactory.Options();
            mDecodeOptions.inMutable = true;
            mDecodeOptions.inSampleSize = sampleSize;
            decodeOptions = mDecodeOptions;
        }
        try {
            return loadBitmap(uri, decodeOptions);
        } finally {
            synchronized (mLock) {
                mDecodeOptions = null;
            }
        }
    
public voidprintBitmap(java.lang.String jobName, android.net.Uri imageFile, android.support.v4.print.PrintHelperKitkat$OnPrintFinishCallback callback)
Prints an image located at the Uri. Image types supported are those of BitmapFactory.decodeStream (JPEG, GIF, PNG, BMP, WEBP)

param
jobName The print job name.
param
imageFile The Uri pointing to an image to print.
param
callback Optional callback to observe when printing is finished.
throws
FileNotFoundException if Uri is not pointing to a valid image.

        final int fittingMode = mScaleMode;

        PrintDocumentAdapter printDocumentAdapter = new PrintDocumentAdapter() {
            private PrintAttributes mAttributes;
            AsyncTask<Uri, Boolean, Bitmap> mLoadBitmap;
            Bitmap mBitmap = null;

            @Override
            public void onLayout(final PrintAttributes oldPrintAttributes,
                                 final PrintAttributes newPrintAttributes,
                                 final CancellationSignal cancellationSignal,
                                 final LayoutResultCallback layoutResultCallback,
                                 Bundle bundle) {

                mAttributes = newPrintAttributes;

                if (cancellationSignal.isCanceled()) {
                    layoutResultCallback.onLayoutCancelled();
                    return;
                }
                // we finished the load
                if (mBitmap != null) {
                    PrintDocumentInfo info = new PrintDocumentInfo.Builder(jobName)
                            .setContentType(PrintDocumentInfo.CONTENT_TYPE_PHOTO)
                            .setPageCount(1)
                            .build();
                    boolean changed = !newPrintAttributes.equals(oldPrintAttributes);
                    layoutResultCallback.onLayoutFinished(info, changed);
                    return;
                }

                mLoadBitmap = new AsyncTask<Uri, Boolean, Bitmap>() {

                    @Override
                    protected void onPreExecute() {
                        // First register for cancellation requests.
                        cancellationSignal.setOnCancelListener(
                                new CancellationSignal.OnCancelListener() {
                                    @Override
                                    public void onCancel() { // on different thread
                                        cancelLoad();
                                        cancel(false);
                                    }
                                });
                    }

                    @Override
                    protected Bitmap doInBackground(Uri... uris) {
                        try {
                            return loadConstrainedBitmap(imageFile, MAX_PRINT_SIZE);
                        } catch (FileNotFoundException e) {
                          /* ignore */
                        }
                        return null;
                    }

                    @Override
                    protected void onPostExecute(Bitmap bitmap) {
                        super.onPostExecute(bitmap);
                        mBitmap = bitmap;
                        if (bitmap != null) {
                            PrintDocumentInfo info = new PrintDocumentInfo.Builder(jobName)
                                    .setContentType(PrintDocumentInfo.CONTENT_TYPE_PHOTO)
                                    .setPageCount(1)
                                    .build();
                            boolean changed = !newPrintAttributes.equals(oldPrintAttributes);

                            layoutResultCallback.onLayoutFinished(info, changed);

                        } else {
                            layoutResultCallback.onLayoutFailed(null);
                        }
                        mLoadBitmap = null;
                    }

                    @Override
                    protected void onCancelled(Bitmap result) {
                        // Task was cancelled, report that.
                        layoutResultCallback.onLayoutCancelled();
                        mLoadBitmap = null;
                    }
                }.execute();
            }

            private void cancelLoad() {
                synchronized (mLock) { // prevent race with set null below
                    if (mDecodeOptions != null) {
                        mDecodeOptions.requestCancelDecode();
                        mDecodeOptions = null;
                    }
                }
            }

            @Override
            public void onFinish() {
                super.onFinish();
                cancelLoad();
                if (mLoadBitmap != null) {
                    mLoadBitmap.cancel(true);
                }
                if (callback != null) {
                    callback.onFinish();
                }
            }

            @Override
            public void onWrite(PageRange[] pageRanges, ParcelFileDescriptor fileDescriptor,
                                CancellationSignal cancellationSignal,
                                WriteResultCallback writeResultCallback) {
                PrintedPdfDocument pdfDocument = new PrintedPdfDocument(mContext,
                        mAttributes);
                try {

                    Page page = pdfDocument.startPage(1);
                    RectF content = new RectF(page.getInfo().getContentRect());

                    // Compute and apply scale to fill the page.
                    Matrix matrix = getMatrix(mBitmap.getWidth(), mBitmap.getHeight(),
                            content, fittingMode);

                    // Draw the bitmap.
                    page.getCanvas().drawBitmap(mBitmap, matrix, null);

                    // Finish the page.
                    pdfDocument.finishPage(page);

                    try {
                        // Write the document.
                        pdfDocument.writeTo(new FileOutputStream(
                                fileDescriptor.getFileDescriptor()));
                        // Done.
                        writeResultCallback.onWriteFinished(
                                new PageRange[]{PageRange.ALL_PAGES});
                    } catch (IOException ioe) {
                        // Failed.
                        Log.e(LOG_TAG, "Error writing printed content", ioe);
                        writeResultCallback.onWriteFailed(null);
                    }
                } finally {
                    if (pdfDocument != null) {
                        pdfDocument.close();
                    }
                    if (fileDescriptor != null) {
                        try {
                            fileDescriptor.close();
                        } catch (IOException ioe) {
                            /* ignore */
                        }
                    }
                }
            }
        };

        PrintManager printManager = (PrintManager) mContext.getSystemService(Context.PRINT_SERVICE);
        PrintAttributes.Builder builder = new PrintAttributes.Builder();
        builder.setColorMode(mColorMode);

        if (mOrientation == ORIENTATION_LANDSCAPE) {
            builder.setMediaSize(PrintAttributes.MediaSize.UNKNOWN_LANDSCAPE);
        } else if (mOrientation == ORIENTATION_PORTRAIT) {
            builder.setMediaSize(PrintAttributes.MediaSize.UNKNOWN_PORTRAIT);
        }
        PrintAttributes attr = builder.build();

        printManager.print(jobName, printDocumentAdapter, attr);
    
public voidprintBitmap(java.lang.String jobName, android.graphics.Bitmap bitmap, android.support.v4.print.PrintHelperKitkat$OnPrintFinishCallback callback)
Prints a bitmap.

param
jobName The print job name.
param
bitmap The bitmap to print.
param
callback Optional callback to observe when printing is finished.

        if (bitmap == null) {
            return;
        }
        final int fittingMode = mScaleMode; // grab the fitting mode at time of call
        PrintManager printManager = (PrintManager) mContext.getSystemService(Context.PRINT_SERVICE);
        PrintAttributes.MediaSize mediaSize = PrintAttributes.MediaSize.UNKNOWN_PORTRAIT;
        if (bitmap.getWidth() > bitmap.getHeight()) {
            mediaSize = PrintAttributes.MediaSize.UNKNOWN_LANDSCAPE;
        }
        PrintAttributes attr = new PrintAttributes.Builder()
                .setMediaSize(mediaSize)
                .setColorMode(mColorMode)
                .build();

        printManager.print(jobName,
                new PrintDocumentAdapter() {
                    private PrintAttributes mAttributes;

                    @Override
                    public void onLayout(PrintAttributes oldPrintAttributes,
                                         PrintAttributes newPrintAttributes,
                                         CancellationSignal cancellationSignal,
                                         LayoutResultCallback layoutResultCallback,
                                         Bundle bundle) {

                        mAttributes = newPrintAttributes;

                        PrintDocumentInfo info = new PrintDocumentInfo.Builder(jobName)
                                .setContentType(PrintDocumentInfo.CONTENT_TYPE_PHOTO)
                                .setPageCount(1)
                                .build();
                        boolean changed = !newPrintAttributes.equals(oldPrintAttributes);
                        layoutResultCallback.onLayoutFinished(info, changed);
                    }

                    @Override
                    public void onWrite(PageRange[] pageRanges, ParcelFileDescriptor fileDescriptor,
                                        CancellationSignal cancellationSignal,
                                        WriteResultCallback writeResultCallback) {
                        PrintedPdfDocument pdfDocument = new PrintedPdfDocument(mContext,
                                mAttributes);
                        try {
                            Page page = pdfDocument.startPage(1);

                            RectF content = new RectF(page.getInfo().getContentRect());

                            Matrix matrix = getMatrix(bitmap.getWidth(), bitmap.getHeight(),
                                    content, fittingMode);

                            // Draw the bitmap.
                            page.getCanvas().drawBitmap(bitmap, matrix, null);

                            // Finish the page.
                            pdfDocument.finishPage(page);

                            try {
                                // Write the document.
                                pdfDocument.writeTo(new FileOutputStream(
                                        fileDescriptor.getFileDescriptor()));
                                // Done.
                                writeResultCallback.onWriteFinished(
                                        new PageRange[]{PageRange.ALL_PAGES});
                            } catch (IOException ioe) {
                                // Failed.
                                Log.e(LOG_TAG, "Error writing printed content", ioe);
                                writeResultCallback.onWriteFailed(null);
                            }
                        } finally {
                            if (pdfDocument != null) {
                                pdfDocument.close();
                            }
                            if (fileDescriptor != null) {
                                try {
                                    fileDescriptor.close();
                                } catch (IOException ioe) {
                                    /* ignore */
                                }
                            }
                        }
                    }

                    @Override
                    public void onFinish() {
                        if (callback != null) {
                            callback.onFinish();
                        }
                    }
                }, attr);
    
public voidsetColorMode(int colorMode)
Sets whether the image will be printed in color (default) {@link #COLOR_MODE_COLOR} or in back and white {@link #COLOR_MODE_MONOCHROME}.

param
colorMode The color mode which is one of {@link #COLOR_MODE_COLOR} and {@link #COLOR_MODE_MONOCHROME}.

        mColorMode = colorMode;
    
public voidsetOrientation(int orientation)
Sets whether to select landscape (default), {@link #ORIENTATION_LANDSCAPE} or portrait {@link #ORIENTATION_PORTRAIT}

param
orientation The page orientation which is one of {@link #ORIENTATION_LANDSCAPE} or {@link #ORIENTATION_PORTRAIT}.

        mOrientation = orientation;
    
public voidsetScaleMode(int scaleMode)
Selects whether the image will fill the paper and be cropped

{@link #SCALE_MODE_FIT} or whether the image will be scaled but leave white space {@link #SCALE_MODE_FILL}.

param
scaleMode {@link #SCALE_MODE_FIT} or {@link #SCALE_MODE_FILL}

        mScaleMode = scaleMode;