Friday, September 12, 2014

Dropbox Print Service Tutorial on Android 4.4

yagi showed a nice tutorial for how to use Android 4.4 Kitkat Print Framework by a Dropbox PrintService

PrintService


PrintServices are plug-in components that know how to talk to printers via some standard protocols. These services serve as a bridge between the system and the printers. Hence, the printer and print protocol specific implementation is factored out of the system and can be independently developed and updated. 

In other wordPrintService is a service that performs the detection of the printer, the processing of the print job. Addition to the role, such as a driver for the network printer, it can also be implemented as a service to be output to any location as a PDF file.



Add and configure PrintService


When you install an application that contains the implementation of PrintService, service will be added to the Printing screen of Settings. The user can launch the settings screen you can switch the On / Off of PrintService each, each PrintService provides.


Execution flow of PrintService


PrintService works with PrintManager managed by the system.


  1. PrintManager to display the Print dialog
  2. (Call of onCreatePrinterDiscoverySession method) that is required to start the session detection of printer from the system
  3. Return an instance of the class PrinterDiscoverySession
  4. Add a printer, delete, or update in PrinterDiscoverySession class
  5. User selects a printer and settings, then printing starts
  6. PrintJob is passed to the method onPrintJobQueued
  7. Printing process based on the information of PrintJob
 Of these flows, PrintService will be implemented in processing of 3, 4, and 5.


PrintService Implementation


PrintService is an abstract class that inherits from the Service. There are three abstract methods.

?
One
Two
Three
Four
Five
Six
Seven
Eight
Nine
Ten
Eleven
Twelve
13
14
Fifteen
Sixteen
17
Eighteen
19
public class SamplePrintService extends PrintService {
  Override
  protected PrinterDiscoverySession OenushiaruieitePrinterDiscoverySession () {
    // I return a search session objects for printer
    Return null ;
  }
  Override
  protected void OnPrintJobQueued (PrintJob ParamPrintJob) {
    // I to the printing process
  }
  Override
  protected void OnRequestCancelPrintJob (PrintJob ParamPrintJob) {
    // Cancel request
  }
}

onCreatePrinterDiscoverySession ()


When the system starts the detection of printer, onCreatePrinterDiscoverySession method of PrintService is called. There is a need to return an instance of PrinterDiscoverySession is PrintService side at this time.  During the detection of the printer, PrinterDiscoverySession is a class that encapsulates the interaction between the system PrintService. Each callback method of PrinterDiscoverySession class will be called, and printer can be added, updated, and deleted.

ItemCommentary
void onStartPrinterDiscovery (List printers)It starts the detection of the printer. Printer information is already discovered. It adds and updates printers in addPrinters method. It deletes printers in removePrinters method.
void onStopPrinterDiscovery ()Callback notifying you that you should stop printer discovery.
void onStartPrinterStateTracking (PrinterId printerId)A callback that asks the user to start tracking of the status of the printer. It is called when the printer is selected in the Print dialog. You must notify the system as soon as possible when the state of the printer has changed
void onStopPrinterStateTracking (PrinterId printerId)A callback to notify that the tracking of the status of the printer is finished.
void onValidatePrinters (List printerIds)A callback to seek validation list of PrinterId passed as if it were a valid. There is a need to update the printer information in addPrinters method if it is valid
void onDestroy ()It will be called when this session is determined to be unnecessary from the system


