【问题标题】:Download POST method's PDF response using retrofit 2使用改造 2 下载 POST 方法的 PDF 响应
【发布时间】:2018-06-05 00:37:05
【问题描述】:

我是使用改造的 android 和 JSON 的新手。我在我的项目中使用改造 2。 这是 post API 之一,它提供一个 pdf 作为响应。

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

我使用下面的代码来执行此功能,我坚持使用响应方法来下载并显示该 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) {

                    }
            });
        }

下面的链接是我从 Postman 那里得到的回复:

click here

writeResponseBodyToDisk() 函数:

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

有人,请帮忙解决一下。这可能包含错误因为我是新手。谢谢。

【问题讨论】:

  • 您能展示一下响应正文的样子吗?我还认为您必须定义自己的响应类型Call&lt;MyResponseType&gt;
  • 您正在授予运行时权限?
  • @ABDevelopers ,我给了外部权限
  • 添加您的 writeResponseBodyToDisk 代码以及您的响应。
  • 我用你的需要更新了我的问题,@ABDevelopers

标签: android rest api retrofit2 httpresponse


【解决方案1】:

您的 API 使用 form-data 作为输入,因此将 @Body 更改为 @Multipart 类型。这会给你一个回应。在onResponse()里面的sn-p下面添加

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

我想这会对你有所帮助。

【讨论】:

    【解决方案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) {
    
           }
        }
    

    只需从方法 writeResponseBodyToDisk 获取文件名:

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

    只需调试并检查您的文件名是否正确。

    【讨论】:

    • 此解决方案提供了一个正文为空的文件。我可以将response 转换为该pdf。
    • 检查来自服务器的响应数据并发布您的 response.body 日志并检查文件名是否正确。如果服务器数据正确,则此代码应该可以工作'
    猜你喜欢
    • 1970-01-01
    • 2017-08-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-02-18
    • 1970-01-01
    • 1970-01-01
    • 2019-01-02
    相关资源
    最近更新 更多