如何将ResponseBody(在我的例子中为PDF)写入外部存储? java.lang.IllegalStateException 问题:已关闭

问题描述 投票:0回答:2

我想将 ResponseBody 写入外部存储(下载文件夹)。直到一周前,一切都运行良好,然后我需要更新 okhttp3 版本,现在当我运行我的应用程序时,发生了以下情况之一:

这是我的改造:

HttpLoggingInterceptor logging = new HttpLoggingInterceptor();
    logging.setLevel(HttpLoggingInterceptor.Level.BODY);
    OkHttpClient client = new OkHttpClient.Builder()
            .addInterceptor(logging)
            .connectTimeout(2, TimeUnit.MINUTES)
            .writeTimeout(2, TimeUnit.MINUTES)
            .readTimeout(2, TimeUnit.MINUTES)
            .build();


    Retrofit retrofit = new Retrofit.Builder()
            .baseUrl(link)
            .addConverterFactory(ScalarsConverterFactory.create())
            .addConverterFactory(create())
            .client(client)
            .build();

这是我将 ResponseBody 写入 ES 的函数:

private boolean writeResponseBodyToDisk(ResponseBody body) {
    File dir = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS), "test.pdf");
    try {
        InputStream fis = body.byteStream();
        long length = body.bytes().length;
        byte[] bytes = new byte[(int) length];
        int offset = 0;
        int numRead = 0;
        while (offset < bytes.length && (numRead = fis.read(bytes, offset, bytes.length - offset)) >= 0) {
            offset += numRead;
        }

        OutputStream op = new FileOutputStream(dir);
        op.write(bytes);
    } catch (Exception ex) {
        Toast.makeText(MainActivity.this, ex.getMessage().toString(), Toast.LENGTH_LONG);
    }
    return true;
}

当我这样放置这部分时:

long length = body.bytes().length;

我得到这个例外:

java.lang.IllegalStateException:已关闭

但是当我离开它时就像版本更新之前一样:

long length = body.contentLength();

然后什么也没有发生。这种方式一直工作得很好,直到我更新了 okhttp3 的版本。

我知道我不能将第一个选项与 bytes.length 一起使用,但我不知道有什么其他选择。

android retrofit okhttp
2个回答
1
投票

只需更改输出流的初始化

    OutputStream op;

    if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q){

        ContentValues values = new ContentValues();
        values.put(MediaStore.Files.FileColumns.DISPLAY_NAME,"test.pdf");
        values.put(MediaStore.Files.FileColumns.MIME_TYPE,"application/pdf");
        values.put(MediaStore.Files.FileColumns.RELATIVE_PATH,Environment.DIRECTORY_DOWNLOADS);


        Uri fileUri = getContentResolver().insert(
                MediaStore.Files.getContentUri("external"),
                values
        );

        try {
            op = getContentResolver().openOutputStream(fileUri);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }

    }else{
        File dir = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS), "test.pdf");
        try {
            op = new FileOutputStream(dir);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
    }

    try {
        InputStream fis = body.byteStream();
        long length = body.bytes().length;
        byte[] bytes = new byte[(int) length];
        int offset = 0;
        int numRead = 0;
        while (offset < bytes.length && (numRead = fis.read(bytes, offset, bytes.length - offset)) >= 0) {
            offset += numRead;
        }
        
        op.write(bytes);
    } catch (Exception ex) {
        Toast.makeText(MainActivity.this, ex.getMessage().toString(), Toast.LENGTH_LONG);
    }

0
投票

如何处理下载文件夹中已存在文件(来自其他应用程序)并且我们希望文件具有相同名称的情况。这是Q以上自动交的但是Q以下这种情况怎么处理

© www.soinside.com 2019 - 2024. All rights reserved.