android - 在 Android 中使用 Google Cloud Print API

标签 android printing google-cloud-print

我正在开发一个需要打印到打印机的 android 应用程序。我决定使用谷歌云打印,因为它看起来很容易设置。最初,我按照找到的步骤 here用于集成到 Android 中。这有效,因为它将打印到我想要​​的打印机。但是,这个过程对用户来说有点复杂。就我而言,过程如下:

  1. 用户选择了我在某些信息旁边显示的打印按钮。
  2. 会显示一个对话框,其中包含将要打印的内容的预览。 ActionBar 中有一个按钮,上面写着“打印”。这开始了这个过程。
  3. 将显示一个新的 Activity ,其中列出了连接到该用户 Google 帐户的打印机。用户必须选择一个。
  4. 显示一个新页面,提供打印作业的说明。
  5. 用户必须选择右上角的“打印”。
  6. 打印作业开始,打印机打印出图片。

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

  1. 使用 Google Play 服务检索用户 Gmail 帐户的 OAuth token 。
  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...
}

最佳答案

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

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

自由贸易协定:

The files needed are apache-mime4j, httpclient, httpcore and httpmime. All are opensource projects built by the Apache foundation.

Download the 4 files and add them to your project then you should be able to use the following code to post strings and files to pages.

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

The image variable in this case is a File that contains an image captured by the camera on the phone.

关于android - 在 Android 中使用 Google Cloud Print API,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14468266/

相关文章:

android - 在 Android Kotlin 中无法访问 dialog.getButton()

android - 如果android :interpolator is unspecified,默认插值器是什么

android - 即使targeSdkVersoin的版本与24相同,Gradle appcompat-v7也会出现错误?

java - 在发送到打印机之前,如何以编程方式实现普通 Windows 打印队列 'spool file' 的假脱机文件头的编辑?

javascript - 打印图像时无法读取数据 - GCP

node.js - 谷歌云打印 API : User credentials required

android - 升级 phonegap 本地数据库 android 应用程序会丢失旧数据吗?

html - A4 页面像 html 中的布局

printing - Lua 在文件读取之前不打印