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

如何在Android Java中执行指定的curl图片上传命令?

在Android中用Java实现指定curl上传请求的方案

完全可以在Android中用Java实现你在CMD中执行的curl上传操作,以下是具体实现方案:

先解析curl请求的核心参数

你执行的curl命令本质是一个带Basic认证的Multipart表单上传请求,核心参数如下:

  • 认证信息:用户名on,密码on
  • 上传地址:https://fr.openfoodfacts.org/cgi/product_image_upload.pl
  • 表单字段:
    • imgupload_front:要上传的图片文件
    • code:8411916819976
    • imagefield:front
    • user_id:id
    • password:pass

推荐实现方式:使用OkHttp库

OkHttp是Android开发中常用的网络请求库,比原生HttpURLConnection更简洁易用,以下是完整实现步骤:

1. 添加OkHttp依赖

在Module级别的build.gradle(或build.gradle.kts)中添加依赖:

implementation("com.squareup.okhttp3:okhttp:4.12.0")

2. 编写上传代码

注意:Android禁止在主线程执行网络请求,所以必须在子线程中处理上传逻辑;同时要确保文件路径正确、权限已配置。

场景1:Android 10以下,直接访问文件路径

如果你的应用目标API低于29,可以直接通过文件路径获取文件对象:

// 获取公共DCIM/Screenshots目录下的a.jpg
File screenshotFile = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM), "Screenshots/a.jpg");

// 在子线程执行上传
new Thread(() -> {
    OkHttpClient client = new OkHttpClient();

    // 构建Multipart表单
    MultipartBody body = new MultipartBody.Builder()
            .setType(MultipartBody.FORM)
            // 添加图片文件字段
            .addFormDataPart("imgupload_front", "a.jpg",
                    RequestBody.create(screenshotFile, MediaType.parse("image/jpeg")))
            // 添加其他表单参数
            .addFormDataPart("code", "8411916819976")
            .addFormDataPart("imagefield", "front")
            .addFormDataPart("user_id", "id")
            .addFormDataPart("password", "pass")
            .build();

    // 构建请求并添加Basic认证
    Request request = new Request.Builder()
            .url("https://fr.openfoodfacts.org/cgi/product_image_upload.pl")
            .header("Authorization", Credentials.basic("on", "on"))
            .post(body)
            .build();

    try (Response response = client.newCall(request).execute()) {
        // 回到主线程处理结果
        runOnUiThread(() -> {
            if (response.isSuccessful()) {
                Toast.makeText(MainActivity.this, "上传成功", Toast.LENGTH_SHORT).show();
            } else {
                Toast.makeText(MainActivity.this, "上传失败,状态码:" + response.code(), Toast.LENGTH_SHORT).show();
            }
        });
    } catch (IOException e) {
        e.printStackTrace();
        runOnUiThread(() -> {
            Toast.makeText(MainActivity.this, "网络错误:" + e.getMessage(), Toast.LENGTH_SHORT).show();
        });
    }
}).start();

场景2:Android 10及以上,通过MediaStore访问文件

Android 10+限制了直接访问公共存储的文件路径,需要通过MediaStore获取文件Uri,再通过流上传:

// 先通过MediaStore查询获取图片Uri
Uri imageUri = null;
String[] projection = {MediaStore.Images.Media._ID};
String selection = MediaStore.Images.Media.DISPLAY_NAME + " = ?";
String[] selectionArgs = {"a.jpg"};
Cursor cursor = getContentResolver().query(
        MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
        projection,
        selection,
        selectionArgs,
        null
);

if (cursor != null && cursor.moveToFirst()) {
    long imageId = cursor.getLong(cursor.getColumnIndexOrThrow(MediaStore.Images.Media._ID));
    imageUri = ContentUris.withAppendedId(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, imageId);
    cursor.close();
}

// 确保获取到Uri后再执行上传
if (imageUri != null) {
    new Thread(() -> {
        OkHttpClient client = new OkHttpClient();
        try (InputStream inputStream = getContentResolver().openInputStream(imageUri)) {
            // 通过文件流构建RequestBody
            RequestBody fileBody = RequestBody.create(inputStream, MediaType.parse("image/jpeg"));

            MultipartBody body = new MultipartBody.Builder()
                    .setType(MultipartBody.FORM)
                    .addFormDataPart("imgupload_front", "a.jpg", fileBody)
                    .addFormDataPart("code", "8411916819976")
                    .addFormDataPart("imagefield", "front")
                    .addFormDataPart("user_id", "id")
                    .addFormDataPart("password", "pass")
                    .build();

            Request request = new Request.Builder()
                    .url("https://fr.openfoodfacts.org/cgi/product_image_upload.pl")
                    .header("Authorization", Credentials.basic("on", "on"))
                    .post(body)
                    .build();

            try (Response response = client.newCall(request).execute()) {
                runOnUiThread(() -> {
                    if (response.isSuccessful()) {
                        Toast.makeText(MainActivity.this, "上传成功", Toast.LENGTH_SHORT).show();
                    } else {
                        Toast.makeText(MainActivity.this, "上传失败,状态码:" + response.code(), Toast.LENGTH_SHORT).show();
                    }
                });
            }
        } catch (IOException e) {
            e.printStackTrace();
            runOnUiThread(() -> {
                Toast.makeText(MainActivity.this, "文件读取/网络错误:" + e.getMessage(), Toast.LENGTH_SHORT).show();
            });
        }
    }).start();
} else {
    Toast.makeText(this, "未找到目标图片", Toast.LENGTH_SHORT).show();
}

关键注意事项

  • 权限处理:除了在AndroidManifest.xml中声明READ_EXTERNAL_STORAGE、INTERNET权限,Android 6.0及以上还需要动态申请READ_EXTERNAL_STORAGE权限;Android 11+若需访问公共存储,可能需要申请MANAGE_EXTERNAL_STORAGE权限(或使用MediaStore方式避免该权限)。
  • 文件存在性检查:上传前要确认目标图片文件存在,否则会抛出FileNotFoundException。
  • 线程处理:必须在子线程执行网络请求,处理结果时通过runOnUiThread回到主线程更新UI。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 21:55:19