본문 바로가기
안드로이드 자바

[Java][Android] 쉐어드프리퍼런스 회원가입 빠르게 만들기

by teamnova 2021. 2. 7.

스틱코드 라는 서비스를 이용해서 회원가입을 빠르게 만드는 방법을 공유하려고 합니다.

 

자주 사용하는 코드를 저장해놓고 필요할 때마다 keyword를 통해서 그때그때 불러와 사용할 수 있어서 유용하게 사용하고 있습니다.

 

스틱코드 포스트 즐겨찾기 기능을 이용하면 다른 사람이 공개한 코드를 사용할 수 있습니다.

 


1. 스틱코드 회원가입 및 포스트 즐겨찾기

 

2. 안드로이드 스튜디오 스틱코드 plug-in 설치

 

3. 스틱코드 사용하여 회원가입 빠르게 만들기

 


 

스틱코드 회원가입 및 포스트 즐겨찾기 하기

 

 

STICKODE - 스틱코드

스틱코드에서 개발에 필요한 모든 코드를 쉽게 사용하세요

stickode.com

 

로그인 완료 화면

먼저 회원가입을 진행해주시면 됩니다.

회원가입 후 로그인 완료하면 메인 화면 상단 검색 창에 "회원가입 빠르게"를 검색 합니다.

 

검색 완료 화면

검색 결과 posts 중에서 "[자바][안드로이드] 회원가입 빠르게 만들기" 포스트 클릭

 

 

포스트 상세 내용
포스트 내용에서 저장한 소스 코드

포스트 작성할 때 포스트 내용과 함께 저장한 소스코드 목록입니다.

해당 포스트를 즐겨 찾기 하면 소스코드 목록에 있는 코드들을 안드로이드 스튜디오에서 불러와서 사용할 수 있습니다.

 

즐겨찾기 버튼은 포스트 상세 페이지 최하단에 있습니다.

회원가입을 빠르게 만들기 위해서 해당 포스트 소스코드를 활용하려고 합니다. 즐겨찾기 버튼을 클릭해주세요.

 

포스트 상세 페이지 즐겨찾기 버튼

 

 

안드로이드 스튜디오 스틱코드 plugin 설치

안드로이드 스튜디오 File - Settings - Plugins

안드로이드 스튜디오 세팅 단축키: ctrl + alt + s

 

안드로이드 스튜디오 세팅에서 plugins 클릭

검색창에 스틱코드 검색

Plugins 스틱코드 검색 결과

install 버튼 클릭 후 설치가 완료되면 안드로이드 스튜디오를 재시작해야 합니다.

 

재시작 하면 상단에 Stickode 메뉴 생성 확인 및 로그인 클릭

재시작하면 상단 메뉴바에 Stickode 메뉴가 생성된 것을 확인할 수 있습니다.

Stickode 메뉴 클릭 후 로그인을 눌러서 로그인을 하시면 됩니다.

 

로그인을 완료하시면 즐겨찾기 한 포스트 소스코드를 사용할 수 있습니다.

 

즐겨찾기한 포스트 소스코드 활용하여 회원가입 빠르게 만들기

즐겨찾기한 소스코드 불러오기

메인 액티비티에서 bookmark라고 입력하면 즐겨찾기한 소스코드가 하단에 나옵니다.

 

즐겨찾기한 소스코드 이름으로 불러오기

 

소스코드 이름을 입력하셔도 소스코드가 하단에 나옵니다.

 

이제부터 즐겨찾기한 소스코드로 회원 가입할 수 있는 화면과 기능을 만들어 보겠습니다.

