Android Retrofit 2上传多个图像到服务器

问题描述:

我是Android开发的新手,我正在开发一款App,就像二手车一样,我有一个活动是用户可以上传那里的项目到服务器(文本和图像),但问题是上传文本很容易,我使用Volley将文本上传到服务器,但是我长时间努力将多个图像上传到服务器。 我看到Retrofit 2对于多个文件上传真的很好,但是我有很多问题。Android Retrofit 2上传多个图像到服务器

这里是ApiService

public interface ApiService { 
@Multipart 
@POST("xxxxxxxxxx.php") 
Call<ServerResponse> uploadFile(
           @Part("uploadedfile")RequestBody uploadedfile, 
           @Part("itemID")RequestBody itemId, 
           @Part MultipartBody.Part file 
); 

public static final Retrofit retrofit = new Retrofit.Builder() 
     .baseUrl("http://xxxxxxxxxxxx/") 
     .addConverterFactory(GsonConverterFactory.create()) 
     .build(); 
} 

下面是serverResponse 公共类ServerResponse {

@SerializedName("message") 
String message; 
@SerializedName("error") 
boolean error; 

public String getMessage(){ 
    return message; 
} 

public boolean isError(){ 
    return error; 
} 
} 

下面是活动

public class upload extends AppCompatActivity { 


public static final String UPLOAD_URL = "http://xxxxxxxxxxxxxxxxxxxxx.php"; 
public static final String KEY_Title = "title"; 
public static final String KEY_DESCRIPTION = "description"; 
public static final String KEY_ISBN = "ISBN"; 
public static final String KEY_PRICE = "price"; 
public static final String KEY_CONTECTNUMBER = "contectNumber"; 

private static final MediaType MEDIA_TYPE_PNG = MediaType.parse("image/png"); 
ProgressDialog progressDialog; 
String data; 

private EditText et_itemTitle; 
private EditText et_ISBN; 
private EditText et_itemPrice; 
private EditText et_itemDescription; 
private EditText et_phone; 
private Button b_chooseImage; 
private Button bPost; 
String id = "4"; 

private LinearLayout lnrImages; 
private ArrayList<String> imagesPathList; 
private Bitmap yourbitmap; 
private Bitmap resized; 
private final int PICK_IMAGE_MULTIPLE = 1; 

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_upload); 

    et_itemTitle = (EditText) findViewById(R.id.et_itemTitle); 
    et_ISBN = (EditText) findViewById(R.id.et_ISBN); 
    et_itemPrice = (EditText) findViewById(R.id.et_itemPrice); 
    et_itemDescription = (EditText) findViewById(R.id.et_itemDescription); 
    et_phone = (EditText) findViewById(R.id.et_phone); 
    b_chooseImage = (Button) findViewById(R.id.b_chooseImage); 
    bPost = (Button) findViewById(R.id.bPost); 

    lnrImages = (LinearLayout) findViewById(R.id.lnrImages); 

    progressDialog = new ProgressDialog(this); 
    progressDialog.setMessage("Uploading..."); 

    bPost.setOnClickListener(new View.OnClickListener() { 
     @Override 
     public void onClick(View v) { 
      final String itemTitle = imagesPathList.get(0).toString(); 
      final String ISBN = et_ISBN.getText().toString(); 
      final String itemPrice = et_itemPrice.getText().toString(); 
      final String itemDescription = et_itemDescription.getText().toString(); 
      final String contectNumber = et_phone.getText().toString(); 

      final String user = ((globalV) getApplication()).getUserID(); 
      final String session = ((globalV) getApplication()).getSessionID(); 
      StringRequest stringRequest = new StringRequest(Request.Method.POST, UPLOAD_URL, new Response.Listener<String>() { 
       @Override 
       public void onResponse(String response) { 
        try { 
         JSONObject jsonResponse = new JSONObject(response); 
         boolean error = jsonResponse.getBoolean("error"); 

         if (error) { 
          String errorMessage = jsonResponse.getString("message"); 
          AlertDialog.Builder builder = new AlertDialog.Builder(upload.this); 
          builder.setMessage(errorMessage) 
            .setNegativeButton("Retry", null) 
            .create() 
            .show(); 
         } else { 
          String successMessage = jsonResponse.getString("message"); 
          System.out.println(successMessage+"---------------"); 
          String itemID = jsonResponse.getString("itemID"); 


          ((globalV) getApplication()).setItemID(itemID); 
          File file = new File(imagesPathList.get(0)); 
          System.out.print(imagesPathList.get(0)+"====-=-=-=-=-=---=-="); 

          Gson gson = new GsonBuilder() 
            .setLenient() 
            .create(); 

          RequestBody requestBody = RequestBody.create(MediaType.parse("image/png"), file); 
          RequestBody uploadedfile = RequestBody.create(MediaType.parse("text/plain"), file.getName()); 
          RequestBody itemId = RequestBody.create(MediaType.parse("text/plain"), file.getName()); 
          MultipartBody.Part fileToUpload = MultipartBody.Part.createFormData("uploadedfile", file.getName(), requestBody); 
          System.out.print(file+"xxxxxxxxxx"); 

          ApiService apiService =ApiService.retrofit.create(ApiService.class); 
          Call<ServerResponse> call = apiService.uploadFile(uploadedfile, itemId, fileToUpload); 
          call.enqueue(new Callback<ServerResponse>() { 
           @Override 
           public void onResponse(Call<ServerResponse> call, retrofit2.Response<ServerResponse> response) { 
            ServerResponse serverResponse = response.body(); 
            if (serverResponse != null) { 
             if (serverResponse.isError()) { 
              Toast.makeText(getApplicationContext(), serverResponse.getMessage(), Toast.LENGTH_SHORT).show(); 
             }else { 
              Toast.makeText(getApplicationContext(), serverResponse.getMessage(), Toast.LENGTH_SHORT).show(); 
             } 
            }else { 
             assert serverResponse != null; 
             Log.v("Response", serverResponse.toString()); 
            } 
            progressDialog.dismiss(); 
           } 

           @Override 
           public void onFailure(Call<ServerResponse> call, Throwable t) { 
            Log.v("OnFailure", t.toString()); 
           } 
          }); //stop 

         } 
        } catch (JSONException e) { 
         e.printStackTrace(); 
        } 
       } 
      }, new Response.ErrorListener() { 
       @Override 
       public void onErrorResponse(VolleyError error) { 
        Toast.makeText(upload.this, error.toString(), Toast.LENGTH_SHORT).show(); 
       } 
      }) { 
       @Override 
       protected Map<String, String> getParams() throws AuthFailureError { 

        Map<String, String> map = new HashMap<String, String>(); 
        map.put(KEY_Title, itemTitle); 
        map.put(KEY_ISBN, ISBN); 
        map.put(KEY_PRICE, itemPrice); 
        map.put(KEY_DESCRIPTION, itemDescription); 
        map.put(KEY_CONTECTNUMBER, contectNumber); 
        map.put("userID", user); 
        map.put("sessionID", session); 
        map.put("id", id); 
        return map; 
       } 
      }; 
      RequestQueue requestQueue = Volley.newRequestQueue(upload.this); 
      requestQueue.add(stringRequest); 

     } 

    }); 
    b_chooseImage.setOnClickListener(new View.OnClickListener() { 
     @Override 
     public void onClick(View v) { 
      Intent intent = new Intent(upload.this, CustomPhotoGalleryActivity.class); 
      startActivityForResult(intent, PICK_IMAGE_MULTIPLE); 
      if (imagesPathList != null) { 
       Toast.makeText(upload.this, " no images are selected", Toast.LENGTH_SHORT).show(); 
      } 
     } 
    }); 
} 

