안드로이드 스튜디오 자동 import 설정하기

 

 

 

 

 1. [File] -> [Settings...] 으로 간다.

 

 

 

 

 

 

 2. [Editor] -> [General] -> [Auto import] 로 간다.   (or 검색창의 Auto import를 검색)

 

 

 

 

 

 

 3. 각 XML 이나 Java에서 자동으로 improt 될 필요가 있다고 생각하는 부분을 체크해준 후 OK 해준다.

 

 

 

 

 

+)

자동으로 import 되기 때문에 최종적으로 작업이 끝났을 경우 사용하지 않는 것들이 import 되어있을 경우가 많다. 

 

import문들을 보면 사용하지 않는 것은 회색으로 처리되어 있으니, 작업이 끝난 후 최종적으로 한 번 import문들을 정리해 주는 것이 좋다.

안드로이드 코드 난독화

 

컴파일된 자바 파일을 디컴파일하면 코드가 노출된다. 디컴파일이란 간단히 말하여 컴파일의 반대 과정이다.

 

 

이러한 디컴파일로 인하여 코드의 노출을 방지하기 위해서 디컴파일해도 코드를 읽기 어렵게 만들기 위한 일종의 코드 보안 기술이다.

 

 

그래서 앱 출시 전 난독화를 하는 것이 좋은데 이는 안드로이드 스튜디오에서 기본적으로 지원하는 난독화 프로그램 프로가드(Proguard) 사용할 수 있다.

 

 

 

 

 

 

 

▲ 1. 모듈 수준의 그레이들 파일을 열어준다.

 

 

 

 

▲ 2. mainfyEnabled의 값으로 true를 준다.

 

 

 

 

 

 3. Sync Now를 클릭한다.

 

 

 

이것으로 코드의 난독화를 하게 된다.

 

 

 

 

 

 

+)

 안드로이드에서는 debug 빌드와 release 빌드를 할 수 있다.

 

debug 빌드 : 코딩 중 <Run>(▶) 버튼으로 연결된 기기나 에뮬레이터로 실행하였을 경우

 

release 빌드 : 작업이 끝나 최종적으로. apk 파일을 만들 경우

 

기본적으로는 release 부분만이 선언되어있지만 이를 복사하여서 dubug문을 만들면 debug 빌드 시에도 코드 난독화가 일어나게 할 수 있다.

 

 

 

안드로이드 DB(데이터베이스)를 사용하는 방법을 알아 보겠슴다.

 

데이터베이스를 이용하는 곳이 많은 만큼 중요한 것이고, 가독성을 높이기 위해서 여러 글로 나누어서 작성하려고 합니다.

 

우선은 안드로이드 DB(데이터베이스) 1편  'DB 생성'입니다.

 

 

 

 

 

실행 화면

 

 

 

 

/* 메인 레이아웃(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">

        <EditText
            android:id="@+id/editText"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:ems="10"
            android:hint="이름"
            android:inputType="textPersonName" />

        <EditText
            android:id="@+id/editText2"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:ems="10"
            android:hint="정보"
            android:inputType="textPersonName" />
    </LinearLayout>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal">

        <Button
            android:id="@+id/button"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:onClick="insert"
            android:text="추가" />

        <Button
            android:id="@+id/button2"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:onClick="delete"
            android:text="삭제" />
    </LinearLayout>

    <Button
        android:id="@+id/button3"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:onClick="listUpdate"
        android:text="Update" />

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

        <ListView
            android:id="@+id/listView"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_weight="1">


        </ListView>

        <ListView
            android:id="@+id/listView2"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_weight="1" />
    </LinearLayout>

</LinearLayout>

 

주 내용은 데이터베이스이므로 대충 그냥 리스트뷰를 2개 사용하여서 각각 출력하도록 만들었다.

 

하지만 데이터베이스를 사용할 때 보통 같이 쓰는 것 중 하나가 바로 커스텀 리스트 뷰인데 이에 관하여서는

2019/04/14 - [Android] - 안드로이드 리사이클 러뷰(RecyclerView) (1)

 

해당 글을 참조하여서 만들어보는 것을 추천한다.

 

 

 

 

 

 

 

/* 메인 자바 코드 ( MainActivity.java ) */

package com.tistory.godog.dbtest;

import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity {

    EditText editText, editText2;
    ListView listView, listView2;

    DBHelper dbHelper;
    SQLiteDatabase db = null;
    Cursor cursor;
    ArrayAdapter adapter, adapter2;

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

        editText = findViewById(R.id.editText);
        editText2 = findViewById(R.id.editText2);
        listView = findViewById(R.id.listView);
        listView2 = findViewById(R.id.listView2);

        dbHelper = new DBHelper(this, 3);
        db = dbHelper.getWritableDatabase();    // 읽기/쓰기 모드로 데이터베이스를 오픈


    }

}

 

