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

Android Studio中向GraphQL服务器上传图片的方法及报错排查

Android GraphQL 文件上传:解决 ENOENT 错误

问题原因

从图库获取的 content:// 类型 Uri 并非直接对应本地文件路径,uri.toFile() 无法正确解析这类 Uri;再加上 Android 10+ 的分区存储限制,直接转换 File 必然触发“文件不存在”的错误。

解决方案

跳过 Uri 转 File 的步骤,直接通过 ContentResolver 获取文件流,用 DefaultUpload 构建上传对象——这是适配 Android 存储机制的正确方式。

实现代码

import android.content.ContentResolver
import android.net.Uri
import okio.buffer
import okio.source
import com.apollographql.apollo3.api.DefaultUpload

// 从 Uri 构建 GraphQL Upload 对象
fun buildGraphQLUpload(contentResolver: ContentResolver, uri: Uri): DefaultUpload {
    // 获取文件名,从 ContentResolver 查询或使用默认值
    val fileName = queryFileName(contentResolver, uri) ?: "uploaded_image.jpg"
    // 获取文件 MIME 类型,默认用 image/jpeg
    val mimeType = contentResolver.getType(uri) ?: "image/jpeg"

    return DefaultUpload.Builder()
        .fileName(fileName)
        .contentType(mimeType)
        .content { sink ->
            contentResolver.openInputStream(uri)?.use { inputStream ->
                inputStream.source().buffer().use { source ->
                    sink.writeAll(source)
                }
            } ?: error("无法打开文件输入流")
        }
        .build()
}

// 辅助方法:从 ContentResolver 查询文件名
private fun queryFileName(contentResolver: ContentResolver, uri: Uri): String? {
    contentResolver.query(uri, null, null, null, null)?.use { cursor ->
        if (cursor.moveToFirst()) {
            val nameColumnIndex = cursor.getColumnIndex("_display_name")
            if (nameColumnIndex != -1) {
                return cursor.getString(nameColumnIndex)
            }
        }
    }
    return null
}

使用方式

在图片选择回调中拿到 Uri 后,调用上述方法生成 DefaultUpload 对象,直接传入 GraphQL 请求的变量中即可。

注意事项

  • Android 10 及以下需申请 READ_EXTERNAL_STORAGE 权限;Android 11+ 通过系统图库选择图片时,无需额外申请权限。
  • 确保处理权限请求逻辑,避免因权限缺失导致无法访问 Uri。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 04:06:13