activity_main.xml 레이아웃 전체 코드

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:background="#231E31"
    tools:context=".MainActivity">

    <androidx.appcompat.widget.Toolbar
        android:id="@+id/toolbar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="#FF6C92">

        <TextView
            android:id="@+id/toolbar_title"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center"
            android:text="맛집 챗봇"
            android:textColor="@android:color/white"
            android:textSize="16dp"
            android:textStyle="bold" />

    </androidx.appcompat.widget.Toolbar>

    <ScrollView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_gravity="center"
        android:fillViewport="true">

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:orientation="vertical">

            <ImageView
                android:id="@+id/profileIv"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_gravity="center"
                android:layout_marginLeft="30dp"
                android:layout_marginTop="30dp"
                android:layout_marginRight="30dp"
                android:layout_marginBottom="30dp"
                android:background="#70708E"
                android:src="@drawable/ic_launcher_foreground" />

            <TextView
                android:id="@+id/intro"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:text="맛집 챗봇를 이용하기 위한\n새로운 계정을 생성합니다."
                android:layout_marginLeft="30dp"
                android:gravity="center"
                android:layout_marginRight="30dp"
                android:layout_marginTop="10dp"
                android:layout_marginBottom="30dp"
                android:textColor="#FFFFFF" />

            <TextView
                android:id="@+id/signagree"
                android:scrollbars="vertical"
                android:overScrollMode="always"
                android:layout_width="match_parent"
                android:maxLines="20"
                android:layout_height="100dp"
                android:layout_marginLeft="30dp"
                android:layout_marginRight="30dp"
                android:layout_marginBottom="10dp"
                android:background="#FFFFFF"
                android:ems="10"
                android:hint="이용약관"
                android:text="@string/agree"
                android:paddingLeft="10dp"
                android:textSize="10dp"
                android:textColor="#231E31"
                android:textColorHint="#CACACA" />


            <CheckBox
                android:id="@+id/agreeCb"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:textColor="#FFFFFF"
                android:buttonTint="#FFFFFF"
                android:layout_marginLeft="30dp"
                android:layout_marginRight="30dp"
                android:text="동의함" />

            <EditText
                android:id="@+id/idEt"
                android:layout_width="match_parent"
                android:layout_height="40dp"
                android:layout_marginLeft="30dp"
                android:layout_marginRight="30dp"
                android:layout_marginBottom="10dp"
                android:background="#FFFFFF"
                android:ems="10"
                android:hint="아이디 입력"
                android:inputType="textPersonName"
                android:maxLength="11"
                android:paddingLeft="10dp"
                android:textColor="#231E31"
                android:textColorHint="#CACACA"/>

            <EditText
                android:id="@+id/pwEt"
                android:layout_width="match_parent"
                android:layout_height="40dp"
                android:layout_marginLeft="30dp"
                android:layout_marginRight="30dp"
                android:layout_marginBottom="10dp"
                android:background="#FFFFFF"
                android:ems="10"
                android:hint="비밀번호"
                android:inputType="textPersonName"
                android:maxLength="11"
                android:paddingLeft="10dp"
                android:textColor="#231E31"
                android:textColorHint="#CACACA"/>

            <EditText
                android:id="@+id/repwEt"
                android:layout_width="match_parent"
                android:layout_height="40dp"
                android:layout_marginLeft="30dp"
                android:layout_marginRight="30dp"
                android:layout_marginBottom="10dp"
                android:background="#FFFFFF"
                android:ems="10"
                android:hint="비밀번호 확인"
                android:inputType="textPersonName"
                android:maxLength="11"
                android:paddingLeft="10dp"
                android:textColor="#231E31"
                android:textColorHint="#CACACA"/>


            <Button
                android:id="@+id/signBtn"
                android:layout_width="match_parent"
                android:layout_height="40dp"
                android:layout_marginLeft="30dp"
                android:layout_marginTop="10dp"
                android:layout_marginRight="30dp"
                android:background="#323151"
                android:text="가입하기"
                android:textColor="#FFFFFF" />

        </LinearLayout>

    </ScrollView>
    
</LinearLayout>

툴바와 이용약관에서 명시한 서비스 명과 위젯(button, textview, edittext, imageview 등) id는 원하는 네이밍으로 수정해서 사용하시면 됩니다.

 

*중요: 위젯(button, textview, edittext, imageview 등)에 속성 값은 목적에 맞도록 수정해서 사용하시면 됩니다.

 

회원가입 레이아웃 위젯 순서

 

toolbar (서비스명)

imageview (프로필 이미지 등록)

textview (회원가입 소개)

textview (이용약관)

checkbox (이용약관 동의 체크박스)

edittext (아이디 입력)

edittext (비밀번호 입력)

edittext (비밀번호 확인)

button (가입 버튼)

 

toolbar 추가 하기

toolbar를 추가한다.

 

위에서 즐겨찾기 한 포스트는 제가 작성한 포스트이기 때문에 저한테는 My Post라고 표시되어 있지만,

즐겨찾기 한 사용자에게는 bookmark라고 표기됩니다.

 

imageView, textview 추가

위젯을 추가하면 액티비티 영역을 넘어서 잘릴 수 있으므로, ScrollView 안에 LinearLayout으로 위젯을 감싸줍니다.

