我必须使用来自http响应的字节来保存pdf文件。
如果文件很小(大约数百个字节,小于1k),一切都还可以,但是如果文件太大,我看到(通过Intent使用另一个应用程序)所有页面都是白色的(页面数量是正确的)。
我将文档保存在外部存储中并将uri传递给intent。
这是我从服务器获取文件并将其保存到外部存储的代码:
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);
更新 我试图使用代理来拦截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?
答案 0 :(得分:1)
我不确定究竟是什么导致了您的问题,但您可以尝试使用Okio API简化代码。
BufferedSource source = response.body().source();
Sink out = Okio.sink(outputFile);
try {
while (!source.exhausted()) {
Buffer buffer = source.buffer();
out.write(buffer, buffer.size());
}
} finally {
out.close();
}
看看是否有任何改变。