Skip to content
Nikita Kalugin edited this page Apr 18, 2021 · 2 revisions

I should show some util files too.

For example, one of them is PreferencesManager.kt. It creates DataStore for saving SortOrder which user choose.

enum class SortOrder { BY_NAME, BY_DATE }

@Singleton
class PreferencesManager @Inject constructor(@ApplicationContext context: Context) {

    private val dataStore = context.createDataStore("user_preferences")

    val readFromDataStore = dataStore.data
            .catch { exception ->
                if (exception is IOException) {
                    Log.e(TAG, "Error reading preferences", exception)
                    emit(emptyPreferences())
                } else {
                    throw exception
                }
            }
            .map { preferences ->
                val sortOrder = SortOrder.valueOf(
                        preferences[PreferencesKeys.SORT_ORDER] ?: SortOrder.BY_NAME.name
                )
                sortOrder
            }

    suspend fun updateSortOrder(sortOrder: SortOrder) {
        dataStore.edit { settings ->
            settings[PreferencesKeys.SORT_ORDER] = sortOrder.name
        }
    }

    private object PreferencesKeys {
        val SORT_ORDER = preferencesKey<String>("sort_order")
    }
}

Another interesting util file is SaveImage.kt it contains one extension function for Bitmap class. With this ext. function bitmap can be saved to user's device (in Pictures folder).

fun Bitmap.saveToGallery(context: Context) {
    val filename = "${System.currentTimeMillis()}.png"
    val write: (OutputStream) -> Boolean = {
        this.compress(Bitmap.CompressFormat.PNG, 100, it)
    }

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
        val contentValues = ContentValues().apply {
            put(MediaStore.MediaColumns.DISPLAY_NAME, filename)
            put(MediaStore.MediaColumns.MIME_TYPE, "image/png")
            put(MediaStore.MediaColumns.RELATIVE_PATH, "${Environment.DIRECTORY_PICTURES}/RecipeApp")
        }

        context.contentResolver.let {
            it.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, contentValues)?.let { uri ->
                it.openOutputStream(uri)?.let(write)
            }
        }
    } else {
        val imagesDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES).toString() + File.separator + "RecipeApp"
        val file = File(imagesDir)
        if (!file.exists()) {
            file.mkdir()
        }
        val image = File(imagesDir, filename)
        write(FileOutputStream(image))
    }
}

Here we need to check for user's android version because since Android 10 Google introduce scoped storage and we need to use it if user's android version if 10 or higher.

Clone this wiki locally