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

安卓中图片上传到服务器

安卓图片上传需先获取图片路径或Bitmap,压缩后转为Base64或Multipart格式,通过OkHttp/Retrofit等库在子线程发起POST请求,需声明存储和网络权限,注意处理异常及进度

安卓图片上传到服务器实现步骤


权限配置

  1. 存储权限(读取/写入本地文件)

    • AndroidManifest.xml 中声明:
      <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
      <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
    • Android 6.0+ 需动态申请权限:
      if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
          ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, REQUEST_CODE);
      }
  2. 网络权限

    • 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);

图片处理

  1. 压缩图片(减少体积)

    • 使用 BitmapFactory.Options 采样压缩:
      BitmapFactory.Options options = new BitmapFactory.Options();
      options.inSampleSize = 4; // 宽高缩小为1/4
      Bitmap bitmap = BitmapFactory.decodeFile(filePath, options);
    • 或使用第三方库(如 Luban):
      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();
  2. 转换为 Base64(可选)

    • 将图片转为字符串上传:
      ByteArrayOutputStream baos = new ByteArrayOutputStream();
      bitmap.compress(Bitmap.CompressFormat.JPEG, 80, baos);
      String base64 = Base64.encodeToString(baos.toByteArray(), Base64.DEFAULT);

上传图片

使用 Retrofit + OkHttp 实现:

安卓中图片上传到服务器

  1. 依赖配置

    implementation 'com.squareup.retrofit2:retrofit:2.9.0'
    implementation 'com.squareup.retrofit2:converter-gson:2.9.0'
  2. 定义 API 接口

    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();
    ApiService apiService = retrofit.create(ApiService.class);
  4. 构建请求体并上传

    安卓中图片上传到服务器

    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) {
            // 网络错误处理
        }
    });

进度监听与错误处理

  1. 添加上传进度监听

    • 自定义 Interceptor 或使用 ProgressRequestBody
      OkHttpClient okHttpClient = new OkHttpClient.Builder()
          .addInterceptor(chain -> {
              Response originalResponse = chain.proceed(chain.request());
              // 获取响应并计算进度
              return originalResponse;
          })
          .build();
  2. 错误处理

    • 网络异常:检查设备网络状态,提示重试。
    • 服务器错误:根据 response.code() 处理(如 404/500)。
    • 文件过大:压缩图片或分片上传。

相关问题与解答

问题1:上传时提示“权限被拒绝”

解答:

  • 检查是否在 AndroidManifest.xml 中声明了 WRITE_EXTERNAL_STORAGEINTERNET 权限。
  • Android 6.0+ 需动态申请存储权限:
    if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
        ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, REQUEST_CODE);
    }
  • 确保用户已授权,否则无法访问本地文件。

问题2:上传失败,服务器返回“400 Bad Request”

解答:

安卓中图片上传到服务器

  • 可能原因1:文件格式不符合要求

    • 检查服务器是否限制图片格式(如仅支持 JPEG/PNG)。
    • 确保 MediaType 正确设置:MediaType.parse("image/jpeg")
  • 可能原因2:缺少必要参数

    • 服务器可能要求额外字段(如 tokenfileName)。
    • MultipartBody.Part 中添加参数:
      MultipartBody.Part part = MultipartBody.Part.createFormData("image", file.getName(), requestBody)
          .addField("token", "your_token_value");
  • 调试方法:

    • 使用 Postman 模拟请求,确认服务器接口参数要求。
    • 查看服务器日志,定位具体错误原因