자동로그인 체크 파일을 만들 때 날짜 데이터도 같이 저장하여 일정기간 동안에만 유효하도록 함
private void processRememberMe() {
// 기존에 저장되어 있던 자동로그인 값을 SharedPreferences로부터 가져오기
SharedPreferences pref = getSharedPreferences("todo", Activity.MODE_PRIVATE);
Intent intent = null;
if (pref == null || !pref.contains("rememberMe")) {
// 로그인 Activity 띄우기
intent = new Intent(getApplicationContext(), LoginActivity.class);
} else { // pref != null || pref.contains("rememberMe")
// rememberMe는 pref에 값이 있는지만 체크만 하면 됨. false값은 쓸모가 없음
// boolean isRememberMe = pref.getBoolean("rememberMe", false);
String id = pref.getString("loginId", "");
String startDate = pref.getString("rememberMeDate", "");
// 로그인 상태유지 기간 확인 (2분 동안만 로그인 상태 유지함)
boolean isInPeriod = checkTimeInPeriod(startDate);
if (!isInPeriod) { // isInPeriod == false, 로그인 한지 2분 이상
// sharedPreferences 파일 데이터 모두 삭제하기
clearRememberMe();
intent = new Intent(this, LoginActivity.class);
} else { // 로그인 한지 2분 이하
intent = new Intent(this, MainActivity.class);
intent.putExtra("loginId", id);
}
}
startActivity(intent);
// 현재 액티비티 닫기(뒤로가기 해도 뜨지않음)
finish();
} // processRememberMe
private boolean checkTimeInPeriod(String strStartDate) {
Date nowDate = new Date();
// 넘어올 Date 타입형식을 맞춰줌
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date startDate = null;
try {
// parse 메소드 : String -> Date 변환하기
startDate = sdf.parse(strStartDate);
} catch (ParseException e) {
e.printStackTrace();
}
long diff = nowDate.getTime() - startDate.getTime(); // 현재 시간에서 저장된 데이터 차이 구하기
Log.d(TAG,"diff : " + diff + "ms");
// 1s = 1000ms
Long diffMinute = diff / (1000*60*1); // 분 구하기
Log.d(TAG,"diffMinute : " + diffMinute + "min");
if (diffMinute <= 2) { // 시간 차이값이 2분 이내인지 확인
return true;
} else {
return false;
}
}
private void saveRememeberMe() {
Date date = new Date(); // 현재 로그인 시점의 날짜시간 정보를 가진 Date 객체 생성
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
// format 메소드: Date -> String으로 변환
String strDate = sdf.format(date); // 문자열로 변환(ex "2022-03-10 09:50:22")
// (파일 이름, 현재 파일 안에서만 사용) 파일 생성
SharedPreferences pref = getSharedPreferences("todo", Activity.MODE_PRIVATE);
SharedPreferences.Editor editor = pref.edit();
editor.putBoolean("rememberMe", true); // 파일에 자동로그인 체크 입력
editor.putString("loginId", id); // 파일에 id 정보 입력
editor.putString("rememberMeDate", strDate);
editor.commit(); // 파일에 쓰기
}// saveRememeberMe
Fragment는 하나의 Activity안에 다른 화면을 출력시키는 것으로 화면을 이동하지 않고 화면정보가 담긴 Fragment를 불러서 JavaScript의 Ajax처럼 Fragment가 activity와 독자적으로 작동함
package com.example.fragment;
import androidx.appcompat.app.AppCompatActivity;
import androidx.fragment.app.FragmentManager;
import android.os.Bundle;
public class MainActivity extends AppCompatActivity {
FragmentManager fragmentManager;
MainFragment mainFragment;
MenuFragment menuFragment;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// 액티비티에 이미 부착되어 있는 프래그먼트 참조를 가져오려면
// FragmentManager를 통해서 가져올 수 있음
fragmentManager = getSupportFragmentManager();
// activity_main에 이미 만들어져 있어서 new 로 새로 객체를 생성할 필요가 없다.
mainFragment = (MainFragment) fragmentManager.findFragmentById(R.id.mainFragment);
menuFragment = new MenuFragment();
}
public void onFragmentChanged(int index) {
if (index == 0 ) { // 0 이면 메인프래그먼트
fragmentManager.beginTransaction()
.replace(R.id.container, mainFragment) // 기존의 것을 제거하고 새로운 것 대체
.commit();
} else if (index == 1) { // 1 이면 메뉴 프래그먼트
// 화면을 바꾸는 작업은 조심해야하기때문에 문제가 생기면 바로 돌릴 수 있게 Transaction을 사용한다.
fragmentManager.beginTransaction()
.replace(R.id.container, menuFragment) // 기존의 것을 제거하고 새로운 것 대체
.commit();
}
}// onFragmentChanged
}
단일 Fragment는 태그를 fragment로 바꿔서 사용한다고 함
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout 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:id="@+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity" >
<fragment
android:id="@+id/mainFragment"
android:name="com.example.fragment.MainFragment"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</FrameLayout>
package com.example.fragment;
import android.os.Bundle;
import androidx.fragment.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
// 프래그먼트는 View를 상속받지 않으르므 화면요소가 아님에 주의
// 화면 요소를 관리하는 객체
public class MainFragment extends Fragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// ViewGroup 프래그먼트와 같은 영역에 위치한 layout
ViewGroup rootView = (ViewGroup) inflater.inflate(R.layout.fragment_main, container, false);
Button btnGoMenu = rootView.findViewById(R.id.btnGo); // 메뉴화면으로 이동하는 버튼
btnGoMenu.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
MainActivity mainActivity = (MainActivity) getActivity();
mainActivity.onFragmentChanged(1); // 1 MenuFragment 부분화면으로 전환하기
}
});
return rootView;
}
}
Main, Menu 같은 버튼을 사용하지만 선언을 다르게 해줘서 프래그먼트마다 다른 기능을 가진다.
package com.example.fragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import androidx.fragment.app.Fragment;
// 프래그먼트는 View를 상속받지 않으르므 화면요소가 아님에 주의
// 화면 요소를 관리하는 객체
public class MenuFragment extends Fragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// ViewGroup 프래그먼트와 같은 영역에 위치한 layout
ViewGroup rootView = (ViewGroup) inflater.inflate(R.layout.fragment_menu, container, false);
Button btnGoMain = rootView.findViewById(R.id.btnGo); // 메인화면으로 이동하는 버튼
btnGoMain.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
MainActivity mainActivity = (MainActivity) getActivity();
mainActivity.onFragmentChanged(0); // 0 MainFragment 부분화면으로 전환하기
}
});
return rootView;
}
}