问题
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