In the following section, an implementation example of PrinterDiscoverySession is showed with DropboxPrintService. It does not do anything except that you are adding a printer in onStartPrinterDiscovery method. PrinterInfo.Builder is created for printer information. You can specify printable paper size, color settings, such as resolution. if you pass a list of PrinterInfo in addPrinters method, printer information is displayed in the print dialog box. Create a PrinterInfo in onStartPrinterDiscovery within the method, it calls addPrinters method, but the detection is performed printer to start the thread normally, it will be able to add the printer information using the Handler, etc. .
?
One
Two
Three
Four
Five
Six
Seven
Eight
Nine
Ten
Eleven
Twelve
13
14
Fifteen
Sixteen
17
Eighteen
19
Twenty
21
22
23
24
25
26
27
28
29
Thirty
31
32
33
34
35
36
37
38
39
Forty
41
42
43
44
45
46
47
48
49
Fifty
51
52
53
54
55
56
57
58
59
Sixty
61
62
63
64
65
66
67
68
69
70
71
72
public class DiaruopibioxPrinterDiscoverySession
  extends PrinterDiscoverySession {
  Private Final Static String TAG =
    . DiaruopibioxPrinterDiscoverySession class .GetSimpleName ();
  Private Final Static String PRINTER_ID = "Dropbox.Print.Service" ;
  Private PrintService MPrintService;
  public DiaruopibioxPrinterDiscoverySession (PrintService PrintServie) {
    mPrintService = printServie;
  }
  Override
  public void OnStartPrinterDiscovery (List printers) {
    Log.D (TAG, "OnStartPrinterDiscovery ()" );
    for (PrinterID id: printers) {
      Log.D (TAG, "PrinterID:" + Id.GetLocalId ());
    }
    List AddPrinters = NEW ArrayList ();
    PrinterId printerId = mPrintService.generatePrinterId (PRINTER_ID);
    PrinterInfo.Builder Builder = NEW PrinterInfo.Builder (PrinterID,
        "Dropbox Printer" , PrinterInfo.STATUS_IDLE);
    PrinterCapabilitiesInfo.Builder capBuilder =
      NEW PrinterCapabilitiesInfo.Builder (PrinterID);
    CapBuilder.AddMediaSize (PrintAttributes.MediaSize.ISO_A4, true );
    CapBuilder.AddMediaSize (PrintAttributes.MediaSize.ISO_B5, false );
    CapBuilder.AddResolution ( NEW PrintAttributes.Resolution (
        "Default" , "default Resolution" , 600 , 600 ), true );
    capBuilder.setColorModes (PrintAttributes.COLOR_MODE_COLOR
        | PrintAttributes.COLOR_MODE_MONOCHROME,
        PrintAttributes.COLOR_MODE_COLOR);
    builder.setCapabilities (capBuilder.build ());
    addPrinters.add (builder.build ());
    addPrinters (addPrinters);
  }
  Override
  public void OnStopPrinterDiscovery () {
    Log.D (TAG, "OnStopPrinterDiscovery ()" );
  }
  Override
  public void OnValidatePrinters (List PrinterIds) {
    Log.D (TAG, "OnValidatePrinters ()" );
    for (PrinterID id: PrinterIds) {
      Log.D (TAG, "PrinterID:" + Id.GetLocalId ());
    }
  }
  Override
  public void OenuStartPrinterStateTracking (PrinterID PrinterID) {
    Log.d (TAG,
        "OnStartPrinterStateTracking (printerId:"
            PrinterId.GetLocalId + () + ")" );
  }
  Override
  public void OnStopPrinterStateTracking (PrinterID PrinterID) {
    Log.d (TAG,
        "OnStopPrinterStateTracking (printerId:"
            PrinterId.GetLocalId + () + ")" );
  }
  Override
  public void onDestroy () {
    Log.D (TAG, "onDestroy ()" );
  }
}

onPrintJobQueued (PrintJob paramPrintJob)


When a printer is detected, the printing starts, PrintJob is passed to onPrintJobQueued method. Other printer ID, ​​and FileDescriptor color information and print size, to a PDF file is included in the PrintJob. This is done using the FileDescriptor is taken out of print data. PrintJob will have a status start, finished, failed, and canceled. Should be set in accordance with the state of printing. The following is an example to save and retrieve the PDF from PrintJob. You have done all the work on onPrintJobQueued method, but will be using the AsyncTask, etc. usually. However, operation of PrintJob must be done on the UI thread. FileDescriptor of PDF data is similar. If you want to send to the network on the PDF data, you will need to use the AsyncTask on which the file was created, etc. time. 

