在Android上使用Google Cloud Print API

我正在开发一个需要打印到打印机的android应用程序。 我决定使用Google云打印,因为它似乎很容易设置。 最初,我遵循这里find的步骤来集成到Android。 这将起作用,因为它会打印到我想要​​的打印机。 但是,这个过程对用户来说有点涉及。 就我而言,过程如下:

  1. 用户select一些信息旁边显示的打印button。
  2. 显示一个对话框,预览将要打印的内容。 在ActionBar中有一个button,显示“打印”。 这开始了这个过程。
  3. 显示一个新的“活动”,显示连接到该用户Google帐户的打印机列表。 用户必须select一个。
  4. 显示一个新页面,给出打印作业的描述。
  5. 用户必须select右上angular的“打印”。
  6. 打印作业已启动,打印机将打印出图片。

不幸的是,我的客户不想要这个过程。 他们希望用户在步骤二中点击“打印”,然后打印图片(步骤1,2和6)。 因此,我不能使用Google提供的Intent,我必须使用实际的API。 这要求我获得一个Google Auth令牌,获得所需的打印机,并以这种方式提交打印作业。 我做了以下几点:

  1. 使用Google Play服务为用户Gmail帐户检索OAuth令牌。
  2. 获取使用/ search API调用的打印机列表。
  3. 使用/提交API调用提交打印作业。

我有前两个完成。 我只是遇到了图片的实际打印问题。 而不是打印图片,图片的字节数据正在打印(Base64编码)。 以下是我如何发送请求的一些代码:

ContentResolver contentResolver = context.getContentResolver(); try { InputStream is = contentResolver.openInputStream(uri); ByteArrayOutputStream baos = new ByteArrayOutputStream(); byte[] buffer = new byte[4096]; int n = is.read(buffer); while (n >= 0) { baos.write(buffer, 0, n); n = is.read(buffer); } is.close(); baos.flush(); content = Base64.encodeToString(baos.toByteArray(), Base64.DEFAULT); } catch (FileNotFoundException e) { Log.d(TAG, "File not found: " + uri.toString(), e); } catch (IOException e) { e.printStackTrace(); } 

此代码检索图片(variables“uri”是该文件的URI),并将其转换为Base64编码的string。 这与Google云打印页面上提供的PrintDialogActivity中使用的方法相同(链接到上面)。 以下是我如何发送:

  • url: http : //www.google.com/cloudprint/submit? access_token=[ AUTH_TOKEN_GOES_HERE]& cookies = false& printerid=[PRINTER_ID_HERE]
  • HTTP方法:POST
  • POST参数:[printerId = PRINTER_ID_HERE,title = TestPrint,contentType = image / jpeg,capabilities = {“capabilities”:[{}]},content = [Base64编码数据string放在这里]]

据我所知,这是应该的。 打印时,我收到{“success”:true}的回复。 但是,正如我上面所说,它打印出实际的Base64数据string。 任何帮助,将不胜感激。

编辑:使用什么powerje下面说,我设法解决这个问题。 而不是使用上面的代码,我使用了以下内容:

 public void submitPrintJobWithFile(String printerId, String title, String token, String filePath, String contentType){ File file = new File(filePath); // Method that gets the correct headers List<Header> headers = getHeaders(contentType, token); // Method that gets the correct post parameters String url = CLOUDPRINT_URL + PATH_SUBMIT; List<NameValuePair> postParams = getParams(title, contentType); String params = "access_token=" + token + "&cookies=false" + "&printerid=" + printerId; url += params; response = sendMultipartData(url, file, postParams, headers); } private String sendMultipartData(String url, File file, List<NameValuePair> fields, List<Header> headers){ HttpPost post = new HttpPost(url); MultipartEntity entity = new MultipartEntity(); for(NameValuePair pair : fields){ String name = pair.getName(); String value = pair.getValue(); try{ entity.addPart(name, new StringBody(value)); }catch (UnsupportedEncodingException e){ Log.d(TAG, "Error turning pair (name=" + name + ", value=" + value + ") into StringBody."); } entity.addPart("content", new FileBody(file)); post.setEntity(entity); // Finish HttpClient request here... } 

Solutions Collecting From Web of "在Android上使用Google Cloud Print API"

看起来你需要使用多部分编码,例如:

http://blog.tacticalnuclearstrike.com/2010/01/using-multipartentity-in-android-applications/

FTA:

需要的文件是apache-mime4j , httpclient,httpcore和httpmime 。 所有这些都是Apache基金会build立的开源项目。

下载4个文件,并将它们添加到您的项目,那么你应该能够使用下面的代码来发布string和文件到页面。

 HttpClient httpclient = new DefaultHttpClient(); HttpPost httppost = new HttpPost("http://www.tumblr.com/api/write"); try { MultipartEntity entity = new MultipartEntity(); entity.addPart("type", new StringBody("photo")); entity.addPart("data", new FileBody(image)); httppost.setEntity(entity); HttpResponse response = httpclient.execute(httppost); } catch (ClientProtocolException e) { } catch (IOException e) { } 

在这种情况下的图像variables是一个文件,其中包含手机上的相机拍摄的图像。

查看Python示例代码 SubmitJob方法,似乎只有PDFtypes需要在Base64中进行编码。

用一点更新来回答这个问题。 截至2013年10月,在4.4和支持库中,内置了处理打印的方法。 请参阅以下文档以了解如何正确执行此操作:

  • PrintHelper – 支持Library类来帮助打印位图。
  • DevBytes:Android 4.4打印API – 详细介绍这些API的Android开发者video
  • 打印内容 – 关于如何使用这些API的Android培训指南。