상세 컨텐츠

본문 제목

[안드로이드] SQLite RecyclerView 연락처 만드는 방법 part2 - 등록

안드로이드

by aries574 2022. 3. 3. 14:55

본문


이번 시간에는 이전에 이어서 연락처 

등록하는 방법을 알아보겠습니다. 

이전 포스팅을 먼저 보고 오시면 됩니다.

2022.03.02 - [안드로이드] - [안드로이드] SQLite RecyclerView 연락처 만드는 방법 part1 - 조회

 

[안드로이드] SQLite RecyclerView 연락처 만드는 방법 part1 - 조회

앞으로 SQLite, RecyclerView를 통해서 연락처 만드는 방법을 알아보겠습니다. 내용이 많다 보니 조회, 등록, 수정, 삭제 별로 나눠 올리겠습니다. 이번에는 조회 부분입니다. 목차 1. 실행 화면 2. 연락

aries574.tistory.com


목차

1. 실행 화면

2. DB 클래스 등록 기능 구현

3. 연락처 등록 화면(Activity) 만들기

4. 설정 파일 수정

5. 라이브러리 등록

6. 테마 변경

7. 메인 화면 구성 activity_main.xml

8. 메인 코드 구현 MainActivity.java


1. 실행 화면

 

2. DB 클래스 등록 기능 구현

 - 설명 - 

 1. 사용자가 입력한 이름, 전화번호, 사진을 저장한다. 

 2. cv.put 를 통해서 저장할 값을 변수에 담는다.  

