아래의 코드는 사진을 S3에 저장하는 코드 이다 .
아래에 내가 해둔 Provider 로 바꿔 주면 된다.
해줘야 하는게 좀 많으니 잘 보고 설정해 줍시다.
하면 잘 돌아갑니당
-------Manifest-------------
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.INTERNET" />
android:networkSecurityConfig 을 해줘야 한다.
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:networkSecurityConfig="@xml/network_security_config"
---------Xml 문서------------------- 새로만들어주기------------------------------------
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
<base-config cleartextTrafficPermitted="true">
<trust-anchors>
<certificates src="system" />
</trust-anchors>
</base-config>
</network-security-config>
------------------------------------------------------------------------------------------------
<uses-library android:name="com.google.android.maps" />
<uses-library
android:name="org.apache.http.legacy"
android:required="false" />
<provider
android:name="androidx.core.content.FileProvider"
android:authorities="com.jhn.googlemaptest.fileprovider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/fileprovider" />
</provider>
-------------ImageApi----------------
interface 입니당
package com.jhn.googlemaptest.api;
import com.jhn.googlemaptest.model.ImageRes;
import java.util.Map;
import okhttp3.MultipartBody;
import okhttp3.RequestBody;
import retrofit2.Call;
import retrofit2.http.GET;
import retrofit2.http.Multipart;
import retrofit2.http.POST;
import retrofit2.http.Part;
import retrofit2.http.PartMap;
public interface ImageApi {
// 이미지 S3에 저장하기
@Multipart
@POST("/dev/api/v1/posting")
Call<ImageRes> posting(@Part MultipartBody.Part image);
// 라벨링하는 코드
@GET("/dev/api/v1/labling")
Call<ImageRes> labling(@Part MultipartBody.Part image,
@PartMap Map<String, RequestBody> params);
}
------------------ImageRes--------------------
package com.jhn.googlemaptest.model;
import java.io.Serializable;
public class ImageRes {
private String result;
public String getResult() {
return result;
}
public void setResult(String result) {
this.result = result;
}
}
---------------------Utils----------------------------
package com.jhn.googlemaptest.utils;
public class Utils {
// AWS URL
public static final String BASE_URL = "서버리스 또는 aws IAM 주소 ";
public static final String IMAGE_URL = "S3 주소 ";
// 저장소 정보
public static final String PREFERENCES_NAME = "yh_Scooter_DB";
}
---------------NetworkClient--------------
import android.content.Context;
import com.jhn.googlemaptest.utils.Utils;
import java.util.concurrent.TimeUnit;
import okhttp3.OkHttpClient;
import okhttp3.logging.HttpLoggingInterceptor;
import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;
public class NetworkClient {
public static Retrofit retrofit;
public static Retrofit getRetrofitClient(Context context){
if(retrofit == null){
HttpLoggingInterceptor loggingInterceptor = new HttpLoggingInterceptor();
loggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BASIC);
OkHttpClient httpClient = new OkHttpClient.Builder()
.connectTimeout(1, TimeUnit.MINUTES)
.readTimeout(1, TimeUnit.MINUTES)
.writeTimeout(1, TimeUnit.MINUTES)
.addInterceptor(loggingInterceptor).build();
retrofit = new Retrofit.Builder().baseUrl(Utils.BASE_URL)
.client(httpClient)
.addConverterFactory(GsonConverterFactory.create())
.build();
}
return retrofit;
}
}
-------------Main Code---------------
Uri fileProvider = FileProvider.getUriForFile(ResultActivity.this,
"com.jhn.googlemaptest.fileprovider", photoFile);
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import androidx.core.content.FileProvider;
import android.Manifest;
import android.annotation.SuppressLint;
import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Matrix;
import android.media.ExifInterface;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.os.ParcelFileDescriptor;
import android.provider.MediaStore;
import android.provider.OpenableColumns;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
import com.jhn.googlemaptest.api.ImageApi;
import com.jhn.googlemaptest.api.NetworkClient;
import com.jhn.googlemaptest.model.ImageRes;
import org.apache.commons.io.IOUtils;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.text.SimpleDateFormat;
import java.util.Date;
import okhttp3.MediaType;
import okhttp3.MultipartBody;
import okhttp3.RequestBody;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
import retrofit2.Retrofit;
public class ResultActivity extends AppCompatActivity {
TextView txt1;
TextView txt2;
Button button;
Button button2;
ImageView imgPhoto;
public static final int REQ_REGISTER_CHECK = 101;
public static final int REQ_LOGIN_CHECK = 102;
public static final int REQ_PHOTO_CAPTURE = 103;
public static final int REQ_PHOTO_SELECTION = 104;
private ProgressDialog progressDialog;
String[] permissions = {
Manifest.permission.INTERNET,
Manifest.permission.CAMERA,
Manifest.permission.READ_EXTERNAL_STORAGE,
Manifest.permission.WRITE_EXTERNAL_STORAGE,
Manifest.permission.ACCESS_COARSE_LOCATION,
Manifest.permission.ACCESS_FINE_LOCATION
};
private File photoFile;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_result);
txt1 = findViewById(R.id.txt1);
txt2 = findViewById(R.id.txt2);
button = findViewById(R.id.button);
button2 = findViewById(R.id.button2);
imgPhoto = findViewById(R.id.imgPhoto);
Intent intent = getIntent();
long duration = intent.getExtras().getLong("duration");
txt1.setText("이용시간 : " + (duration / 60000) + "분");
txt2.setText("이용금액 : " + (duration / 60000) * 200 + "원");
// 사진촬영하기 버튼
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
showDialog();
}
});
button2.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent intent = new Intent(ResultActivity.this, LastActivity.class);
startActivity(intent);
}
});
}
private void camera(){
int permissionCheck = ContextCompat.checkSelfPermission(
ResultActivity.this, Manifest.permission.CAMERA);
if(permissionCheck != PackageManager.PERMISSION_GRANTED){
ActivityCompat.requestPermissions(ResultActivity.this,
new String[]{Manifest.permission.CAMERA} ,
1000);
Toast.makeText(ResultActivity.this, "카메라 권한 필요합니다.",
Toast.LENGTH_SHORT).show();
return;
} else {
Intent i = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if(i.resolveActivity(ResultActivity.this.getPackageManager()) != null ){
// 사진의 파일명을 만들기
String fileName = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
photoFile = getPhotoFile(fileName);
Uri fileProvider = FileProvider.getUriForFile(ResultActivity.this,
"com.jhn.googlemaptest.fileprovider", photoFile);
i.putExtra(MediaStore.EXTRA_OUTPUT, fileProvider);
startActivityForResult(i, 100);
} else{
Toast.makeText(ResultActivity.this, "이폰에는 카메라 앱이 없습니다.",
Toast.LENGTH_SHORT).show();
}
}
}
private void album(){
if(checkPermission()){
displayFileChoose();
}else{
requestPermission();
}
}
private File getPhotoFile(String fileName) {
File storageDirectory = getExternalFilesDir(Environment.DIRECTORY_PICTURES);
try{
return File.createTempFile(fileName, ".jpg", storageDirectory);
}catch (IOException e){
e.printStackTrace();
return null;
}
}
private boolean checkPermission(){
int result = ContextCompat.checkSelfPermission(ResultActivity.this,
Manifest.permission.WRITE_EXTERNAL_STORAGE);
if(result == PackageManager.PERMISSION_DENIED){
return false;
}else{
return true;
}
}
private void displayFileChoose() {
Intent i = new Intent();
i.setType("image/*");
i.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(Intent.createChooser(i, "SELECT IMAGE"), 300);
}
private void requestPermission() {
if(ActivityCompat.shouldShowRequestPermissionRationale(ResultActivity.this,
Manifest.permission.WRITE_EXTERNAL_STORAGE)){
Toast.makeText(ResultActivity.this, "권한 수락이 필요합니다.",
Toast.LENGTH_SHORT).show();
}else{
ActivityCompat.requestPermissions(ResultActivity.this,
new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 500);
}
}
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
switch (requestCode) {
case 1000: {
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
Toast.makeText(ResultActivity.this, "권한 허가 되었음",
Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(ResultActivity.this, "아직 승인하지 않았음",
Toast.LENGTH_SHORT).show();
}
break;
}
case 500: {
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
Toast.makeText(ResultActivity.this, "권한 허가 되었음",
Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(ResultActivity.this, "아직 승인하지 않았음",
Toast.LENGTH_SHORT).show();
}
}
}
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
if(requestCode == 100 && resultCode == RESULT_OK){
// 카메라로 찍은 사진은 사진으로 바꾸는 코드
Bitmap photo = BitmapFactory.decodeFile(photoFile.getAbsolutePath());
ExifInterface exif = null;
try {
exif = new ExifInterface(photoFile.getAbsolutePath());
} catch (IOException e) {
e.printStackTrace();
}
int orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION,
ExifInterface.ORIENTATION_UNDEFINED);
photo = rotateBitmap(photo, orientation);
// 압축시킨다. 해상도 낮춰서
OutputStream os;
try {
os = new FileOutputStream(photoFile);
photo.compress(Bitmap.CompressFormat.JPEG, 100, os);
os.flush();
os.close();
} catch (Exception e) {
Log.e(getClass().getSimpleName(), "Error writing bitmap", e);
}
SendImage();
}else if(requestCode == 300 && resultCode == RESULT_OK && data != null &&
data.getData() != null){
// 앨범 을 Uri 로 바꾸고 S3에 저장시키는 코드
Uri albumUri = data.getData( );
String fileName = getFileName( albumUri );
try {
ParcelFileDescriptor parcelFileDescriptor = getContentResolver( ).openFileDescriptor( albumUri, "r" );
if ( parcelFileDescriptor == null ) return;
FileInputStream inputStream = new FileInputStream( parcelFileDescriptor.getFileDescriptor( ) );
photoFile = new File( this.getCacheDir( ), fileName );
FileOutputStream outputStream = new FileOutputStream( photoFile );
IOUtils.copy( inputStream, outputStream );
// 압축시킨다. 해상도 낮춰서
Bitmap photo = BitmapFactory.decodeFile(photoFile.getAbsolutePath());
OutputStream os;
try {
os = new FileOutputStream(photoFile);
photo.compress(Bitmap.CompressFormat.JPEG, 100, os);
os.flush();
os.close();
} catch (Exception e) {
Log.e(getClass().getSimpleName(), "Error writing bitmap", e);
}
SendImage();
} catch ( Exception e ) {
e.printStackTrace( );
}
}
super.onActivityResult(requestCode, resultCode, data);
}
private void showProgress(String message) {
progressDialog = new ProgressDialog(this);
progressDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
progressDialog.setMessage(message);
progressDialog.show();
}
public static Bitmap rotateBitmap(Bitmap bitmap, int orientation) {
Matrix matrix = new Matrix();
switch (orientation) {
case ExifInterface.ORIENTATION_NORMAL:
return bitmap;
case ExifInterface.ORIENTATION_FLIP_HORIZONTAL:
matrix.setScale(-1, 1);
break;
case ExifInterface.ORIENTATION_ROTATE_180:
matrix.setRotate(180);
break;
case ExifInterface.ORIENTATION_FLIP_VERTICAL:
matrix.setRotate(180);
matrix.postScale(-1, 1);
break;
case ExifInterface.ORIENTATION_TRANSPOSE:
matrix.setRotate(90);
matrix.postScale(-1, 1);
break;
case ExifInterface.ORIENTATION_ROTATE_90:
matrix.setRotate(90);
break;
case ExifInterface.ORIENTATION_TRANSVERSE:
matrix.setRotate(-90);
matrix.postScale(-1, 1);
break;
case ExifInterface.ORIENTATION_ROTATE_270:
matrix.setRotate(-90);
break;
default:
return bitmap;
}
try {
Bitmap bmRotated = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
bitmap.recycle();
return bmRotated;
}
catch (OutOfMemoryError e) {
e.printStackTrace();
return null;
}
}
// private void dismissProgress() {
// progressDialog.dismiss();
// }
private void showDialog() {
AlertDialog.Builder builder = new AlertDialog.Builder(ResultActivity.this);
builder.setTitle("선택하세요").setItems(R.array.camera_array, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
if (i == 0) {
// 카메라로 사진찍는 함수 실행
camera();
} else if (i == 1) {
// 앨범에서 사진 가져오는 함수 실행
album();
}
}
}); AlertDialog alertDialog = builder.create();
alertDialog.show();
}
private void SendImage() {
// S3에 보내는 코드
Retrofit retrofit = NetworkClient.getRetrofitClient(ResultActivity.this);
ImageApi api = retrofit.create(ImageApi.class);
Log.i("ImageAPi 성공 시 ", "1111");
// MemoReq memoReq = new MemoReq(title, datetime, content);
RequestBody fileBody = RequestBody.create(photoFile,
MediaType.parse("image/*"));
MultipartBody.Part part = MultipartBody.Part.createFormData(
"image", photoFile.getName(), fileBody
);
Log.i("img_url", photoFile.getName());
Call< ImageRes > call = api.posting(part);
Log.i("MyMemoApp", "2222");
call.enqueue(new Callback<ImageRes>() {
@Override
public void onResponse(Call<ImageRes> call, Response<ImageRes> response) {
// dismissProgress();
if (response.isSuccessful()) {
Toast.makeText(getApplicationContext(),"성공적으로 잘 갔습니다.",Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(ResultActivity.this,
"문제 발생",
Toast.LENGTH_SHORT).show();
return;
}
}
@Override
public void onFailure(Call<ImageRes> call, Throwable t) {
// dismissProgress();
Toast.makeText(ResultActivity.this,
"네트워크 문제 발생",
Toast.LENGTH_SHORT).show();
return;
}
});
}
//앨범에서 선택한 사진이름 가져오기
public String getFileName( Uri uri ) {
Cursor cursor = getContentResolver( ).query( uri, null, null, null, null );
try {
if ( cursor == null ) return null;
cursor.moveToFirst( );
@SuppressLint("Range") String fileName = cursor.getString( cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME) );
cursor.close( );
return fileName;
} catch ( Exception e ) {
e.printStackTrace( );
cursor.close( );
return null;
}
}
}
'프론트엔드 > 안드로이드 스튜디오' 카테고리의 다른 글
안드로이드 스튜디오 : 시간 카운터하기 / CountDownTimer /카운트 다운 (0) | 2022.03.22 |
---|---|
안드로이드 스튜디오 : 핸들러와 스레드 이용해서 현재시간 갱신하기 (0) | 2022.03.22 |
안드로이드 스튜디오 : Multipart 이미지 전송하기 / 여러 데이터 전송하기 /@Part MultipartBody.Part (0) | 2022.03.16 |
안드로이드 스튜디오 : 사진찍기/갤러리 불러오기 (0) | 2022.03.16 |
안드로이드 스듀디오 : Intent 를 이용하여 다른 클래스에 string,int 보내기 (0) | 2022.03.15 |