관리 메뉴

나만을 위한 블로그

[Android] 카메라로 이미지 가져와 이미지뷰에 붙이는 법 본문

Android

[Android] 카메라로 이미지 가져와 이미지뷰에 붙이는 법

참깨빵위에참깨빵_ 2020. 6. 16. 13:26
728x90
반응형

매니페스트의 <application> 태그 최하단에 <provider>를 만들어준다.

현재 안드로이드 스튜디오가 androidx로 버전업된 상태고 구글링하면 android.support 이런 식의 코드들이 나오는데 다 필요없고 이렇게 쓰면 된다.

 

<provider
            android:name="androidx.core.content.FileProvider"
            android:authorities="{com.example.패키지명}.provider"
            android:exported="false"
            android:grantUriPermissions="true">
            <meta-data
                android:name="android.support.FILE_PROVIDER_PATHS"
                android:resource="@xml/paths" />
        </provider>

 

3번째 줄의 authorities 옆 com.example.패키지명에는 자신의 프로젝트의 패키지명을 쓰면 된다.

패키지명 부분이 absolute라면 {com.example.absolute}.provider라고 써주면 된다.

 

그리고 자바 클래스의 카메라에서 이미지를 가져오는 함수는 이렇게 설정하면 된다.

 

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

        try {
            tempFile = createImageFile();
        }   catch (Exception e) {
            Toast.makeText(this, "이미지 처리 오류", Toast.LENGTH_SHORT).show();
            finish();
            e.printStackTrace();
        }

        if (tempFile != null)
        {
            Uri photoUri = FileProvider.getUriForFile(this, "{com.example.패키지명}.provider", tempFile);
            intent.putExtra(MediaStore.EXTRA_OUTPUT, photoUri);
            startActivityForResult(intent, PICK_FROM_CAMERA);
        }
    }

위에서 매니페스트에 com.example.absolute라고 쓰라 했는데 자바 클래스에서도 똑같이 써주면 된다.

패키지명을 지우고 자기 프로젝트의 패키지명을 써주자. 가운데가 example이 아니라면 마찬가지로 이곳도 바꿔주면 된다.

 

아래는 카메라에서 이미지를 가져오는 코드다. 매니페스트에 3개의 권한을 설정해야 한다.

 

<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.CAMERA" />

아래 변수들은 전역변수로 두면 된다.

 

private Boolean isPermission = true;
private static final int PICK_FROM_CAMERA = 2;
private File tempFile;

 

아래 함수들은 액티비티의 아무 곳에나 두고 쓰면 된다.

버튼 클릭 리스너가 람다식으로 되어 있어서 안될 수 있는데 이 부분만 일반적인 버튼 클릭 리스너 호출문으로 바꿔주면 된다.

 

picture_btn.setOnClickListener(view -> {
            tedPermission();
            if (isPermission)
            {
                takePhoto();
            }
            else
            {
                Toast.makeText(this, getResources().getString(R.string.permission_denied), Toast.LENGTH_SHORT).show();
            }
        });
        
        // 카메라에서 이미지 가져오기
    private void takePhoto()
    {
        Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);

        try {
            tempFile = createImageFile();
        }   catch (Exception e) {
            Toast.makeText(this, "이미지 처리 오류, 다시 시도해 주세요", Toast.LENGTH_SHORT).show();
            finish();
            e.printStackTrace();
        }

        if (tempFile != null)
        {
            Uri photoUri = FileProvider.getUriForFile(this, "{com.example.패키지명}.provider", tempFile);
            intent.putExtra(MediaStore.EXTRA_OUTPUT, photoUri);
            startActivityForResult(intent, PICK_FROM_CAMERA);
        }
    }
    
    // 폴더 및 파일 만들기
    private File createImageFile() throws IOException
    {
        // 이미지 파일명
        String timeStamp = new SimpleDateFormat("HHmmss", Locale.KOREA).format(new Date());
        String imageFileName = "imgFile_" + timeStamp + "_";

        // 이미지가 저장될 폴더명
        File storageDir = new File(Environment.getExternalStorageDirectory() + "/");
        if (!storageDir.exists())
        {
            storageDir.mkdirs();
        }
        // 파일 생성
        File image = File.createTempFile(imageFileName, ".jpg", storageDir);
        Log.e(TAG, "createImageFile : " + image.getAbsolutePath());
        return image;
    }
    
    @Override
    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data)
    {
        super.onActivityResult(requestCode, resultCode, data);
        if (resultCode != Activity.RESULT_OK)
        {
            Toast.makeText(this, "취소됨", Toast.LENGTH_SHORT).show();
            if (tempFile != null)
            {
                if (tempFile.exists())
                {
                    if (tempFile.delete())
                    {
                        Log.e(TAG, tempFile.getAbsolutePath() + " 삭제 성공");
                        tempFile = null;
                    }
                }
            }
            return;
        }

        if (requestCode == PICK_FROM_CAMERA)
        {
            setImage();
        }
    }
    
    private void setImage()
    {
        ImageView imageView = (ImageView) findViewById(R.id.study_profile);

        BitmapFactory.Options options = new BitmapFactory.Options();
        Bitmap originalBm = BitmapFactory.decodeFile(tempFile.getAbsolutePath(), options);
        Log.e(TAG, "setImage : " + tempFile.getAbsolutePath());

        imageView.setImageBitmap(originalBm);
        tempFile = null;
    }
    
    private void tedPermission()
    {
        PermissionListener permissionListener = new PermissionListener() {
            @Override
            public void onPermissionGranted()
            {
                isPermission = true;
            }

            @Override
            public void onPermissionDenied(List<String> deniedPermissions)
            {
                isPermission = false;
            }
        };

        TedPermission.with(this)
                .setPermissionListener(permissionListener)
                .setRationaleMessage(getResources().getString(R.string.permission_pls))
                .setDeniedMessage(getResources().getString(R.string.permission_denied))
                .setPermissions(Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.CAMERA)
                .check();
    }
반응형
Comments