phoneBookDB.java

    /**
     * 연락처 등록
     * @param name //이름
     * @param phone_number 전화번호
     * @param phone_photo // 사진
     */
    public void addPhoneNumber(String name, String phone_number, byte[] phone_photo){

        SQLiteDatabase db = this.getWritableDatabase();
        ContentValues cv = new ContentValues();

        cv.put(COLUMN_NAME, name);
        cv.put(COLUMN_PHONE_NUMBER, phone_number);
        cv.put(COLUMN_PHONE_PHOTO, phone_photo);

        long result = db.insert(TABLE_NAME, null, cv);
        if(result == -1){
            Toast.makeText(context, "Failed", Toast.LENGTH_SHORT).show();
        }else{
            Toast.makeText(context, "Successfully", Toast.LENGTH_SHORT).show();
        }

 

- 전체 코드 -

public class PhoneBookDB extends SQLiteOpenHelper {
    
    private Context context;
    public static final String DATABASE_NAME = "address.db";
    public static final int DATABASE_VERSION = 1;

    public static final String TABLE_NAME = "phone_info";
    public static final String COLUMN_ID = "_id";
    public static final String COLUMN_NAME = "phone_name";
    public static final String COLUMN_PHONE_NUMBER = "phone_number";
    public static final String COLUMN_PHONE_PHOTO = "user_image";


    public PhoneBookDB(Context context){
        super(context, DATABASE_NAME, null, DATABASE_VERSION);
        this.context = context;
    }
    
    @Override
    public void onCreate(SQLiteDatabase db) {
        
        String query = "CREATE TABLE " + TABLE_NAME + 
                " (" + COLUMN_ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " + 
                COLUMN_NAME + " TEXT, " +
                COLUMN_PHONE_NUMBER + " TEXT, " + 
                COLUMN_PHONE_PHOTO + " BLOP);";
        db.execSQL(query);
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int i, int i1) {
        db.execSQL("DROP TABLE IF EXISTS " + TABLE_NAME);
        onCreate(db);
    }

    /**
     * 연락처 전체 가져오기
     * @return
     */
    public Cursor readAllData(){
        
        String query = "SELECT * FROM " + TABLE_NAME;
        
        SQLiteDatabase db = this.getReadableDatabase();
        
        Cursor cursor = null;
        if(db != null){
            cursor = db.rawQuery(query, null);
        }
        
        return cursor;
    }

    /**
     * 연락처 등록
     * @param name //이름
     * @param phone_number 전화번호
     * @param phone_photo // 사진
     */
    public void addPhoneNumber(String name, String phone_number, byte[] phone_photo){

        SQLiteDatabase db = this.getWritableDatabase();
        ContentValues cv = new ContentValues();

        cv.put(COLUMN_NAME, name);
        cv.put(COLUMN_PHONE_NUMBER, phone_number);
        cv.put(COLUMN_PHONE_PHOTO, phone_photo);

        long result = db.insert(TABLE_NAME, null, cv);
        if(result == -1){
            Toast.makeText(context, "Failed", Toast.LENGTH_SHORT).show();
        }else{
            Toast.makeText(context, "Successfully", Toast.LENGTH_SHORT).show();
        }
    }
}

 

3. 연락처 등록 화면(Activity) 만들기

app -> 마우스 오른쪽 -> New -> Activity -> Empty Activity

 Activity Name: AddActivity

 - 설명 - 

1. 사진 보여줄 이미지뷰, 사진 찍기 기능 버튼, 사진 선택 기능 버튼

 이름입력 에디트 텍스트, 전화번호 입력 에디트 텍스트, 저장 버튼으로

 구성되어 있습니다. 

3-1 activity_add.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="center"
    android:orientation="vertical"
    tools:context=".AddActivity">

    <ImageView
        android:id="@+id/imageView"
        android:layout_width="128dp"
        android:layout_height="128dp"
        android:scaleType="centerCrop"
        android:src="@drawable/photo" />

    <androidx.appcompat.widget.LinearLayoutCompat
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="10dp"
        android:gravity="center"
        android:orientation="horizontal">

        <Button
            android:id="@+id/picture_btn"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="사진찍기" />

        <Button
            android:id="@+id/select_btn"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginStart="10dp"
            android:text="사진선택" />
    </androidx.appcompat.widget.LinearLayoutCompat>

    <EditText
        android:id="@+id/add_name_edit"
        android:layout_width="200dp"
        android:layout_height="wrap_content"
        android:layout_marginTop="30dp"
        android:hint="이름"
        android:inputType="text" />

    <EditText
        android:id="@+id/add_phone_edit"
        android:layout_width="200dp"
        android:layout_height="wrap_content"
        android:layout_marginTop="30dp"
        android:hint="전화번호"
        android:maxLength="13"
        android:inputType="phone" />

    <Button
        android:id="@+id/add_btn"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="30dp"
        android:text="저장" />

</LinearLayout>

이미지 res -> drawable

 - 설명 - 

 1. addTextChangedListener를 통해 전화번호 하이픈 처리를 한다.

 2. ACTION_IMAGE_CAPTURE : 사진 찍기 위한 인텐트(Intent)

 3. ACTION_PICK:  사진 가져오기위한 인텐트(Intent)

 4. imageViewToByte: 이미지를 저장하기 위해서는 타입 변환을 해야 한다. 

  3-2 AddActivity.java

public class AddActivity extends AppCompatActivity {

    Uri uri;

    ImageView imageView;

    EditText addNameEdit, addPhoneEdit;

    Bitmap bitmap;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_add);

        addNameEdit = findViewById(R.id.add_name_edit);
        addPhoneEdit = findViewById(R.id.add_phone_edit);
        imageView = findViewById(R.id.imageView);

        //전화번호 하이픈(-) 자동입력
        addPhoneEdit.addTextChangedListener(new PhoneNumberFormattingTextWatcher());

        Button pictureBtn = findViewById(R.id.picture_btn); //사진찍기 버튼
        Button selectBtn = findViewById(R.id.select_btn);//사진선택 버튼

        //사진찍기
        pictureBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
                activityResultPicture.launch(intent);
            }
        });

        //사진선택
        selectBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Intent intent = new Intent(Intent.ACTION_PICK);
                intent.setType("image/*");
                activityResultSelect.launch(intent);
            }
        });

        //저장버튼
        Button addBtn = findViewById(R.id.add_btn);
        addBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {

                //입력값 변수에 담기
                String name = addNameEdit.getText().toString();
                String phone = addPhoneEdit.getText().toString();

                byte[] data = imageViewToByte(imageView);

                //DB 객체 생성
                PhoneBookDB addressDB = new PhoneBookDB(AddActivity.this);

                //DB에 저장하기
                addressDB.addPhoneNumber(name, phone, data);
            }
        });
    }

    //사진 찍기
    ActivityResultLauncher<Intent> activityResultPicture = registerForActivityResult(
            new ActivityResultContracts.StartActivityForResult(),
            new ActivityResultCallback<ActivityResult>() {
                @Override
                public void onActivityResult(ActivityResult result) {
                    if( result.getResultCode() == RESULT_OK && result.getData() != null){

                        Bundle extras = result.getData().getExtras();

                        bitmap = (Bitmap) extras.get("data");

                        imageView.setImageBitmap(bitmap);
                    }
                }
            });

    //사진 가져오기
    ActivityResultLauncher<Intent> activityResultSelect = registerForActivityResult(
            new ActivityResultContracts.StartActivityForResult(),
            new ActivityResultCallback<ActivityResult>() {
                @Override
                public void onActivityResult(ActivityResult result) {
                    if( result.getResultCode() == RESULT_OK && result.getData() != null){

                        try {
                            uri = result.getData().getData();

                            bitmap = MediaStore.Images.Media.getBitmap(getContentResolver(), uri);

                            imageView.setImageBitmap(bitmap);

                        }catch (FileNotFoundException e){
                            e.printStackTrace();
                        }catch (IOException e){
                            e.printStackTrace();
                        }
                    }
                }
            });

    /**
     * 이미지 바이트로 변환
     * @param image 이미지
     * @return
     */
    public static byte[] imageViewToByte(ImageView image) {

        Bitmap bitmap = ((BitmapDrawable)image.getDrawable()).getBitmap();
        ByteArrayOutputStream stream =  new ByteArrayOutputStream();
        bitmap.compress(Bitmap.CompressFormat.JPEG, 100, stream);
        byte[] byteArray = stream.toByteArray();
        return byteArray;
    }
}

 

 

 

4. 설정파일 수정

 manifests -> AndroidManifest.xml

 - 설명 - 

 1. 등록화면에서 메인화면으로 가기 위한 뒤로 가기 버튼 구현

   <activity
            android:name=".AddActivity"
            android:exported="false"
            android:parentActivityName=".MainActivity"
            />

 

5. 라이브러리 등록

build.gradle(Module:프로젝트명:app)

dependencies 괄호 안에 아래 코드를 넣어주시면 됩니다.

implementation 'com.google.android.material:material:1.4.0'

 

6. 테마 변경

( res -> value -> themes)

 <style name="Theme.MaterialExam" parent="Theme.MaterialComponents.Light.DarkActionBar">

 

7. 메인 화면 구성 activity_main.xml

 - 설명 - 

 1. 등록 화면으로 가기 위한 등록버튼을 플로팅 액션 버튼으로 구현

<com.google.android.material.floatingactionbutton.FloatingActionButton
        android:id="@+id/add_btn"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentEnd="true"
        android:layout_alignParentBottom="true"
        android:layout_marginEnd="16dp"
        android:layout_marginBottom="20dp"
        android:backgroundTint="@android:color/holo_green_dark"
        app:tint="@android:color/white"
        app:srcCompat="@drawable/ic_add" />

 - 전체 코드 -

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".MainActivity">

    <androidx.recyclerview.widget.RecyclerView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:id="@+id/recyclerView"/>

    <TextView
        android:id="@+id/noData_text"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="No Data"
        android:textSize="30sp"
        android:layout_centerInParent="true"/>

    <com.google.android.material.floatingactionbutton.FloatingActionButton
        android:id="@+id/add_btn"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentEnd="true"
        android:layout_alignParentBottom="true"
        android:layout_marginEnd="16dp"
        android:layout_marginBottom="20dp"
        android:backgroundTint="@android:color/holo_green_dark"
        app:tint="@android:color/white"
        app:srcCompat="@drawable/ic_add" />
</RelativeLayout>

 아이콘 res -> drawable

ic_add.xml
0.00MB

 

8. 메인 코드 구현 MainActivity.java

