MyPrintService.java revision 8650104109cd83aaab861d69c83f49a65d37a49e
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    @Override
43    protected void onConnected() {
44        mHandler = new MyHandler(getMainLooper());
45        Log.i(LOG_TAG, "#onConnected()");
46    }
47
48    @Override
49    protected void onDisconnected() {
50        cancellAddingFakePrinters();
51        Log.i(LOG_TAG, "#onDisconnected()");
52    }
53
54    @Override
55    protected void onStartPrinterDiscovery() {
56        Log.i(LOG_TAG, "#onStartDiscoverPrinters()");
57        Message message1 = mHandler.obtainMessage(MyHandler.MESSAGE_ADD_FIRST_FAKE_PRINTER);
58        mHandler.sendMessageDelayed(message1, 0);
59
60        Message message2 = mHandler.obtainMessage(MyHandler.MESSAGE_ADD_SECOND_FAKE_PRINTER);
61        mHandler.sendMessageDelayed(message2, 10000);
62    }
63
64    @Override
65    protected void onStopPrinterDiscovery() {
66        cancellAddingFakePrinters();
67        Log.i(LOG_TAG, "#onStopDiscoverPrinters()");
68    }
69
70    @Override
71    public void onPrintJobQueued(final PrintJob printJob) {
72        Log.i(LOG_TAG, "#onPrintJobQueued()");
73        PrintJobInfo info = printJob.getInfo();
74        final File file = new File(getFilesDir(), info.getLabel() + ".pdf");
75        if (file.exists()) {
76            file.delete();
77        }
78        AsyncTask<Void, Void, Void> task = new AsyncTask<Void, Void, Void>() {
79            @Override
80            protected Void doInBackground(Void... params) {
81                InputStream in = new BufferedInputStream(
82                        new FileInputStream(printJob.getDocument().getData()));
83                OutputStream out = null;
84                try {
85                    out = new BufferedOutputStream(new FileOutputStream(file));
86                    final byte[] buffer = new byte[8192];
87                    while (true) {
88                        final int readByteCount = in.read(buffer);
89                        if (readByteCount < 0) {
90                            break;
91                        }
92                        out.write(buffer, 0, readByteCount);
93                    }
94                } catch (IOException ioe) {
95                    /* ignore */
96                } finally {
97                    IoUtils.closeQuietly(in);
98                    IoUtils.closeQuietly(out);
99                }
100                return null;
101            }
102
103            @Override
104            protected void onPostExecute(Void result) {
105                file.setExecutable(true, false);
106                file.setWritable(true, false);
107                file.setReadable(true, false);
108
109                Intent intent = new Intent(Intent.ACTION_VIEW);
110                intent.setDataAndType(Uri.fromFile(file), "application/pdf");
111                intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
112                startActivity(intent, null);
113
114                if (printJob.isQueued()) {
115                    printJob.start();
116                }
117
118                PrintJobInfo info =  printJob.getInfo();
119
120                Toast.makeText(MyPrintService.this,
121                        "[STARTED] Printer: " + info.getPrinterId().getLocalId(),
122                        Toast.LENGTH_SHORT).show();
123
124                SystemClock.sleep(5000);
125
126                Toast.makeText(MyPrintService.this,
127                        "[COMPLETED] Printer: " + info.getPrinterId().getLocalId(),
128                        Toast.LENGTH_SHORT).show();
129
130                if (printJob.isStarted()) {
131                    printJob.complete();
132                }
133            }
134        };
135        task.executeOnExecutor(AsyncTask.SERIAL_EXECUTOR, (Void[]) null);
136    }
137
138    private void addFirstFakePrinter() {
139        PrinterId printerId = generatePrinterId("1");
140        PrinterInfo printer = new PrinterInfo.Builder(printerId, "Printer 1")
141                .setStatus(PrinterInfo.STATUS_READY)
142                .setMinMargins(new Margins(0, 0, 0, 0), new Margins(0, 0, 0, 0))
143                .addMediaSize(MediaSize.createMediaSize(getPackageManager(),
144                        MediaSize.ISO_A2), true)
145                .addMediaSize(MediaSize.createMediaSize(getPackageManager(),
146                        MediaSize.ISO_A3), false)
147                .addMediaSize(MediaSize.createMediaSize(getPackageManager(),
148                        MediaSize.ISO_A4), false)
149                .addMediaSize(MediaSize.createMediaSize(getPackageManager(),
150                        MediaSize.NA_LETTER), false)
151                .addResolution(new Resolution("R1", getString(
152                        R.string.resolution_600x600), 600, 600), true)
153                .addInputTray(new Tray("FirstInputTray", getString(
154                        R.string.input_tray_first)), false)
155                .addOutputTray(new Tray("FirstOutputTray", getString(
156                        R.string.output_tray_first)), false)
157                .setDuplexModes(PrintAttributes.DUPLEX_MODE_NONE
158                        | PrintAttributes.DUPLEX_MODE_LONG_EDGE
159                        | PrintAttributes.DUPLEX_MODE_SHORT_EDGE,
160                        PrintAttributes.DUPLEX_MODE_NONE)
161                .setColorModes(PrintAttributes.COLOR_MODE_COLOR
162                        | PrintAttributes.COLOR_MODE_MONOCHROME,
163                        PrintAttributes.COLOR_MODE_COLOR)
164                .setFittingModes(PrintAttributes.FITTING_MODE_NONE
165                        | PrintAttributes.FITTING_MODE_FIT_TO_PAGE,
166                        PrintAttributes.FITTING_MODE_NONE)
167                .setOrientations(PrintAttributes.ORIENTATION_PORTRAIT
168                        | PrintAttributes.ORIENTATION_LANDSCAPE,
169                        PrintAttributes.ORIENTATION_PORTRAIT)
170                .create();
171        List<PrinterInfo> printers = new ArrayList<PrinterInfo>();
172        printers.add(printer);
173        addDiscoveredPrinters(printers);
174    }
175
176    private void addSecondFakePrinter() {
177        PrinterId printerId = generatePrinterId("2");
178        PrinterInfo printer = new PrinterInfo.Builder(printerId, "Printer 2")
179                .setStatus(PrinterInfo.STATUS_READY)
180                .setMinMargins(new Margins(0, 0, 0, 0), new Margins(0, 0, 0, 0))
181                .addMediaSize(MediaSize.createMediaSize(getPackageManager(),
182                        MediaSize.ISO_A4), true)
183                .addMediaSize(MediaSize.createMediaSize(getPackageManager(),
184                        MediaSize.ISO_A5), false)
185                .addResolution(new Resolution("R1", getString(
186                        R.string.resolution_200x200), 200, 200), true)
187                .addResolution(new Resolution("R2", getString(
188                        R.string.resolution_300x300), 300, 300), false)
189                .addInputTray(new Tray("FirstInputTray", getString(
190                        R.string.input_tray_first)), false)
191                .addInputTray(new Tray("SecondInputTray", getString(
192                        R.string.input_tray_second)), true)
193                .addOutputTray(new Tray("FirstOutputTray", getString(
194                        R.string.output_tray_first)), false)
195                .addOutputTray(new Tray("SecondOutputTray",  getString(
196                        R.string.output_tray_second)), true)
197                .setDuplexModes(PrintAttributes.DUPLEX_MODE_NONE
198                        | PrintAttributes.DUPLEX_MODE_LONG_EDGE
199                        | PrintAttributes.DUPLEX_MODE_SHORT_EDGE,
200                        PrintAttributes.DUPLEX_MODE_SHORT_EDGE)
201                .setColorModes(PrintAttributes.COLOR_MODE_COLOR
202                        | PrintAttributes.COLOR_MODE_MONOCHROME,
203                        PrintAttributes.COLOR_MODE_MONOCHROME)
204                .setFittingModes(PrintAttributes.FITTING_MODE_FIT_TO_PAGE
205                        | PrintAttributes.FITTING_MODE_NONE,
206                        PrintAttributes.FITTING_MODE_FIT_TO_PAGE)
207                .setOrientations(PrintAttributes.ORIENTATION_PORTRAIT
208                        | PrintAttributes.ORIENTATION_LANDSCAPE,
209                        PrintAttributes.ORIENTATION_LANDSCAPE)
210                .create();
211        List<PrinterInfo> printers = new ArrayList<PrinterInfo>();
212        printers.add(printer);
213        addDiscoveredPrinters(printers);
214    }
215
216    private void cancellAddingFakePrinters() {
217        mHandler.removeMessages(MyHandler.MESSAGE_ADD_FIRST_FAKE_PRINTER);
218        mHandler.removeMessages(MyHandler.MESSAGE_ADD_FIRST_FAKE_PRINTER);
219    }
220
221    private final class MyHandler extends Handler {
222
223        public static final int MESSAGE_ADD_FIRST_FAKE_PRINTER = 1;
224        public static final int MESSAGE_ADD_SECOND_FAKE_PRINTER = 2;
225
226        public MyHandler(Looper looper) {
227            super(looper, null, true);
228        }
229
230        @Override
231        public void handleMessage(Message message) {
232            switch (message.what) {
233                case MESSAGE_ADD_FIRST_FAKE_PRINTER: {
234                    addFirstFakePrinter();
235                } break;
236                case MESSAGE_ADD_SECOND_FAKE_PRINTER: {
237                    addSecondFakePrinter();
238                } break;
239            }
240        }
241    }
242}
243