Я работаю над приложением для Android, которое нужно печатать на принтере. Я решил использовать Виртуальный принтер Google, так как он был легко настроен. Первоначально я выполнил шаги, найденные здесь для интеграции в Android. Это работает, так как в нем будет печататься на моем желаемом принтере. Однако этот процесс немного зависит от пользователя. В моем случае процесс выглядит следующим образом:
- Пользователь выбирает кнопку печати, которую я отобразил рядом с некоторой информацией.
- Диалог показан с предварительным просмотром распечатки. В ActionBar есть кнопка с надписью "Печать" . Это начинает процесс.
- Отображается новое действие, показывающее список принтеров, которые подключены к этой учетной записи Google. Пользователь должен выбрать один.
- Отображается новая страница с описанием задания на печать.
- Пользователь должен выбрать "Печать" в правом верхнем углу.
- Запускается задание на печать, и принтер распечатывает изображение.
К сожалению, мой клиент не хочет этого процесса. Они хотят, чтобы пользователь нажимал "Печать" на втором шаге, а затем печатал изображение (шаги 1, 2 и 6). Таким образом, я не могу использовать Intent, предоставляемые Google, я должен использовать фактический API. Это требует от меня получения токена Google Auth, получения требуемого принтера и отправки задания печати таким образом. Я делаю следующее:
- Используйте Службы Google Play для извлечения токена OAuth для учетной записи пользователя Gmail.
- Получить список принтеров с помощью вызова /search API.
- Отправьте задание на печать с помощью вызова API/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. Это тот же метод, который используется в PrintDialogActivity, который указан на странице Виртуального принтера Google (связанный с выше). Ниже приводится способ отправки этого сообщения:
- 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, capability = { "возможности": [{}]}, content = [Base64 Кодированная строка данных размещена здесь]]
Насколько я могу судить, так оно и должно быть. При печати вы получаете ответ { "success": true}. Но, как я сказал выше, он печатает фактическую строку данных Base64. Любая помощь будет оценена по достоинству.
РЕДАКТИРОВАТЬ: Используя то, что сказано ниже, я смог это исправить. Вместо использования вышеприведенного кода я использовал следующее:
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...
}