프로필 이미지를 추가할 ImageView와 서비스 회원가입 설명을 표시할 TextView를 추가해줍니다.

 

 

다음으로 이용약관을 추가해보겠습니다.

 

이용 약관에 경우 글자 수가 많기 때문에 textView text속성에 바로 추가하는 방법보다 strings.xml를 이용해서 처리해 보겠습니다.

 

아래 이용약관 내용은 예시일 뿐입니다. 만드시는 서비스에 맞게 내용을 수정해서 사용하시면 됩니다.

 

이용약관 내용:

"이용약관\n\n제1조(목적)\n이 약관은 (주)맛집챗봇(이하 '회사')가 디바이스를 통해 제공하는 모바일 서비스(이하 '서비스')를 이용하는 서비스 이용자 (이하 '이용자')와 회사간에 서비스 이용에 관한 기본적인 사항을 규정하는 것을 목적으로 합니다."

 

strings.xml

strings.xml 에서 아래 내용 추가

 

<string name="agree">"이용약관\n\n제1조(목적)\n이 약관은 (주)맛집챗봇(이하 '회사')가 디바이스를 통해 제공하는 모바일 서비스(이하 '서비스')를 이용하는 서비스 이용자 (이하 '이용자')와 회사 간에 서비스 이용에 관한 기본적인 사항을 규정하는 것을 목적으로 합니다."</string>

 

strings.xml 등록한 리소스 불러오기

@string/agree를 통해서 해당 문자열 값을 불러올 수 있습니다.

 

 

 

지금부터는 차례대로 아래 위젯을 아래 이름으로 검색하여 추가해주시면 됩니다.

checkbox (이용약관 동의 체크박스)

edittext (아이디 입력)

edittext (비밀번호 입력)

edittext (비밀번호 확인)

button (가입 버튼)

 

 

activity_main.java 전체 코드

package com.project.stickode_blog;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;

import android.Manifest;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.PackageManager;
import android.database.Cursor;
import android.graphics.drawable.ShapeDrawable;
import android.graphics.drawable.shapes.OvalShape;
import android.net.Uri;
import android.os.Bundle;
import android.provider.MediaStore;
import android.text.method.ScrollingMovementMethod;
import android.util.Log;
import android.view.View;
import android.view.inputmethod.InputMethodManager;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;

import com.squareup.picasso.Picasso;

import java.io.File;

public class MainActivity extends AppCompatActivity {

    //접속정보와 태그명 지정
    private String TAG = "memberJoinTest";

    private TextView singagree;

    //뷰 객체 생성
    EditText idEt, pwEt, repwEt;//사용자 ID ,비밀번호, 비밀번호 확인
    Button signBtn; //회원가입 버튼
    CheckBox agreeCb; //약관 동의 여부 체크 박스
    ImageView profileIv; //프로필 이미지

    //변수 객체 생성
    String name, password, repassword; //아이디, 암호, 암호재입력 String

    private static final int PICK_FORM_ALBUM = 1;
    private File tempFile;

    SharedPreferences memberPref, profilePref;
    SharedPreferences.Editor editor;



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

        singagree = (TextView) findViewById(R.id.signagree); //동의약관
        singagree.setMovementMethod(new ScrollingMovementMethod()); //동의약관 스크롤되도록

        agreeCb = findViewById(R.id.agreeCb);
        idEt = (EditText) findViewById(R.id.idEt); //아이디
        pwEt = (EditText) findViewById(R.id.pwEt); //암호
        repwEt = (EditText) findViewById(R.id.repwEt); //암호재입력
        profileIv = findViewById(R.id.profileIv);   //프로필 사진 등록

        signBtn = (Button) findViewById(R.id.signBtn); //회원가입 버튼

