Обновлена ​​ссылка на последнюю версию с Kotlin: https://saopayne.medium.com/android-image-upload-to-server-with-kotlin-2-96605f14845a

Загрузка изображений - это то, что было интегрировано в нашу жизнь, и мы действительно не беспокоим наш мозг, выбирая, загружать или нет. Instagram построил свою компанию с миллиардным доходом именно на этой уникальной особенности, но затем было задействовано множество других вещей.

Другие примеры того, где мы выполняем это действие, включают Facebook, Twitter, Whatsapp, BBM и некоторые мобильные приложения, требующие изменения профиля и изображений обложки.

Как разработчики, это представляет собой интересную техническую задачу, и мы рады этой проблеме.

Эта статья посвящена реализации этого на Android, который отправляет изображение и хранится на сервере, где-то реализованном с помощью выбранных инструментов.

Загрузку изображений можно рассматривать на верхнем уровне как серию шагов, перечисленных ниже;

1. Выберите изображение для загрузки через намерение.

2. Действуйте на результат в случае успеха

3. Загрузить на сервер

4. Если загрузка прошла успешно / нет, передайте сообщение соответствующим образом.

Позвольте мне немного сохранить детали и сразу перейти к коду.

  1. Обработка нажатия пользователем кнопки для изменения / загрузки изображения.
private int PICK_PROFILE_IMAGE_REQUEST = 1;
changeProfileImage.setOnClickListener(new View.OnClickListener(){
@Override
public void onClick(View view){
showFileChooser(PICK_PROFILE_IMAGE_REQUEST);
}
});

2. Селектор Намерение выбрать изображение через галерею

private void showFileChooser(int number){
Intent intent= new Intent();
intent.setType("image/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
switch(number){
case 1:
   startActivityForResult(Intent.createChooser(intent,"Select              
  Picture"), PICK_PROFILE_IMAGE_REQUEST)
   break;
 }
}

3. Обработка результата Намерения, когда изображение было выбрано пользователем.

@Override
public void onActivityResult(intrequestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode,data);
if(requestCode == PICK_PROFILE_IMAGE_REQUEST && resultCode == 
getActivity().RESULT_OK && data != null && data.getData() != null){
Uri filePath = data.getData();
String fileName = getFileNameByUri(getActivity(),filePath);
try {
bitmap = MediaStore.Images.Media .getBitmap(getActivity().getContentResolver(), filePath);
uploadProfileImage(fileName);
profilePicture.setImageBitmap(bitmap);
} catch(IOException e){
e.printStackTrace();
}
}

4. Загрузка на сервер в фоновом режиме (с использованием AsyncTask, чтобы не блокировать пользовательский интерфейс)

public byte[] getBytesImage(Bitmapbmp){
ByteArrayOutputStream baos = new ByteArrayOutputStream();
bmp.compress(Bitmap.CompressFormat.PNG,100, baos);
byte[] imageBytes = baos.toByteArray();
return imageBytes;
}
public static String getFileNameByUri(Context context, Uri uri){
String fileName="unknown";//default fileName
Uri filePathUri = uri;
if (uri.getScheme().toString().compareTo("content")==0)
  Cursor cursor = context.getContentResolver().query(uri,null,null,
     null, null);
  if (cursor.moveToFirst()){
     int column_index =      
        cursor.getColumnIndex(MediaStore.Images.Media.DATA);
     filePathUri = Uri.parse(cursor.getString(column_index));   
     if(filePathUri == null){ 
         fileName = "xxx.png";//load a default Image from server
     }else{
         fileName = filePathUri.getLastPathSegment().toString();
     }
  }
}else
    if (uri.getScheme().compareTo("file")==0){
        fileName = filePathUri.getLastPathSegment().toString();
    }else{ 
        fileName = fileName+"_"+filePathUri.getLastPathSegment();
    }
  return fileName;
}
public void uploadProfileImage(final String fileName){
    byte[] imageBytes = getBytesImage(bitmap);
    httpclient = new DefaultHttpClient();
    httpPost = new HttpPost(“URL to upload image to...“); 
    String boundary = "-------------" + System.currentTimeMillis();
    httpPost.setHeader("Content-type", "multipart/form-data; 
    boundary="+boundary);
    ByteArrayBody bab = new ByteArrayBody(imageBytes,fileName);
    StringBody userId = new StringBody(mPrefs.getUser().getId(),
                        ContentType.TEXT_PLAIN); 
    StringBody type = new StringBody("baby",ContentType.TEXT_PLAIN);
    HttpEntity entity = MultipartEntityBuilder.create() 
                      .setMode(HttpMultipartMode.BROWSER_COMPATIBLE)
                      .setBoundary(boundary)
                      .addPart("imageUpload",bab)  
                      .addPart("userid",userId) 
                      .addPart("type",type)
                      .build();
    httpPost.setEntity(entity);
class UploadImage extends AsyncTask<Void,Void,String> {
   ProgressDialog loading;
   @Override 
   protected void onPreExecute() {
       super.onPreExecute();
       loading = ProgressDialog.show(getActivity(),"Please
                wait...","uploading picture",false,false);
   }
   @Override 
   protected void onPostExecute(String s){
       super.onPostExecute(s);
       loading.dismiss();
       Toast.makeText(getActivity(), s, Toast.LENGTH_LONG).show();
   }
   
  @Override
  protected String doInBackground(Void...param){ 
      String res = "";
      HttpResponse response; 
      try{
         response = httpclient.execute(httpPost);
         res = response.getStatusLine().toString();
         User user = mPrefs.getUser();
         user.setProfileImageUrl(PICTURE_URL+fileName);  
         mPrefs.saveUser(user);
      }catch(IOException e){
         e.printStackTrace();
      } 
     return "Profile image upload successful"
  }
}
UploadImage u = new UploadImage();
u.execute();
}

Это так просто, как кажется, ждем ваших отзывов и комментариев.

Удачи.