- 우선은 데이터베이스 생성만을 알아보는 것이므로 메인에서는 변수 선언과 초기화 말고 별거 없다.

 

- 18라인 : 만들어야 할 클래스 파일.

 

- 19라인 : SQLiteDatabase에는 SQL 명령을 생성, 삭제, 실행하고 기타 일반적인 데이터베이스 관리 작업을 수행하는 메소들이 있다.

 

- 20라인 : Cursor는 안드로이드에서 DB에서 가져온 데이터를 쉽게 처리하기 위해서 제공하는 2차원 테이블을 가지는 인터페이스이다.

 

 

 

 

 

 

이제 18라인에서 만들어야 한다고 했던 자바 파일을 만들기 위해서 자바 파일만을 하나 생성해준다.

/* DBHelper.java */

package com.tistory.godog.dbtest;

import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;

public class DBHelper extends SQLiteOpenHelper {

    static final String DATABASE_NAME = "test.db";
    //static final int DATABASE_VERSION = 2;

    public DBHelper(Context context, int version) {
        super(context, DATABASE_NAME, null, version);
    }
/*
    public DBHelper(Context context, String name, SQLiteDatabase.CursorFactory factory, int version) {
        super(context, name, factory, version);
    }
*/

    @Override
    public void onCreate(SQLiteDatabase db) {
        db.execSQL("CREATE TABLE tableName ( name TEXT, info TEXT);");
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        db.execSQL("DROP TABLE IF EXISTS tableName");
        onCreate(db);
    }

}

 

- 파일을 생성하였으면 SQLiteOpenHelper를 상속받아준다.

 

- SQLiteOpenHelper는 데이터베이스 생성 및 버전 관리를 관리하도록 도와주는 클래스이다.

 

 

+ 상속을 받아준 후 클래스 안에서 "Ctrl+i"를 눌러서 모두 추가해 준 후,

 "Alt + Insert"->"Constructor"로 생성자 하나를 추가해주면 기본적인 세팅은 끝난다.

 

 

- 주석된 부분을 보면 본래 생성자를 볼 수 있다. 이는 선언한 생성자와 많이 매개변수가 다른데 별 의미는 없다. 단, 데이터베이스 파일을 하나만 사용할 경우 위처럼 상수로 데이터베이스 이름과 버전을 선언해두고 인수로 줌으로써 에러를 줄이고 수정을 용이하게 만든다.

(+ 보통 파일 내에서 테이블 단위로 나눌 수 있으므로 db파일을 하나만 사용한다. )

 

 

- onCreate : 데이터베이스가 처음 생성될 때 호출된다. 그러므로 테이블의 생성이 일어난다.

 

※ execSQL :  Select 명령 외에 SQL 명령들을 실행한다. 

 

- 23라인 :  괄호 안을 보면 ( name TEXT, info TEXT)로 되어있다. 이는 ( '열 항목명' '데이터 형', )이다. 숫자 데이터 형을 만들려면 "(num INTEGER)" 이렇게 만들면 된다.

 

 

- onUpgrade

2019/04/21 - [Android] - 안드로이드 DB(데이터베이스) onUpgrade

 

 

 

여기까지 데이터베이스 생성 및 관리를 도와주는 SQLiteOpenHelper를 상속받은 클래스 파일을 만들었으면 데이터베이스를 만들 준비는 끝났다.

 

 

 

다음 글에서는 이어서 데이터베이스의 데이터를 추가, 삭제하는 방법을 알아보겠다.

 

안드로이드(자바)에서 년, 월, 일, 시간, 분, 초를 구해서 변수에 저장

 

 

 

실행 결과

 

 

 

 

 

 

 

/* 레이아웃 */

<?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=".MainActivity">


    <Button
        android:id="@+id/button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="날짜 받기"
        android:textStyle="bold" />

    <TextView
        android:id="@+id/textView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />
</LinearLayout>

 

버튼을 클릭하면 텍스트뷰에 날짜와 시간을 표시하도록 한다.

 

 

 

/* 자바 코드 */

package com.tistory.godog.test3;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;

import java.util.Calendar;

public class MainActivity extends AppCompatActivity {

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

        textView = findViewById(R.id.textView);
        Button button = findViewById(R.id.button);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                getDT();
            }
        });
    }

    public void getDT() {
        Calendar cal = Calendar.getInstance();
        int y=0, m=0, d=0, h=0, mi=0, s=0;

        y = cal.get(Calendar.YEAR);
        m = cal.get(Calendar.MONTH) +1;
        d = cal.get(Calendar.DAY_OF_MONTH);
        h = cal.get(Calendar.HOUR);
        mi = cal.get(Calendar.MINUTE);
        s = cal.get(Calendar.SECOND);

        textView.setText(y+"/"+m+"/"+d+" "+h+":"+mi+":"+s);
    }
}

 

