Wednesday, October 19, 2011

Setting up a Cloud Print Printer using the Cloud-X API

The Cloud-X Java API makes it easy to set up a Google Cloud Print aware printer. In the latest API version Cloud Print push notifications are supported.


The below sample code shows the registration of a new printer (if not already present) and how to listen to push notifications.
For the sake of simplicity this is straight forward code, so there might be cleaner ways to do is ;)

Here is the sample code with comments:

/*
  * Process print job
  */
 public static void processJobs(CloudPrintConnection gcp, Printer printer) {
  try {
   List<Job> jobs = gcp.fetch(printer);
   if (jobs != null) {
    for (Job job : jobs) {
     System.out.println("Processing job " + job.getId() + " ("
       + job.getTitle() + ")");
     gcp.deletJob(job);
    }
   }
  } catch (Exception e) {
   e.printStackTrace();
  }
 }

 public static void main(String[] args) {
  try {
   String printProxy = "testprinter-" + NetworkUtil.getMacAddress();

   /*
    * Our printer
    */
   final Printer printer = new Printer();
   printer.setProxy(printProxy);
   printer.setName("Test Printer");
   printer.setStatus("Online");

   final CloudPrintConnection gcp = new CloudPrintConnection();
   gcp.connect(username, password, "cloudprint",
     "Cloud Print Test Client", null);

   /*
    * Register printer if not already present
    */
   List<Printer> printers = gcp.list(printProxy);
   if (printers.size() == 0) {
    System.out.println("Registering Printer with Proxy "
      + printProxy);
    gcp.register(printer, null);
   } else {
    printer.setId(printers.get(0).getId());
   }

   /*
    * Refetch all printer info
    */
   gcp.printer(printer);

   System.out.println("Printer Name: " + printer.getName());
   System.out.println("Printer ID: " + printer.getId());
   System.out.println("---------------------------------------------");

   processJobs(gcp, printer);

   /*
    * Wait for push notifications
    */
   PushReceiver pr = new PushReceiver("Cloud-X API - Push Receiver");
   pr.addListener(new PushListener() {

    @Override
    public void onReceive(String printerId) {
     if (printerId.equals(printer.getId())) {
      processJobs(gcp, printer);
     }
    }

    @Override
    public void onConnect() {
      System.out.println("Connected to Google Talk!");
    }

    @Override
    public void onDisconnect() {
      // Do nothing
    }
   });

   pr.connectPlain(username, password);

  } catch (Exception e) {
   e.printStackTrace();
  }

 }

21 comments:

  1. Some API writers are expected to generate UML (Unified Modeling Language) diagrams as well. That's why advanced knowledge of such diagramming and flowcharting tools as MS Visio comes in handy.

    apis jobs

    ReplyDelete
  2. I tried your library in Android, the methods connect and search work fine, but submit method fail :
    java.lang.NoClassDefFoundError: de.fun2code.google.cloudprint.CountingFileBody at de.fun2code.google.cloudprint.CloudPrintConnection.submit(CloudPrintConnection.java:1036)

    Can you help me?

    Thanks.

    ReplyDelete
    Replies
    1. I'll check. May take a while...

      Delete
    2. Just tried with the current gcp.jar, worked fine with a JRE.
      I re-checked and the class CountingFileBody is included in that jar file.
      Do you have the latest gcp.jar?

      Delete
  3. yes, i have the latest gcp.jar, and i saw the CountingFileBody.class is included in the jar file.
    I don't know what's happend...

    ReplyDelete
    Replies
    1. If you like, you can send me your code by mail: jochen [at] fun2code.de

      Delete
    2. Thanks, now it work fine.

      Delete
    3. Hi ,
      I am facing the same error-
      java.lang.NoClassDefFoundError: de.fun2code.google.cloudprint.CountingFileBody at de.fun2code.google.cloudprint.CloudPrintConnection.submit(CloudPrintConnection.java:1036)

      Could you please mention Anonymous, about how you fixed it ?


      Delete
    4. Try to put the following Apache jars to your build path:
      httpclient
      httpcore
      httpmime

      Delete
  4. Hi, I was able to print by putting all the Apache jars in the libs folder (including the non-relevant ones. However, your comment helped me in discarding those). Thanks

    Now, I have another question -
    Using -
    gcp.connect(username, password, "cloudprint",
    "Cloud Print Test Client", null); printing works.
    However, I also tried using -
    gcp.connect(oauthToken, null);
    Earlier it worked for multiple times that I tried calling this API.
    But gcp.search() returns me null printers in the list although there are printers available for the avccount I am using.

    ReplyDelete
    Replies
    1. Modifying this line----
      But NOW gcp.search() returns me null printers in the list although there are printers available for the avccount I am using. The same call earlier gave me the list of printers.

      Delete
    2. Did you try this?
      gcp.search(null, "ALL");

      Delete
    3. Hi, yes I tried with the same method. The problem was the SCOPE that I had used for obtaining token was scope=https://www.googleapis.com/auth/cloudprint as it was mentioned in https://developers.google.com/cloud-print/docs/devguide. It gave me the token but not the one expected by search API of this jar. When I changed the scope to "cloudprint" I got the right token as now it lists all the printers registered to the account.

      Also, I have a question,are there any known issues of using this jar. So far it worked fine for me. But if the jar is to be used for commercial purpose, will it be reliable in providing print feature.

      Delete
    4. I haven't tested this in a production environment, so I can't tell.
      But I would guess that it's quite stable.

      Delete
  5. Alright thanx for the response :)

    ReplyDelete
  6. Hi Jochen , the build that included print feature worked very fine for the production environment too...however , when thhe code obfuscation step was carried out , some warnings were found that did not let us obfuscate the code ... httpclient, httpcore , httpmime these jars that we included for print feature are also build in android ...so there seems to be conflict while obfuscation.....

    -dontwarn org.apache.http.commons.** such type of line were added in proguard file .. it stopped giving warning & produced obfuscated apk ... but the communication failed to the our server because it required android's httpclient & somehow obfuscation takes http class from jar included & ignores android's httpclient ... (my assumption)

    Pease guide me if you have any solution or if you know any links related . Just this obfuscation step & then no further problem !

    ReplyDelete
    Replies
    1. Hi,
      I've uploaded the sources to Google Drive.
      You can pick them up here: https://drive.google.com/file/d/0B8T86cdxxvu-N04xZ2FST2N1azA/edit?usp=sharing

      Hope that helps...

      Delete
  7. Hi Jochen,
    Thanks a lot. We have included the source code you provided and deleted the httpclient, httpcore jars from the libs folder. Now the classes from the package - de.fun2code.google.cloudprint refers to httpclient, httpcore that are already present in android system libraries, hence there is no conflicting issue while obfuscating the build . Only httpmime jar is referred externally as it has additional classes that are not present in android libs.
    Now, the obfuscated build with print feature works as desired. Thanks a ton Jochen !!! :)

    ReplyDelete
  8. Hello can i get that jar file. I searched everywhere but did not find any where.

    ReplyDelete
    Replies
    1. Here is the link to the JAR: https://goo.gl/0oNaAP
      But it's no longer working properly, Google has changed the API.

      Delete