Android端图片无法上传服务器且提示用户未注册如何解决
Android Studio图片上传服务器失败解决方案
问题说明
你在开发中遇到的上传失败问题,是由多处代码逻辑错误、参数不匹配、路径获取错误共同导致的,以下是具体问题点和修复方案:
已发现的核心问题
- 全局filepath变量从未赋值:你声明了全局变量
String filepath=" ",但在相册选图的onActivityResult回调中仅把路径赋值给了TextView,完全没有更新filepath的值,调用uploadImage时创建的所有File对象都是基于空字符串生成的,直接触发文件找不到异常。 - Content URI直接转路径错误:
data.getData().getPath()拿到的是Content Provider的虚拟URI路径,不是本地文件的真实物理路径,Android 4.4及以上系统用这个路径无法找到真实文件。 - ApiInterface参数完全不匹配:
uploadimage方法声明的参数存在大量无注解的冗余参数(比如无注解的String part、String part1),参数顺序、数量和你调用时传入的参数完全对不上,Retrofit会直接抛出参数解析异常。 - 多文件共用同一个无效路径:你5个上传文件的File对象都用同一个空filepath创建,就算filepath赋值成功,也只能拿到最后一张选择的图片,其余4个文件都是无效的。
- Spinner取值逻辑错误:注册接口传参时你用
spinner.getSelectedItem().getClass().toString()取值,拿到的是Spinner选项的类名,不是用户选中的文本内容。 - 注册和上传共用同一个接口:两个接口都指向
api/register,一个用FormUrlEncoded格式一个用Multipart格式,后端如果没有做兼容会直接拒绝请求。
修复步骤
1. 新增Uri转真实路径的工具方法
在Sign_up类中新增如下方法,把选图拿到的Content URI转为真实的本地文件路径:
private String getRealPathFromUri(Uri uri) { String[] projection = {MediaStore.Images.Media.DATA}; Cursor cursor = getContentResolver().query(uri, projection, null, null, null); if (cursor == null) return uri.getPath(); int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA); cursor.moveToFirst(); String path = cursor.getString(column_index); cursor.close(); return path; }
2. 声明5个独立的路径变量存储不同图片路径
替换原来的全局String filepath=" "为:
String passPhotoPath, afPath, abPath, markPath, paymentPath;
3. 修复onActivityResult的路径赋值逻辑
把每个选图回调里的String path=data.getData().getPath();替换为真实路径获取,并赋值给对应的全局变量:
// 示例:case 10的逻辑修改,其余case按对应变量修改即可 case 10: if (resultCode==RESULT_OK){ passPhotoPath = getRealPathFromUri(data.getData()); R_passphoto.setText(passPhotoPath); } break; case 20: if (resultCode==RESULT_OK){ afPath = getRealPathFromUri(data.getData()); R_af.setText(afPath); } break; // 剩下的case 30、40、50按上面的逻辑,分别赋值给abPath、markPath、paymentPath即可
4. 修复ApiInterface的uploadimage方法参数
删除冗余无注解参数,保证参数顺序和调用时一致:
@Multipart @POST("api/register") Call<responsemodel> uploadimage( @Part("adharfront") String adharfront, @Part("adharback") String adharback, @Part("mark") String mark, @Part("pay") String pay, @Part("pass") String pass, @Part MultipartBody.Part filename, @Part MultipartBody.Part filename1, @Part MultipartBody.Part filename2, @Part MultipartBody.Part filename3, @Part MultipartBody.Part filename4 );
5. 修复uploadImage方法的File创建逻辑
每个File对象使用对应独立的路径创建:
private void uploadImage(){ File file_pass = new File(passPhotoPath); File file_af = new File(afPath); File file_ab = new File(abPath); File file_mark = new File(markPath); File file_pay = new File(paymentPath); // 后续RequestBody、MultipartBody.Part创建逻辑对应修改为上面的5个File对象即可 }
6. 修复注册接口的Spinner取值
把spinner.getSelectedItem().getClass().toString()改为spinner.getSelectedItem().toString(),同理修改spinner1的取值逻辑。
7. 添加上传错误日志
在uploadImage的onFailure回调中添加日志打印,方便后续排查问题:
@Override public void onFailure(Call<responsemodel> call, Throwable t) { Log.e("UPLOAD_ERROR", "上传失败", t); Toast.makeText(Sign_up.this,"图片上传失败",Toast.LENGTH_LONG).show(); }
内容的提问来源于stack exchange,提问作者Alok Jain
相关产品推荐
相关产品推荐