        //프로필 사진 등록 이미지를 클릭 하면, 사진첩으로 이동
        profileIv.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Log.v("main goToAlbum", "goToAlbum");
                Intent intent = new Intent(Intent.ACTION_PICK);
                intent.setType(MediaStore.Images.Media.CONTENT_TYPE);
                startActivityForResult(intent, PICK_FORM_ALBUM);
            }
        });


        signBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                name = idEt.getText().toString(); //아이디
                password = pwEt.getText().toString(); //비밀번호
                repassword = repwEt.getText().toString(); //비밀번호재입력

                if (!agreeCb.isChecked()) {
                    //약관동의를 안했다면 실행
                    Toast.makeText(getApplicationContext(), "약관을 읽고 동의 해주세요.", Toast.LENGTH_SHORT).show();
                    //checkbox2로 이동
                    agreeCb.requestFocus();

                } else if (name.equals("")) {
                    Toast.makeText(getApplicationContext(), "전화번호를 입력해주세요.", Toast.LENGTH_SHORT).show();
                    //signid로 커서 이동
                    idEt.requestFocus();

                    //키보드 보이게 하는 부분
                    InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
                    imm.toggleSoftInput(InputMethodManager.SHOW_FORCED, InputMethodManager.HIDE_IMPLICIT_ONLY);

                }
                else if (password.equals("")) {
                    Toast.makeText(getApplicationContext(), "비밀번호를 입력해주세요.", Toast.LENGTH_SHORT).show();
                    //signpassword로 커서 이동
                    pwEt.requestFocus();

                    //키보드 보이게 하는 부분
                    InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
                    imm.toggleSoftInput(InputMethodManager.SHOW_FORCED, InputMethodManager.HIDE_IMPLICIT_ONLY);
                } else if (repassword.equals("")) {
                    Toast.makeText(getApplicationContext(), "비밀번호를 확인해주세요.", Toast.LENGTH_SHORT).show();
                    //signrepassword로 커서 이동
                    repwEt.requestFocus();

                    //키보드 보이게 하는 부분
                    InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
                    imm.toggleSoftInput(InputMethodManager.SHOW_FORCED, InputMethodManager.HIDE_IMPLICIT_ONLY);
                } else if (!password.equals(repassword)) {
                    //비밀번호와 비밀번호 확인이 같지 않다면
                    Toast.makeText(getApplicationContext(), "비밀번호가 일치하지 않습니다.", Toast.LENGTH_SHORT).show();
                    //signpassword로 커서 이동
                    pwEt.requestFocus();

                    //키보드 보이게 하는 부분
                    InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
                    imm.toggleSoftInput(InputMethodManager.SHOW_FORCED, InputMethodManager.HIDE_IMPLICIT_ONLY);
                } else {
                    //회원가입 정보를 모두 입력 했다면 회원가입 정보 쉐어드에 저장
                    signCheck();

                    //버튼을 누를 때마다 기존 내용 초기화
                    idEt.setText("");
                    pwEt.setText("");
                    repwEt.setText("");

                }


            }
        });


        //사진, 카메라 권한 부여 확인 및 권한요청 코드
        if (ContextCompat.checkSelfPermission(MainActivity.this,
                Manifest.permission.WRITE_EXTERNAL_STORAGE)
                != PackageManager.PERMISSION_GRANTED) {

            // 설명이 필요한가?
            if (ActivityCompat.shouldShowRequestPermissionRationale(MainActivity.this,
                    Manifest.permission.WRITE_EXTERNAL_STORAGE)) {

                // 사용자에게 설명을 보여줍니다.
                // 권한 요청을 다시 시도합니다.

            } else {
                // 카메라, 파일 접근 권한요청
                Log.v("권한요청","권한요청");
                ActivityCompat.requestPermissions(MainActivity.this,
                        new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.CAMERA,
                                Manifest.permission.READ_EXTERNAL_STORAGE},
                        10);

            }
        }


    }


    //권한요청을 사용자에게 허락받았는지 못받았는지 결과를 알수 있는 콜백 메서드
    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);

        switch (requestCode) {
            case 10: {

                if (grantResults.length > 0
                        && grantResults[0] == PackageManager.PERMISSION_GRANTED) {

                    // 권한 획득 성공

                } else {

                    // 권한 획득 실패
                }
                return;
            }

        }
    }

    //회원 가입 정보 쉐어드에 저장
    protected void signCheck()
    {
        memberPref = this.getSharedPreferences("memberPref", MainActivity.MODE_PRIVATE);
        editor = memberPref.edit();
        editor.putString(name,password);
        editor.commit();
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        super.onActivityResult(requestCode, resultCode, data);

        Log.v("main onActivityResult", "onActivityResult 호출");
        if (resultCode == RESULT_OK) {

            Log.v("resultCode == RESULT_OK", "resultCode == RESULT_OK");
            if (requestCode == PICK_FORM_ALBUM) {

                Log.v("PICK_FORM_ALBUM", "requestCode == PICK_FORM_ALBUM");
                Uri photoUri = data.getData();

                Cursor cursor = null;

                try {

                    /*
                     *  Uri 스키마를
                     *  content:/// 에서 file:/// 로  변경한다.
                     */
                    String[] proj = {MediaStore.Images.Media.DATA};

                    assert photoUri != null;
                    cursor = getContentResolver().query(photoUri, proj, null, null, null);

                    assert cursor != null;
                    int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);

                    cursor.moveToFirst();

                    tempFile = new File(cursor.getString(column_index));

                } finally {
                    if (cursor != null) {
                        cursor.close();
                    }
                }

                setImage(tempFile.getAbsolutePath());

            }

        }
    }


    //이미지 경로 가져오기
    public void setImage(String imagePath) {

//        imagePath = "file:/"+imagePath;
        File upload_file = new File(imagePath);

        Log.d("setImage", imagePath);
        profilePref = this.getSharedPreferences("profilePref", MainActivity.MODE_PRIVATE);
        editor = profilePref.edit();
        editor.putString("profile",imagePath);
        editor.commit();

        Log.d("setImage", upload_file.getAbsolutePath());

        Picasso.get().load("file://" + upload_file.getPath()).resize(150, 150).into(profileIv);

    }


}

 

