loading

프로그래밍/안드로이드

[Android Studio] Fragment에서 갤러리의 이미지 가져와서 서버로 전송하기

침착곰 2021. 4. 29. 10:47
반응형

안녕하세요

이번 프로젝트를 진행하면서 안드로이드 스튜디오[Android Studio]에서 Activity에서 갤러리 사진을 가져오는 것이 아닌 Fragment에서 갤러리 사진을 가져와 서버로 전송하는 프로그램을 짜게되었습니다

구글링을 하니 전부 Activity에서 동작하는 방법밖에 없어서 제가 구현한 소스를 적어봅니다

전체 소스를 올리기에는 힘들어서 일부 작성한 소스만 올려봅니다

 

WAS(Spring 소스)

서버에서 MultipartFile 형식으로 이미지를 받아서 WAS 서버의 APP\IMG_UPLOAD\ 경로에 이미지파일을 저장하는 부분입니다

@SuppressWarnings({ "rawtypes" })
@RequestMapping(value = "APP_IMG_UPLOAD.do",   method = RequestMethod.POST)
@ResponseBody
public Map SIGN_UPLOAD(   @RequestParam(value = "WORK_TYPE") String WORK_TYPE
						, @RequestParam(value = "IMG_TITLE") String IMG_TITLE
						, @RequestParam(value = "IMG_FILE", required = false) MultipartFile multipartFile    
						, @RequestParam(value = "USER_ID") String USER_ID   
						, HttpSession httpSession 
						 ) throws Exception
{
	String defaultPath = httpSession.getServletContext().getRealPath("/"); //서버기본경로 (프로젝트 폴더 아님)
        String savePath  = defaultPath + "APP" + File.separator + "IMG_UPLOAD" + File.separator + ""; 
        
        long sizeLimit = 10 * 1024 * 1024;
         
	File dir = new File(savePath); 
	if (!dir.isDirectory()) {
		dir.mkdirs();
	} 

	String ext  = multipartFile.getOriginalFilename().substring(multipartFile.getOriginalFilename().lastIndexOf('.') + 1);
	String o_FileName  = multipartFile.getOriginalFilename().substring(multipartFile.getOriginalFilename().lastIndexOf('.'));
	String StrToday = (new SimpleDateFormat("yyyyMMddHHmmss").format(Calendar.getInstance().getTime()));
	String strFileName =  USER_ID+"_"+StrToday+"."+ext;
	if (!dir.isDirectory()) {
		dir.mkdirs();
	}
	try
	{
		multipartFile.transferTo(new File(savePath+strFileName));
	}catch(Exception e)
	{
		System.out.println(e.toString());
	}
	Map<String, Object> fileInfo = new HashMap<String, Object>();
		
	String WRITE_DATE = (new SimpleDateFormat("yyyyMMdd").format(Calendar.getInstance().getTime()));
		
	fileInfo.put("WORK_TYPE", WORK_TYPE);
	fileInfo.put("WRITE_DATE", WRITE_DATE);
	fileInfo.put("IMG_TITLE", IMG_TITLE);
	fileInfo.put("IMG_TYPE",  ext);
	fileInfo.put("IMG_PATH",  strFileName);
	fileInfo.put("USER_ID",  USER_ID);
	 
	List<String> freeboardlist = AppService.P_APP_ADE310T_PHOTO_SET(fileInfo);
	Map<String, Object> map = new HashMap<String, Object>();
		
	map.put("ERROR_CODE", fileInfo.get("error_code"));
	map.put("ERROR_TEXT", fileInfo.get("error_str"));
	return map;
}

 


사진 전송(Android Studio 소스)

 - 화면 UI

  화면의 UI입니다

  상단의 갤러리에서 사진업로드를 하면 서버에 사진을 전송하여 저장하도록 구성되어있습니다

 

- 클릭 이벤트

