上一篇
安卓图片上传到服务器
- 行业动态
- 2025-04-24
- 2884
安卓图片上传至服务器需用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
调用系统相册选择图片:
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+ 推荐使用 ContentResolver 或 MediaStore 替代直接文件路径。 |
图片格式兼容性 | 服务器需支持 multipart/form-data ,并正确解析字段名(如 file )。 |
大图处理 | 避免直接上传原图,建议压缩后上传(如限制宽高或文件大小)。 |
网络异常处理 | 需处理超时、断开等异常,可结合 OkHttp 配置重试机制。 |
常见问题与解答
问题1:如何选择多张图片并批量上传?
解答:
- 修改
Intent
为ACTION_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);
- 在
onActivityResult
中遍历选中的图片列表,逐个压缩并添加到上传队列。
问题2:如何实现后台静默上传?
解答:
- 使用
WorkManager
或JobScheduler
调度后台任务:OneTimeWorkRequest uploadWork = new OneTimeWorkRequest.Builder(UploadWorker.class) .setInputData(new Data.Builder().putString("filePath", filePath).build()) .build(); WorkManager.getInstance(context).enqueue(uploadWork);
- 在
UploadWorker
中执行上传逻辑,需确保应用具有后台网络权限