사용 이미지 처리 라이브러리: Picasso

앨범 및 카메라 권한 허용 처리: manifast, 권한 허용 요청하는 코드

 

 

Picasso 라이브러리 추가 [ 추가 위치: Gradle Scripts - build.gradle(Module: app) - dependencies ]

dependencies {

    //picasso 라이브러리 추가
    implementation 'com.squareup.picasso:picasso:2.71828'

}

 

manifast 저장소 접근 권한 코드 추가

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

 

앨범 및 카메라 권한 허용 java 코드 [ mainactivity.java onCreate() 안에 작성 ]

//사진, 카메라 권한 부여 확인 및 권한요청 코드
 if (ContextCompat.checkSelfPermission(MainActivity.this,
                Manifest.permission.WRITE_EXTERNAL_STORAGE)
                != PackageManager.PERMISSION_GRANTED) {

            // 설명이 필요한가?
            if (ActivityCompat.shouldShowRequestPermissionRationale(MainActivity.this,
                    Manifest.permission.WRITE_EXTERNAL_STORAGE)) {

                // 사용자에게 설명을 보여줍니다.
                // 권한 요청을 다시 시도합니다.

            } else {
                // 카메라, 파일 접근 권한요청
                Log.v("권한요청","권한요청");
                ActivityCompat.requestPermissions(MainActivity.this,
                        new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.CAMERA,
                                Manifest.permission.READ_EXTERNAL_STORAGE},
                        10);

            }
 }
        
        
        
    

 

권한 요청을 사용자가 승인했는지 거부했는지 여부 확인 메서드 [ onCreate() 밖에 작성 ]

//권한요청을 사용자에게 허락받았는지 못받았는지 결과를 알수 있는 콜백 메서드
 @Override
 public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);

        switch (requestCode) {
            case 10: {

                if (grantResults.length > 0
                        && grantResults[0] == PackageManager.PERMISSION_GRANTED) {

                    // 권한 획득 성공

                } else {

                    // 권한 획득 실패
                }
                return;
            }

        }
  }

 

 

쉐어드에 저장된 값 확인 [ 회원가입 성공 확인 ]

쉐어드 저장소 위치: data/data/프로젝트명/shared_prefs

저장된 쉐어드 위치

안드로이드 스튜디오 우측 하단 Device File Explorer 클릭

data/data/프로젝트명/shared_prefs 아래에 보면

사진 정보를 저장한 profilePref.xml

사용자 정보(ID/PW)를 저장한 memberPref.xml 파일이 생성된 것을 확인할 수 있습니다.

 

프로필 이미지 경로를 저장한 쉐어드
사용자 ID와 비밀번호를 저장한 쉐어드

 

2개의 쉐어드에 작성한 값이 저장되어 있다면 회원가입에 성공했다고 볼 수 있습니다.

 

로그인 화면에서 입력한 아이디와 비밀번호를  memberPref.xml 파일에 저장된 값과 비교하여

 

값이 일치하면 로그인 성공

값이 없거나 값이 일치하지 않는다면 실패로 처리하여 로그인 기능을 구현할 수 있습니다.

 

 

스틱코드 포스트 URL : stickode.com/detail.html?no=1866