Skip to content

Commit 938c050

Browse files
committed
Implemented backupNotes and other functions in Context.kt
1 parent c93e7fe commit 938c050

File tree

1 file changed

+121
-2
lines changed
  • app/src/main/kotlin/com/simplemobiletools/notes/pro/extensions

1 file changed

+121
-2
lines changed

app/src/main/kotlin/com/simplemobiletools/notes/pro/extensions/Context.kt

Lines changed: 121 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,28 @@
11
package com.simplemobiletools.notes.pro.extensions
22

3+
import android.app.AlarmManager
4+
import android.app.PendingIntent
35
import android.appwidget.AppWidgetManager
46
import android.content.ComponentName
57
import android.content.Context
68
import android.content.Intent
9+
import androidx.core.app.AlarmManagerCompat
710
import com.simplemobiletools.commons.activities.BaseSimpleActivity
11+
import com.simplemobiletools.commons.extensions.*
12+
import com.simplemobiletools.commons.helpers.ExportResult
13+
import com.simplemobiletools.commons.helpers.ensureBackgroundThread
14+
import com.simplemobiletools.commons.helpers.isRPlus
815
import com.simplemobiletools.notes.pro.R
916
import com.simplemobiletools.notes.pro.databases.NotesDatabase
1017
import com.simplemobiletools.notes.pro.dialogs.UnlockNotesDialog
11-
import com.simplemobiletools.notes.pro.helpers.Config
12-
import com.simplemobiletools.notes.pro.helpers.MyWidgetProvider
18+
import com.simplemobiletools.notes.pro.helpers.*
1319
import com.simplemobiletools.notes.pro.interfaces.NotesDao
1420
import com.simplemobiletools.notes.pro.interfaces.WidgetsDao
1521
import com.simplemobiletools.notes.pro.models.Note
22+
import com.simplemobiletools.notes.pro.receivers.AutomaticBackupReceiver
23+
import org.joda.time.DateTime
24+
import java.io.File
25+
import java.io.FileOutputStream
1626

1727
val Context.config: Config get() = Config.newInstance(applicationContext)
1828

@@ -43,3 +53,112 @@ fun BaseSimpleActivity.requestUnlockNotes(notes: List<Note>, callback: (unlocked
4353
callback(emptyList())
4454
}
4555
}
56+
57+
fun Context.getAutomaticBackupIntent(): PendingIntent {
58+
val intent = Intent(this, AutomaticBackupReceiver::class.java)
59+
return PendingIntent.getBroadcast(this, AUTOMATIC_BACKUP_REQUEST_CODE, intent, PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE)
60+
}
61+
62+
fun Context.scheduleNextAutomaticBackup() {
63+
if (config.autoBackup) {
64+
val backupAtMillis = getNextAutoBackupTime().millis
65+
val pendingIntent = getAutomaticBackupIntent()
66+
val alarmManager = getSystemService(Context.ALARM_SERVICE) as AlarmManager
67+
try {
68+
AlarmManagerCompat.setExactAndAllowWhileIdle(alarmManager, AlarmManager.RTC_WAKEUP, backupAtMillis, pendingIntent)
69+
} catch (e: Exception) {
70+
showErrorToast(e)
71+
}
72+
}
73+
}
74+
75+
fun Context.cancelScheduledAutomaticBackup() {
76+
val alarmManager = getSystemService(Context.ALARM_SERVICE) as AlarmManager
77+
alarmManager.cancel(getAutomaticBackupIntent())
78+
}
79+
80+
fun Context.checkAndBackupNotesOnBoot() {
81+
if (config.autoBackup) {
82+
val previousRealBackupTime = config.lastAutoBackupTime
83+
val previousScheduledBackupTime = getPreviousAutoBackupTime().millis
84+
val missedPreviousBackup = previousRealBackupTime < previousScheduledBackupTime
85+
if (missedPreviousBackup) {
86+
// device was probably off at the scheduled time so backup now
87+
backupNotes()
88+
}
89+
}
90+
}
91+
92+
fun Context.backupNotes() {
93+
require(isRPlus())
94+
ensureBackgroundThread {
95+
val config = config
96+
NotesHelper(this).getNotes { notesToBackup ->
97+
if (notesToBackup.isEmpty()) {
98+
toast(R.string.no_entries_for_exporting)
99+
config.lastAutoBackupTime = DateTime.now().millis
100+
scheduleNextAutomaticBackup()
101+
return@getNotes
102+
}
103+
104+
105+
val now = DateTime.now()
106+
val year = now.year.toString()
107+
val month = now.monthOfYear.ensureTwoDigits()
108+
val day = now.dayOfMonth.ensureTwoDigits()
109+
val hours = now.hourOfDay.ensureTwoDigits()
110+
val minutes = now.minuteOfHour.ensureTwoDigits()
111+
val seconds = now.secondOfMinute.ensureTwoDigits()
112+
113+
val filename = config.autoBackupFilename
114+
.replace("%Y", year, false)
115+
.replace("%M", month, false)
116+
.replace("%D", day, false)
117+
.replace("%h", hours, false)
118+
.replace("%m", minutes, false)
119+
.replace("%s", seconds, false)
120+
121+
val outputFolder = File(config.autoBackupFolder).apply {
122+
mkdirs()
123+
}
124+
125+
var exportFile = File(outputFolder, "$filename.json")
126+
var exportFilePath = exportFile.absolutePath
127+
val outputStream = try {
128+
if (hasProperStoredFirstParentUri(exportFilePath)) {
129+
val exportFileUri = createDocumentUriUsingFirstParentTreeUri(exportFilePath)
130+
if (!getDoesFilePathExist(exportFilePath)) {
131+
createSAFFileSdk30(exportFilePath)
132+
}
133+
applicationContext.contentResolver.openOutputStream(exportFileUri, "wt") ?: FileOutputStream(exportFile)
134+
} else {
135+
var num = 0
136+
while (getDoesFilePathExist(exportFilePath) && !exportFile.canWrite()) {
137+
num++
138+
exportFile = File(outputFolder, "${filename}_${num}.json")
139+
exportFilePath = exportFile.absolutePath
140+
}
141+
FileOutputStream(exportFile)
142+
}
143+
} catch (e: Exception) {
144+
showErrorToast(e)
145+
scheduleNextAutomaticBackup()
146+
return@getNotes
147+
}
148+
149+
val exportResult = try {
150+
NotesHelper(this).exportNotes(notesToBackup, outputStream)
151+
} catch (e: Exception) {
152+
showErrorToast(e)
153+
}
154+
155+
when (exportResult) {
156+
ExportResult.EXPORT_OK -> toast(R.string.exporting_successful)
157+
else -> toast(R.string.exporting_failed)
158+
}
159+
160+
config.lastAutoBackupTime = DateTime.now().millis
161+
scheduleNextAutomaticBackup()
162+
}
163+
}
164+
}

0 commit comments

Comments
 (0)