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