@Override 
protected void onActivityResult(int requestCode, int resultCode, Intent data) { 
    super.onActivityResult(requestCode, resultCode, data); 
    if (resultCode == RESULT_OK) { 
     if (requestCode == PICK_IMAGE_MULTIPLE) { 
      imagesPathList = new ArrayList<String>(); 
      String[] imagesPath = data.getStringExtra("data").split("\\|"); 
      try { 
       lnrImages.removeAllViews(); 
      } catch (Throwable e) { 
       e.printStackTrace(); 
      } 
      for (int i = 0; i < imagesPath.length; i++) { 
       imagesPathList.add(imagesPath[i]); 
       yourbitmap = BitmapFactory.decodeFile(imagesPath[i]); 
       ImageView imageView = new ImageView(this); 
       imageView.setImageBitmap(yourbitmap); 
       imageView.setAdjustViewBounds(true); 
       lnrImages.addView(imageView); 
      } 
     } 
    } 
} 
} 

而且我还有其他的活动选择图像

public class CustomPhotoGalleryActivity extends Activity { 
private GridView grdImages; 
private Button btnSelect; 

private ImageAdapter imageAdapter; 
private String[] arrPath; 
private boolean[] thumbnailsselection; 
private int ids[]; 
private int count; 
int MY_PERMISSIONS_REQUEST_READ_EXTERNAL_STORAGE; 
@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.custom_gallery); 
    grdImages = (GridView) findViewById(R.id.grdImages); 
    btnSelect = (Button) findViewById(R.id.btnSelect); 

    if (ContextCompat.checkSelfPermission(this,Manifest.permission.READ_EXTERNAL_STORAGE) 
      != PackageManager.PERMISSION_GRANTED){ 
     if (ActivityCompat.shouldShowRequestPermissionRationale(this,Manifest.permission.READ_EXTERNAL_STORAGE)){ 

     }else { 
      ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.READ_EXTERNAL_STORAGE},MY_PERMISSIONS_REQUEST_READ_EXTERNAL_STORAGE); 
     } 
    } 

    final String[] columns = {MediaStore.Images.Media.DATA, MediaStore.Images.Media._ID}; 
    final String orderBy = MediaStore.Images.Media._ID; 
    @SuppressWarnings("deprecation") 
    Cursor imagecursor = managedQuery(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, columns, null, null, orderBy); 
    int image_column_index = imagecursor.getColumnIndex(MediaStore.Images.Media._ID); 
    this.count = imagecursor.getCount(); 
    this.arrPath = new String[this.count]; 
    ids = new int[count]; 
    this.thumbnailsselection = new boolean[this.count]; 
    for (int i = 0; i < this.count; i++) { 
     imagecursor.moveToPosition(i); 
     ids[i] = imagecursor.getInt(image_column_index); 
     int dataColumnIndex = imagecursor.getColumnIndex(MediaStore.Images.Media.DATA); 
     arrPath[i] = imagecursor.getString(dataColumnIndex); 
    } 
    imageAdapter = new ImageAdapter(); 
    grdImages.setAdapter(imageAdapter); 
    imagecursor.close(); 

    btnSelect.setOnClickListener(new View.OnClickListener() { 
     @Override 
     public void onClick(View v) { 
      final int len = thumbnailsselection.length; 
      int cnt = 0; 
      String selectImages = ""; 
      for (int i = 0; i < len; i++) { 
       if (thumbnailsselection[i]) { 
        cnt++; 
        selectImages = selectImages + arrPath[i] + "|"; 
       } 
      } 
      if (cnt == 0) { 
       Toast.makeText(getApplicationContext(), "Please select at least one image", Toast.LENGTH_LONG).show(); 
      } else { 

       Log.d("SelectedImages", selectImages); 
       Intent i = new Intent(); 
       i.putExtra("data", selectImages); 
       setResult(Activity.RESULT_OK, i); 
       System.out.print("===="+selectImages); 
       finish(); 
      } 
     } 
    }); 
} 
    @Override 
    public void onBackPressed() { 
     setResult(Activity.RESULT_CANCELED); 
     super.onBackPressed(); 
    } 