- Calendar 클래스가 추상 클래스이여서 new로 인스턴스를 생성할 수 없다.

 

└> 이는 날짜와 시간을 계산하는 방법이 지역, 나라에 따라 다르기 때문이다. 그래서 getInstance() 메소드를 사용하면 운영체제에 설정되어 있는 시간을 기준으로 객체를 얻어온다.

 

 

 

- 월을 구할 때는 0~11에 값을 가지므로 우리가 사용하는 1~12 값의 월을 얻기 위해서는 +1을 해주어야 한다.

 

 

안드로이드 날짜/시간 다이로그 실행하여서 날짜와 시간을 변수에 저장

 

 

실행 화면

설정한 날짜와 시간을 "날짜/시간 확인"버튼을 누르면 토스트 메시지로 확인할 수 있도록 만들었다.

 

 

 

 

/* 레이아웃 */

메인 / 달력 / 시계


<?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=".MainActivity">

    <Button
        android:id="@+id/button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="달력" />

    <Button
        android:id="@+id/button2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="시간" />

    <Button
        android:id="@+id/button3"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="날짜/시간 확인" />


</LinearLayout>

- 달력 버튼을 클릭하면 달력 다이로그가 실행.

- 시간 버튼을 클릭하면 시간 다이로그가 실행.

- 날짜/시간 확인 버튼을 클릭하면 위 다이로그에서 저장한 날짜와 시간을 토스트 메시지로 보여준다.

 

 

 

/* 자바 코드 */


package com.tistory.godog.test2;

import android.app.DatePickerDialog;
import android.app.TimePickerDialog;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.Gravity;
import android.view.View;
import android.widget.Button;
import android.widget.DatePicker;
import android.widget.TimePicker;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity {

    int y=0, m=0, d=0, h=0, mi=0;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Button button = findViewById(R.id.button);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                showDate();
            }
        });

        Button button1 = findViewById(R.id.button2);
        button1.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                showTime();
            }
        });
        Button button2 = findViewById(R.id.button3);
        button2.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Toast.makeText(getApplicationContext(), y+"."+m+"."+d+"\n"+h+":" + mi, Toast.LENGTH_SHORT).show();
            }
        });
    }

    void showDate() {
        DatePickerDialog datePickerDialog = new DatePickerDialog(this, new DatePickerDialog.OnDateSetListener() {
            @Override
            public void onDateSet(DatePicker view, int year, int month, int dayOfMonth) {
                y = year;
                m = month+1;
                d = dayOfMonth;

            }
        },2019, 1, 11);

        datePickerDialog.setMessage("메시지");
        datePickerDialog.show();
    }

    void showTime() {
        TimePickerDialog timePickerDialog = new TimePickerDialog(this, new TimePickerDialog.OnTimeSetListener() {
            @Override
            public void onTimeSet(TimePicker view, int hourOfDay, int minute) {
                h = hourOfDay;
                mi = minute;

            }
        }, 21, 12, true);
        
        timePickerDialog.setMessage("메시지");
        timePickerDialog.show();
    }
}

 

- DatePickerDialog( Context , 이벤트 리스너, 년, 월, 일) : 여기서 년, 월, 일은 Date다이로그가 처음 보여주는 년, 월, 일이다. 

즉, 다이로그에 초기값 같은 것으로 오늘 날짜로 설정하고 싶다면 Calendar변수를 사용하여 설정해 주면 된다.

 

└> onDateSet 메소드에서 year, month, dayOfMonth를 미리 선언해둔 변수에 저장하여 다른 곳에서 사용할 수 있다.

 

└> 주의할점은 우리가 아는 월은 1~12지만 여기서는 0~11로 되어있기 때문에 초기값을 줄 때에도 값을 가져올 때에도 +1을 해야 생각했던 월의 값을 받을 수 있다. 실제로 위 코드에서 DateDialog의 월 초기값을 1로 주었지만 실행된 Dialog에서는 2월을 보여준다.

 

└> datePickerDialog.setMessage("메시지") 이곳에 메시지를 입력하면 다이로그 위에 보여준다. 인터페이스로서 이용하여도 되지만 생략하여도 무관하다.

 

 

 

- TimePickerDialog( Context, 이벤트 리스터, 시간, 분, 오전/오후 구분) : 여기서 시간과 분은 DatePickerDialog처럼 초기값을 주는 것이다. 마지막 인자로 오전/오후 구분이라고 하였는데 이를 true로 주었을 때는 0~24시간을 선택할 수 있는 뷰를 보여준다.

반대로 false를 주었을 때는 0~12시간만을 선택할 수 있으며, 따로 오전/오후를 선택할수 있는 버튼이 주어진다.

 

└> 마찬가지로 onTimeSet에서 hourOfDay, minute를 변수에 저장하여서 입력받은 시간과 분을 이용할 수 있다.

 

 

+ Recent posts