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

Android开发如何实现相册本地图片通过API接口上传并获取返回结果

问题原因
  • 你当前调用的是Azure自定义视觉的公网URL图片预测接口,要求传入的url参数必须是公网服务器可以直接访问的HTTP/HTTPS链接,你从相册Uri拿到的URILOCATION是手机本地的文件路径,第三方服务器根本无法访问,所以会报无效URL错误。
  • Uri.getPath()无法拿到有效文件路径:Android 4.4之后系统相册返回的是content://开头的Uri,直接调用getPath()得到的是类似/media/123的相对路径,既不能直接读取也不能作为公网URL使用。
解决方案:用multipart/form-data提交本地图片

既然目标API支持multipart/form-data格式提交,直接改用自定义视觉的本地文件预测接口即可,不需要额外把图片上传到公网存储,修改步骤如下:

步骤1:替换请求接口地址

把原接口URL末尾的/url改为/image,这是Azure自定义视觉专门用来提交本地图片二进制数据的专用接口。

步骤2:从相册Uri读取图片流

通过系统ContentResolver直接读取Uri对应的图片输入流,不需要获取真实文件路径,完美适配Android分区存储规则。

步骤3:替换原有JSON请求体为Multipart格式

修改后的完整可运行代码如下:

// 设置选中的图片到预览控件
Uri selectedImage = data.getData();
imageView.setImageURI(selectedImage);

HttpClient httpclient = HttpClients.createDefault();
try
{
    // 替换为本地文件预测接口
    URIBuilder builder = new URIBuilder("https://eastus.api.cognitive.microsoft.com/customvision/v3.0/Prediction/aaead50a-95cd-403c-a3c2-9b774399e43b/classify/iterations/Iteration6/image");
    URI uri = builder.build();
    HttpPost request = new HttpPost(uri);
    request.setHeader("Prediction-key", predictionApiKey);
    // 不需要手动设置Content-Type,Multipart实体会自动生成带boundary的请求头

    // 从相册Uri获取图片输入流
    ContentResolver resolver = getContentResolver();
    InputStream inputStream = resolver.openInputStream(selectedImage);

    // 构建Multipart请求体
    MultipartEntityBuilder multipartBuilder = MultipartEntityBuilder.create();
    multipartBuilder.addBinaryBody("image", inputStream, ContentType.DEFAULT_BINARY, "upload.jpg");
    HttpEntity reqEntity = multipartBuilder.build();
    request.setEntity(reqEntity);

    HttpResponse response = httpclient.execute(request);
    HttpEntity entity = response.getEntity();

    if (entity != null)
    {
        String result = EntityUtils.toString(entity);
        System.out.println(result);
        // 此处自行处理返回的预测结果
    }
    // 关闭输入流避免内存泄漏
    if (inputStream != null) {
        inputStream.close();
    }
} catch (IOException e) {
    e.printStackTrace();
}

注意事项

  • 提前申请存储权限:Android 12及以下需要申请READ_EXTERNAL_STORAGE权限,Android 13及以上需要申请READ_MEDIA_IMAGES权限,targetSdkVersion >= 23时需要做动态权限申请,不能仅在AndroidManifest中静态声明。
  • 如果编译时找不到MultipartEntityBuilder类,需要在模块build.gradle的依赖中添加implementation 'org.apache.httpcomponents:httpmime:4.5.13'。
  • Apache HttpClient在Android 6.0之后已被官方移除,长期维护的项目推荐改用OkHttp实现网络请求,兼容性更好。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 20:18:01