비교적 간단한 데이터를 저장하기위해 안드로이드 개발 시 SharedPreferences를 사용한다.
설정에 따라서 SharedPreferences 파일은 프레임워크에서 관리하며 비공개이거나 공개로 설정할 수 있다.


비공개로 설정할 경우 일반적인 방법으로는 저장된 데이터를 확인할수는 없지만, 루팅을 통해 관리자 권한을 획득한 경우 저장된 데이터를 확인할 수있다. 개인정보(카드번호, 인증 비밀번호) 등 중요한 데이터가 저장하여야 하는경우에는 SharedPreferences는 적합하지 않다.

Android SDK 23부터 androidx.security를 통해 EncryptedSharedPreferences를 제공한다.

https://developer.android.com/reference/androidx/security/crypto/EncryptedSharedPreferences

 

EncryptedSharedPreferences  |  Android Developers

androidx.constraintlayout.core.motion.parse

developer.android.com

 

기본적인 사용방법은

MasterKey masterKey = new MasterKey.Builder(context)
        .setKeyScheme(MasterKey.KeyScheme.AES256_GCM)
        .build();

_sharedPreferences = EncryptedSharedPreferences.create(
        context,
        "secret_shared_pref",
        masterKey,
        EncryptedSharedPreferences.PrefKeyEncryptionScheme.AES256_SIV,
        EncryptedSharedPreferences.PrefValueEncryptionScheme.AES256_GCM
);

 

AES256방식에   암호화 키를 생성하여 생성한 암호화 키로 저장되는 데이터의 AES256_SIV(key) ,AES256_GCM (data)방식으로 키와 데이터를 각각 암호화한다. 

 

(암호화 키 생성 시 keystore를 사용하기 때문에 별도의 키입력을 하지 않으며, 생성된 암호화 키는 컨테이너에 저장되어 저장된 암호화키는 외부에서 추출하기 어렵다.)

https://developer.android.com/training/articles/keystore?hl=ko 

 

SharedPreferences와 동일하게 앱 삭제 시 저장된 데이터도 함꼐 삭제되며, 저장된 데이터는 아래와 같이 암호화되어 저장된다.

 

<?xml version='1.0' encoding='utf-8' standalone='yes' ?>
<map>
    <string name="__androidx_security_crypto_encrypted_prefs_key_keyset__">12a90125a94b1b6aa4f97a630764baecf0e5f4c046a82c8b7947dabc06e71c5170a654d27c1903ffe2da75f84fd1dd011f37c917e9b8ce21d6b4673bbec9127ea066e6adb177f34bc98ff7259331f0d854b78d318226ed62dca1b38ec2dd32598a9357432e0e524a91e9a27393370337acbc5611f8808a6d8bcb724506dcb0e5513e6d6c0cb93d9af1f22cde840c93f3c213adce4bf1cd38aea6464724a1f0bf0bc7153ea84df9b5f4f4344b1a4408b191c8fc03123c0a30747970652e676f6f676c65617069732e636f6d2f676f6f676c652e63727970746f2e74696e6b2e4165735369764b6579100118b191c8fc032001</string>
    <string name="AT+SCLGWnuSnzmogArPsMQJbMe92S7STOQ==">AR4mc1e8vYohj66Q91oCIoaMmklTD+DDPStaqibMtsDXatXDJJeskjW7eW9WNTGR</string>
    <string name="__androidx_security_crypto_encrypted_prefs_value_keyset__">128801163831f1d036fdc9a33da123fee29b5cda21a49d89684f5fac67e3d54a634de5d8ca990106d0535f0ce74e824f8352e027a37a7512a189a67c183781bf6ce08894b3a622bda2632205c5e5f64389cbff75556bd05d0f8dcd8dc495b9cff09681a7e1e18bae625b7d1513e7301c4ed2aa1e592b97df72474ee9437f75e20e1a019803d7cb3cd9f78f1a4408d7e699f101123c0a30747970652e676f6f676c65617069732e636f6d2f676f6f676c652e63727970746f2e74696e6b2e41657347636d4b6579100118d7e699f1012001</string>
    <string name="AT+SCLEaHEykuXI9WqXm7wB0ZOTyX/dPWI4=">AR4mc1euqAo6fPFARiDB0ACt92fHt3w1P+64D76rk9Dlyv4ya/hKWgQ5dHy6COIN</string>
</map>

 

 

EncryptedSharedPreferences 을 사용하기 위해서는 Security 라이브러리를 추가 해야함.

(build.gradle의 dependencies추가)

 

implementation "androidx.security:security-crypto-ktx:1.1.0-alpha03"

 

EncryptedSharedPreferences 공통 Class로 사용하기 위한 샘플 소스

 

import android.content.Context;
import android.content.SharedPreferences;

import androidx.security.crypto.EncryptedSharedPreferences;
import androidx.security.crypto.MasterKey;

import java.io.IOException;
import java.security.GeneralSecurityException;

public class SharedPreferenceUtil {

    private static SharedPreferenceUtil sharedInstance;
    private Context _context = null;
    private MasterKey masterKey = null;

    private SharedPreferences _sharedPreferences = null;
    private SharedPreferences.Editor _shEditor = null;

    private final static String SECRET_PREFERENCE = "secret_shared_prefs";


    public static synchronized SharedPreferenceUtil getInstance(Context context) throws GeneralSecurityException, IOException {
        if (null == sharedInstance) {
            sharedInstance = new SharedPreferenceUtil(context);
        }
        return sharedInstance;
    }

