Hi, I'm Nazmul Idris, a developer advocate
on the Android team, and welcome to this episode of DevBytes.
In today's episode, we're going to cover the new printing
API that was released with KitKat, AKA Android 4.4.
Android 4.4 introduces native platform support for printing,
along with APIs for managing printing and adding
new types of printer support.
The platform provides a print manager
that mediates between applications requesting
printing and installed print services that
actually do the printing.
The print manager provides shared services
and a system user interface for printing, giving users
consistent control over printing from any application.
The print manager also ensures the security of content
as it passes across processes from an application
to a print service.
Most devices running Android 4.4 will
include Google Cloud Print pre-installed
as a print service out of the box,
as well as several Google Apps that
support printing, including Chrome, Drive, Gallery,
and Quickoffice.
So what is this printing API?
Well, the print API allows app developers
to write applications that can print
any type of content to printers that could be connected
over Wi-Fi or Bluetooth, or any other kind of printing service,
for example, Google Cloud Print.
It also allows printer OEMs to generate print services
and distribute them as APKs on the Play Store
so that their printers will plug seamlessly into the framework,
so that users can print their documents
to any connected printer.
The system handles a transaction between an application that
wants to print a document and the services that
deliver print jobs to an actual printer.
The print framework provides all the APIs
necessary to specify a print document
and deliver it to the system for printing.
As an app developer, which APIs you actually
need for a given print job depends on the type of content
that you actually want to print.
For example, are they images, HTML, or a PDF canvas?
In print-enabled applications, users
can discover available printers, change paper sizes,
choose specific pages to print, and print
almost any kind of document, image, or file.
Print services are pluggable components
that contain vendor-specific logic, services, and so on.
These are managed by the system and are
responsible for discovering printers, interacting
with them, and reporting their state about what's
going on with the print jobs.
As a printer OEM, you can use the print service framework
to provide interoperability with your printers
from Android devices.
And this is really important.
You can build and distribute these services
as APKS, which users can install on their devices.
And they can be updated over the air via the Play Store, which
is pretty awesome.
A print service application operates primarily
as a headless service by subclassing the print service
class, which receives print jobs from the system
and communicates it to printers using
the appropriate protocols.
The print services will get printed content as a PDF file
and may apply whatever transformations
they need to make to the data so that it's optimal for printing.
And print services have to implement APIs
for being queried by the printers that they manage.
So now, from an application developer perspective,
I will show you how to use the print
API to quickly print content.
So for the broadest compatibility,
Android uses PDF as its primary file format for printing.
Before printing, your application
needs to generate a properly paginated PDF
version of your content.
And for your convenience, we actually
have helper classes that allow you to very quickly print
WebViews and also pretty quickly create PDF documents as
well-- actually, PDF output.
So if your application knows how to draw the content,
it can quickly create a PDF for printing.
Now if you want to print a bitmap,
it's actually very easy to do this.
With very little code, you can print out images.
And the only one option you have to think about
is whether you want the printed output to scale
to fit or scale to fill the actual printed page.
So what's the difference?
Scale to fit makes sure that your bitmap
fits within the maximum dimensions of the printed
output page.
So with a square bitmap on a rectangular page,
it actually results in white space on the top
and the bottom of the page, as you can see in this example.
Scale to fill, on the other hand,
makes sure that your bitmap is scaled to fill as much
of the printed output page as possible.
And this might mean that some portions of the image
are not actually printed because they exceeded
the bounds of the printed page, again,
as you can see in the example.
So here's some code that shows you
how easy it is to actually do this.
So again, the only option that you really
need to be mindful of is what parameter
to pass the getScaleMode method.
So once the printBitmap method is called,
no further action from your app is required.
The Android modal dialogue box for printing
appears and allows the user to select the printer and whatever
print options they want.
The user can then print the image or cancel the action.
If they choose to print the image,
then a print job is created, and a printing notification
appears in the system bar.
Now let's say you wanted to print some HTML content.
So here's some code that will show you how to do that.
The first thing you do is you can generate some HTML,
put it in a string, then load that in a WebView,
and finally, attach a WebView client to the WebView
so that once the content is actually loaded,
you can submit the print job to the print services.
So if you want to include graphics in your HTML content,
just place them in the assets directory for a project
and specify the path to this folder as a parameter
to the loadDataWithBaseURL method instead of passing null,
as we did in this example.
You can also load an actual web page
for printing just by replacing loadDataWithBase method
call with load URL.
And this is very convenient if you actually have HTML content
that you've generated on the server side.
Now there are a few limitations of using HTML printing.
And one is you cannot add headers or footers,
and this includes page numbers.
Also, the user can't specify print ranges.
So for example, you can't print page two to four
of a 10-page HTML document.
And also, an instance of WebView can only
process one print job at a time.
And finally, WebView printing from JavaScript
is not yet supported.
For example, window.print JavaScript call will not work.
We are planning to address these limitations in future releases.
And please feel free to open Android open source
bugs for features that you feel are important that
are missing or changes that you want to see,
because this feedback is very valuable to us.
So finally, there is a PdfDocument class
which allows you to very quickly generate PDF content
using the platform drawing APIs.
So this new PDF document API offers a convenient way
for you do this by getting a canvas object by calling
the getCanvas method on PdfDocument.
Once you have the canvas, you can draw your printable content
on it using the standard graphics APIs on Android.
And when you're done drawing your content,
you simply submit the document to the printing sub-system,
and it'll just sprint.
So finally, this DevByte has been a quick overview
of all that's available.
If you want more information, we actually
have a training guide called "Printing a Document"
on developers.android.com.
Thank you for joining us today.
Take care.