2013-01-22 64 views
18

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

  1. 用户选择我已经显示的打印按钮旁边的某些信息。
  2. 显示一个对话框,其中会显示要打印的内容。在ActionBar中有一个按钮,显示“打印”。这开始了这个过程。
  3. 显示一个新的活动,显示连接到该用户Google帐户的打印机列表。用户必须选择一个。
  4. 显示一个新页面,给出打印作业的说明。
  5. 用户必须在右上角选择“打印”。
  6. 打印作业已启动并且打印机打印出图片。

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

  1. 使用Google Play服务为用户Gmail帐户检索OAuth令牌。
  2. 获取使用/ search API调用的打印机列表。
  3. 使用/ submit 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(); 
} 

此代码检索图片(变量“URI”是该文件的URI),并把它变成一个Base64编码的字符串。这与在Google云打印页面上提供的PrintDialogActivity中使用的方法相同(链接到上面)。以下是我如何发送了起来:

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

编辑:使用下面说的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... 
} 
+0

您能否提供一些关于处理前两步的工作样本? – Skiba

+0

我想这样做,但没有第3步 我想显示连接到同一本地网络的打印机,并支持使用其IP地址搜索打印机 –

+0

你好@ariets可以分享你完成1和2的步骤ü然后 – SaravanaRaja

回答

2

它看起来像你需要使用多编码,例如这里:

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

FTA:

需要的文件为apache-mime4jhttpclient, httpcore and httpmime。全部都是由Apache基金会建立的开源项目。

下载4个文件并将它们添加到您的项目中,那么您应该可以使用以下代码将字符串和文件发布到页面。

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) { 
} 

在这种情况下的图像变量是一个包含由手机上的照相机拍摄的图像文件。

+1

这确实有效。谢谢。 – ariets

1

望着Python Sample Code SubmitJob方法似乎只有PDF typs需要为Base64编码的。

+0

啊,你说得对。不知道我是如何错过的。我会给这个镜头。 – ariets

+0

只是要注意,这并不适合我。 – ariets

0

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

相关问题