Download POST method's PDF response using retrofit 2

时光毁灭记忆、已成空白 提交于 2021-02-08 06:46:34

问题


I am new to android and JSON using retrofit. I am using retrofit 2 with my project. This is one of post API and it gives a pdf as the response.

@POST("examples/campaign_report_new.php")
Call<ResponseBody> getAddressTrackingReport(@Body ModelCredentialsAddressTracking credentials);

I used the below code to do this function and I stuck in the response method to download and show that pdf.

private void downloadPdf() { 
ModelCredentialsAddressTracking
    credentials = new ModelCredentialsAddressTracking(campaign,
    dateFrom, dateTo);            
                ApiService apiService = RetroClient.getApiService();
                Call<ResponseBody> call = apiService.getAddressTrackingReport(credentials);            
                call.enqueue(new Callback<ResponseBody>() {
                    @Override
                    public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
                        try {
                            Log.d(TAG, String.valueOf(response.body().bytes()));
                        } catch (IOException e) {
                            e.printStackTrace();
                        }            
                        boolean writtenToDisk = writeResponseBodyToDisk(response.body());            
                    }            
                    @Override
                    public void onFailure(Call<ResponseBody> call, Throwable t) {

                    }
            });
        }

Below link is the response I got from Postman:

click here

writeResponseBodyToDisk() function :

private boolean writeResponseBodyToDisk(ResponseBody body) {
    try {
        File mediaStorageDir = new File(
                Environment
                        .getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES),
                "Door Tracker");

        // Create the storage directory if it does not exist
        if (!mediaStorageDir.exists()) {
            if (!mediaStorageDir.mkdirs()) {
                Log.d("door tracker", "Oops! Failed create "
                        + "door tracker" + " directory");
            }
        }

        // Create a media file name
        String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss",
                Locale.getDefault()).format(new Date());
        File mediaFile = new File(mediaStorageDir.getPath() + File.separator
                + "AddressTrackingReport "+ timeStamp + ".pdf");

        InputStream inputStream = null;
        OutputStream outputStream = null;

        try {
            byte[] fileReader = new byte[4096];

            long fileSize = body.contentLength();
            long fileSizeDownloaded = 0;

            inputStream = body.byteStream();
            outputStream = new FileOutputStream(mediaFile);

            while (true) {
                int read = inputStream.read(fileReader);

                if (read == -1) {
                    break;
                }

                outputStream.write(fileReader, 0, read);

                fileSizeDownloaded += read;

                Log.d(TAG, "file download: " + fileSizeDownloaded + " of " + fileSize);
            }

            outputStream.flush();

            return true;
        } catch (IOException e) {
            return false;
        } finally {
            if (inputStream != null) {
                inputStream.close();
            }

            if (outputStream != null) {
                outputStream.close();
            }
        }
    } catch (IOException e) {
        return false;
    }
}

Somebody, please help a solution. This may contain errors Because I am new to it.Thanks.


回答1:


Your API using form-data as input, So change @Body to @Multipart Type. This will give you a response. Add below snippet inside onResponse()

if (response.isSuccessful()) {

progressDialog.dismiss();

new AsyncTask<Void, Void, Void>() {
     boolean writtenToDisk = false;

        @Override
        protected Void doInBackground(Void... voids) {

            try {
                writtenToDisk = writeResponseBodyToDisk(AddressTrackingActivity.this,
                        response.body());
            } catch (IOException e) {
                Log.w(TAG, "Asynch Excep : ", e);
            }
            Log.d(TAG, "file download was a success? " + writtenToDisk);
            return null;
        }

        @Override
        protected void onPostExecute(Void aVoid) {
            super.onPostExecute(aVoid);
            if (writtenToDisk) {
                String pdfPath = Environment.getExternalStorageDirectory().toString()
                        + "/Door Tracker/" + fileName;
                Log.d(TAG, "file name : " + fileName);
                File file = new File(pdfPath);
                Uri bmpUri;
                if (Build.VERSION.SDK_INT < 24) {
                    bmpUri = Uri.fromFile(file);
                    Log.d(TAG, "bmpUri : " + bmpUri);
                } else {
                    bmpUri = FileProvider.getUriForFile(AddressTrackingActivity.this,
                            getApplicationContext().getPackageName() + ".provider", file);

                    Log.d(TAG, "bmpUri : " + bmpUri);
                }
                Intent intent = new Intent(Intent.ACTION_VIEW);
                intent.setDataAndType(bmpUri, "application/pdf");
                intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
                try {
                    startActivity(intent);
                } catch (ActivityNotFoundException e) {
                    Log.d(TAG, "ActivityNotFoundException : ", e);
                }
            }
        }
    }.execute();
} else {
    progressDialog.dismiss();
    Toast.makeText(AddressTrackingActivity.this, "Network error, Please retry", Toast.LENGTH_SHORT).show();
    Log.d(TAG, "server contact failed");
}

I think this will help you.




回答2:


String fileName = "";
boolean writtenToDisk = writeResponseBodyToDisk(response.body(),fileName);
    if(writtenToDisk){
     String pdfPath = Environment.getExternalStorageDirectory().toString() + "/Door Tracker/"+fileName;
     File file = new File(pdfPath);
     Uri bmpUri;
     if (Build.VERSION.SDK_INT < 24) {
         bmpUri = Uri.fromFile(file);
     } else {
          bmpUri = FileProvider.getUriForFile(this,getApplicationContext().getPackageName() + ".provider", file);
     }

      Intent intent = new Intent(Intent.ACTION_VIEW);
      intent.setDataAndType(bmpUri, "application/pdf");
      intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
      try {
              startActivity(intent);
      }
       catch (ActivityNotFoundException e) {

       }
    }

Just get the File Name from method writeResponseBodyToDisk :

 File mediaFile = new File(mediaStorageDir.getPath() + File.separator
                + "AddressTrackingReport "+ timeStamp + ".pdf");

 fileName = mediaFile.getName();

Just Debug and Check your file name is correct.



来源:https://stackoverflow.com/questions/47940121/download-post-methods-pdf-response-using-retrofit-2

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!