存储权限(读取/写入本地文件)
AndroidManifest.xml
中声明: <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) { ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, REQUEST_CODE); }
网络权限
AndroidManifest.xml
中声明: <uses-permission android:name="android.permission.INTERNET"/>
方式 | 实现方法 | 说明 |
---|---|---|
从相册选择 | Intent.createChooser(Intent.ACTION_GET_CONTENT, "选择图片") | URI获取图片 |
拍照获取 | MediaStore.ACTION_IMAGE_CAPTURE | 需指定文件路径保存照片 |
从文件选择 | 通过文件管理器或第三方库(如 FilePicker ) | 直接获取文件路径 |
示例代码(从相册选择):
Intent intent = new Intent(Intent.ACTION_GET_CONTENT); intent.setType("image/"); startActivityForResult(intent, REQUEST_CODE_SELECT_IMAGE);
压缩图片(减少体积)
BitmapFactory.Options
采样压缩: BitmapFactory.Options options = new BitmapFactory.Options(); options.inSampleSize = 4; // 宽高缩小为1/4 Bitmap bitmap = BitmapFactory.decodeFile(filePath, options);
Luban.with(this) .load(filePath) .setCompressListener(new OnCompressListener() { @Override public void onStart() {} @Override public void onSuccess(File file) { // 压缩后的文件 } @Override public void onError(Throwable e) {} }).launch();
转换为 Base64(可选)
ByteArrayOutputStream baos = new ByteArrayOutputStream(); bitmap.compress(Bitmap.CompressFormat.JPEG, 80, baos); String base64 = Base64.encodeToString(baos.toByteArray(), Base64.DEFAULT);
使用 Retrofit + OkHttp 实现:
依赖配置
implementation 'com.squareup.retrofit2:retrofit:2.9.0' implementation 'com.squareup.retrofit2:converter-gson:2.9.0'
定义 API 接口
public interface ApiService { @Multipart @POST("upload/image") Call<ResponseBody> uploadImage(@Part MultipartBody.Part image); }
创建 Retrofit 实例
Retrofit retrofit = new Retrofit.Builder() .baseUrl("https://yourserver.com/") // 替换为服务器地址 .addConverterFactory(GsonConverterFactory.create()) .build(); ApiService apiService = retrofit.create(ApiService.class);
构建请求体并上传
File file = new File(imagePath); // 本地图片路径 RequestBody requestBody = RequestBody.create(MediaType.parse("image/jpeg"), file); MultipartBody.Part part = MultipartBody.Part.createFormData("image", file.getName(), requestBody); apiService.uploadImage(part).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) { // 网络错误处理 } });
添加上传进度监听
Interceptor
或使用 ProgressRequestBody
: OkHttpClient okHttpClient = new OkHttpClient.Builder() .addInterceptor(chain -> { Response originalResponse = chain.proceed(chain.request()); // 获取响应并计算进度 return originalResponse; }) .build();
错误处理
response.code()
处理(如 404/500)。 解答:
AndroidManifest.xml
中声明了 WRITE_EXTERNAL_STORAGE
和 INTERNET
权限。 if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) { ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, REQUEST_CODE); }
解答:
可能原因1:文件格式不符合要求
MediaType
正确设置:MediaType.parse("image/jpeg")
。可能原因2:缺少必要参数
token
或 fileName
)。 MultipartBody.Part
中添加参数: MultipartBody.Part part = MultipartBody.Part.createFormData("image", file.getName(), requestBody) .addField("token", "your_token_value");
调试方法: