Мне нужно сохранить pdf-файл, используя байты из ответа HTTP.Пустой PDF при сохранении с okHttp
Если файл небольшой (около сотни байт, менее 1k), все в порядке, но если файл слишком велик, я видел (используя другое приложение через Intent) все страницы белого (количество страниц верное).
Я сохраняю документ во внешнем хранилище и передаю uri на намерение.
Это мой код, чтобы получить файл с сервера и сохранить его на внешнее устройство хранения:
public static Observable<Integer> getDocument(final String id, final String service, final String filename){
return Observable.create(new Observable.OnSubscribe<Integer>() {
@Override
public void call(Subscriber<? super Integer> subscriber) {
InputStream inputStream = null;
FileOutputStream outputStream = null;
OkHttpClient client = HypeHttpClientBuilder.getOkHttpClient(200); //timeout
RequestBody formBody = new FormEncodingBuilder()
.add("platform", HypeApplication.getDeviceType())
.add("function", service)
.add("pdfid",id)
.build();
Request requests = HttpRequestBuilder.getRequest(formBody);
try {
Response response = client.newCall(requests).execute();
inputStream = response.body().byteStream();
File dir = new File(Environment.getExternalStorageDirectory(),"Hype");
if (!dir.mkdirs()) {
Log.e(TAG, "Directory not created");
}
outputStream = new FileOutputStream(new File(dir, filename));
int totalCount = inputStream.available();
byte[] buffer = new byte[1024 * 1024];
int len;
int readLen = 0;
while ((len = inputStream.read(buffer)) != -1) {
//System.out.println("download loop " + Thread.currentThread().getName());
outputStream.write(buffer, 0, len);
readLen += len;
}
subscriber.onNext(readLen);
}catch (Exception e){
subscriber.onError(e);
}finally {
try {
if (inputStream != null) {
inputStream.close();
}
if (outputStream != null) {
outputStream.flush();
outputStream.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
subscriber.onCompleted();
}
});
}
и это код, чтобы начать другую деятельность:
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(FileProvider.getUriForFile(getActivity(),getActivity().getApplicationContext().getPackageName() + ".provider",f)
, "application/pdf");
intent.setFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
startActivity(intent);
UPDATE Я пытался используйте прокси-сервер для перехвата HTTP-вызова. Итак, я получил файл из прокси и файла, сгенерированного моим кодом, и я их сравнил: есть некоторые отличия.
Я получил простое решение, используя класс UrlConnection
.
URL url = new URL(URLSetting.getOldUrl());
HttpURLConnection conn = (HttpURLConnection)url.openConnection();
conn.setReadTimeout(10000);
conn.setConnectTimeout(15000);
conn.setRequestMethod("POST");
conn.setDoInput(true);
conn.setDoOutput(true);
conn.setRequestProperty("appversion","2.0.0");
conn.setRequestProperty("Content-Type",
"application/x-www-form-urlencoded");
Uri.Builder builder = new Uri.Builder()
.appendQueryParameter("platform", HypeApplication.getDeviceType())
.appendQueryParameter("function", service)
.appendQueryParameter("deviceid",HypeApplication.getDeviceId())
.appendQueryParameter("pdfid", id);
OutputStream os = conn.getOutputStream();
BufferedWriter writer = new BufferedWriter(
new OutputStreamWriter(os, "UTF-8"));
writer.write(builder.build().getEncodedQuery());
writer.flush();
writer.close();
os.close();
conn.connect();
inputStream = conn.getInputStream();
Итак, вы знаете, если okHttp установлен как кодировка по умолчанию UTF-8?
Я рекомендую 'getFD(). Sync()' между 'flush()' и 'close()' на вашем 'FileOutputStream'. Помимо этого, загрузите PDF с устройства и посмотрите, все ли в порядке. – CommonsWare
Нет. Я положил 'getFD.sync()', как вы сказали мне, но я продолжаю видеть белые страницы документа. – hooloovoo