- 설명 - 

 저장된 사진을 불러올때, 크기 때문에 오류가 발생하는 걸 방지하는 코드

        //이미지 크기 오류 방지
        try {
            Field field = CursorWindow.class.getDeclaredField("sCursorWindowSize");
            field.setAccessible(true);
            field.set(null, 100 * 1024 * 1024); //the 100MB is the new size
        } catch (Exception e) {
            e.printStackTrace();
        }

 플로팅액션버튼 클릭 시에 등록 화면으로 이동하는 기능 구현

        FloatingActionButton addBtn = findViewById(R.id.add_btn);
        addBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {

                //등록화면으로 이동
                Intent intent = new Intent(MainActivity.this, AddActivity.class);
                startActivity(intent);
            }
        });

 - 전체 코드 -

public class MainActivity extends AppCompatActivity {

    PhoneBookDB db;

    ArrayList<PhoneBook> phoneList = new ArrayList<>();

    RecyclerView recyclerView;

    PhoneBookAdapter adapter;

    TextView noDataText;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        //이미지 크기 오류 방지
        try {
            Field field = CursorWindow.class.getDeclaredField("sCursorWindowSize");
            field.setAccessible(true);
            field.set(null, 100 * 1024 * 1024); //the 100MB is the new size
        } catch (Exception e) {
            e.printStackTrace();
        }

        //데이터 유무 텍스트
        noDataText = findViewById(R.id.noData_text);

        //리스트 보여줄 화면
        recyclerView = findViewById(R.id.recyclerView);

        //어뎁터
        adapter = new PhoneBookAdapter(MainActivity.this);

        //어뎁터 등록
        recyclerView.setAdapter(adapter);

        //레이아웃 설정
        recyclerView.setLayoutManager(new LinearLayoutManager(MainActivity.this));

        //DB 생성성
        db = new PhoneBookDB(MainActivity.this);

        storeDataInArray();

        FloatingActionButton addBtn = findViewById(R.id.add_btn);
        addBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {

                //등록화면으로 이동
                Intent intent = new Intent(MainActivity.this, AddActivity.class);
                startActivity(intent);
            }
        });
    }

    /**
     * 데이터 가져오기
     */
    void storeDataInArray(){

        Cursor cursor = db.readAllData();

        if(cursor.getCount() == 0){

            noDataText.setVisibility(noDataText.VISIBLE);
        }else{
            noDataText.setVisibility(noDataText.GONE);

            while(cursor.moveToNext()){

                PhoneBook phone = new PhoneBook(cursor.getString(0),
                        cursor.getString(1),
                        cursor.getString(2),
                        cursor.getBlob(3));

                //데이터 등록
                phoneList.add(phone);
                adapter.addItem(phone);

                //적용
                adapter.notifyDataSetChanged();
            }
        }
    }
}

2022.03.01 - [안드로이드] - [안드로이드] 온보딩(Onboarding) 페이지 쉽게 만드는 방법

 

[안드로이드] 온보딩(Onboarding) 페이지 쉽게 만드는 방법

이번 시간에는 앱 실행 시에 앱에 관한 설명들을 페이지 형태로 넘겨가면서 보여주는 형태인 온보딩(Onboarding) 페이지 만드는 방법에 대하여 알아보겠습니다. 1. 실행 화면 2. 라이브러리 등록

aries574.tistory.com

2022.03.01 - [안드로이드] - [안드로이드] 온보딩(Onboarding) 페이지 쉽게 만드는 방법

 

[안드로이드] 온보딩(Onboarding) 페이지 쉽게 만드는 방법

이번 시간에는 앱 실행 시에 앱에 관한 설명들을 페이지 형태로 넘겨가면서 보여주는 형태인 온보딩(Onboarding) 페이지 만드는 방법에 대하여 알아보겠습니다. 1. 실행 화면 2. 라이브러리 등록

aries574.tistory.com

2022.02.28 - [안드로이드] - [안드로이드] 알림(Alerter) 쉽게 만드는 방법

 

[안드로이드] 알림(Alerter) 쉽게 만드는 방법

이번 시간에는 알림(Alerter) 쉽게 만드는 방법에 대하여 알아보겠습니다. 목차 1. 실행 화면 2. 라이브러리 등록 3. 메인 화면 구성 activity_main.xml 4. 메인 코드 구현 MainActivity.java 1. 실..

aries574.tistory.com

반응형

관련글 더보기

댓글 영역