Pracuję nad aplikacją na Androida, która musi drukować na drukarce. Zdecydowałem się na korzystanie z Google Cloud Print, ponieważ wydawało się łatwe do skonfigurowania. Początkowo postępowałem zgodnie z instrukcjami znalezionymi pod here dla integracji z Androidem. To działa tak, jak w przypadku drukowania do wybranej drukarki. Jednak proces ten jest nieco skomplikowany dla użytkownika. W moim przypadku proces wygląda następująco:Używanie interfejsu Google Cloud Print z Androidem
- Użytkownik wybiera przycisk drukowania, który został wyświetlony obok niektórych informacji.
- Zostanie wyświetlone okno dialogowe z podglądem tego, co zostanie wydrukowane. W pasku akcji znajduje się przycisk z napisem "Drukuj". To rozpoczyna proces.
- Wyświetlane jest nowe działanie z listą drukarek podłączonych do konta Google tego użytkownika. Użytkownik musi wybrać jeden.
- Zostanie wyświetlona nowa strona z opisem zadania drukowania.
- Użytkownik musi wybrać "Drukuj" w prawym górnym rogu.
- Zadanie drukowania zostaje uruchomione, a drukarka wydrukuje zdjęcie.
Niestety, mój klient nie chce tego procesu. Chcą, aby użytkownik kliknął "Drukuj" w kroku drugim, a następnie wydrukował zdjęcie (kroki 1, 2 i 6). W związku z tym nie mogę korzystać z intencji dostarczonej przez Google, muszę korzystać z rzeczywistego interfejsu API. Wymaga to ode mnie uzyskania tokena uwierzytelniania Google, pobrania żądanej drukarki i przesłania zadania drukowania w ten sposób. Wykonuję następujące czynności:
- Skorzystaj z usług Google Play, aby pobrać token OAuth dla konta Gmail użytkownika.
- Uzyskaj listę drukarek za pomocą wywołania funkcji API/search.
- Prześlij zadanie drukowania za pomocą wywołania funkcji API/submit.
Mam pierwsze dwa wykończone. Mam problem z faktycznym drukowaniem obrazu. Zamiast drukować obraz, drukowane są bajtowe dane obrazu (zakodowane w Base64). Oto kod, jak Ja was posyłam się wniosek:
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();
}
Ten kod pobiera plik (zmienna „uri” jest URI tego pliku) i zamienia ją w Base64 zakodowany ciąg. Jest to ta sama metoda, którą użyto w narzędziu PrintDialogActivity, dostępnym na stronie Google Cloud Print (z powyższymi linkami). Poniżej jak wyślę że up:
- URL: http://www.google.com/cloudprint/submit?access_token=[AUTH_TOKEN_GOES_HERE]&cookies=false&printerid=[PRINTER_ID_HERE]
- Metoda HTTP: POST
- POST parametry: [printerId = PRINTER_ID_HERE, title = TestPrint, contenttype = image/jpeg, możliwości = {” Możliwości ": [{}]}, zawartość = [Base64 Zakodowany ciąg danych jest umieszczony tutaj]]
O ile wiem, tak właśnie powinno być. Otrzymuję odpowiedź {"success": true} podczas drukowania. Ale, jak wspomniałem powyżej, wypisuje rzeczywisty ciąg danych Base64. Każda pomoc będzie doceniona.
EDYCJA: Używając tego, co powiedziałem poniżej, udało mi się to naprawić.Zamiast używać powyższy kod, użyłem następujących czynności:
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...
}
Czy możesz podać kilka próbek swojej pracy na temat pierwszych dwóch kroków? – Skiba
Chcę zrobić to samo, ale bez kroku 3 Chcę wyświetlić drukarki, które są podłączone do tej samej sieci lokalnej i obsługują wyszukiwanie drukarki za pomocą jego adresu IP. –
Witaj @ ariets może udostępnić krok u, którego należy przestrzegać, aby wypełnić 1 & 2 – SaravanaRaja