当前位置:首页 > 行业动态 > 正文

安卓图片上传到服务器

安卓图片上传至服务器需用HTTP请求,选合适库如OkHttp,构造Multipart表单,设置文件参数,处理响应与异常

安卓图片上传服务器流程

权限配置

AndroidManifest.xml 中声明必要权限:

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

注意:Android 10+ 需动态申请存储权限,并适配分区存储。

图片选择与获取

通过 Intent 调用系统相册选择图片:

安卓图片上传到服务器  第1张

Intent intent = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
startActivityForResult(intent, REQUEST_CODE_SELECT_IMAGE);

onActivityResult 中获取图片路径:

@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if (requestCode == REQUEST_CODE_SELECT_IMAGE && resultCode == RESULT_OK) {
        Uri imageUri = data.getData();
        // 转换为文件路径或直接处理 Uri
    }
}

图片压缩处理(可选)

为减少流量和提升上传速度,可对图片进行压缩:

public File compressImage(Uri imageUri) throws IOException {
    Bitmap bitmap = MediaStore.Images.Media.getBitmap(this, imageUri);
    // 计算压缩比例(例如宽高各缩放50%)
    bitmap = Bitmap.createScaledBitmap(bitmap, bitmap.getWidth() / 2, bitmap.getHeight() / 2, true);
    File compressedFile = new File(getCacheDir(), "compressed_image.jpg");
    FileOutputStream fos = new FileOutputStream(compressedFile);
    bitmap.compress(Bitmap.CompressFormat.JPEG, 80, fos); // 质量设为80%
    fos.close();
    return compressedFile;
}

上传图片到服务器

使用 Retrofit 上传图片(以 Multipart 形式):

// 1. 添加依赖
implementation 'com.squareup.retrofit2:retrofit:2.9.0'
implementation 'com.squareup.retrofit2:converter-gson:2.9.0'
// 2. 定义接口
public interface ApiService {
    @Multipart
    @POST("upload/image")
    Call<ResponseBody> uploadImage(@Part MultipartBody.Part image);
}
// 3. 创建 Retrofit 实例
Retrofit retrofit = new Retrofit.Builder()
        .baseUrl("https://yourserver.com/") // 替换为实际服务器地址
        .addConverterFactory(GsonConverterFactory.create())
        .build();
// 4. 构建请求体并上传
File imageFile = compressImage(imageUri); // 获取压缩后的文件
RequestBody requestBody = RequestBody.create(MediaType.parse("image/jpeg"), imageFile);
MultipartBody.Part part = MultipartBody.Part.createFormData("file", imageFile.getName(), requestBody);
ApiService apiService = retrofit.create(ApiService.class);
Call<ResponseBody> call = apiService.uploadImage(part);
call.enqueue(new Callback<ResponseBody>() {
    @Override
    public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
        if (response.isSuccessful()) {
            // 上传成功
        } else {
            // 处理错误(如服务器返回错误码)
        }
    }
    @Override
    public void onFailure(Call<ResponseBody> call, Throwable t) {
        // 网络错误处理
    }
});

关键配置与注意事项

事项 说明
动态权限申请 Android 6.0+ 需动态申请存储权限,使用 ActivityCompat.requestPermissions
文件路径转换 Android 10+ 推荐使用 ContentResolverMediaStore 替代直接文件路径。
图片格式兼容性 服务器需支持 multipart/form-data,并正确解析字段名(如 file)。
大图处理 避免直接上传原图,建议压缩后上传(如限制宽高或文件大小)。
网络异常处理 需处理超时、断开等异常,可结合 OkHttp 配置重试机制。

常见问题与解答

问题1:如何选择多张图片并批量上传?

解答

  1. 修改 IntentACTION_GET_CONTENT 并设置 EXTRA_ALLOW_MULTIPLE
    Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
    intent.setType("image/");
    intent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true);
    startActivityForResult(intent, REQUEST_CODE_SELECT_IMAGE);
  2. onActivityResult 中遍历选中的图片列表,逐个压缩并添加到上传队列。

问题2:如何实现后台静默上传?

解答

  1. 使用 WorkManagerJobScheduler 调度后台任务:
    OneTimeWorkRequest uploadWork = new OneTimeWorkRequest.Builder(UploadWorker.class)
        .setInputData(new Data.Builder().putString("filePath", filePath).build())
        .build();
    WorkManager.getInstance(context).enqueue(uploadWork);
  2. UploadWorker 中执行上传逻辑,需确保应用具有后台网络权限
0