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