2013-01-22 41 views
18

Tôi đang làm việc trên một ứng dụng Android cần in tới máy in. Tôi đã quyết định sử dụng Google Cloud Print vì có vẻ dễ thiết lập. Ban đầu, tôi làm theo các bước tìm thấy here để tích hợp vào Android. Điều này hoạt động, như trong nó sẽ in đến máy in mong muốn của tôi. Tuy nhiên, quá trình này là một chút liên quan đến người dùng. Trong trường hợp của tôi, quy trình như sau:Sử dụng API Google Cloud Print với Android

  1. Người dùng chọn nút in mà tôi đã hiển thị bên cạnh một số thông tin.
  2. Hộp thoại được hiển thị với bản xem trước nội dung sẽ được in. Có một nút trong ActionBar có nội dung "In". Điều này bắt đầu quá trình.
  3. Hoạt động mới được hiển thị hiển thị danh sách máy in được kết nối với tài khoản Google của người dùng đó. Người dùng phải chọn một.
  4. Trang mới được hiển thị cho mô tả công việc in.
  5. Người dùng phải chọn "In" ở góc trên bên phải.
  6. Lệnh in được bắt đầu và máy in in ra hình ảnh.

Thật không may, khách hàng của tôi không muốn quá trình này. Họ muốn người dùng nhấp vào "In" ở bước hai, sau đó in ảnh (bước 1, 2 và 6). Do đó, tôi không thể sử dụng Intent do Google cung cấp, tôi phải sử dụng API thực tế. Điều này yêu cầu tôi nhận mã thông báo Google Auth, nhận máy in mong muốn và gửi lệnh in theo cách đó. Tôi làm như sau:

  1. Sử dụng Dịch vụ của Google Play để truy xuất mã thông báo OAuth cho tài khoản Gmail của người dùng.
  2. Nhận danh sách máy in sử dụng lệnh gọi/tìm kiếm API.
  3. Gửi lệnh in bằng cách sử dụng lệnh gọi/gửi API.

Tôi có hai kết thúc đầu tiên. Tôi chỉ gặp rắc rối với việc in ảnh thực tế. Thay vì in ảnh, dữ liệu byte của ảnh đang được in (mã hóa Base64). Dưới đây là một số mã như thế nào Tôi gửi lên yêu cầu:

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(); 
} 

Mã này lấy hình ảnh (các "uri" biến là URI của tập tin đó), và biến nó thành một chuỗi Base64 mã hóa. Đây là phương pháp tương tự được sử dụng trong PrintDialogActivity được cung cấp trên trang Google Cloud Print (được liên kết đến ở trên). Sau đây là cách tôi gửi mà lên:

Theo tôi có thể nói, đây là cách nó được cho là vậy. Tôi nhận được phản hồi của {"success": true} khi in. Nhưng, như tôi đã nói ở trên, nó in ra chuỗi dữ liệu Base64 thực tế. Bất kỳ trợ giúp sẽ được đánh giá cao.

CHỈNH SỬA: Sử dụng powerje đã nói bên dưới, tôi đã khắc phục được điều này.Thay vì sử dụng đoạn mã trên, tôi đã sử dụng như sau:

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

Bạn có thể cung cấp một số mẫu về công việc của mình để xử lý hai bước đầu tiên không? – Skiba

+0

Tôi muốn thực hiện tương tự nhưng không cần bước 3 Tôi muốn hiển thị các máy in kết nối với cùng mạng cục bộ và hỗ trợ tìm kiếm máy in với địa chỉ IP của nó –

+0

Hello @ariets có thể chia sẻ bước u theo sau để hoàn thành 1 & 2 – SaravanaRaja

Trả lời

2

Có vẻ như bạn cần phải sử dụng mã hóa nhiều phần dữ liệu, ví dụ ở đây:

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

FTA:

Các tập tin cần thiết là apache-mime4j, httpclient, httpcore and httpmime. Tất cả đều là các dự án mã nguồn mở được xây dựng bởi nền tảng Apache.

Tải xuống 4 tệp và thêm chúng vào dự án của bạn, sau đó bạn sẽ có thể sử dụng mã sau để đăng chuỗi và tệp lên trang.

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

Biến hình ảnh trong trường hợp này là một tập tin có chứa một hình ảnh được chụp bằng camera trên điện thoại.

+1

Điều này đã làm trong thực tế công việc. Cảm ơn. – ariets

1

Nhìn vào phương pháp Python Sample Code SubmitJob có vẻ như rằng chỉ có typs PDF cần được mã hóa trong Base64.

+0

Ah, bạn nói đúng. Không chắc tôi đã bỏ lỡ điều đó như thế nào. Tôi sẽ cho một phát bắn. – ariets

+0

Chỉ cần lưu ý, điều đó không hiệu quả đối với tôi. – ariets

0

Trả lời câu hỏi bằng một chút cập nhật. Tính đến tháng 10 năm 2013, trong 4.4 và thư viện hỗ trợ, có sẵn các phương pháp để xử lý in. Xem tài liệu sau đây để làm thế nào để làm điều đó đúng:

Các vấn đề liên quan