기억 저장소

클라우드 기반 인공지능 개발과 DevOps 실무

프론트엔드/안드로이드 스튜디오

안드로이드 스튜디오 : 사진 찍으면 S3에 저장하기 / 갤러리에 사진을 S3에 저장하기

하늘.98 2022. 3. 16. 18:06

아래의 코드는 사진을 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;
        }
    }

    }