getSharedPreferences()
if multiple preference files are
required. First parameter is the name of the preference filegetPreferences()
if only one preference file is needededit()
on the SharedPreferences instance putBoolean()
and putString()
with the key as the first parameter and the
value as the second parametercommit()
getBoolean()
and getString()
Example code, reading values in onCreate()
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
enableEdgeToEdge()
val settings = getSharedPreferences(PREFS_NAME, 0)
val silent = settings.getBoolean("silentMode", false)
setSilent(silent)
...
}
}
// ...
override fun onStop() {
super.onStop()
// We need an Editor object to make preference changes.
// All objects are from android.context.Context
val settings = getSharedPreferences(PREFS_NAME, 0)
val editor = settings.edit()
editor.putBoolean("silentMode", mSilentMode)
// Commit the edits!
editor.commit()
}
// ...
openFileOutput()
with the filename and an operating mode:MODE_PRIVATE
will create or replace a file and make it private to your applicationMODE_APPEND
appends to an existing filewrite()
close()
val FILENAME = "hello_file"
val string = "hello world!"
val fos = openFileOutput(FILENAME, MODE_PRIVATE)
fos.write(string.toByteArray())
fos.close()
openInputFile()
with the name of the file as parameter to retrieve a
FileInputStream
read()
close()
res/raw/
directory,
use openRawResource()
and pass the filename using R.raw.\<filename>
READ_EXTERNAL_STORAGE
or
WRITE_EXTERNAL_STORAGE
must be requested and granted by the user. Do this in the
Androidmanifest.xml
file:<manifest ...>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
...
</manifest>
If both, reading and writing, is required, only the WRITE_EXTERNAL_STORAGE
permission is required.
Before writing to the external storage, make sure that it is available by calling
getExternalStorageState()
:
/**
* Checks if external storage is available for read and write
*/
fun isExternalStorageWritable(): Boolean {
val state = Environment.getExternalStorageState()
if (Environment.MEDIA_MOUNTED == state) {
return true
}
return false
}
getExternalStoragePublicDirectory()
DIRECTORY_MUSIC
or DIRECTORY_PICTURES
fun getAlbumStorageDir(albumName: String?): File {
// Get the directory for the user's public pictures directory.
val file = File(
Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_PICTURES
), albumName
)
if (!file.mkdirs()) {
Log.e(LOG_TAG, "Directory not created")
}
return file
}
getExternalFilesDir()
DIRECTORY_MOVIES
) or null
if a specific media
directory is not necessaryWRITE_EXTERNAL_STORAGE
permissionMediaStore
ContentProvider
does not scan private directories for mediaclass DictionaryOpenHelper internal constructor(context: Context?) :
SQLiteOpenHelper(context, DATABASE_NAME, null, DATABASE_VERSION) {
override fun onCreate(db: SQLiteDatabase) {
db.execSQL(CREATE)
}
override fun onUpgrade(db: SQLiteDatabase?, oldVersion: Int, newVersion: Int) {
db?.execSQL(UPGRADE)
}
}
getWritableDatabase()
getReadableDatabase()
SQLiteDatabase
object that provides methods for SQLite operationsSQLiteDatabase
query()
methodsSQLiteQueryBuilder
Cursor
that points to the rows found by the query/Users/\<username>/Library/Android/sdk/platform-tools
Ad this dependency to your app build.gradle.kts
:
implementation(libs.androidx.room.gradle.plugin)
implementation(libs.androidx.room.runtime)
annotationProcessor(libs.androidx.room.compiler)
ksp(libs.androidx.room.compiler)
implementation(libs.androidx.room.ktx)
Entity
class can be reused with other libraries like Retrofit@Entity
annotationUse @PrimaryKey(autoGenerate = true)
to let Room create and auto increment unique ids for your
entries.
@Entity
data class Movie(
@PrimaryKey(autoGenerate = true) val uid: Int = 0,
@ColumnInfo(name = "title") val title: String,
@ColumnInfo(name = "year") val year: String,
@ColumnInfo(name = "poster") val poster: String
)
import androidx.room.Dao
import androidx.room.Delete
import androidx.room.Insert
import androidx.room.Query
@Dao
interface MovieDao {
@Query("SELECT * FROM movie")
fun getAllMovies(): List<Movie>
@Insert
suspend fun insert(movie: Movie)
@Delete
suspend fun delete(movie: Movie)
}
@Database(entities = [Movie::class], version = 1, exportSchema = false)
abstract class MovieDatabase : RoomDatabase() {
abstract fun movieDao(): MovieDao
companion object {
@Volatile
private var Instance: MovieDatabase? = null
fun getDatabase(context: Context): MovieDatabase {
return Instance ?: synchronized(this) {
Room.databaseBuilder(context, MovieDatabase::class.java, "movie-database")
.build()
.also { Instance = it }
}
}
}
}
Insert an entity into database. This is a suspend operation which needs to run in a background thread so use coroutines:
lifecycleScope.launch(Dispatchers.IO) {
MovieDatabase.getDatabase(applicationContext).movieDao().insert(movie)
withContext(Dispatchers.Main) {
refresh()
}
}
Get a list of entities from database:
lifecycleScope.launch(Dispatchers.IO) {
val movies = MovieDatabase.getDatabase(applicationContext).movieDao().getAllMovies()
Log.d("TAG", movies[0].title)
withContext(Dispatchers.Main) {
refresh()
}
}