// 클릭 이벤트
@Override
public void onClick(View view) {
    switch (view.getId()) {
        // 갤러리에서 사진 업로드 클릭
        case R.id.gallery:
            // 갤러리에서 사진 가져오기 창을 띄운다.
            Intent intent = new Intent();
            intent.setData(android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
            intent.setType("image/*");
            intent.setAction(Intent.ACTION_GET_CONTENT);
            
            // 위의 Activity를 실행한 이후 이벤트를 정의
            startActivityForResult(intent, REQUEST_CODE);
            break;
    }
}

 

- OnActivityResult

 사진을 선택하는 경우 타는 이벤트입니다

@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    switch (requestCode) {
        // 사진업로드 이벤트
        case REQUEST_CODE:
            // 사진 선택
            if(resultCode == Activity.RESULT_OK)
            {
                try{
                    // Image 상대경로를 가져온다
                    Uri uri = data.getData();
                    // Image의 절대경로를 가져온다
                    String imagePath = getRealPathFromURI(uri);
                    // File변수에 File을 집어넣는다
                    destFile = new File(imagePath);

                    // 이미지 전송
                    SendImage();
                }
                catch(Exception e) {
                    // 대기메시지 종료
                    activity.progressDismiss();
                }
            }
            // 사진 선택 취소
            else if(resultCode == activity.RESULT_CANCELED)
            {
                Toast.makeText(activity, "사진 선택 취소", Toast.LENGTH_LONG).show();
            }
            break;
    }
}

 

- 이미지의 절대경로를 가져오는 메소드

 이미지를 파일형태로 가져오기 위해 이미지의 절대경로를 가져옵니다

// Image의 절대경로를 가져오는 메소드
private String getRealPathFromURI(Uri contentUri) {
    if (contentUri.getPath().startsWith("/storage")) {
        return contentUri.getPath();
    }
    String id = DocumentsContract.getDocumentId(contentUri).split(":")[1];
    String[] columns = { MediaStore.Files.FileColumns.DATA };
    String selection = MediaStore.Files.FileColumns._ID + " = " + id;
    Cursor cursor = activity.getContentResolver().query(MediaStore.Files.getContentUri("external"), columns, selection, null, null);
    try {
        int columnIndex = cursor.getColumnIndex(columns[0]);
        if (cursor.moveToFirst())
        { return cursor.getString(columnIndex);
        }
    } finally {
        cursor.close();
    } return null;
}

 

- 서버에 이미지를 전송하는 메소드

 서버에 이미지를 전송합니다

 MultipartBody.Part로 이미지를 Convert해서 전송하게됩닏

private void SendImage()
{
    // 서버와 송수신을 하기위한 APIInterface 선언
    APIInterface apiInterface = NetwrokModule.getIns().getApiInterface();

    // 대기메시지 띄움
    activity.progressShow();

    // RequestBody로 변환 후 MultipartBody.Part로 파일 컨버전
    RequestBody requestBmp = RequestBody.create(MediaType.parse("multipart/form-data"), destFile);
    MultipartBody.Part Bmp = MultipartBody.Part.createFormData("IMG_FILE", destFile.getName(), requestBmp);

    // 나머지 String변수는 HashMap으로 전송한다
    HashMap<String, RequestBody> map = new HashMap<>();
    RequestBody langCode = createPartFromString("KOR");
    RequestBody workType = createPartFromString("N");
    RequestBody Title = createPartFromString(destFile.getName());
    RequestBody userId = createPartFromString(UserDatas.getIns().userInfo.saUserID);

    map.put("WORK_TYPE",workType);
    map.put("IMG_TITLE",Title);
    map.put("USER_ID",userId);

    // Api 호출
    Call<BaseNetwrok> call1 = apiInterface.doGetPhotoUpload(map, Bmp);
    call1.enqueue(new Callback<BaseNetwrok>() {
        @Override
        public void onResponse(Call<BaseNetwrok> call, Response<BaseNetwrok> response) {
            Log.e("####", "BaseNetwrok" +  new Gson().toJson(response.body()));

            // 대기메시지 종료
            activity.progressDismiss();
            if(response.body().isSuccess()) {
                // 이미지 리스트 불러오기
                getPhotoList();
            }
            else {
            }
        }

        // 실패 시 이벤트
        @Override
        public void onFailure(Call<BaseNetwrok> call, Throwable t) {
            // 대기메시지 종료
            activity.progressDismiss();
        }
    });
}

 

- APIInterface

 서버의 API와 연결하는 부분입니다

@Multipart
@POST("inout_sjt/APP_IMG_UPLOAD.do")
Call<BaseNetwrok> doGetPhotoUpload(@PartMap() Map<String, RequestBody> partMap,
                                   @Part MultipartBody.Part ImgFile);

 

 

여기까지 제가 구현했던 안드로이드 프로젝트의 갤러리에서 이미지를 가져와서 서버에 전송하기 까지 구현한 내용입니다

