Mikeysadleir Mikeysadleir - 4 months ago 116
Java Question

Submit a PDF print job to google cloudprint in android using the URL API

Im having trouble getting the correct code to send submit a multipart form with a PDF included to google cloud print( the reason I'm not using the inbuilt intent in android is that you cant automatically select a printer it need to be done manually when using the intent)

I have been using Volley to submit it but I have been reading its not great with large files?

final RequestQueue queue = Volley1.getInstance(this).getRequestQueue();
String url3 = "https://www.google.com/cloudprint/submit";
final VolleyMultipartRequest multipartRequest = new VolleyMultipartRequest(Request.Method.POST, url3 ,new Response.Listener<NetworkResponse>() {

@Override
public void onResponse(NetworkResponse response) {
String resultResponse = new String(response.data);
Log.d("responseis",resultResponse);
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
error.printStackTrace();
}
}){
@Override
protected Map<String, String> getParams() {

Map<String, String> params = new HashMap<>();
// the POST parameters:
params.put("redirect_uri", "xxxxx");
params.put("printerid","xxxxxx");
params.put("title", "result1.pdf");
params.put("contentType", "application/pdf");
params.put("ticket", "{\"print\":{},\"version\":\"1.0\"}");
params.put("hl", "en");
return params;
}
@Override
public Map getHeaders() throws AuthFailureError {
Map headers = new HashMap();
headers.put("Authorization", "OAuth"+" "+res);
headers.put("Content-Type", "multipart/form-data; boundary=__1466595844361__");
//headers.put("Content-Type","application/x-www-form-urlencoded");
//Logger.debugE(Constants.accesstoken, headers.toString());
return headers;
}
@Override
protected Map<String, DataPart> getByteData() {
Map<String, DataPart> params = new HashMap<>();
//String yourFilePath = Environment.getExternalStorageDirectory().getAbsolutePath()+ "/PDFs/result1.pdf";
String yourFilePath=Environment.getExternalStorageDirectory().getAbsolutePath()+ "/PDFs/result1.pdf";
File dir = new File(Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_DOWNLOADS), "PDF_reader");

File text = new File(dir + File.separator + "test_r.pdf");
String input = text.getAbsolutePath();
byte[] data = new byte[(int) input.length()];
try {
//convert file into array of bytes
data = FileUtils.readFileToByteArray(text);

}catch(Exception e){
e.printStackTrace();
}

params.put("content", new DataPart("result1.pdf",data , "application/pdf"));
return params;
}
};
queue.add(multipartrequest);

Answer

After a lot of trial and error I ended up using OKHTTP library and that allows you to encode the parameters with the url and I was successfully able to submit a print job to google cloud print using the API. It was tricky to the multipart form with the pdf file included, the correct request is below.

public void run() throws Exception {

//File directory
File dir = Environment.getExternalStorageDirectory();
File file = new File(dir, "PDFs/result1.pdf");
if(file.canRead()){
    Log.d("file", "can read");
}else {Log.d("file","cant read");};


// Final request body
RequestBody requestBody = new MultipartBody.Builder()
        .setType(MultipartBody.FORM)
        .addFormDataPart("content","result1.pdf",RequestBody.create(MediaType.parse("application/pdf"), file))
        .build();

//URL Parameters
HttpUrl url = new HttpUrl.Builder()
        .scheme("https")
        .host("www.google.com")
        .addPathSegments("cloudprint/submit")
        .addQueryParameter("printerid", "82d70sde-694b-3385-f263-164cb04320c3")
        .build();

Request request = new Request.Builder()
        .header("Authorization", "OAuth ya29.Cl0jAxDuQni_Dskz6Y2r-wRaJVMxEw8fy5hPNfAm02pDLnZc9HX-RfHpmMoS0OL-Wv_SKxBtYIwRK9jVpJDwl7Qs-RFt02Qc5Yoid4w1kV8b4vBIpcleIQ8lBEto")
        .url(url)
        .post(requestBody)
        .build();

client.newCall(request)
        .enqueue(new Callback() {
            @Override
            public void onFailure(final Call call, IOException e) {
                // Error

                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        // For the example, you can show an error dialog or a toast
                        // on the main UI thread
                    }
                });
            }

            @Override
            public void onResponse(Call call, final Response response) throws IOException {
                String res = response.body().string();

                // Do something with the response
            }
        });
}