?
One
Two
Three
Four
Five
Six
Seven
Eight
Nine
Ten
Eleven
Twelve
13
14
Fifteen
Sixteen
17
Eighteen
19
Twenty
21
22
23
24
25
26
27
28
29
Thirty
31
32
33
34
Override
protected void OnPrintJobQueued ( Final PrintJob PRINTJOB) {
  printJob.start ();
  File tmp = NEW File (GetExternalCacheDir (), PrintJob.GetDocument ()
      . .getInfo () getName ());
  FileOutputStream fos = null ;
  FileInputStream FIN = null ;
  TRY {
    fos = NEW FileOutputStream (tmp);
    FIN = NEW FileInputStream (PrintJob.GetDocument ()
        . .getData () getFileDescriptor ());
    int c;
    byte [] bytes = NEW byte [ 1024 ];
    while ((c = Fin.Read (bytes)) = -! 1 ) {
      Fos.Write (bytes, 0 , c);
    }
    fos.close ();
    fin.close ();
  } catch (Exception e) {
    e.printStackTrace ();
    printJob.fail (e.getMessage ());
    Return ;
  } finally {
    if (fos =! null ) { TRY {Fos.Close ();} catch (Exception e) {}}
    if (FIN =! null ) { TRY {Fin.Close ();} catch (Exception e) {}}
  }
  printJob.complete ();
}

PrintJob so are queued automatically PrintService, you do not need to be the handling of the queue on your own again.PrintJob active can be retrieved in getActivePrintJobs method.

onRequestCancelPrintJob (PrintJob paramPrintJob)


onRequestCancelPrintJob method is called when the user cancels the print job. PrintJob are passed, you need to stop the process corresponding. You can also check in isCancelled method of PrintJob class 

?
One
Two
Three
Four
Five
Six
Seven
Eight
Nine
Ten
protected void OnPostExecute (PrintStatus result) {
    if (PrintJob.IsCancelled ()) {
        I toast ( "has been canceled" );
    } else if (Result.IsError ()) {
        printJob.fail (result.getMessage ());
    } else {
        printJob.complete ();
    }
    toast (result.getMessage ());
};

AndroidManifest.xml


Add PrintService to AndroidManifest.xml
?
One
Two
Three
Four
Five
Six
Seven
  Android: name = "App.Package.Name..YourPrintService"
  Android: permission = "Android.Permission.BIND_PRINT_SERVICE" >
  
    "Andraoid.Printservice.PrintService" />
  </ Intent-filter>
</ Service>

Setting Screen


In many cases, you will need to PrintService settings to connect to the printer over a network. Alternatively, you can configure the metadata when you define a PrintService in AndroidManifest.xml. 
?
One
Two
Three
Four
  Android: description = "@ string / description"
  Android: SettingsActivity = "App.Package.Name.YourSettingActivity" />

You can specify the metadata of AndroidManifest.xml the XML file that you create and define Activity of the setting screen.
?
One
Two
Three
Four
Five
Six
Seven
Eight
Nine
Ten
Eleven
Twelve
13
14
Fifteen
Sixteen
17
Eighteen
19
  Android: name = "App.Package.Name.YourPrintService"
  Android: permission = "Android.Permission.BIND_PRINT_SERVICE" >
  
    "Andraoid.Printservice.PrintService" />
  </ Intent-filter>
  
    Android: name = "Android.Printservice"
    Android: resource = "@ xml / Your_printservice" >
  </ Meta-data>
</ Service>
  Android: name = "App.Package.Name.YourSettingActivity"
  Android: exported = "true"
  Android: Label = "@ string / Title_activity_setting"
  Android: permission = "Android.Permission.BIND_PRINT_SERVICE" >
</ Activity>

DropboxPrintService

  • Source is here → DropboxPrintService
    • It does not include an API key towards the source, be sure to get the API key in Dropbox If you want to use it to build from source.
  • apk here → DropboxPrintService.Apk


Log in to the Dropbox


When you have made ​​all of your installed the DropboxPrintService, first log in to the Dropbox. Select the DropboxPrintService in Printing screen of Settings, turn ON the DropboxPrintService open the detail screen. Please log in to Dropbox so open the setting screen from the bottom menu. 





Print


PDF is uploaded to Dropbox





1 comment:

Sriharsha byloor said...

Thank you this blog was really usefull.
i have a question can we disable options in screen such as number of copies, range and others because while uploading number of copies is not useful. if this option is available please help me with this.

Thanks in advance

Followers

About Me

My photo
HD Multimedia Technology player