从okHttp保存时的空白PDF

时间:2017-02-20 21:51:17

标签: android pdf okhttp

我必须使用来自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?

1 个答案:

答案 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();
}

看看是否有任何改变。