プリンターに印刷する必要のあるAndroidアプリケーションに取り組んでいます。設定が簡単だったので、Googleクラウドプリントを使うことにしました。最初は、Androidに統合するためにここにある手順に従いました。これは、目的のプリンターに印刷されるため、機能します。ただし、このプロセスはユーザーにとって少し複雑です。私の場合、プロセスは次のとおりです。
- ユーザーは、いくつかの情報の横に表示した印刷ボタンを選択します。
- 印刷される内容のプレビューを含むダイアログが表示されます。アクションバーには「印刷」というボタンがあります。これでプロセスが始まります。
- そのユーザーのGoogleアカウントに接続されているプリンターのリストを示す新しいアクティビティが表示されます。ユーザーは1つを選択する必要があります。
- 印刷ジョブの説明を示す新しいページが表示されます。
- ユーザーは右上隅にある[印刷]を選択する必要があります。
- 印刷ジョブが開始され、プリンターが画像を印刷します。
残念ながら、私のクライアントはこのプロセスを望んでいません。ユーザーがステップ2で[印刷]をクリックしてから、画像を印刷するようにします(ステップ1、2、6)。したがって、Googleが提供するインテントを使用することはできません。実際のAPIを使用する必要があります。これには、Google Authトークンを取得し、目的のプリンターを取得して、その方法で印刷ジョブを送信する必要があります。私は次のことをします:
- Google Playサービスを使用して、ユーザーのGmailアカウントのOAuthトークンを取得します。
- /searchAPI呼び出しを使用してプリンターのリストを取得します。
- /submitAPI呼び出しを使用して印刷ジョブを送信します。
最初の2つは終了しました。写真の実際の印刷に問題があります。画像を印刷する代わりに、画像のバイトデータが印刷されます(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で使用されているのと同じ方法です。以下は私がそれを送る方法です:
- 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エンコードされたデータ文字列はここに配置されます]]
私の知る限り、これが本来あるべき姿です。印刷時に{"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...
}