Android

@Multipart 이용하여 이미지 서버로 업로드하기

juju824 2020. 9. 28. 01:25

❓ 서버에서 @multer 모듈을 사용했을 경우 

안드로이드에서는 S3로 어떻게 이미지를 업로드 할까 ❓

 

아무리 구글링을 해봐도 내가 겪었던 문제들은 안 가르쳐주었기에 

한번 개발 초보인 내가 정리를 해보겠다!

 

✔️ 인터넷을 통해 이미지를 업로드 해주므로 permission 허용해주기

👇 Androidmanifest.xml 👇
	//아주 중요하다!
    <uses-permission android:name="android.permission.INTERNET"/>
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

 

✔️ ServiceApi에 @multipart 추가하기

👇 ServiceApi.java 👇

@Multipart
    @POST("/user/profile") //프로필 사진 업데이트
    Call<ProfileResponse> profile (@Part MultipartBody.Part profile, @Header("token") String token);
    

 

✔️Response 받는 부분

👇 ProfileResponse.java 👇

package ...
import ...
import java.util.List;

public class ProfileResponse {

    private int status;
    private boolean success;
    private String message;
    private List<CalendarPhotoResponse.CalendarPhoto> data;

    public int getStatus(){
        return status;
    }

    public boolean getSuccess(){
        return success;
    }

    public String getMessage(){
        return message;
    }

    public List<CalendarPhotoResponse.CalendarPhoto> getData(){
        return data;
    }

    public class Profile {
        private int useridx;
        private String photo;

        public int getUseridx() {
            return useridx;
        }

        public String getPhoto() {
            return photo;
        }
    }

}

 

✔️ Setmyinfo.java 에 이미지뷰를 클릭해서 그 경로를 먼저 파악해야 한다

이미지의 경로 확인

 👇 Setmyinfo.java 👇
 
 imageView = findViewById(R.id.profile);
        imageView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Intent intent = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
                startActivityForResult(intent, REQUEST_CODE);
           }
        });

 

✔️ Cursor를 이용해 Path 가져오기

 @Override
    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        super.onActivityResult(requestCode, resultCode, data);

        if(requestCode== REQUEST_CODE && resultCode==RESULT_OK && data!=null) {
            selectedImage = data.getData();
            
            //여기서부터
            Uri photoUri = data.getData();
            Bitmap bitmap = null;
            try {
                bitmap = MediaStore.Images.Media.getBitmap(getContentResolver(),photoUri);
                bitmap = rotateImage(bitmap, 90);
            } catch (IOException e) {
                e.printStackTrace();
            }
            imageView.setImageBitmap(bitmap);
            //여기까지는 이미지를 갤러리에서 클릭해서 그 사진을 이미지뷰에 보여주는 코드
            
            Cursor cursor = getContentResolver().query(Uri.parse(selectedImage.toString()), null, null, null, null);
            assert cursor != null;
            cursor.moveToFirst();
            mediaPath = cursor.getString(cursor.getColumnIndex(MediaStore.MediaColumns.DATA));
            //커서 사용해서 경로 확인 

        }else{
            Toast.makeText(this, "사진 업로드 실패", Toast.LENGTH_LONG).show();
        }
    }

 

✔️경로를 확인 한 상태에서 '저장'버튼을 누르면 그 경로를 서버에 보내고 S3에 보낸다

=> 저장 버튼 : finish_button

 button = (Button) findViewById(R.id.finish_button);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
              		//update Photo
                    UpdatePhoto();
                    infoInputCheck(new RegisterData());
            }
        });
    }
    

 

✔️버튼을 클릭시 UpdatePhoto() 함수로 이동

👇 updatePhoto 함수 👇

private void UpdatePhoto() {
        if(mediaPath != null){
        	File file = new File(mediaPath);
        
        	//아래 두줄이 중요하다!!!
        	RequestBody requestBody = RequestBody.create(MediaType.parse("image/jpeg"), file);
        	MultipartBody.Part fileToUpload = MultipartBody.Part.createFormData("profile", file.getName(), requestBody);
		
        	//token을 header에 넣는 두 줄의 코드
        	SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
        	String token = sp.getString("TOKEN", "");

        	service.profile(fileToUpload, token).enqueue(new Callback<ProfileResponse>() {
            
            	@Override
            	public void onResponse(Call<ProfileResponse> call, Response<ProfileResponse> response) {
                	ProfileResponse result = response.body();
            	}

                @Override
            	public void onFailure(Call<ProfileResponse> call, Throwable t) {
                	Toast.makeText(SetPuppy.this, "통신 실패", Toast.LENGTH_SHORT).show();
                	Log.d("에러",  t.getMessage());
            	}
        	});
    }}

❗️mediaPath == null 인 경우가 있기 때문에 if 문으로 감싸주어야 튕기지 않는다

서버 통신 service.profile을 통해 서버로 multipart이용해서 이미지를 보내주었다.

 

 

👉 디비를 확인해보면 

image column에 뭔가가 추가
복붙해서 엔터 치면 사진이 뜬다. 사진 확인 가능

📌 안드로이드 => 서버 

이 과정은 이렇게 진행하면 된다.

 

📌서버 => aws S3 

이 과정은 nodejs multer 부분을 참고하면 된다

2020/09/14 - [nodejs] - 🖼 nodejs 이미지 관련 모듈 multer 사용해보기

 

🖼 nodejs 이미지 관련 모듈 multer 사용해보기

✔️ multer는 서버에서 사용하는 multipart/form-data 로 들어온 이미지를 처리하는 모듈이다 📌multer의 흐름 1. 클라이언트에서 이미지 파일을 업로드 2. 서버 내의 multer module을 거친다 3. 코드 내에 mul

juju-marooooo.tistory.com