본문 바로가기

안드로이드

[안드로이드] 간단한 이미지뷰어 / SD카드에서 이미지 파일 읽기

728x90

# 기능
이전 사진 보기 버튼
다음 사진 보기 버튼
커스텀 이미지 뷰어

# AVM SD카드에 이미지 저장하기

1) SD카드에 이미지 파일 넣기

- Device File Explorer 에서 

 ` (1) sdcard \ Pictures 폴더를 우클릭 upload로 저장

 ` (2) storage \ emulated \ 0 \ Pictures 폴더 우클릭 upload로 저장

 ` 같은 곳을 가리키기 때문에 (1)번, 2(번) 아무 방법이나 하셔도 둘 다 생성되어 있습니다.

 

- Device File Explorer 윈도우가 안보인다면

 ` View \ Tool Windows 에서 찾을 수 있습니다.

 ` Device Manager 의 해당 AVM 설정에서도 찾을 수 있습니다.

 

# 커스텀 위젯 만들기

1. Project Tree \ app \ java \ "패키지 명" 을 우클릭
2. New \ Java Class 클릭
3. "myPictureView" 로 이름짓고 엔터 (하단에는 Java가 선택되어 있어야 합니다)
package com.siku.imageviewer;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.util.AttributeSet;
import android.view.View;

import androidx.annotation.Nullable;

// View 클래스 상속
public class myPictureView extends View{
    String imagePath = null;
    
    // ctrl+o, View(context:Context, attrs:AttributeSet) 메서드 추가
    public myPictureView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
    }
	
    // ctrl+o, onDraw 메서드 추가
    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);

        if(imagePath != null){
        	// 화면에 그림파일을 출력한다.
            Bitmap bitmap = BitmapFactory.decodeFile(imagePath);
            canvas.drawBitmap(bitmap, 0, 0, null);
            bitmap.recycle();
        }
    }
}

 

# AndroidManifest.xml

안드로이드는 보안 문제로 앱에서 파일, 사진, 미디어 등에 접근하려면 액세스 가능하도록 코딩해야합니다.

- Project Tree \ add \ mainfests \ AndroidManifest.xml 열기
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.sikuroku.project8_2_imageviewer">
    
    // ↓ 이 부분을 추가해야 합니다.
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
    // ↑
    
    <application
    	
        // ↓ 이 부분을 추가해야 합니다.
        android:requestLegacyExternalStorage="true"
        // ↑
        
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/Theme.Project8_2_ImageViewer">
        <activity
            android:name=".MainActivity"
            android:exported="true">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

 

# activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        >
        <Button
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:id="@+id/btnPrev"
            android:text="prev"/>
        <Button
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:id="@+id/btnNext"
            android:text="Next"/>
    </LinearLayout>
	
    // 위에서 생성한 myPictureView.java를 위젯으로 사용합니다.
    <com.siku.imageviewer.myPictureView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/myPictureView1"/>

</LinearLayout>

 

# MainActivity.java

package com.siku.imageviewer;

import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;

import android.Manifest;
import android.os.Bundle;
import android.os.Environment;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;

import java.io.File;

public class MainActivity extends AppCompatActivity {

    // 이전 버튼, 다음 버튼
    Button btnPrev, btnNext;
    
    // 커스텀 위젯
    myPictureView myPicture;
    
    // 사진을 순서대로 참조할 참조 변수
    int curNum=0;
    
    // 불러온 이미지가 저장될 배열
    File[] imageFiles;
    
    // 이미지 파일 이름
    String imageFname;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        setTitle("간단한 이미지 뷰어");
	
    	// 액세스 허용 메시지 상자가 나옵니다.
        // 허용을 눌러야 저장소의 파일 접근이 가능합니다.
        ActivityCompat.requestPermissions(this, new String[] {
                Manifest.permission.WRITE_EXTERNAL_STORAGE}, MODE_PRIVATE);
        
        // 각 위젯 변수 선언
        btnPrev = findViewById(R.id.btnPrev);
        btnNext = findViewById(R.id.btnNext);
        myPicture = findViewById(R.id.myPictureView1);
		
        // 파일을 읽어 배열에 저장
        imageFiles = new File(Environment.getExternalStorageDirectory().getAbsolutePath()
        					  +"/Pictures").listFiles();
                              
		// 이미지 파일 이름 저장
        imageFname = imageFiles[curNum].toString();
        
        // 이미지출력 위젯에 파일 이름을 전달합니다.
        myPicture.imagePath = imageFname;
		
        // 이전 버튼
        btnPrev.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                
                // 첫번째 사진에서 이전 버튼을 누르면
                if(curNum==0){
                    Toast.makeText(getApplicationContext(), "첫 번째 사진입니다.",
                    				Toast.LENGTH_SHORT).show();
                }
                else{
                    curNum--;
                    
                    // 이전 이미지 파일 이름 가져오기
                    imageFname = imageFiles[curNum].toString();
                    
                    // 이미지 위젯에 파일 이름 전달하기
                    myPicture.imagePath = imageFname;
                    
                    // 이미지 위젯 화면 갱신하기
                    myPicture.invalidate();
                }

            }
        });
		
        // 다음 버튼
        btnNext.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                
                // 
                if(curNum == imageFiles.length-2){
                    Toast.makeText(getApplicationContext(), "마지막 사진입니다.", 
                    				Toast.LENGTH_SHORT).show();
                }else{
                    curNum++;
                    imageFname = imageFiles[curNum].toString();
                    myPicture.imagePath = imageFname;
                    myPicture.invalidate();
                }
            }
        });
    }
}

 

끝.

728x90