I'm creating an app for Android. Part of the desired app functionality is that the user can select a special printer (let's just call it Transfer Printer) which will pass on the document-to-be-printed to a process running on an external server.
*What steps do I need to take to add a custom printer to the list of printers in the Android print panel, accessible from the Print option of the Overflow menu?* It is desirable to use the existing Android print panel functionality rather than, for example, an additional Share option in the App Selector because of user experience considerations; it won't be intuitive to the user to click Share rather than Print for the desired functionality. I think the PrintService <http://developer.android.com/reference/android/printservice/PrintService.html> class is likely to prove fruitful: A print service is responsible for discovering printers, adding discovered > printers, removing added printers, and updating added printers. > The same page details Declaration and Configuration of the print service. I've tried this as shown below. *Declaration and Configuration* In AndroidManifest.xml: ... <application ... > ... <service android:name=".TransferPrintService" android:permission="android.permission.BIND_PRINT_SERVICE" android:enabled="true" android:exported="false"> <intent-filter> <action android:name="android.printservice.PrintService" /> </intent-filter> <meta-data android:name="android.printservice" android:resource="@xml/transfer_print_service" /> </service> </application> *Meta-data* It's unclear to me exactly where the meta-data is supposed to be specified. >From the SERVICE_META_DATA sectio <http://developer.android.com/reference/android/printservice/PrintService.html#SERVICE_META_DATA>n of the PrintService page on the Android Developer site: This meta-data must reference a XML resource containing a print-service tag. > I created a new document, res/xml/transfer_print_service.xml: <print-service android:label="TransferPrintService" android:vendor="Company Ltd." /> *TransferPrintService Class* This creates a custom PrinterDiscoverySession. My goal at this stage is to just get a printer appearing in the print panel and work from there. public class TransferPrintService extends PrintService { public TransferPrintService() { } @Override public void onPrintJobQueued(PrintJob printJob) { printJob.start(); printJob.complete(); } @Override public PrinterDiscoverySession onCreatePrinterDiscoverySession() { return new TransferPrinterDiscoverySession(this); } @Override public void onRequestCancelPrintJob(PrintJob printJob) { } } The service is started in a BroadcastReceiver on an ACTION_BOOT_COMPLETED intent. *TransferPrinterDiscoverySession Class* This actually creates the custom printer. public class TransferPrinterDiscoverySession extends PrinterDiscoverySession { private transferPrintService printService; private static final String PRINTER = "Transfer Printer"; public transferPrinterDiscoverySession(TransferPrintService printService) { this.printService = printService; } @Override public void onStartPrinterDiscovery(List<PrinterId> printerList) { PrinterId id = printService.generatePrinterId(PRINTER); PrinterInfo.Builder builder = new PrinterInfo.Builder(id, PRINTER, PrinterInfo.STATUS_IDLE); PrinterInfo info = builder.build(); List<PrinterInfo> infos = new ArrayList<>(); infos.add(info); addPrinters(infos); } @Override public void onStopPrinterDiscovery() { } @Override public void onValidatePrinters(List<PrinterId> printerIds) { } @Override public void onStartPrinterStateTracking(PrinterId printerId) { PrinterInfo.Builder builder = new PrinterInfo.Builder(printerId, PRINTER, PrinterInfo.STATUS_IDLE); PrinterCapabilitiesInfo.Builder capBuilder = new PrinterCapabilitiesInfo.Builder(printerId); capBuilder.addMediaSize(PrintAttributes.MediaSize.ISO_A4, true); capBuilder.addResolution(new PrintAttributes.Resolution( "Default", "Default", 360, 360), true); capBuilder.setColorModes(PrintAttributes.COLOR_MODE_COLOR + PrintAttributes.COLOR_MODE_MONOCHROME, PrintAttributes.COLOR_MODE_COLOR); capBuilder.setMinMargins(PrintAttributes.Margins.NO_MARGINS); PrinterCapabilitiesInfo caps = capBuilder.build(); builder.setCapabilities(caps); PrinterInfo info = builder.build(); List<PrinterInfo> infos = new ArrayList<PrinterInfo>(); infos.add(info); addPrinters(infos); } @Override public void onStopPrinterStateTracking(PrinterId printerId) { } @Override public void onDestroy() { } } *Concerns and Outstanding Questions* - This doesn't produce an additional printer option. - Is the arrangement of documents correct? Specifically, should I have the <printer-service> tag in a separate XML document under res, as I have done? Trying to place the tag elsewhere in the AndroidManifest.xml document produces IDE errors. - How do I call into the TransferPrintService? As an example, suppose I'm in Chrome, I open the Overflow menu, and select Print... Which PrintService is invoked? How do I make sure it's mine? - Am I on completely the wrong track here? -- You received this message because you are subscribed to the Google Groups "Android Developers" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. To post to this group, send email to [email protected]. Visit this group at https://groups.google.com/group/android-developers. To view this discussion on the web visit https://groups.google.com/d/msgid/android-developers/6599495c-ba92-43e0-a6fb-101b121515cc%40googlegroups.com. For more options, visit https://groups.google.com/d/optout.