    public SharedPreferenceUtil(Context context) throws GeneralSecurityException, IOException {
        MasterKey masterKey = new MasterKey.Builder(context)
                .setKeyScheme(MasterKey.KeyScheme.AES256_GCM)
                .build();

        _sharedPreferences = EncryptedSharedPreferences.create(
                context,
                SECRET_PREFERENCE,
                masterKey,
                EncryptedSharedPreferences.PrefKeyEncryptionScheme.AES256_SIV,
                EncryptedSharedPreferences.PrefValueEncryptionScheme.AES256_GCM
        );
    }

    public void putString(String key, String data) {
        _shEditor.putString(key, data);
        _shEditor.commit();
    }

    public void putInt(String key, int data) {
        _shEditor.putInt(key, data);
        _shEditor.commit();
    }

    public void putFloat(String key, float data) {
        _shEditor.putFloat(key, data);
        _shEditor.commit();
    }

    public void putLong(String key, long data) {
        _shEditor.putLong(key, data);
        _shEditor.commit();
    }

    public void putBoolean(String key, boolean data) {
        _shEditor.putBoolean(key, data);
        _shEditor.commit();
    }

    public void clear() {
        if (null != _shEditor) {
            _shEditor.clear();
            _shEditor.commit();
        }
    }

    public String getString(String key, String defValue) {
        return _sharedPreferences.getString(key, defValue);
    }

    public int getInt(String key, int defValue) {
        return _sharedPreferences.getInt(key, defValue);
    }

    public float getFloat(String key, float defValue) {
        return _sharedPreferences.getFloat(key, defValue);
    }

    public long getLong(String key, long defValue) {
        return _sharedPreferences.getLong(key, defValue);
    }

    public boolean getBoolean(String key, boolean defValue) {
        return _sharedPreferences.getBoolean(key, defValue);
    }
}

 

프로젝트 진행 중 실 시간으로 시간을 날짜 시간을 표기 해달라는 고객 요청사항이 있어 Thread와 Handler를 사용하여 TextView에 표시해야곘다는 생각을 했다. 

 

구글링을 하다가 TextClock으로 손쉽게 현재 날짜 시간을 표기할수 있다는것을 알게되었다.

(https://developer.android.com/reference/android/widget/TextClock)

 

API level 17부터 지원되기 시작한 기능으로 TextView를 상속받아 구현되었다.

<TextClock
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:format12Hour="yyyy년 MM월 dd일 EE요일"
    android:textSize="18dp" />

<TextClock
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:format12Hour="hh:mm a"
    android:textSize="45dp" />

format 안에 내용은

yyyy : 년

MM : 월

dd : 일

EE : 요일

hh : 시간

mm : 분

a : 오전/오후를 나타낸다

android:format12Hour="hh:mm a"
android:format24Hour="hh:mm"

format12Hour은 12시간 시간표기방식, format24Hour은 24시간 시간표기 방식을 설정할수 있다.

요일과 오전/오후의 경우는 시스템의 local언어에 따라 다르게 표기된다.

(개발 단말의 언어가 한국어인 경우는 기본적으로 위와 같이 한글로 요일과 오전/오후가 표기 되지만 영어인 경우는 영어로 요일과 AM/PM으로 표기 된다.)

 

예전에 시간 갱신하는 로직을 일일히 다 구현해 줘야하는 번거로움이 있었는데, TextClock사용으로 이러한 번거로움을 줄일수 있었다.

Node js는 chrome v8 javascript 엔진으로 빌드된 JavaScript 런타임 환경을 말한다.
※ 기본적으로 HTML, CSS, JavaScript으로만으로도 웹개발이 가능하지만, 효율적인 웹 개발을 위해 Node js를 사용한다.

Node js 설치 시 LTS(Long Term Supported) 버전과, 최신 버전이 존재한다.

보통 LTS버전은 짝수 버전 (ex:12.x.x,14.x.x,16.x.x 등) 최신버전은 홀수 버전(ex:11.x.x,13.x.x,15.x.x 등)으로 되어 있다.
LTS 버전은 장기적으로 안정되고 신뢰성이 높으며 안정적 지원이 보장된 버전이다. 주로 안정적인 유지/보수가 필요한 서버보안등에 사용된다.
최신 버전의 경우는 웹에서 사용되는 최신의 기술들을 사용할수 있지만, 안정적이지 않아 업데이트가 빈번하게 발생하는 등의 안전성 문제가 발생할수있어 테스트 용으로 사용된다.
실제 개발 시에는 LTS 버전 사용을 권장하며, 보통 개발 시 한개의 Node js만 설치하여 사용하는 것이 아니라 프로젝트 별로 여러 개의 Node js 버전을 사용하기 때문에 nvm(Node Version Manager)을 사용한다.

 nvm(Node Version Manager) : node js를 버전별로 설치하여 필요한 버전으로 node js 버전을 변경할수 있음

프로젝트 빌드 환경에 따라 nvm을 이용하여 Node js 버전을 변경해가며 사용한다.

Node js를 사용하면, npm(Node Package Manager)을 사용할 수 있다.

※ npm (Node Package Manager) : node js 개발 시 전 세계의 개발자들이 만든 다양한 기능(패키지, 모듈)을 관리, 개발 시 필요한 기능을 설치하여 쉽게 사용할수 있다.

npm을 사용함으로 관리 효율증가와 손쉬운 기능 고도화가 가능하지만 구성이 복잡해지고, 기능에대한 학습의 난이도가 증가하는 Trade-off(상충관계)가 발생한다.

+ Recent posts