Skip to content

Commit

Permalink
Merge pull request #95 from mhss1/dev
Browse files Browse the repository at this point in the history
Dev
  • Loading branch information
mhss1 authored Oct 26, 2022
2 parents a8cc131 + ac61a38 commit ea35e61
Show file tree
Hide file tree
Showing 53 changed files with 1,434 additions and 178 deletions.
43 changes: 27 additions & 16 deletions app/build.gradle
Original file line number Diff line number Diff line change
@@ -1,25 +1,26 @@
plugins {
id 'com.android.application'
id 'org.jetbrains.kotlin.android'
id 'kotlin-kapt'
id 'dagger.hilt.android.plugin'
id 'kotlin-kapt'
}

android {
compileSdk 33

defaultConfig {
applicationId "com.mhss.app.mybrain"
namespace "com.mhss.app.mybrain"
minSdk 24
targetSdk 33
versionCode 3
versionName "1.0.2"
versionCode 4
versionName "1.0.3"

testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
vectorDrawables {
useSupportLibrary true
}
resConfigs "en", "ar", "zh-rCN", "hi", "pl", "ru"
resConfigs "en", "ar", "zh-rCN", "hi", "pl", "ru", "ro", "pt-rBR", "de"
kapt {
arguments {
arg("room.schemaLocation", "$projectDir/schemas")
Expand Down Expand Up @@ -69,27 +70,28 @@ kotlin {
}

dependencies {
def nav_version = "2.5.1"
def room_version = "2.4.3"
def coroutines_version = "1.6.1"

implementation 'androidx.core:core-ktx:1.8.0'
implementation "androidx.compose.ui:ui:$compose_version"
implementation "androidx.compose.material:material:$compose_version"
implementation "androidx.compose.ui:ui-tooling-preview:$compose_version"
implementation platform('androidx.compose:compose-bom:2022.10.00')

implementation 'androidx.core:core-ktx:1.9.0'
implementation "androidx.compose.ui:ui"
implementation "androidx.compose.material:material"
implementation "androidx.compose.ui:ui-tooling-preview"
implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.5.1'
implementation 'androidx.activity:activity-compose:1.5.1'
implementation 'androidx.activity:activity-compose:1.6.0'
testImplementation 'junit:junit:4.13.2'
androidTestImplementation 'androidx.test.ext:junit:1.1.3'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
androidTestImplementation "androidx.compose.ui:ui-test-junit4:$compose_version"
debugImplementation "androidx.compose.ui:ui-tooling:$compose_version"
androidTestImplementation "androidx.compose.ui:ui-test-junit4"
debugImplementation "androidx.compose.ui:ui-tooling"

// Compose navigation
implementation "androidx.navigation:navigation-compose:$nav_version"
implementation "androidx.navigation:navigation-compose:2.5.2"
implementation 'androidx.hilt:hilt-navigation-compose:1.0.0'

// Room
// Room
implementation "androidx.room:room-runtime:$room_version"
kapt "androidx.room:room-compiler:$room_version"
implementation "androidx.room:room-ktx:$room_version"
Expand All @@ -98,13 +100,14 @@ dependencies {
implementation "com.google.dagger:hilt-android:2.43.2"
kapt "com.google.dagger:hilt-android-compiler:2.43.2"
kapt "androidx.hilt:hilt-compiler:1.0.0"
implementation 'androidx.hilt:hilt-work:1.0.0'

// Coroutines
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:$coroutines_version"
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:$coroutines_version"

// Gson
implementation 'com.google.code.gson:gson:2.9.0'
implementation 'com.google.code.gson:gson:2.9.1'

// Preferences DataStore
implementation "androidx.datastore:datastore-preferences:1.0.0"
Expand All @@ -118,8 +121,16 @@ dependencies {
implementation 'com.github.jeziellago:compose-markdown:0.2.9'

// Compose Glance (Widgets)
implementation "androidx.glance:glance-appwidget:1.0.0-alpha03"
implementation "androidx.glance:glance-appwidget:1.0.0-alpha05"

//Moshi
implementation "com.squareup.moshi:moshi-kotlin:1.14.0"

// WorkManager
implementation "androidx.work:work-runtime-ktx:2.7.1"

// Compose live data
implementation "androidx.compose.runtime:runtime-livedata"
}

kapt {
Expand Down
3 changes: 2 additions & 1 deletion app/proguard-rules.pro
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,5 @@

# If you keep the line number information, uncomment this to
# hide the original source file name.
#-renamesourcefileattribute SourceFile
#-renamesourcefileattribute SourceFile
-dontobfuscate
37 changes: 23 additions & 14 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -1,31 +1,33 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="com.mhss.app.mybrain">
xmlns:tools="http://schemas.android.com/tools">

<!-- For the Calendar events features -->
<uses-permission android:name="android.permission.READ_CALENDAR" />
<uses-permission android:name="android.permission.WRITE_CALENDAR" />
<!-- For reminders -->
<uses-permission android:name="android.permission.SCHEDULE_EXACT_ALARM" /> <!-- to start the alarms after restart. (By default, all alarms are canceled when a device shuts down) -->
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<!-- For backup -->
<uses-permission
android:name="android.permission.WRITE_EXTERNAL_STORAGE"
android:maxSdkVersion="28"/>

<application
android:name=".app.MyBrainApplication"
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:localeConfig="@xml/locales_config"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.MyBrain"
android:localeConfig="@xml/locales_config"
tools:targetApi="33">
<activity
android:name=".presentation.main.MainActivity"
android:exported="true"
android:theme="@style/Theme.MyBrain"
android:windowSoftInputMode="adjustResize"
>
android:windowSoftInputMode="adjustResize">
<intent-filter>
<action android:name="android.intent.action.MAIN" />

Expand Down Expand Up @@ -95,8 +97,8 @@
<receiver
android:name=".presentation.glance_widgets.CalendarWidgetReceiver"
android:enabled="@bool/glance_appwidget_available"
android:label="@string/calendar"
android:exported="true">
android:exported="true"
android:label="@string/calendar">
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
</intent-filter>
Expand All @@ -111,18 +113,19 @@
android:enabled="@bool/glance_appwidget_available"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.PROVIDER_CHANGED"/>
<data android:scheme="content"/>
<data android:host="com.android.calendar"/>
<action android:name="android.intent.action.PROVIDER_CHANGED" />

<data android:scheme="content" />
<data android:host="com.android.calendar" />
</intent-filter>
</receiver>

<!-- Tasks widget-->
<receiver
android:name=".presentation.glance_widgets.TasksWidgetReceiver"
android:enabled="@bool/glance_appwidget_available"
android:label="@string/tasks"
android:exported="false">
android:exported="false"
android:label="@string/tasks">
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
</intent-filter>
Expand All @@ -134,8 +137,14 @@
<receiver
android:name=".presentation.glance_widgets.CompleteTaskWidgetReceiver"
android:enabled="@bool/glance_appwidget_available"
android:exported="false">
</receiver>
android:exported="false" />

<provider
android:name="androidx.startup.InitializationProvider"
android:authorities="${applicationId}.androidx-startup"
tools:node="remove" />


</application>

</manifest>
13 changes: 12 additions & 1 deletion app/src/main/java/com/mhss/app/mybrain/app/MyBrainApplication.kt
Original file line number Diff line number Diff line change
Expand Up @@ -9,19 +9,30 @@ import androidx.annotation.StringRes
import androidx.datastore.core.DataStore
import androidx.datastore.preferences.core.Preferences
import androidx.datastore.preferences.preferencesDataStore
import androidx.hilt.work.HiltWorkerFactory
import androidx.work.Configuration
import com.mhss.app.mybrain.R
import com.mhss.app.mybrain.util.Constants
import dagger.hilt.android.HiltAndroidApp
import javax.inject.Inject

val Context.dataStore: DataStore<Preferences> by preferencesDataStore(name = Constants.SETTINGS_PREFERENCES)

@HiltAndroidApp
class MyBrainApplication : Application() {
class MyBrainApplication : Application(), Configuration.Provider {

companion object {
lateinit var appContext: Context
}

@Inject
lateinit var workerFactory: HiltWorkerFactory

override fun getWorkManagerConfiguration() =
Configuration.Builder()
.setWorkerFactory(workerFactory)
.build()

override fun onCreate() {
super.onCreate()
appContext = this
Expand Down
123 changes: 123 additions & 0 deletions app/src/main/java/com/mhss/app/mybrain/data/backup/ExportWorker.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
package com.mhss.app.mybrain.data.backup

import android.content.ContentUris
import android.content.ContentValues
import android.content.Context
import android.net.Uri
import android.os.Build
import android.os.Environment
import android.provider.MediaStore
import androidx.hilt.work.HiltWorker
import androidx.work.CoroutineWorker
import androidx.work.WorkerParameters
import androidx.work.workDataOf
import com.mhss.app.mybrain.data.local.dao.BookmarkDao
import com.mhss.app.mybrain.data.local.dao.DiaryDao
import com.mhss.app.mybrain.data.local.dao.NoteDao
import com.mhss.app.mybrain.data.local.dao.TaskDao
import com.mhss.app.mybrain.domain.model.NotesBackUp
import com.mhss.app.mybrain.util.BackupUtil.toJson
import com.mhss.app.mybrain.util.Constants
import dagger.assisted.Assisted
import dagger.assisted.AssistedInject
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.withContext
import java.io.File
import java.io.FileOutputStream


@HiltWorker
class ExportWorker @AssistedInject constructor(
@Assisted appContext: Context,
@Assisted workerParams: WorkerParameters,
private val notesDao: NoteDao,
private val tasksDao: TaskDao,
private val diaryDao: DiaryDao,
private val bookmarksDao: BookmarkDao
) : CoroutineWorker(appContext, workerParams) {

override suspend fun doWork() = withContext(Dispatchers.IO) {
export()
}

private suspend fun export(): Result {
return try {
val notes = notesDao.getAllNotes().first()
val folders = notesDao.getAllNoteFolders().first()
val notesBackup = NotesBackUp(notes, folders).toJson()
saveFile(Constants.BACKUP_NOTES_FILE_NAME, notesBackup)
setProgress(workDataOf("progress" to 25))

val tasks = tasksDao.getAllTasks().first().toJson()
saveFile(Constants.BACKUP_TASKS_FILE_NAME, tasks)
setProgress(workDataOf("progress" to 50))

val diary = diaryDao.getAllEntries().first().toJson()
saveFile(Constants.BACKUP_DIARY_FILE_NAME, diary)
setProgress(workDataOf("progress" to 75))

val bookmarks = bookmarksDao.getAllBookmarks().first().toJson()
saveFile(Constants.BACKUP_BOOKMARKS_FILE_NAME, bookmarks)
setProgress(workDataOf("progress" to 100))

Result.success(workDataOf("success" to true))
} catch (e: Exception) {
e.printStackTrace()
Result.failure()
}
}


private fun saveFile(fileName: String, content: String) {
val contentResolver = applicationContext.contentResolver
val values = ContentValues().apply {
put(MediaStore.MediaColumns.DISPLAY_NAME, fileName)
put(MediaStore.MediaColumns.MIME_TYPE,"text/plain")
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
values.put(MediaStore.MediaColumns.RELATIVE_PATH, Environment.DIRECTORY_DOCUMENTS + File.separator + "${Constants.EXPORT_DIR}/")
}
val fileUri = getFileUri(fileName) ?: contentResolver.insert(MediaStore.Files.getContentUri("external"), values)

fileUri?.let {
contentResolver.openFileDescriptor(it, "w")?.use { pfd ->
FileOutputStream(pfd.fileDescriptor).use { outputStream ->
outputStream.write(content.toByteArray())
}
}
}
}

private fun getFileUri(name: String): Uri? {
val projection = arrayOf(
MediaStore.Files.FileColumns._ID,
MediaStore.Files.FileColumns.DISPLAY_NAME
)
val selection = "${MediaStore.MediaColumns.RELATIVE_PATH} = ? AND ${MediaStore.Files.FileColumns.DISPLAY_NAME} = ?"
val selectionArgs = arrayOf(
Environment.DIRECTORY_DOCUMENTS + File.separator + "${Constants.EXPORT_DIR}/",
name
)
val resolver = applicationContext.contentResolver
val query = resolver.query(
MediaStore.Files.getContentUri("external"),
projection,
selection,
selectionArgs,
null
)
query?.use { cursor ->
val idColumn = cursor.getColumnIndexOrThrow(MediaStore.Files.FileColumns._ID)
if (cursor.moveToFirst()) {
val id = cursor.getLong(idColumn)
return ContentUris.withAppendedId(
MediaStore.Files.getContentUri("external"),
id
)
}
}
return null
}

}
Loading

0 comments on commit ea35e61

Please sign in to comment.