밑에는 구분 지은 것이 아닌 전체 소스입니다

// 클릭 이벤트
@Override
public void onClick(View view) {
    switch (view.getId()) {
        // 갤러리에서 사진 업로드 클릭
        case R.id.gallery:
            // 갤러리에서 사진 가져오기 창을 띄운다.
            Intent intent = new Intent();
            intent.setData(android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
            intent.setType("image/*");
            intent.setAction(Intent.ACTION_GET_CONTENT);
            
            // 위의 Activity를 실행한 이후 이벤트를 정의
            startActivityForResult(intent, REQUEST_CODE);
            break;
    }
}

// 서버에 이미지 전송
private void SendImage()
{
    // 서버와 송수신을 하기위한 APIInterface 선언
    APIInterface apiInterface = NetwrokModule.getIns().getApiInterface();

    // 대기메시지 띄움
    activity.progressShow();

    // RequestBody로 변환 후 MultipartBody.Part로 파일 컨버전
    RequestBody requestBmp = RequestBody.create(MediaType.parse("multipart/form-data"), destFile);
    MultipartBody.Part Bmp = MultipartBody.Part.createFormData("IMG_FILE", destFile.getName(), requestBmp);

    // 나머지 String변수는 HashMap으로 전송한다
    HashMap<String, RequestBody> map = new HashMap<>();
    RequestBody langCode = createPartFromString("KOR");
    RequestBody workType = createPartFromString("N");
    RequestBody Title = createPartFromString(destFile.getName());
    RequestBody userId = createPartFromString(UserDatas.getIns().userInfo.saUserID);

    map.put("WORK_TYPE",workType);
    map.put("IMG_TITLE",Title);
    map.put("USER_ID",userId);

    // Api 호출
    Call<BaseNetwrok> call1 = apiInterface.doGetPhotoUpload(map, Bmp);
    call1.enqueue(new Callback<BaseNetwrok>() {
        @Override
        public void onResponse(Call<BaseNetwrok> call, Response<BaseNetwrok> response) {
            Log.e("####", "BaseNetwrok" +  new Gson().toJson(response.body()));

            // 대기메시지 종료
            activity.progressDismiss();
            if(response.body().isSuccess()) {
                // 이미지 리스트 불러오기
                getPhotoList();
            }
            else {
            }
        }

        // 실패 시 이벤트
        @Override
        public void onFailure(Call<BaseNetwrok> call, Throwable t) {
            // 대기메시지 종료
            activity.progressDismiss();
        }
    });
}

// Image의 절대경로를 가져오는 메소드
private String getRealPathFromURI(Uri contentUri) {
    if (contentUri.getPath().startsWith("/storage")) {
        return contentUri.getPath();
    }
    String id = DocumentsContract.getDocumentId(contentUri).split(":")[1];
    String[] columns = { MediaStore.Files.FileColumns.DATA };
    String selection = MediaStore.Files.FileColumns._ID + " = " + id;
    Cursor cursor = activity.getContentResolver().query(MediaStore.Files.getContentUri("external"), columns, selection, null, null);
    try {
        int columnIndex = cursor.getColumnIndex(columns[0]);
        if (cursor.moveToFirst())
        { return cursor.getString(columnIndex);
        }
    } finally {
        cursor.close();
    } return null;
}

@NonNull
private RequestBody createPartFromString(String descriptionString) {
    return RequestBody.create(okhttp3.MultipartBody.FORM, descriptionString);
}

@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    switch (requestCode) {
        // 사진업로드 이벤트
        case REQUEST_CODE:
            // 사진 선택
            if(resultCode == Activity.RESULT_OK)
            {
                try{
                    // Image 상대경로를 가져온다
                    Uri uri = data.getData();
                    // Image의 절대경로를 가져온다
                    String imagePath = getRealPathFromURI(uri);
                    // File변수에 File을 집어넣는다
                    destFile = new File(imagePath);

                    // 이미지 전송
                    SendImage();
                }
                catch(Exception e) {
                    // 대기메시지 종료
                    activity.progressDismiss();
                }
            }
            // 사진 선택 취소
            else if(resultCode == activity.RESULT_CANCELED)
            {
                Toast.makeText(activity, "사진 선택 취소", Toast.LENGTH_LONG).show();
            }
            break;
    }
}

 

이 글이 안드로이드 개발을 하는 개발자 분들에게 도움이 되었으면 좋겠습니다

반응형
그리드형