val file = File(filesDir, "test.txt") // 내장 메모리 공간에 파일 객체 할당
val writeStream: OutputStreamWriter = file.writer()
writeStream.write("hello world")
writeStream.flush()
Activity.getPreferences(int mode)
- 하나의 액티비티를 위한 데이터 저장을 목적으로 하는 경우
- 이 함수를 이용한 액티비티 클래스명으로 XML 파일명이 만들어짐.
Context.getSharedPreferences(String name, int mode)
- 앱 전체의 데이터를 key-value 형태로 저장
val sharedPref = getSharedPreferences("my_prefs", Context.MODE_PRIVATE)
putBoolean(String key, boolean value)
putInt(String key, int value)
putFloat(String key, float value)
putLong(String key, long value)
putString(String key, String value)
getBoolean(String key, boolean defValue)
getInt(String key, int defValue)
getFloat(String key, float defValue)
getLong(String key, long defValue)
getString(String key, String defValue)
<?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"
tools:context=".MainActivity"
android:orientation="vertical"
android:gravity="center">
<EditText
android:id="@+id/editView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
/>
<CheckBox
android:id="@+id/checkView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="check"/>
<Button
android:id="@+id/saveButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="SAVE"/>
<Button
android:id="@+id/getButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Get Data"/>
<TextView
android:id="@+id/resultView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</LinearLayout>
package com.tutorial.c55
import android.content.Context
import android.os.Bundle
import android.widget.Button
import android.widget.CheckBox
import android.widget.EditText
import android.widget.TextView
import androidx.appcompat.app.AppCompatActivity
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val editView = findViewById<EditText>(R.id.editView)
val checkView = findViewById<CheckBox>(R.id.checkView)
val saveButton = findViewById<Button>(R.id.saveButton)
val getButton = findViewById<Button>(R.id.getButton)
val resultView = findViewById<TextView>(R.id.resultView)
// 앱 전체의 데이터 저장을 위해 SharedPreferences 객체 생성
val sharedPref = getSharedPreferences("my_prefs",
Context.MODE_PRIVATE)
// sharedPref에 데이터 저장
saveButton.setOnClickListener {
sharedPref.edit().run {
putString("data1", editView.text.toString())
putBoolean("data2", checkView.isChecked)
commit()
}
}
// sharedPref에 저장된 데이터 획득
getButton.setOnClickListener {
val data1 = sharedPref.getString("data1", "none")
val data2 = sharedPref.getBoolean("data2", false)
resultView.text = "data1: $data1, data2: $data2"
}
}
}
implementation 'androidx.preference:preference-ktx:${version}'
<PreferenceScreen xmins:app="http://schemas.android.com/apk/res-auto">
<SwitchPreferenceCompat
app:key="notifications"
app:title="Enable message notifications"/>
</PreferenceScreen>
class SettingsFragment: PreferenceFragmentCompat() {
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
setPreferencesFromResource(R.xml.settings, rootKey)
}
이렇게 settings.xml 파일만 적용해주면, 설정 화면의 UI와 이벤트 처리, 그리고 데이터 저장까지 모두 자동화 된다.
implementation 'androidx.preference:preference-ktx:1.2.0'
cf) 위의 dependency를 추가했더니
Duplicate class androidx.lifecycle.ViewModelLazy found in modules jetified-lifecycle-viewmodel-ktx-2.3.1-runtime (androidx.lifecycle:lifecycle-viewmodel-ktx:2.3.1) and lifecycle-viewmodel-2.5.1-runtime (androidx.lifecycle:lifecycle-viewmodel:2.5.1)
이런 에러가 발생했다.
👉 이 링크를 참고하여implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.5.1'
이 코드를 추가했더니 에러가 사라졌다. preference와 viewmodel이 관련있는 걸까..?! 정확한 이유를 모르겠다.....
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
<PreferenceCategory
android:key="a_category"
android:title="A Setting">
<SwitchPreferenceCompat
android:key="a1"
android:title="A - 1 Setting"/>
<SwitchPreferenceCompat
android:key="a2"
android:title="A - 2 Setting"/>
</PreferenceCategory>
<PreferenceCategory
android:key="b_category"
android:title="B Setting">
<SwitchPreferenceCompat
android:key="b1"
android:title="B - 1 Setting"/>
<SwitchPreferenceCompat
android:key="b2"
android:title="B - 2 Setting"/>
</PreferenceCategory>
</PreferenceScreen>
package com.tutorial.c56
import android.os.Bundle
import androidx.preference.PreferenceFragmentCompat
class SettingsFragment : PreferenceFragmentCompat() {
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
setPreferencesFromResource(R.xml.settings, rootKey)
}
}
<?xml version="1.0" encoding="utf-8"?>
<fragment xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:name="com.tutorial.c56.SettingsFragment" />
앱을 종료시켰다가 다시 실행해도 설정 값이 그대로 유지되는 것을 확인할 수 있다!
설정을 위해 사용한 태그에 해당되는 객체를 findPreference() 함수로 획득
<EditTextPreference
android:key="id"
android:title="ID 설정"
android:isPreferenceVisible="false"/>
val idPref: EditTextPreference? = findPreference("id")
idPref?.isVisible = true
soundPreference!!.setSummaryProvider(ListPreference.SimpleSummaryProvider.getInstance())
idPref?.setOnPreferenceClickListener {
true
}
앱을 나갔다가 다시 들어와도 설정값이 그대로 유지되어 있음을 확인할 수 있다!
implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.5.1'
implementation 'androidx.preference:preference-ktx:1.2.0'
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
<SwitchPreferenceCompat
android:key="server_flag"
android:summaryOff="서버 연동 비활성화 상태"
android:summaryOn="서버 연동 활성화 상태"
android:title="서버 연동"/>
<PreferenceCategory
android:dependency="server_flag"
android:title="서버 연동 정보">
<EditTextPreference
android:key="server_id"
android:title="ID"/>
<ListPreference
android:key="sound_list"
android:title="서버 메시지 알림음"
android:entries="@array/array_voice"
android:entryValues="@array/array_voice"/>
</PreferenceCategory>
</PreferenceScreen>
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string-array name="array_voice">
<item>카톡</item>
<item>카톡왔숑</item>
<item>카카오톡</item>
</string-array>
</resources>
package com.tutorial.c57
import android.os.Bundle
import android.text.TextUtils
import android.widget.Toast
import androidx.preference.EditTextPreference
import androidx.preference.ListPreference
import androidx.preference.Preference
import androidx.preference.PreferenceFragmentCompat
class SettingsFragment : PreferenceFragmentCompat() {
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
setPreferencesFromResource(R.xml.settings, rootKey)
val idPref = findPreference<EditTextPreference>("server_id")
val soundPref = findPreference<ListPreference>("sound_list")
// id 값이 변경되는 경우
idPref?.setOnPreferenceChangeListener { preference, newValue ->
Toast.makeText(activity, "새로운 값: $newValue", Toast.LENGTH_SHORT).show()
true
}
// soundPref는 summary 그대로 출력
soundPref!!.setSummaryProvider(ListPreference.SimpleSummaryProvider.getInstance())
// idPref는 summary를 커스텀하여 출력
idPref!!.summaryProvider =
Preference.SummaryProvider<EditTextPreference> { preference ->
val text = preference.text
if(TextUtils.isEmpty(text)){
"id 값이 설정되지 않았습니다."
}else{
"설정된 값은 $text 입니다."
}
}
}
}
<?xml version="1.0" encoding="utf-8"?>
<fragment xmlns:android="http://schemas.android.com/apk/res/android"
android:name="com.tutorial.c57.SettingsFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"/>