Обновлена ссылка на последнюю версию с Kotlin: https://saopayne.medium.com/android-image-upload-to-server-with-kotlin-2-96605f14845a
Загрузка изображений - это то, что было интегрировано в нашу жизнь, и мы действительно не беспокоим наш мозг, выбирая, загружать или нет. Instagram построил свою компанию с миллиардным доходом именно на этой уникальной особенности, но затем было задействовано множество других вещей.
Другие примеры того, где мы выполняем это действие, включают Facebook, Twitter, Whatsapp, BBM и некоторые мобильные приложения, требующие изменения профиля и изображений обложки.
Как разработчики, это представляет собой интересную техническую задачу, и мы рады этой проблеме.
Эта статья посвящена реализации этого на Android, который отправляет изображение и хранится на сервере, где-то реализованном с помощью выбранных инструментов.
Загрузку изображений можно рассматривать на верхнем уровне как серию шагов, перечисленных ниже;
1. Выберите изображение для загрузки через намерение.
2. Действуйте на результат в случае успеха
3. Загрузить на сервер
4. Если загрузка прошла успешно / нет, передайте сообщение соответствующим образом.
Позвольте мне немного сохранить детали и сразу перейти к коду.
- Обработка нажатия пользователем кнопки для изменения / загрузки изображения.
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(); }
Это так просто, как кажется, ждем ваших отзывов и комментариев.
Удачи.