MyPrintService.java revision 282209e42c32d712fd5685f283047d84e813297e
1package foo.bar.printservice;
2
3import android.content.Intent;
4import android.net.Uri;
5import android.os.AsyncTask;
6import android.os.Handler;
7import android.os.Looper;
8import android.os.Message;
9import android.os.SystemClock;
10import android.print.PrintAttributes;
11import android.print.PrintAttributes.Margins;
12import android.print.PrintAttributes.MediaSize;
13import android.print.PrintAttributes.Resolution;
14import android.print.PrintAttributes.Tray;
15import android.print.PrintJobInfo;
16import android.print.PrinterId;
17import android.print.PrinterInfo;
18import android.printservice.PrintJob;
19import android.printservice.PrintService;
20import android.util.Log;
21import android.widget.Toast;
22
23import libcore.io.IoUtils;
24
25import java.io.BufferedInputStream;
26import java.io.BufferedOutputStream;
27import java.io.File;
28import java.io.FileInputStream;
29import java.io.FileOutputStream;
30import java.io.IOException;
31import java.io.InputStream;
32import java.io.OutputStream;
33import java.util.ArrayList;
34import java.util.List;
35
36public class MyPrintService extends PrintService {
37
38    private static final String LOG_TAG = MyPrintService.class.getSimpleName();
39
40    private Handler mHandler;
41
42    private PrinterId mFirstFakePrinterId;
43
44    private PrinterId mSecondFakePrinterId;
45
46    @Override
47    public void onCreate() {
48        mFirstFakePrinterId = generatePrinterId("1");
49        mSecondFakePrinterId = generatePrinterId("2");
50    }
51
52    @Override
53    protected void onConnected() {
54        mHandler = new MyHandler(getMainLooper());
55        Log.i(LOG_TAG, "#onConnected()");
56    }
57
58    @Override
59    protected void onDisconnected() {
60        cancellAddingFakePrinters();
61        Log.i(LOG_TAG, "#onDisconnected()");
62    }
63
64    @Override
65    protected void onStartPrinterDiscovery() {
66        Log.i(LOG_TAG, "#onStartDiscoverPrinters()");
67        Message message1 = mHandler.obtainMessage(MyHandler.MESSAGE_ADD_FIRST_FAKE_PRINTER);
68        mHandler.sendMessageDelayed(message1, 0);
69
70        Message message2 = mHandler.obtainMessage(MyHandler.MESSAGE_ADD_SECOND_FAKE_PRINTER);
71        mHandler.sendMessageDelayed(message2, 10000);
72    }
73
74    @Override
75    protected void onStopPrinterDiscovery() {
76        cancellAddingFakePrinters();
77        Log.i(LOG_TAG, "#onStopDiscoverPrinters()");
78    }
79
80    @Override
81    protected void onRequestUpdatePrinters(List<PrinterId> printerIds) {
82        List<PrinterInfo> udpatedPrinters = new ArrayList<PrinterInfo>();
83        final int printerIdCount = printerIds.size();
84        for (int i = 0; i < printerIdCount; i++) {
85            PrinterId printerId = printerIds.get(i);
86            if (printerId.equals(mFirstFakePrinterId)) {
87                PrinterInfo printer = new PrinterInfo.Builder(printerId, "Printer 1")
88                        .setStatus(PrinterInfo.STATUS_READY)
89                        .setMinMargins(new Margins(0, 0, 0, 0), new Margins(0, 0, 0, 0))
90                        .addMediaSize(MediaSize.createMediaSize(getPackageManager(),
91                                MediaSize.ISO_A2), true)
92                        .addMediaSize(MediaSize.createMediaSize(getPackageManager(),
93                                MediaSize.ISO_A3), false)
94                        .addMediaSize(MediaSize.createMediaSize(getPackageManager(),
95                                MediaSize.ISO_A4), false)
96                        .addMediaSize(MediaSize.createMediaSize(getPackageManager(),
97                                MediaSize.NA_LETTER), false)
98                        .addResolution(new Resolution("R1", getString(
99                                R.string.resolution_600x600), 600, 600), true)
100                        .addInputTray(new Tray("FirstInputTray", getString(
101                                R.string.input_tray_first)), false)
102                        .addOutputTray(new Tray("FirstOutputTray", getString(
103                                R.string.output_tray_first)), false)
104                        .setDuplexModes(PrintAttributes.DUPLEX_MODE_NONE
105                                | PrintAttributes.DUPLEX_MODE_LONG_EDGE
106                                | PrintAttributes.DUPLEX_MODE_SHORT_EDGE,
107                                PrintAttributes.DUPLEX_MODE_NONE)
108                        .setColorModes(PrintAttributes.COLOR_MODE_COLOR
109                                | PrintAttributes.COLOR_MODE_MONOCHROME,
110                                PrintAttributes.COLOR_MODE_COLOR)
111                        .setFittingModes(PrintAttributes.FITTING_MODE_NONE
112                                | PrintAttributes.FITTING_MODE_FIT_TO_PAGE,
113                                PrintAttributes.FITTING_MODE_NONE)
114                        .setOrientations(PrintAttributes.ORIENTATION_PORTRAIT
115                                | PrintAttributes.ORIENTATION_LANDSCAPE,
116                                PrintAttributes.ORIENTATION_PORTRAIT)
117                        .create();
118                udpatedPrinters.add(printer);
119            } else if (printerId.equals(mSecondFakePrinterId)) {
120                PrinterInfo printer = new PrinterInfo.Builder(printerId, "Printer 2")
121                        .setStatus(PrinterInfo.STATUS_READY)
122                        .setMinMargins(new Margins(0, 0, 0, 0), new Margins(0, 0, 0, 0))
123                        .addMediaSize(MediaSize.createMediaSize(getPackageManager(),
124                                MediaSize.ISO_A4), true)
125                        .addMediaSize(MediaSize.createMediaSize(getPackageManager(),
126                                MediaSize.ISO_A5), false)
127                        .addResolution(new Resolution("R1", getString(
128                                R.string.resolution_200x200), 200, 200), true)
129                        .addResolution(new Resolution("R2", getString(
130                                R.string.resolution_300x300), 300, 300), false)
131                        .addInputTray(new Tray("FirstInputTray", getString(
132                                R.string.input_tray_first)), false)
133                        .addInputTray(new Tray("SecondInputTray", getString(
134                                R.string.input_tray_second)), true)
135                        .addOutputTray(new Tray("FirstOutputTray", getString(
136                                R.string.output_tray_first)), false)
137                        .addOutputTray(new Tray("SecondOutputTray",  getString(
138                                R.string.output_tray_second)), true)
139                        .setDuplexModes(PrintAttributes.DUPLEX_MODE_NONE
140                                | PrintAttributes.DUPLEX_MODE_LONG_EDGE
141                                | PrintAttributes.DUPLEX_MODE_SHORT_EDGE,
142                                PrintAttributes.DUPLEX_MODE_SHORT_EDGE)
143                        .setColorModes(PrintAttributes.COLOR_MODE_COLOR
144                                | PrintAttributes.COLOR_MODE_MONOCHROME,
145                                PrintAttributes.COLOR_MODE_MONOCHROME)
146                        .setFittingModes(PrintAttributes.FITTING_MODE_FIT_TO_PAGE
147                                | PrintAttributes.FITTING_MODE_NONE,
148                                PrintAttributes.FITTING_MODE_FIT_TO_PAGE)
149                        .setOrientations(PrintAttributes.ORIENTATION_PORTRAIT
150                                | PrintAttributes.ORIENTATION_LANDSCAPE,
151                                PrintAttributes.ORIENTATION_LANDSCAPE)
152                        .create();
153                udpatedPrinters.add(printer);
154            }
155            if (!udpatedPrinters.isEmpty()) {
156                updateDiscoveredPrinters(udpatedPrinters);
157            }
158        }
159    }
160
161    @Override
162    public void onPrintJobQueued(final PrintJob printJob) {
163        Log.i(LOG_TAG, "#onPrintJobQueued()");
164        PrintJobInfo info = printJob.getInfo();
165        final File file = new File(getFilesDir(), info.getLabel() + ".pdf");
166        if (file.exists()) {
167            file.delete();
168        }
169        AsyncTask<Void, Void, Void> task = new AsyncTask<Void, Void, Void>() {
170            @Override
171            protected Void doInBackground(Void... params) {
172                InputStream in = new BufferedInputStream(
173                        new FileInputStream(printJob.getDocument().getData()));
174                OutputStream out = null;
175                try {
176                    out = new BufferedOutputStream(new FileOutputStream(file));
177                    final byte[] buffer = new byte[8192];
178                    while (true) {
179                        final int readByteCount = in.read(buffer);
180                        if (readByteCount < 0) {
181                            break;
182                        }
183                        out.write(buffer, 0, readByteCount);
184                    }
185                } catch (IOException ioe) {
186                    /* ignore */
187                } finally {
188                    IoUtils.closeQuietly(in);
189                    IoUtils.closeQuietly(out);
190                }
191                return null;
192            }
193
194            @Override
195            protected void onPostExecute(Void result) {
196                file.setExecutable(true, false);
197                file.setWritable(true, false);
198                file.setReadable(true, false);
199
200                Intent intent = new Intent(Intent.ACTION_VIEW);
201                intent.setDataAndType(Uri.fromFile(file), "application/pdf");
202                intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
203                startActivity(intent, null);
204
205                if (printJob.isQueued()) {
206                    printJob.start();
207                }
208
209                PrintJobInfo info =  printJob.getInfo();
210
211                Toast.makeText(MyPrintService.this,
212                        "[STARTED] Printer: " + info.getPrinterId().getLocalId(),
213                        Toast.LENGTH_SHORT).show();
214
215                SystemClock.sleep(5000);
216
217                Toast.makeText(MyPrintService.this,
218                        "[COMPLETED] Printer: " + info.getPrinterId().getLocalId(),
219                        Toast.LENGTH_SHORT).show();
220
221                if (printJob.isStarted()) {
222                    printJob.complete();
223                }
224            }
225        };
226        task.executeOnExecutor(AsyncTask.SERIAL_EXECUTOR, (Void[]) null);
227    }
228
229    private void addFirstFakePrinter() {
230        PrinterId printerId = generatePrinterId("1");
231        PrinterInfo printer = new PrinterInfo.Builder(printerId, "Printer 1").create();
232        List<PrinterInfo> printers = new ArrayList<PrinterInfo>();
233        printers.add(printer);
234        addDiscoveredPrinters(printers);
235    }
236
237    private void addSecondFakePrinter() {
238        PrinterId printerId = generatePrinterId("2");
239        PrinterInfo printer = new PrinterInfo.Builder(printerId, "Printer 2").create();
240        List<PrinterInfo> printers = new ArrayList<PrinterInfo>();
241        printers.add(printer);
242        addDiscoveredPrinters(printers);
243    }
244
245    private void cancellAddingFakePrinters() {
246        mHandler.removeMessages(MyHandler.MESSAGE_ADD_FIRST_FAKE_PRINTER);
247        mHandler.removeMessages(MyHandler.MESSAGE_ADD_FIRST_FAKE_PRINTER);
248    }
249
250    private final class MyHandler extends Handler {
251
252        public static final int MESSAGE_ADD_FIRST_FAKE_PRINTER = 1;
253        public static final int MESSAGE_ADD_SECOND_FAKE_PRINTER = 2;
254
255        public MyHandler(Looper looper) {
256            super(looper, null, true);
257        }
258
259        @Override
260        public void handleMessage(Message message) {
261            switch (message.what) {
262                case MESSAGE_ADD_FIRST_FAKE_PRINTER: {
263                    addFirstFakePrinter();
264                } break;
265                case MESSAGE_ADD_SECOND_FAKE_PRINTER: {
266                    addSecondFakePrinter();
267                } break;
268            }
269        }
270    }
271}
272