일부 코드만 살펴보도록 하겠습니다.

 

서버 통신에 대한 자세한 정보는 구글링하면 많이 나오고, 저 같은 경우 파이썬과 연동하기 위해서 온갖 자료를 찾다가, 겨우 찾은 동영상에서 엄청난 도움을 받았습니다.

 

https://www.youtube.com/watch?v=b7VkbAUqMqMhttps://youtu.be/b7VkbAUqMqM

 

해당 링크입니다. 저는 Face Detect를 Measuring size of object로 바꿔 응용했을 뿐입니다.

 

1. 파일 선택, 저장을 위한 메소드

서버로 파일, 그러니까 사진을 전송하기 전 저장소에 접근하고 가져와야합니다.

 

private void onCamera() {
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);

if (intent.resolveActivity(getPackageManager()) != null) {
File photoFile = null;
try {
photoFile = saveImageFile();
} catch (IOException e) {
// Error occurred while creating the File
e.printStackTrace();
println("저장 실패");
}
// 파일 생성에 성공했을 경우에만 동작
if (photoFile != null) {
Uri photoURI = FileProvider.getUriForFile(this,
"com.example.upload.fileprovider",
photoFile);
intent.putExtra(MediaStore.EXTRA_OUTPUT, photoURI);
startActivityForResult(intent, CAMERA_REQUEST);
}
}
}

 

//이미지 파일을 내부 저장소에 저장하는 메소드
private File saveImageFile() throws IOException {
File storageDir = new File("/sdcard/DCIM/Camera");
println("sdir : " + storageDir.toString());

current = System.currentTimeMillis();
date = new Date(current);
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd_hhmmss");
String name = sdf.format(date);

File image = File.createTempFile(
name, /* prefix */
".jpg", /* suffix */
storageDir /* directory */
);

currentImagePath = image.getAbsolutePath();

return image;
}

 

onCamera는 앱에서 카메라를 사용하는 메소드입니다. 실패했을 경우 log를 남깁니다.

try구문에서 saveImageFile() 메소드로 이동하게 되는데 이것은 이미지 파일을 저장하는 메소드입니다.

 

/sdcard/DCIM/Camera 경로에 name(현재시간)으로 파일을 저장합니다.

 

2. 사진을 서버에 업로드

private void uploadImage() {
if (selectedFileUri != null) {
dialog = new ProgressDialog(MeasureActivity.this);
dialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
dialog.setMessage("Uploading....");
dialog.setIndeterminate(false);
dialog.setMax(100);
dialog.setCancelable(false);
dialog.show();

File file = null;
try {
file = new File(Common.getFilePath(this, selectedFileUri));
} catch (URISyntaxException e) {
e.printStackTrace();
}

if (file != null) {
final ProgressRequestBody requestBody = new ProgressRequestBody(file, this);

final MultipartBody.Part body = MultipartBody.Part.createFormData("image", file.getName(), requestBody);

new Thread(new Runnable() {
@Override
public void run() {
mService.uploadFile(body)
.enqueue(new Callback<String>() {
@Override
public void onResponse(Call<String> call, Response<String> response) {
dialog.dismiss();

String image_processed_link;

image_processed_link = new StringBuffer("http://10.11.6.53:8000/" +
response.body().replace("\\", "")).toString();


String[] str = image_processed_link.split("\"");
String imageLink = "";
for (int i = 0; i < str.length; i++)
imageLink += str[i];

Picasso.get().load(imageLink).into(imageView);
basicsImage.setImageBitmap(null);

}

@Override
public void onFailure(Call<String> call, Throwable t) {
dialog.dismiss();
t.printStackTrace();
Toast.makeText(MeasureActivity.this, "" + t.getMessage(), Toast.LENGTH_SHORT).show();
}
});
}
}).start();
}
} else {
Toast.makeText(this, "Cannot upload this file!!", Toast.LENGTH_SHORT).show();
}
}

 

업로드 버튼을 눌렀을 때 동작하는 메소드입니다.

ImageView에 이미지가 있을 경우 업로드를 시도하며, dialog로 확인할 수 있습니다. 하지만 제대로 동작한다면 dialog는 보이지 않을 정도로 순식간에 지나가고, 문제가 있을 경우 dialog 화면이 지속되다가 오류 메시지를 보게 됩니다.

 

중요한 부분은

 

if (file != null) {
final ProgressRequestBody requestBody = new ProgressRequestBody(file, this);

 

부터입니다. 스레드가 실행되면서 mService.uploadFile(업로드API)가 body를 변수로 받아 서버로 보내면

응답(response)을 받게 되는데 그것을 Picasso를 이용하여 imageView에 set합니다.

 

여기서 주의할 점은 영상을 따라가다 보면 RetrofitClient 클래스를 만들게 되는데

해당 클래스의 Retrofit의 baseUrI와 uploadImage()의 image_processed_link의 Uri가 같아야 한다는 겁니다.

 

둘이 다르면 절대로 동작하지 않습니다. 추가로 설명하면 영상에서는 10.0.2.2를 사용하는데, 실제 디바이스의 경우 PC의 IP를 사용해야합니다.

 

또 하나 주의할 점은 이 코드는 http를 기준으로 동작한다는 겁니다. 서버가 https일 경우 오류가 발생할 겁니다.

 

 

다른 코드의 경우 링크 영상에 전부 있는 내용이라 생략하겠습니다.

+ Recent posts