You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android 11/API 30调用openOutputStream生成0字节空白图片原因排查

问题根因分析
  • 核心原因:未写入实际的媒体资源数据
    你当前的代码仅在MediaStore中创建了一个空的媒体条目,打开输出流后没有将从服务器下载得到的图片/视频二进制数据写入流中,直接执行了flush和close操作,最终生成的自然是0字节的空白文件。
  • 缺少Android 10+必填的媒体状态标记
    API 29及以上系统要求,插入MediaStore的媒体文件在写入过程中需要标记IS_PENDING状态为1,表示文件尚未就绪,全部数据写入完成后再将该状态更新为0,通知系统媒体库完成扫描,否则就算写入了数据也可能出现相册无法识别、文件状态异常的问题。
  • 异常处理逻辑不完善
    当前代码仅捕获异常打印堆栈,没有做错误兜底判断,如果输出流打开失败、写入失败等异常发生时,上层逻辑无法感知故障,也会表现为生成的文件异常。
修复参考代码

你需要将下载得到的媒体字节数据作为参数传入该方法,补充写入逻辑和状态标记,示例如下:

// 新增byte[] resource参数传入下载好的媒体二进制数据
private Uri mediaStoreInsert(String fileName, String mimeType, String directoryPath, byte[] resource){
    Log.d(TAG, "mediaStoreInsert: Values = "+fileName+" "+directoryPath+" "+mimeType);
    if (resource == null || resource.length == 0) {
        Log.e(TAG, "媒体资源数据为空,插入失败");
        return null;
    }
    ContentResolver resolver = MyApplication.getmContext().getContentResolver();
    ContentValues contentValues = new ContentValues();
    contentValues.put(MediaStore.MediaColumns.DISPLAY_NAME, fileName);
    contentValues.put(MediaStore.MediaColumns.MIME_TYPE, mimeType);
    contentValues.put(MediaStore.MediaColumns.RELATIVE_PATH,Environment.DIRECTORY_PICTURES+"/"+directoryPath);
    // 标记文件处于待写入状态
    contentValues.put(MediaStore.MediaColumns.IS_PENDING, 1);
    Uri mediaStore;
    if (mimeType.equals(imageType)){
       mediaStore = MediaStore.Images.Media.getContentUri(MediaStore.VOLUME_EXTERNAL_PRIMARY);
    }else {
       mediaStore = MediaStore.Video.Media.getContentUri(MediaStore.VOLUME_EXTERNAL_PRIMARY);
    }
    Uri uri = resolver.insert(mediaStore, contentValues);
    if (uri == null) {
        Log.e(TAG, "MediaStore插入条目失败");
        return null;
    }
    Log.d(TAG, "mediaStoreInssert: URI Check = "+uri);
    try (OutputStream outputStream = resolver.openOutputStream(uri)) {
        // 写入下载得到的媒体数据
        outputStream.write(resource);
    } catch (IOException e) {
        e.printStackTrace();
        // 写入失败删除无效的空条目
        resolver.delete(uri, null, null);
        return null;
    }
    // 写入完成,更新状态为可用
    contentValues.clear();
    contentValues.put(MediaStore.MediaColumns.IS_PENDING, 0);
    resolver.update(uri, contentValues, null, null);
    return uri;
}

内容的提问来源于stack exchange,提问作者Ritu

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.03 08:57:01