1 /*
2  * Copyright (C) 2013 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package android.support.v4.print;
18 
19 import android.content.Context;
20 import android.graphics.Bitmap;
21 import android.os.Build;
22 
23 import android.net.Uri;
24 
25 import java.io.FileNotFoundException;
26 
27 /**
28  * Helper for printing bitmaps.
29  */
30 public final class PrintHelper {
31     /**
32      * image will be scaled but leave white space
33      */
34     public static final int SCALE_MODE_FIT = 1;
35 
36     /**
37      * image will fill the paper and be cropped (default)
38      */
39     public static final int SCALE_MODE_FILL = 2;
40 
41     /**
42      * this is a black and white image
43      */
44     public static final int COLOR_MODE_MONOCHROME = 1;
45 
46     /**
47      * this is a color image (default)
48      */
49     public static final int COLOR_MODE_COLOR = 2;
50 
51     /**
52      * Print the image in landscape orientation (default).
53      */
54     public static final int ORIENTATION_LANDSCAPE = 1;
55 
56     /**
57      * Print the image in  portrait orientation.
58      */
59     public static final int ORIENTATION_PORTRAIT = 2;
60 
61     /**
62      * Callback for observing when a print operation is completed.
63      * When print is finished either the system acquired the
64      * document to print or printing was cancelled.
65      */
66     public interface OnPrintFinishCallback {
67 
68         /**
69          * Called when a print operation is finished.
70          */
onFinish()71         public void onFinish();
72     }
73 
74     PrintHelperVersionImpl mImpl;
75 
76     /**
77      * Gets whether the system supports printing.
78      *
79      * @return True if printing is supported.
80      */
systemSupportsPrint()81     public static boolean systemSupportsPrint() {
82         if (Build.VERSION.SDK_INT >= 19) {
83             // Supported on Android 4.4 or later.
84             return true;
85         }
86         return false;
87     }
88 
89     /**
90      * Interface implemented by classes that support printing
91      */
92     static interface PrintHelperVersionImpl {
93 
setScaleMode(int scaleMode)94         public void setScaleMode(int scaleMode);
95 
getScaleMode()96         public int getScaleMode();
97 
setColorMode(int colorMode)98         public void setColorMode(int colorMode);
99 
getColorMode()100         public int getColorMode();
101 
setOrientation(int orientation)102         public void setOrientation(int orientation);
103 
getOrientation()104         public int getOrientation();
105 
printBitmap(String jobName, Bitmap bitmap, OnPrintFinishCallback callback)106         public void printBitmap(String jobName, Bitmap bitmap, OnPrintFinishCallback callback);
107 
printBitmap(String jobName, Uri imageFile, OnPrintFinishCallback callback)108         public void printBitmap(String jobName, Uri imageFile, OnPrintFinishCallback callback)
109                 throws FileNotFoundException;
110     }
111 
112     /**
113      * Implementation used when we do not support printing
114      */
115     private static final class PrintHelperStubImpl implements PrintHelperVersionImpl {
116         int mScaleMode = SCALE_MODE_FILL;
117         int mColorMode = COLOR_MODE_COLOR;
118         int mOrientation = ORIENTATION_LANDSCAPE;
119         @Override
setScaleMode(int scaleMode)120         public void setScaleMode(int scaleMode) {
121             mScaleMode = scaleMode;
122         }
123 
124         @Override
getColorMode()125         public int getColorMode() {
126             return mColorMode;
127         }
128 
129         @Override
setColorMode(int colorMode)130         public void setColorMode(int colorMode) {
131             mColorMode = colorMode;
132         }
133 
134         @Override
setOrientation(int orientation)135         public void setOrientation(int orientation) { mOrientation = orientation; }
136 
137         @Override
getOrientation()138         public int getOrientation() { return mOrientation; }
139 
140         @Override
getScaleMode()141         public int getScaleMode() {
142             return mScaleMode;
143         }
144 
145         @Override
printBitmap(String jobName, Bitmap bitmap, OnPrintFinishCallback callback)146         public void printBitmap(String jobName, Bitmap bitmap, OnPrintFinishCallback callback) {
147         }
148 
149         @Override
printBitmap(String jobName, Uri imageFile, OnPrintFinishCallback callback)150         public void printBitmap(String jobName, Uri imageFile, OnPrintFinishCallback callback) {
151         }
152     }
153 
154     /**
155      * Generic implementation for KitKat to Api24
156      */
157     private static class PrintHelperImpl<RealHelper extends PrintHelperKitkat>
158             implements PrintHelperVersionImpl {
159         private final RealHelper mPrintHelper;
160 
PrintHelperImpl(RealHelper helper)161         protected PrintHelperImpl(RealHelper helper) {
162             mPrintHelper = helper;
163         }
164 
165         @Override
setScaleMode(int scaleMode)166         public void setScaleMode(int scaleMode) {
167             mPrintHelper.setScaleMode(scaleMode);
168         }
169 
170         @Override
getScaleMode()171         public int getScaleMode() {
172             return mPrintHelper.getScaleMode();
173         }
174 
175         @Override
setColorMode(int colorMode)176         public void setColorMode(int colorMode) {
177             mPrintHelper.setColorMode(colorMode);
178         }
179 
180         @Override
getColorMode()181         public int getColorMode() {
182             return mPrintHelper.getColorMode();
183         }
184 
185         @Override
setOrientation(int orientation)186         public void setOrientation(int orientation) {
187             mPrintHelper.setOrientation(orientation);
188         }
189 
190         @Override
getOrientation()191         public int getOrientation() {
192             return mPrintHelper.getOrientation();
193         }
194 
195         @Override
printBitmap(String jobName, Bitmap bitmap, final OnPrintFinishCallback callback)196         public void printBitmap(String jobName, Bitmap bitmap,
197                 final OnPrintFinishCallback callback) {
198             RealHelper.OnPrintFinishCallback delegateCallback = null;
199             if (callback != null) {
200                 delegateCallback = new RealHelper.OnPrintFinishCallback() {
201                     @Override
202                     public void onFinish() {
203                         callback.onFinish();
204                     }
205                 };
206             }
207             mPrintHelper.printBitmap(jobName, bitmap, delegateCallback);
208         }
209 
210         @Override
printBitmap(String jobName, Uri imageFile, final OnPrintFinishCallback callback)211         public void printBitmap(String jobName, Uri imageFile,
212                 final OnPrintFinishCallback callback) throws FileNotFoundException {
213             RealHelper.OnPrintFinishCallback delegateCallback = null;
214             if (callback != null) {
215                 delegateCallback = new RealHelper.OnPrintFinishCallback() {
216                     @Override
217                     public void onFinish() {
218                         callback.onFinish();
219                     }
220                 };
221             }
222             mPrintHelper.printBitmap(jobName, imageFile, delegateCallback);
223         }
224     }
225 
226     /**
227      * Implementation used on KitKat
228      */
229     private static final class PrintHelperKitkatImpl extends PrintHelperImpl<PrintHelperKitkat> {
PrintHelperKitkatImpl(Context context)230         PrintHelperKitkatImpl(Context context) {
231             super(new PrintHelperKitkat(context));
232         }
233     }
234 
235     /**
236      * Implementation used on Api20 to Api22
237      */
238     private static final class PrintHelperApi20Impl extends PrintHelperImpl<PrintHelperApi20> {
PrintHelperApi20Impl(Context context)239         PrintHelperApi20Impl(Context context) {
240             super(new PrintHelperApi20(context));
241         }
242     }
243 
244     /**
245      * Implementation used on Api23
246      */
247     private static final class PrintHelperApi23Impl extends PrintHelperImpl<PrintHelperApi23> {
PrintHelperApi23Impl(Context context)248         PrintHelperApi23Impl(Context context) {
249             super(new PrintHelperApi23(context));
250         }
251     }
252 
253 
254     /**
255      * Implementation used on Api24 and above
256      */
257     private static final class PrintHelperApi24Impl extends PrintHelperImpl<PrintHelperApi24> {
PrintHelperApi24Impl(Context context)258         PrintHelperApi24Impl(Context context) {
259             super(new PrintHelperApi24(context));
260         }
261     }
262 
263     /**
264      * Returns the PrintHelper that can be used to print images.
265      *
266      * @param context A context for accessing system resources.
267      * @return the <code>PrintHelper</code> to support printing images.
268      */
PrintHelper(Context context)269     public PrintHelper(Context context) {
270         if (systemSupportsPrint()) {
271             if (Build.VERSION.SDK_INT >= 24) {
272                 mImpl = new PrintHelperApi24Impl(context);
273             } else if (Build.VERSION.SDK_INT >= 23) {
274                 mImpl = new PrintHelperApi23Impl(context);
275             } else if (Build.VERSION.SDK_INT >= 20) {
276                 mImpl = new PrintHelperApi20Impl(context);
277             } else {
278                 mImpl = new PrintHelperKitkatImpl(context);
279             }
280         } else {
281             mImpl = new PrintHelperStubImpl();
282         }
283     }
284 
285     /**
286      * Selects whether the image will fill the paper and be cropped
287      * {@link #SCALE_MODE_FIT}
288      * or whether the image will be scaled but leave white space
289      * {@link #SCALE_MODE_FILL}.
290      *
291      * @param scaleMode {@link #SCALE_MODE_FIT} or
292      *                  {@link #SCALE_MODE_FILL}
293      */
setScaleMode(int scaleMode)294     public void setScaleMode(int scaleMode) {
295         mImpl.setScaleMode(scaleMode);
296     }
297 
298     /**
299      * Returns the scale mode with which the image will fill the paper.
300      *
301      * @return The scale Mode: {@link #SCALE_MODE_FIT} or
302      * {@link #SCALE_MODE_FILL}
303      */
getScaleMode()304     public int getScaleMode() {
305         return mImpl.getScaleMode();
306     }
307 
308     /**
309      * Sets whether the image will be printed in color (default)
310      * {@link #COLOR_MODE_COLOR} or in back and white
311      * {@link #COLOR_MODE_MONOCHROME}.
312      *
313      * @param colorMode The color mode which is one of
314      * {@link #COLOR_MODE_COLOR} and {@link #COLOR_MODE_MONOCHROME}.
315      */
setColorMode(int colorMode)316     public void setColorMode(int colorMode) {
317         mImpl.setColorMode(colorMode);
318     }
319 
320     /**
321      * Gets the color mode with which the image will be printed.
322      *
323      * @return The color mode which is one of {@link #COLOR_MODE_COLOR}
324      * and {@link #COLOR_MODE_MONOCHROME}.
325      */
getColorMode()326     public int getColorMode() {
327         return mImpl.getColorMode();
328     }
329 
330     /**
331      * Sets whether the image will be printed in landscape {@link #ORIENTATION_LANDSCAPE} (default)
332      * or portrait {@link #ORIENTATION_PORTRAIT}.
333      *
334      * @param orientation The page orientation which is one of
335      *                    {@link #ORIENTATION_LANDSCAPE} or {@link #ORIENTATION_PORTRAIT}.
336      */
setOrientation(int orientation)337     public void setOrientation(int orientation) {
338         mImpl.setOrientation(orientation);
339     }
340 
341     /**
342      * Gets whether the image will be printed in landscape or portrait.
343      *
344      * @return The page orientation which is one of
345      * {@link #ORIENTATION_LANDSCAPE} or {@link #ORIENTATION_PORTRAIT}.
346      */
getOrientation()347     public int getOrientation() {
348         return mImpl.getOrientation();
349     }
350 
351 
352     /**
353      * Prints a bitmap.
354      *
355      * @param jobName The print job name.
356      * @param bitmap  The bitmap to print.
357      */
printBitmap(String jobName, Bitmap bitmap)358     public void printBitmap(String jobName, Bitmap bitmap) {
359         mImpl.printBitmap(jobName, bitmap, null);
360     }
361 
362     /**
363      * Prints a bitmap.
364      *
365      * @param jobName The print job name.
366      * @param bitmap  The bitmap to print.
367      * @param callback Optional callback to observe when printing is finished.
368      */
printBitmap(String jobName, Bitmap bitmap, OnPrintFinishCallback callback)369     public void printBitmap(String jobName, Bitmap bitmap, OnPrintFinishCallback callback) {
370         mImpl.printBitmap(jobName, bitmap, callback);
371     }
372 
373     /**
374      * Prints an image located at the Uri. Image types supported are those of
375      * {@link android.graphics.BitmapFactory#decodeStream(java.io.InputStream)
376      * android.graphics.BitmapFactory.decodeStream(java.io.InputStream)}
377      *
378      * @param jobName   The print job name.
379      * @param imageFile The <code>Uri</code> pointing to an image to print.
380      * @throws FileNotFoundException if <code>Uri</code> is not pointing to a valid image.
381      */
printBitmap(String jobName, Uri imageFile)382     public void printBitmap(String jobName, Uri imageFile) throws FileNotFoundException {
383         mImpl.printBitmap(jobName, imageFile, null);
384     }
385 
386     /**
387      * Prints an image located at the Uri. Image types supported are those of
388      * {@link android.graphics.BitmapFactory#decodeStream(java.io.InputStream)
389      * android.graphics.BitmapFactory.decodeStream(java.io.InputStream)}
390      *
391      * @param jobName   The print job name.
392      * @param imageFile The <code>Uri</code> pointing to an image to print.
393      * @throws FileNotFoundException if <code>Uri</code> is not pointing to a valid image.
394      * @param callback Optional callback to observe when printing is finished.
395      */
printBitmap(String jobName, Uri imageFile, OnPrintFinishCallback callback)396     public void printBitmap(String jobName, Uri imageFile, OnPrintFinishCallback callback)
397             throws FileNotFoundException {
398         mImpl.printBitmap(jobName, imageFile, callback);
399     }
400 }
401