private void setBitmap(final ImageView iv, final int id) { 

    new AsyncTask<Void, Void, Bitmap>() { 

     @Override 
     protected Bitmap doInBackground(Void... params) { 
      return MediaStore.Images.Thumbnails.getThumbnail(getApplicationContext().getContentResolver(), id, MediaStore.Images.Thumbnails.MICRO_KIND, null); 
     } 

     @Override 
     protected void onPostExecute(Bitmap result) { 
      super.onPostExecute(result); 
      iv.setImageBitmap(result); 
     } 
    }.execute(); 

} 

public class ImageAdapter extends BaseAdapter{ 
    private LayoutInflater mInflater; 

    public ImageAdapter(){ 
     mInflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
    } 

    @Override 
    public int getCount() { 
     return count; 
    } 

    @Override 
    public Object getItem(int position) { 
     return position; 
    } 

    @Override 
    public long getItemId(int position) { 
     return position; 
    } 

    @Override 
    public View getView(int position, View convertView, ViewGroup parent) { 
     final ViewHolder holder; 
     if (convertView == null) { 
      holder = new ViewHolder(); 
      convertView = mInflater.inflate(R.layout.custom_gallery_item, null); 
      holder.imgThumb = (ImageView) convertView.findViewById(R.id.imgThumb); 
      holder.chkImage = (CheckBox) convertView.findViewById(R.id.chkImage); 

      convertView.setTag(holder); 
     } else { 
      holder = (ViewHolder) convertView.getTag(); 
     } 
     holder.chkImage.setId(position); 
     holder.imgThumb.setId(position); 
     holder.chkImage.setOnClickListener(new View.OnClickListener() { 

      public void onClick(View v) { 
       CheckBox cb = (CheckBox) v; 
       int id = cb.getId(); 
       if (thumbnailsselection[id]) { 
        cb.setChecked(false); 
        thumbnailsselection[id] = false; 
       } else { 
        cb.setChecked(true); 
        thumbnailsselection[id] = true; 
       } 
      } 
     }); 
     holder.imgThumb.setOnClickListener(new View.OnClickListener() { 

      public void onClick(View v) { 
       int id = holder.chkImage.getId(); 
       if (thumbnailsselection[id]) { 
        holder.chkImage.setChecked(false); 
        thumbnailsselection[id] = false; 
       } else { 
        holder.chkImage.setChecked(true); 
        thumbnailsselection[id] = true; 
       } 
      } 
     }); 
     try { 
      setBitmap(holder.imgThumb, ids[position]); 
     } catch (Throwable e) { 
     } 
     holder.chkImage.setChecked(thumbnailsselection[position]); 
     holder.id = position; 
     return convertView; 
    } 
} 

class ViewHolder { 
    ImageView imgThumb; 
    CheckBox chkImage; 
    int id; 
} 

} 

也许我需要向服务器请求的同时,请有人可以帮助我.............

如果你想上传多个图片与单个键。将MultipartBody.Part设置为数组。

Call<ServerResponse> uploadFile(
    @Part("uploadedfile")RequestBody uploadedfile, 
    @Part("itemID")RequestBody itemId, 
    @Part MultipartBody.Part[] file 
); 


MultipartBody.Part[] imageParts = new MultipartBody.Part[10]; 

for (int index = 0; index < 10; index++) { 
    File file = new File(IMAGE_FILE[index]); 
    RequestBody surveyBody = RequestBody.create(MediaType.parse("image/*"), file); 
    imageParts[index] = MultipartBody.Part.createFormData("SurveyImage", file.getName(), uploadedfile); 
}