mirror of
https://github.com/SimpleMobileTools/Simple-Calendar.git
synced 2025-02-03 20:17:43 +01:00
remove Google Sync as a standalone feature
This commit is contained in:
parent
257144241a
commit
214a95eb5d
@ -42,20 +42,7 @@ dependencies {
|
||||
compile 'com.facebook.stetho:stetho:1.4.1'
|
||||
compile 'com.bignerdranch.android:recyclerview-multiselect:0.2'
|
||||
compile 'com.android.support:multidex:1.0.1'
|
||||
|
||||
compile 'com.google.code.gson:gson:2.8.0'
|
||||
compile('com.google.http-client:google-http-client-gson:1.22.0') {
|
||||
exclude group: 'org.apache.httpcomponents'
|
||||
}
|
||||
|
||||
compile 'com.google.android.gms:play-services-auth:10.0.1'
|
||||
compile('com.google.api-client:google-api-client-android:1.22.0') {
|
||||
exclude group: 'org.apache.httpcomponents'
|
||||
}
|
||||
compile('com.google.apis:google-api-services-calendar:v3-rev249-1.22.0') {
|
||||
exclude group: 'org.apache.httpcomponents'
|
||||
}
|
||||
|
||||
compile "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
|
||||
}
|
||||
|
||||
|
@ -7,12 +7,8 @@
|
||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
|
||||
<uses-permission android:name="android.permission.VIBRATE"/>
|
||||
|
||||
<uses-permission android:name="android.permission.INTERNET"/>
|
||||
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
|
||||
<uses-permission android:name="android.permission.GET_ACCOUNTS"/>
|
||||
|
||||
<uses-permission android:name="android.permission.READ_CALENDAR" />
|
||||
<uses-permission android:name="android.permission.WRITE_CALENDAR" />
|
||||
<uses-permission android:name="android.permission.READ_CALENDAR"/>
|
||||
<uses-permission android:name="android.permission.WRITE_CALENDAR"/>
|
||||
|
||||
<application
|
||||
android:name=".App"
|
||||
@ -138,8 +134,6 @@
|
||||
</intent-filter>
|
||||
</receiver>
|
||||
|
||||
<receiver android:name=".receivers.GoogleSyncReceiver"/>
|
||||
|
||||
<provider
|
||||
android:name="android.support.v4.content.FileProvider"
|
||||
android:authorities="com.simplemobiletools.calendar.fileprovider"
|
||||
|
@ -473,7 +473,6 @@ class EventActivity : SimpleActivity(), DBHelper.EventUpdateListener {
|
||||
toast(R.string.event_added)
|
||||
}
|
||||
|
||||
GoogleSyncHandler().tryInsertToGoogle(this, mEvent)
|
||||
finish()
|
||||
}
|
||||
} else {
|
||||
@ -502,7 +501,6 @@ class EventActivity : SimpleActivity(), DBHelper.EventUpdateListener {
|
||||
}
|
||||
|
||||
private fun eventUpdated() {
|
||||
GoogleSyncHandler().tryUpdateGoogleEvent(this, mEvent)
|
||||
toast(R.string.event_updated)
|
||||
finish()
|
||||
}
|
||||
|
@ -18,7 +18,6 @@ import com.simplemobiletools.calendar.R
|
||||
import com.simplemobiletools.calendar.adapters.MyMonthPagerAdapter
|
||||
import com.simplemobiletools.calendar.adapters.MyWeekPagerAdapter
|
||||
import com.simplemobiletools.calendar.adapters.MyYearPagerAdapter
|
||||
import com.simplemobiletools.calendar.asynctasks.FetchGoogleEventsTask
|
||||
import com.simplemobiletools.calendar.dialogs.ExportEventsDialog
|
||||
import com.simplemobiletools.calendar.dialogs.FilterEventTypesDialog
|
||||
import com.simplemobiletools.calendar.dialogs.ImportEventsDialog
|
||||
@ -27,7 +26,6 @@ import com.simplemobiletools.calendar.fragments.EventListFragment
|
||||
import com.simplemobiletools.calendar.fragments.WeekFragment
|
||||
import com.simplemobiletools.calendar.helpers.*
|
||||
import com.simplemobiletools.calendar.helpers.Formatter
|
||||
import com.simplemobiletools.calendar.interfaces.GoogleSyncListener
|
||||
import com.simplemobiletools.calendar.interfaces.NavigationListener
|
||||
import com.simplemobiletools.calendar.models.Event
|
||||
import com.simplemobiletools.calendar.models.EventType
|
||||
@ -86,18 +84,9 @@ class MainActivity : SimpleActivity(), NavigationListener {
|
||||
storeStateVariables()
|
||||
updateViewPager()
|
||||
|
||||
if (!hasGetAccountsPermission()) {
|
||||
config.googleSync = false
|
||||
}
|
||||
|
||||
if (!hasCalendarPermission()) {
|
||||
config.caldavSync = false
|
||||
}
|
||||
|
||||
if (isGoogleSyncActive()) {
|
||||
FetchGoogleEventsTask(applicationContext, googleSyncListener).execute()
|
||||
}
|
||||
scheduleGoogleSync(isGoogleSyncActive())
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
@ -538,12 +527,6 @@ class MainActivity : SimpleActivity(), NavigationListener {
|
||||
supportFragmentManager.beginTransaction().replace(R.id.calendar_event_list_holder, EventListFragment(), "").commit()
|
||||
}
|
||||
|
||||
val googleSyncListener = object : GoogleSyncListener {
|
||||
override fun syncCompleted() {
|
||||
refreshViewPager()
|
||||
}
|
||||
}
|
||||
|
||||
override fun goLeft() {
|
||||
main_view_pager.currentItem = main_view_pager.currentItem - 1
|
||||
}
|
||||
|
@ -1,33 +1,21 @@
|
||||
package com.simplemobiletools.calendar.activities
|
||||
|
||||
import android.Manifest
|
||||
import android.accounts.AccountManager
|
||||
import android.app.Activity
|
||||
import android.content.Intent
|
||||
import android.content.pm.PackageManager
|
||||
import android.content.res.Resources
|
||||
import android.graphics.Color
|
||||
import android.media.RingtoneManager
|
||||
import android.net.Uri
|
||||
import android.os.Bundle
|
||||
import android.os.Parcelable
|
||||
import android.support.v4.app.ActivityCompat
|
||||
import com.google.android.gms.common.ConnectionResult
|
||||
import com.google.android.gms.common.GoogleApiAvailability
|
||||
import com.google.api.client.googleapis.extensions.android.gms.auth.GoogleAccountCredential
|
||||
import com.google.api.client.googleapis.extensions.android.gms.auth.UserRecoverableAuthIOException
|
||||
import com.google.api.client.util.ExponentialBackOff
|
||||
import com.google.api.services.calendar.CalendarScopes
|
||||
import com.google.api.services.calendar.model.CalendarListEntry
|
||||
import com.simplemobiletools.calendar.R
|
||||
import com.simplemobiletools.calendar.asynctasks.FetchGoogleEventsTask
|
||||
import com.simplemobiletools.calendar.dialogs.CustomEventReminderDialog
|
||||
import com.simplemobiletools.calendar.dialogs.SnoozePickerDialog
|
||||
import com.simplemobiletools.calendar.extensions.*
|
||||
import com.simplemobiletools.calendar.helpers.*
|
||||
import com.simplemobiletools.calendar.interfaces.GoogleSyncListener
|
||||
import com.simplemobiletools.calendar.models.Event
|
||||
import com.simplemobiletools.commons.dialogs.ConfirmationDialog
|
||||
import com.simplemobiletools.calendar.helpers.FONT_SIZE_LARGE
|
||||
import com.simplemobiletools.calendar.helpers.FONT_SIZE_MEDIUM
|
||||
import com.simplemobiletools.calendar.helpers.FONT_SIZE_SMALL
|
||||
import com.simplemobiletools.commons.dialogs.RadioGroupDialog
|
||||
import com.simplemobiletools.commons.extensions.toast
|
||||
import com.simplemobiletools.commons.extensions.updateTextColors
|
||||
@ -36,9 +24,6 @@ import kotlinx.android.synthetic.main.activity_settings.*
|
||||
|
||||
class SettingsActivity : SimpleActivity() {
|
||||
private val GET_RINGTONE_URI = 1
|
||||
private val ACCOUNTS_PERMISSION = 2
|
||||
private val REQUEST_ACCOUNT_NAME = 3
|
||||
private val REQUEST_GOOGLE_PLAY_SERVICES = 4
|
||||
private val CALENDAR_PERMISSION = 5
|
||||
|
||||
lateinit var res: Resources
|
||||
@ -52,7 +37,6 @@ class SettingsActivity : SimpleActivity() {
|
||||
super.onCreate(savedInstanceState)
|
||||
setContentView(R.layout.activity_settings)
|
||||
res = resources
|
||||
setupGoogleSync()
|
||||
setupCaldavSync()
|
||||
}
|
||||
|
||||
@ -113,26 +97,6 @@ class SettingsActivity : SimpleActivity() {
|
||||
}
|
||||
}
|
||||
|
||||
private fun setupGoogleSync() {
|
||||
settings_google_sync.isChecked = isGoogleSyncActive()
|
||||
settings_google_sync_holder.setOnClickListener {
|
||||
if (config.googleSync) {
|
||||
ConfirmationDialog(this, getString(R.string.google_sync_disabling), positive = R.string.ok, negative = R.string.cancel) {
|
||||
dbHelper.deleteAllGoogleSyncEvents()
|
||||
toggleGoogleSync()
|
||||
}
|
||||
} else {
|
||||
if (isOnline()) {
|
||||
ConfirmationDialog(this, getString(R.string.google_sync_testing), positive = R.string.ok, negative = 0) {
|
||||
toggleGoogleSync()
|
||||
}
|
||||
} else {
|
||||
toast(R.string.cannot_while_offline)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun setupCaldavSync() {
|
||||
settings_caldav_sync.isChecked = config.caldavSync
|
||||
settings_caldav_sync_holder.setOnClickListener {
|
||||
@ -153,16 +117,6 @@ class SettingsActivity : SimpleActivity() {
|
||||
config.caldavSync = settings_caldav_sync.isChecked
|
||||
}
|
||||
|
||||
private fun toggleGoogleSync() {
|
||||
settings_google_sync.toggle()
|
||||
|
||||
if (settings_google_sync.isChecked) {
|
||||
tryEnablingSync()
|
||||
} else {
|
||||
disableGoogleSync()
|
||||
}
|
||||
}
|
||||
|
||||
private fun setupSundayFirst() {
|
||||
settings_sunday_first.isChecked = config.isSundayFirst
|
||||
settings_sunday_first_holder.setOnClickListener {
|
||||
@ -333,136 +287,17 @@ class SettingsActivity : SimpleActivity() {
|
||||
settings_reminder_sound.text = RingtoneManager.getRingtone(this, uri as Uri)?.getTitle(this)
|
||||
config.reminderSound = uri.toString()
|
||||
}
|
||||
} else if (requestCode == REQUEST_ACCOUNT_NAME && data?.extras != null) {
|
||||
val accountName = data.getStringExtra(AccountManager.KEY_ACCOUNT_NAME)
|
||||
config.syncAccountName = accountName
|
||||
tryEnablingSync()
|
||||
} else if (requestCode == REQUEST_AUTHORIZATION) {
|
||||
tryEnablingSync()
|
||||
}
|
||||
} else if (resultCode == Activity.RESULT_CANCELED) {
|
||||
if (requestCode == REQUEST_ACCOUNT_NAME || requestCode == REQUEST_AUTHORIZATION) {
|
||||
disableGoogleSync()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun tryEnablingSync() {
|
||||
if (!isGooglePlayServicesAvailable()) {
|
||||
acquireGooglePlayServices()
|
||||
} else if (!hasGetAccountsPermission()) {
|
||||
ActivityCompat.requestPermissions(this, arrayOf(Manifest.permission.GET_ACCOUNTS), ACCOUNTS_PERMISSION)
|
||||
} else if (config.syncAccountName.isEmpty()) {
|
||||
showAccountChooser()
|
||||
} else {
|
||||
Thread({
|
||||
fetchEventsIfHasPermissions()
|
||||
}).start()
|
||||
}
|
||||
}
|
||||
|
||||
private fun isGooglePlayServicesAvailable(): Boolean {
|
||||
val apiAvailability = GoogleApiAvailability.getInstance()
|
||||
val connectionStatusCode = apiAvailability.isGooglePlayServicesAvailable(this)
|
||||
return connectionStatusCode == ConnectionResult.SUCCESS
|
||||
}
|
||||
|
||||
private fun acquireGooglePlayServices() {
|
||||
val apiAvailability = GoogleApiAvailability.getInstance()
|
||||
val connectionStatusCode = apiAvailability.isGooglePlayServicesAvailable(this)
|
||||
if (apiAvailability.isUserResolvableError(connectionStatusCode)) {
|
||||
GoogleApiAvailability.getInstance().getErrorDialog(this, connectionStatusCode, REQUEST_GOOGLE_PLAY_SERVICES).show()
|
||||
}
|
||||
}
|
||||
|
||||
private fun fetchEventsIfHasPermissions() {
|
||||
try {
|
||||
getGoogleSyncService().colors().get().execute() // just checking if we have the permission for fetching user data
|
||||
storeCalendarData()
|
||||
config.googleSync = true
|
||||
FetchGoogleEventsTask(applicationContext, googleSyncListener).execute()
|
||||
runOnUiThread {
|
||||
settings_google_sync.isChecked = true
|
||||
val eventsToExport = dbHelper.getEventsToExport(true)
|
||||
if (eventsToExport.isNotEmpty()) {
|
||||
offerEventsUpload(eventsToExport)
|
||||
}
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
if (e is UserRecoverableAuthIOException) {
|
||||
startActivityForResult(e.intent, REQUEST_AUTHORIZATION)
|
||||
} else {
|
||||
toast(R.string.unknown_error_occurred)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun disableGoogleSync() {
|
||||
settings_google_sync.isChecked = false
|
||||
config.googleSync = false
|
||||
config.syncAccountName = ""
|
||||
config.googleDefaultEventColor = config.primaryColor
|
||||
}
|
||||
|
||||
private fun storeCalendarData() {
|
||||
Thread({
|
||||
val calendar = getGoogleSyncService().calendarList().get(PRIMARY).execute()
|
||||
config.googleDefaultEventColor = Color.parseColor(calendar.backgroundColor)
|
||||
storeDefaultReminders(calendar)
|
||||
}).start()
|
||||
}
|
||||
|
||||
private fun storeDefaultReminders(calendar: CalendarListEntry) {
|
||||
val reminderMinutes = ArrayList<Int>()
|
||||
val reminders = calendar.defaultReminders
|
||||
reminders.forEach {
|
||||
if (it.method == POPUP) {
|
||||
reminderMinutes.add(it.minutes)
|
||||
}
|
||||
}
|
||||
config.googleDefaultReminders = reminderMinutes.joinToString(",")
|
||||
}
|
||||
|
||||
private val googleSyncListener = object : GoogleSyncListener {
|
||||
override fun syncCompleted() {
|
||||
toast(R.string.events_imported_successfully)
|
||||
}
|
||||
}
|
||||
|
||||
private fun offerEventsUpload(eventsToExport: ArrayList<Event>) {
|
||||
ConfirmationDialog(this, messageId = R.string.google_sync_existing) {
|
||||
Thread({
|
||||
eventsToExport.forEach {
|
||||
try {
|
||||
GoogleSyncHandler().tryInsertToGoogle(this, it)
|
||||
} catch (e: Exception) {
|
||||
}
|
||||
}
|
||||
}).start()
|
||||
}
|
||||
}
|
||||
|
||||
override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<String>, grantResults: IntArray) {
|
||||
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
|
||||
|
||||
if (requestCode == ACCOUNTS_PERMISSION) {
|
||||
if (grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
|
||||
showAccountChooser()
|
||||
} else {
|
||||
disableGoogleSync()
|
||||
}
|
||||
} else if (requestCode == CALENDAR_PERMISSION) {
|
||||
if (requestCode == CALENDAR_PERMISSION) {
|
||||
if (grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
|
||||
toggleCaldavSync()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun showAccountChooser() {
|
||||
if (config.syncAccountName.isEmpty()) {
|
||||
// more about oauth at https://developers.google.com/google-apps/calendar/auth
|
||||
val credential = GoogleAccountCredential.usingOAuth2(this, arrayListOf(CalendarScopes.CALENDAR)).setBackOff(ExponentialBackOff())
|
||||
startActivityForResult(credential.newChooseAccountIntent(), REQUEST_ACCOUNT_NAME)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,227 +0,0 @@
|
||||
package com.simplemobiletools.calendar.asynctasks
|
||||
|
||||
import android.content.Context
|
||||
import android.graphics.Color
|
||||
import android.os.AsyncTask
|
||||
import android.util.SparseIntArray
|
||||
import android.widget.Toast
|
||||
import com.google.api.client.googleapis.json.GoogleJsonResponseException
|
||||
import com.google.gson.Gson
|
||||
import com.google.gson.JsonObject
|
||||
import com.google.gson.reflect.TypeToken
|
||||
import com.simplemobiletools.calendar.R
|
||||
import com.simplemobiletools.calendar.extensions.*
|
||||
import com.simplemobiletools.calendar.helpers.*
|
||||
import com.simplemobiletools.calendar.interfaces.GoogleSyncListener
|
||||
import com.simplemobiletools.calendar.models.*
|
||||
import com.simplemobiletools.commons.extensions.isOnMainThread
|
||||
import com.simplemobiletools.commons.extensions.toast
|
||||
import org.joda.time.DateTime
|
||||
import java.util.*
|
||||
|
||||
// more info about event fields at https://developers.google.com/google-apps/calendar/v3/reference/events/insert
|
||||
class FetchGoogleEventsTask(val context: Context, val googleSyncListener: GoogleSyncListener? = null) : AsyncTask<Void, Void, String>() {
|
||||
private val ITEMS = "items"
|
||||
private val NEXT_PAGE_TOKEN = "nextPageToken"
|
||||
|
||||
private var dbHelper = context.dbHelper
|
||||
private var eventTypes = ArrayList<EventType>()
|
||||
private var eventColors = SparseIntArray()
|
||||
private var service = context.getGoogleSyncService()
|
||||
private var parseError: Exception? = null
|
||||
private var noTitleText = context.getString(R.string.no_title)
|
||||
|
||||
override fun doInBackground(vararg params: Void): String {
|
||||
if (!context.isGoogleSyncActive() || !context.isOnline())
|
||||
return ""
|
||||
|
||||
// always handle queued operations before fetching new data
|
||||
val queuedOperations = context.googleSyncQueue.getOperations()
|
||||
queuedOperations.forEach {
|
||||
when (it.operation) {
|
||||
OPERATION_INSERT -> {
|
||||
val event = dbHelper.getEventWithId(it.eventId)
|
||||
if (event != null)
|
||||
GoogleSyncHandler().insertToGoogle(context, event)
|
||||
context.googleSyncQueue.clearOperationsOf(it.eventId)
|
||||
}
|
||||
OPERATION_UPDATE -> {
|
||||
val event = dbHelper.getEventWithId(it.eventId)
|
||||
if (event != null)
|
||||
GoogleSyncHandler().updateGoogleEvent(context, event)
|
||||
context.googleSyncQueue.clearOperationsOf(it.eventId)
|
||||
}
|
||||
OPERATION_DELETE -> {
|
||||
GoogleSyncHandler().deleteFromGoogle(context, it.importId)
|
||||
context.googleSyncQueue.clearOperationsOf(it.eventId)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
getColors()
|
||||
getDataFromApi()
|
||||
googleSyncListener?.syncCompleted()
|
||||
} catch (e: Exception) {
|
||||
parseError = e
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
override fun onPostExecute(result: String?) {
|
||||
super.onPostExecute(result)
|
||||
if (context.isOnMainThread() && parseError != null && parseError is GoogleJsonResponseException) {
|
||||
val msg = String.format(context.getString(R.string.google_sync_error_fetch), parseError!!.getGoogleMessageError())
|
||||
context.toast(msg, Toast.LENGTH_LONG)
|
||||
}
|
||||
}
|
||||
|
||||
private fun getColors() {
|
||||
val colors = service.colors().get().execute()
|
||||
for ((id, color) in colors.event.entries) {
|
||||
eventColors.put(id.toInt(), Color.parseColor(color.background))
|
||||
}
|
||||
}
|
||||
|
||||
private fun getDataFromApi() {
|
||||
var currToken = ""
|
||||
while (true) {
|
||||
service.colors().get().execute()
|
||||
val events = service.events().list(PRIMARY)
|
||||
.setPageToken(currToken)
|
||||
.execute()
|
||||
|
||||
for ((key, value) in events) {
|
||||
if (key == ITEMS) {
|
||||
eventTypes = dbHelper.fetchEventTypes()
|
||||
val localGoogleEvents = dbHelper.getGoogleSyncEvents()
|
||||
val remoteGoogleEvents = parseEvents(value.toString())
|
||||
removeRedundantLocalEvents(localGoogleEvents, remoteGoogleEvents)
|
||||
}
|
||||
}
|
||||
|
||||
if (events.containsKey(NEXT_PAGE_TOKEN)) {
|
||||
currToken = events[NEXT_PAGE_TOKEN] as String
|
||||
} else {
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun parseEvents(json: String): ArrayList<String> {
|
||||
val remoteImportIds = ArrayList<String>()
|
||||
var updateEvent = false
|
||||
var eventId = 0
|
||||
val importIDs = context.dbHelper.getImportIds()
|
||||
val token = object : TypeToken<List<GoogleEvent>>() {}.type
|
||||
val googleEvents = Gson().fromJson<ArrayList<GoogleEvent>>(json, token) ?: ArrayList<GoogleEvent>(8)
|
||||
for (googleEvent in googleEvents) {
|
||||
val importId = googleEvent.id
|
||||
remoteImportIds.add(importId)
|
||||
if (!googleEvent.status.equals(CONFIRMED, true))
|
||||
continue
|
||||
|
||||
val lastUpdate = DateTime(googleEvent.updated).millis
|
||||
if (importIDs.contains(importId)) {
|
||||
val oldEvent = dbHelper.getEventWithImportId(importId)
|
||||
if (oldEvent != null) {
|
||||
if (oldEvent.lastUpdated >= lastUpdate) {
|
||||
continue
|
||||
} else {
|
||||
updateEvent = true
|
||||
eventId = oldEvent.id
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val start = googleEvent.start
|
||||
val end = googleEvent.end
|
||||
var startTS: Int
|
||||
var endTS: Int
|
||||
var flags = 0
|
||||
|
||||
if (start.date != null) {
|
||||
startTS = DateTime(start.date).withHourOfDay(1).seconds()
|
||||
endTS = DateTime(end.date).withHourOfDay(1).seconds()
|
||||
flags = flags or FLAG_ALL_DAY
|
||||
} else {
|
||||
startTS = DateTime(start.dateTime).seconds()
|
||||
endTS = DateTime(end.dateTime).seconds()
|
||||
}
|
||||
|
||||
val summary = googleEvent.summary ?: "($noTitleText)"
|
||||
val description = googleEvent.description ?: ""
|
||||
val reminders = getReminders(googleEvent.reminders)
|
||||
val repeatRule = getRepeatRule(googleEvent, startTS)
|
||||
val eventTypeId = getEventTypeId(googleEvent.colorId)
|
||||
val event = Event(eventId, startTS, endTS, summary, description, reminders.getOrElse(0, { -1 }),
|
||||
reminders.getOrElse(1, { -1 }), reminders.getOrElse(2, { -1 }), repeatRule.repeatInterval, importId, flags, repeatRule.repeatLimit,
|
||||
repeatRule.repeatRule, eventTypeId, lastUpdated = lastUpdate, source = SOURCE_GOOGLE_SYNC)
|
||||
|
||||
if (event.getIsAllDay() && endTS > startTS) {
|
||||
event.endTS -= DAY
|
||||
}
|
||||
|
||||
if (updateEvent) {
|
||||
dbHelper.update(event) {}
|
||||
} else {
|
||||
importIDs.add(importId)
|
||||
dbHelper.insert(event) {}
|
||||
}
|
||||
}
|
||||
return remoteImportIds
|
||||
}
|
||||
|
||||
private fun removeRedundantLocalEvents(localGoogleEvents: List<Event>, remoteGoogleEvents: ArrayList<String>) {
|
||||
val filtered = localGoogleEvents.filter { !remoteGoogleEvents.contains(it.importId) }
|
||||
val filteredIds = Array(filtered.size, { i -> (filtered[i].id.toString()) })
|
||||
dbHelper.deleteEvents(filteredIds, false)
|
||||
}
|
||||
|
||||
private fun getEventTypeId(colorId: Int): Int {
|
||||
var eventTypeId = -1
|
||||
val eventType = "google_sync_$colorId"
|
||||
eventTypes.forEach {
|
||||
if (it.title.toLowerCase() == eventType)
|
||||
eventTypeId = it.id
|
||||
}
|
||||
|
||||
if (eventTypeId == -1) {
|
||||
val newColor = if (eventColors[colorId] != 0) eventColors[colorId] else context.config.googleDefaultEventColor
|
||||
val newEventType = EventType(0, eventType, newColor)
|
||||
eventTypeId = dbHelper.insertEventType(newEventType)
|
||||
eventTypes.add(newEventType)
|
||||
}
|
||||
|
||||
return eventTypeId
|
||||
}
|
||||
|
||||
private fun getRepeatRule(googleEvent: GoogleEvent, startTS: Int): RepeatRule {
|
||||
val recurrence = googleEvent.recurrence?.firstOrNull()
|
||||
return if (recurrence != null) {
|
||||
Parser().parseRepeatInterval(recurrence.toString().trim('\"').substring(RRULE.length), startTS)
|
||||
} else {
|
||||
RepeatRule(0, 0, 0)
|
||||
}
|
||||
}
|
||||
|
||||
private fun getReminders(json: JsonObject?): List<Int> {
|
||||
val reminderMinutes = ArrayList<Int>()
|
||||
if (json?.has(OVERRIDES) == true) {
|
||||
val array = json.getAsJsonArray(OVERRIDES)
|
||||
val token = object : TypeToken<List<GoogleEventReminder>>() {}.type
|
||||
val reminders = Gson().fromJson<ArrayList<GoogleEventReminder>>(array, token) ?: ArrayList<GoogleEventReminder>(2)
|
||||
for ((method, minutes) in reminders) {
|
||||
if (method == POPUP) {
|
||||
reminderMinutes.add(minutes)
|
||||
}
|
||||
}
|
||||
} else if (json?.has(USE_DEFAULT) == true) {
|
||||
val minutes = context.config.googleDefaultReminders.splitToSequence(',')
|
||||
minutes.forEach {
|
||||
reminderMinutes.add(it.toInt())
|
||||
}
|
||||
}
|
||||
return reminderMinutes
|
||||
}
|
||||
}
|
@ -12,22 +12,15 @@ import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.content.pm.PackageManager
|
||||
import android.graphics.Color
|
||||
import android.net.ConnectivityManager
|
||||
import android.net.Uri
|
||||
import android.os.Build
|
||||
import android.support.v4.content.ContextCompat
|
||||
import android.support.v7.app.NotificationCompat
|
||||
import com.google.api.client.extensions.android.http.AndroidHttp
|
||||
import com.google.api.client.googleapis.extensions.android.gms.auth.GoogleAccountCredential
|
||||
import com.google.api.client.json.gson.GsonFactory
|
||||
import com.google.api.client.util.ExponentialBackOff
|
||||
import com.google.api.services.calendar.CalendarScopes
|
||||
import com.simplemobiletools.calendar.R
|
||||
import com.simplemobiletools.calendar.activities.EventActivity
|
||||
import com.simplemobiletools.calendar.helpers.*
|
||||
import com.simplemobiletools.calendar.helpers.Formatter
|
||||
import com.simplemobiletools.calendar.models.Event
|
||||
import com.simplemobiletools.calendar.receivers.GoogleSyncReceiver
|
||||
import com.simplemobiletools.calendar.receivers.NotificationReceiver
|
||||
import com.simplemobiletools.calendar.services.SnoozeService
|
||||
import com.simplemobiletools.commons.extensions.getContrastColor
|
||||
@ -237,41 +230,10 @@ fun Context.launchNewEventIntent(startNewTask: Boolean = false, today: Boolean =
|
||||
}
|
||||
}
|
||||
|
||||
fun Context.getGoogleSyncService(): com.google.api.services.calendar.Calendar {
|
||||
val credential = GoogleAccountCredential.usingOAuth2(this, arrayListOf(CalendarScopes.CALENDAR)).setBackOff(ExponentialBackOff())
|
||||
credential.selectedAccountName = config.syncAccountName
|
||||
val transport = AndroidHttp.newCompatibleTransport()
|
||||
return com.google.api.services.calendar.Calendar.Builder(transport, GsonFactory(), credential)
|
||||
.setApplicationName(resources.getString(R.string.app_name))
|
||||
.build()
|
||||
}
|
||||
|
||||
fun Context.isOnline(): Boolean {
|
||||
val connectivityManager = getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
|
||||
return connectivityManager.activeNetworkInfo != null
|
||||
}
|
||||
|
||||
fun Context.scheduleGoogleSync(activate: Boolean) {
|
||||
val syncIntent = Intent(this, GoogleSyncReceiver::class.java)
|
||||
val pendingIntent = PendingIntent.getBroadcast(this, 0, syncIntent, PendingIntent.FLAG_CANCEL_CURRENT)
|
||||
val alarm = getSystemService(Context.ALARM_SERVICE) as AlarmManager
|
||||
|
||||
if (activate) {
|
||||
val syncCheckInterval = 4 * AlarmManager.INTERVAL_HOUR
|
||||
alarm.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + syncCheckInterval, syncCheckInterval, pendingIntent)
|
||||
} else {
|
||||
alarm.cancel(pendingIntent)
|
||||
}
|
||||
}
|
||||
|
||||
fun Context.getNewEventTimestampFromCode(dayCode: String) = Formatter.getLocalDateTimeFromCode(dayCode).withTime(13, 0, 0, 0).seconds()
|
||||
|
||||
fun Context.getCurrentOffset() = SimpleDateFormat("Z", Locale.getDefault()).format(Date())
|
||||
|
||||
fun Context.isGoogleSyncActive() = config.googleSync && config.syncAccountName.isNotEmpty()
|
||||
|
||||
val Context.config: Config get() = Config.newInstance(this)
|
||||
|
||||
val Context.dbHelper: DBHelper get() = DBHelper.newInstance(this)
|
||||
|
||||
val Context.googleSyncQueue: GoogleSyncQueueDB get() = GoogleSyncQueueDB.newInstance(this)
|
||||
|
@ -1,10 +0,0 @@
|
||||
package com.simplemobiletools.calendar.extensions
|
||||
|
||||
import com.google.gson.Gson
|
||||
import com.simplemobiletools.calendar.models.GoogleError
|
||||
|
||||
fun Exception.getGoogleMessageError(): String {
|
||||
val json = message!!.substring(message!!.indexOf('{'))
|
||||
val error = Gson().fromJson<GoogleError>(json, GoogleError::class.java)
|
||||
return error.message
|
||||
}
|
@ -4,8 +4,6 @@ import android.content.Context
|
||||
import android.media.RingtoneManager
|
||||
import android.text.format.DateFormat
|
||||
import com.simplemobiletools.calendar.R
|
||||
import com.simplemobiletools.calendar.extensions.googleSyncQueue
|
||||
import com.simplemobiletools.calendar.extensions.scheduleGoogleSync
|
||||
import com.simplemobiletools.commons.helpers.BaseConfig
|
||||
import java.util.*
|
||||
|
||||
@ -72,32 +70,10 @@ class Config(context: Context) : BaseConfig(context) {
|
||||
get() = prefs.getInt(FONT_SIZE, FONT_SIZE_MEDIUM)
|
||||
set(size) = prefs.edit().putInt(FONT_SIZE, size).apply()
|
||||
|
||||
var googleSync: Boolean
|
||||
get() = prefs.getBoolean(GOOGLE_SYNC, false)
|
||||
set(googleSync) {
|
||||
context.scheduleGoogleSync(googleSync)
|
||||
if (!googleSync)
|
||||
context.googleSyncQueue.clearQueue()
|
||||
|
||||
prefs.edit().putBoolean(GOOGLE_SYNC, googleSync).apply()
|
||||
}
|
||||
|
||||
var caldavSync: Boolean
|
||||
get() = prefs.getBoolean(CALDAV_SYNC, false)
|
||||
set(caldavSync) = prefs.edit().putBoolean(CALDAV_SYNC, caldavSync).apply()
|
||||
|
||||
var syncAccountName: String
|
||||
get() = prefs.getString(SYNC_ACCOUNT_NAME, "")
|
||||
set(syncAccountName) = prefs.edit().putString(SYNC_ACCOUNT_NAME, syncAccountName).apply()
|
||||
|
||||
var googleDefaultEventColor: Int
|
||||
get() = prefs.getInt(GOOGLE_DEFAULT_EVENT_COLOR, primaryColor)
|
||||
set(color) = prefs.edit().putInt(GOOGLE_DEFAULT_EVENT_COLOR, color).apply()
|
||||
|
||||
var googleDefaultReminders: String
|
||||
get() = prefs.getString(GOOGLE_DEFAULT_REMINDERS, "")
|
||||
set(reminders) = prefs.edit().putString(GOOGLE_DEFAULT_REMINDERS, reminders).apply()
|
||||
|
||||
fun addDisplayEventType(type: String) {
|
||||
addDisplayEventTypes(HashSet<String>(Arrays.asList(type)))
|
||||
}
|
||||
|
@ -41,13 +41,10 @@ val VIEW = "view"
|
||||
val REMINDER_MINUTES = "reminder_minutes"
|
||||
val DISPLAY_EVENT_TYPES = "display_event_types"
|
||||
val FONT_SIZE = "font_size"
|
||||
val GOOGLE_SYNC = "google_sync"
|
||||
val CALDAV_SYNC = "caldav_sync"
|
||||
val SYNC_ACCOUNT_NAME = "sync_account_name"
|
||||
val SNOOZE_DELAY = "snooze_delay"
|
||||
val DISPLAY_PAST_EVENTS = "display_past_events"
|
||||
val GOOGLE_DEFAULT_EVENT_COLOR = "google_default_event_color"
|
||||
val GOOGLE_DEFAULT_REMINDERS = "google_default_reminders"
|
||||
|
||||
val letterIDs = intArrayOf(R.string.sunday_letter, R.string.monday_letter, R.string.tuesday_letter, R.string.wednesday_letter,
|
||||
R.string.thursday_letter, R.string.friday_letter, R.string.saturday_letter)
|
||||
@ -121,15 +118,4 @@ val FONT_SIZE_MEDIUM = 1
|
||||
val FONT_SIZE_LARGE = 2
|
||||
|
||||
val SOURCE_SIMPLE_CALENDAR = 0
|
||||
val SOURCE_GOOGLE_SYNC = 1
|
||||
val SOURCE_IMPORTED_ICS = 2
|
||||
|
||||
// Google Sync
|
||||
val PRIMARY = "primary"
|
||||
val POPUP = "popup"
|
||||
val OPERATION_INSERT = 1
|
||||
val OPERATION_UPDATE = 2
|
||||
val OPERATION_DELETE = 3
|
||||
val OVERRIDES = "overrides"
|
||||
val DEFAULT_REMINDERS = "defaultReminders"
|
||||
val USE_DEFAULT = "useDefault"
|
||||
|
@ -323,7 +323,7 @@ class DBHelper private constructor(val context: Context) : SQLiteOpenHelper(cont
|
||||
return null
|
||||
}
|
||||
|
||||
fun deleteEvents(ids: Array<String>, deleteFromGoogle: Boolean = true) {
|
||||
fun deleteEvents(ids: Array<String>) {
|
||||
val args = TextUtils.join(", ", ids)
|
||||
val selection = "$MAIN_TABLE_NAME.$COL_ID IN ($args)"
|
||||
val cursor = getEventsCursor(selection)
|
||||
@ -344,15 +344,10 @@ class DBHelper private constructor(val context: Context) : SQLiteOpenHelper(cont
|
||||
context.cancelNotification(it.toInt())
|
||||
}
|
||||
|
||||
deleteChildEvents(args, deleteFromGoogle)
|
||||
if (deleteFromGoogle) {
|
||||
events.forEach {
|
||||
GoogleSyncHandler().tryDeleteFromGoogle(context, it)
|
||||
}
|
||||
}
|
||||
deleteChildEvents(args)
|
||||
}
|
||||
|
||||
private fun deleteChildEvents(ids: String, deleteFromGoogle: Boolean) {
|
||||
private fun deleteChildEvents(ids: String) {
|
||||
val projection = arrayOf(COL_ID)
|
||||
val selection = "$COL_PARENT_EVENT_ID IN ($ids)"
|
||||
val childIds = ArrayList<String>()
|
||||
@ -370,19 +365,7 @@ class DBHelper private constructor(val context: Context) : SQLiteOpenHelper(cont
|
||||
}
|
||||
|
||||
if (childIds.isNotEmpty())
|
||||
deleteEvents(childIds.toTypedArray(), deleteFromGoogle)
|
||||
}
|
||||
|
||||
fun getGoogleSyncEvents(): List<Event> {
|
||||
val selection = "$COL_SOURCE = $SOURCE_GOOGLE_SYNC"
|
||||
val cursor = getEventsCursor(selection)
|
||||
return fillEvents(cursor)
|
||||
}
|
||||
|
||||
fun deleteAllGoogleSyncEvents() {
|
||||
val events = getGoogleSyncEvents()
|
||||
val eventIDs = Array(events.size, { i -> (events[i].id.toString()) })
|
||||
deleteEvents(eventIDs, false)
|
||||
deleteEvents(childIds.toTypedArray())
|
||||
}
|
||||
|
||||
fun addEventRepeatException(parentEventId: Int, occurrenceTS: Int) {
|
||||
|
@ -1,126 +0,0 @@
|
||||
package com.simplemobiletools.calendar.helpers
|
||||
|
||||
import android.content.Context
|
||||
import android.widget.Toast
|
||||
import com.google.api.client.googleapis.json.GoogleJsonResponseException
|
||||
import com.google.api.services.calendar.model.EventDateTime
|
||||
import com.google.api.services.calendar.model.EventReminder
|
||||
import com.simplemobiletools.calendar.R
|
||||
import com.simplemobiletools.calendar.activities.SimpleActivity
|
||||
import com.simplemobiletools.calendar.extensions.*
|
||||
import com.simplemobiletools.calendar.models.Event
|
||||
import com.simplemobiletools.commons.extensions.toast
|
||||
import java.util.*
|
||||
|
||||
class GoogleSyncHandler {
|
||||
fun tryInsertToGoogle(activity: SimpleActivity, event: Event) {
|
||||
if (activity.isGoogleSyncActive()) {
|
||||
if (activity.isOnline()) {
|
||||
Thread({
|
||||
val errorMsg = insertToGoogle(activity, event)
|
||||
if (errorMsg.isNotEmpty()) {
|
||||
val msg = String.format(activity.getString(R.string.google_sync_error_insert), errorMsg)
|
||||
activity.toast(msg, Toast.LENGTH_LONG)
|
||||
}
|
||||
}).start()
|
||||
} else {
|
||||
activity.googleSyncQueue.addOperation(event.id, OPERATION_INSERT, event.importId)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun insertToGoogle(context: Context, event: Event): String {
|
||||
val googleEvent = mergeMyEventToGoogleEvent(com.google.api.services.calendar.model.Event(), event)
|
||||
try {
|
||||
context.getGoogleSyncService().events().insert(PRIMARY, googleEvent).execute()
|
||||
} catch (e: GoogleJsonResponseException) {
|
||||
return e.getGoogleMessageError()
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
fun tryUpdateGoogleEvent(activity: SimpleActivity, event: Event) {
|
||||
if (activity.isGoogleSyncActive()) {
|
||||
if (activity.isOnline()) {
|
||||
Thread({
|
||||
val errorMsg = updateGoogleEvent(activity.applicationContext, event)
|
||||
if (errorMsg.isNotEmpty()) {
|
||||
val msg = String.format(activity.getString(R.string.google_sync_error_update), errorMsg)
|
||||
activity.toast(msg, Toast.LENGTH_LONG)
|
||||
}
|
||||
}).start()
|
||||
} else {
|
||||
activity.googleSyncQueue.addOperation(event.id, OPERATION_UPDATE, event.importId)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun updateGoogleEvent(context: Context, event: Event): String {
|
||||
try {
|
||||
val googleEvent = context.getGoogleSyncService().events().get(PRIMARY, event.importId).execute()
|
||||
val newGoogleEvent = mergeMyEventToGoogleEvent(googleEvent, event)
|
||||
context.getGoogleSyncService().events().update(PRIMARY, newGoogleEvent.id, newGoogleEvent).execute()
|
||||
} catch (e: GoogleJsonResponseException) {
|
||||
return e.getGoogleMessageError()
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
fun tryDeleteFromGoogle(context: Context, event: Event) {
|
||||
Thread({
|
||||
if (context.isOnline()) {
|
||||
deleteFromGoogle(context, event.importId)
|
||||
} else {
|
||||
context.googleSyncQueue.addOperation(event.id, OPERATION_DELETE, event.importId)
|
||||
}
|
||||
}).start()
|
||||
}
|
||||
|
||||
fun deleteFromGoogle(context: Context, importId: String) {
|
||||
try {
|
||||
context.getGoogleSyncService().events().delete(PRIMARY, importId).execute()
|
||||
} catch (ignored: Exception) {
|
||||
}
|
||||
}
|
||||
|
||||
private fun mergeMyEventToGoogleEvent(googleEvent: com.google.api.services.calendar.model.Event, event: Event): com.google.api.services.calendar.model.Event {
|
||||
googleEvent.apply {
|
||||
summary = event.title
|
||||
description = event.description
|
||||
|
||||
if (event.getIsAllDay()) {
|
||||
start = EventDateTime().setDate(com.google.api.client.util.DateTime(true, event.startTS * 1000L, null))
|
||||
end = EventDateTime().setDate(com.google.api.client.util.DateTime(true, (event.endTS + DAY) * 1000L, null))
|
||||
} else {
|
||||
start = EventDateTime().setDateTime(com.google.api.client.util.DateTime(event.startTS * 1000L)).setTimeZone(TimeZone.getDefault().id)
|
||||
end = EventDateTime().setDateTime(com.google.api.client.util.DateTime(event.endTS * 1000L)).setTimeZone(TimeZone.getDefault().id)
|
||||
}
|
||||
|
||||
id = event.importId
|
||||
status = CONFIRMED.toLowerCase()
|
||||
Parser().getShortRepeatInterval(event).let {
|
||||
if (it.isNotEmpty()) {
|
||||
recurrence = listOf(it)
|
||||
} else {
|
||||
recurrence = null
|
||||
}
|
||||
}
|
||||
|
||||
if (event.getReminders().isNotEmpty()) {
|
||||
reminders = getEventReminders(event).setUseDefault(false)
|
||||
} else {
|
||||
reminders = com.google.api.services.calendar.model.Event.Reminders().setUseDefault(false)
|
||||
}
|
||||
}
|
||||
return googleEvent
|
||||
}
|
||||
|
||||
private fun getEventReminders(event: Event): com.google.api.services.calendar.model.Event.Reminders {
|
||||
val reminders = ArrayList<EventReminder>()
|
||||
event.getReminders().forEach {
|
||||
val reminder = EventReminder().setMinutes(it).setMethod(POPUP)
|
||||
reminders.add(reminder)
|
||||
}
|
||||
return com.google.api.services.calendar.model.Event.Reminders().setOverrides(reminders)
|
||||
}
|
||||
}
|
@ -1,112 +0,0 @@
|
||||
package com.simplemobiletools.calendar.helpers
|
||||
|
||||
import android.content.ContentValues
|
||||
import android.content.Context
|
||||
import android.database.Cursor
|
||||
import android.database.sqlite.SQLiteDatabase
|
||||
import android.database.sqlite.SQLiteOpenHelper
|
||||
import com.simplemobiletools.calendar.models.GoogleOperation
|
||||
import com.simplemobiletools.commons.extensions.getIntValue
|
||||
import com.simplemobiletools.commons.extensions.getStringValue
|
||||
|
||||
// database for storing operations performed on google events locally, while the user was offline
|
||||
class GoogleSyncQueueDB private constructor(val context: Context) : SQLiteOpenHelper(context, DB_NAME, null, DB_VERSION) {
|
||||
private val OPERATIONS_TABLE_NAME = "operations"
|
||||
private val COL_ID = "id"
|
||||
private val COL_EVENT_ID = "event_id"
|
||||
private val COL_OPERATION = "operation"
|
||||
private val COL_IMPORT_ID = "import_id"
|
||||
|
||||
private val mDb: SQLiteDatabase = writableDatabase
|
||||
|
||||
companion object {
|
||||
private val DB_VERSION = 1
|
||||
private val DB_NAME = "googlesyncqueue.db"
|
||||
var dbInstance: GoogleSyncQueueDB? = null
|
||||
|
||||
fun newInstance(context: Context): GoogleSyncQueueDB {
|
||||
if (dbInstance == null)
|
||||
dbInstance = GoogleSyncQueueDB(context)
|
||||
|
||||
return dbInstance!!
|
||||
}
|
||||
}
|
||||
|
||||
override fun onCreate(db: SQLiteDatabase) {
|
||||
db.execSQL("CREATE TABLE $OPERATIONS_TABLE_NAME ($COL_ID INTEGER PRIMARY KEY AUTOINCREMENT, $COL_EVENT_ID INTEGER, $COL_OPERATION INTEGER, " +
|
||||
"$COL_IMPORT_ID TEXT)")
|
||||
}
|
||||
|
||||
override fun onUpgrade(db: SQLiteDatabase, oldVersion: Int, newVersion: Int) {
|
||||
|
||||
}
|
||||
|
||||
fun addOperation(eventId: Int, operation: Int, importId: String) {
|
||||
val hadInsertOperation = getOperationOf(eventId)?.operation?.equals(OPERATION_INSERT) == true
|
||||
if (operation == OPERATION_DELETE) {
|
||||
clearOperationsOf(eventId)
|
||||
if (hadInsertOperation) {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
if (operation == OPERATION_UPDATE) {
|
||||
if (hadInsertOperation) {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
val contentValues = ContentValues().apply {
|
||||
put(COL_EVENT_ID, eventId)
|
||||
put(COL_OPERATION, operation)
|
||||
put(COL_IMPORT_ID, importId)
|
||||
}
|
||||
mDb.insert(OPERATIONS_TABLE_NAME, null, contentValues)
|
||||
}
|
||||
|
||||
fun getOperationOf(eventId: Int): GoogleOperation? {
|
||||
val selection = "$COL_EVENT_ID = $eventId"
|
||||
val projection = arrayOf(COL_OPERATION, COL_IMPORT_ID)
|
||||
var cursor: Cursor? = null
|
||||
try {
|
||||
cursor = mDb.query(OPERATIONS_TABLE_NAME, projection, selection, null, null, null, null)
|
||||
if (cursor?.moveToFirst() == true) {
|
||||
val operation = cursor.getIntValue(COL_OPERATION)
|
||||
val importId = cursor.getStringValue(COL_IMPORT_ID)
|
||||
return GoogleOperation(eventId, operation, importId)
|
||||
}
|
||||
} finally {
|
||||
cursor?.close()
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
fun getOperations(): ArrayList<GoogleOperation> {
|
||||
val operations = ArrayList<GoogleOperation>()
|
||||
val projection = arrayOf(COL_EVENT_ID, COL_OPERATION, COL_IMPORT_ID)
|
||||
var cursor: Cursor? = null
|
||||
try {
|
||||
cursor = mDb.query(OPERATIONS_TABLE_NAME, projection, null, null, null, null, null)
|
||||
if (cursor?.moveToFirst() == true) {
|
||||
do {
|
||||
val eventId = cursor.getIntValue(COL_EVENT_ID)
|
||||
val operation = cursor.getIntValue(COL_OPERATION)
|
||||
val importId = cursor.getStringValue(COL_IMPORT_ID)
|
||||
operations.add(GoogleOperation(eventId, operation, importId))
|
||||
} while (cursor.moveToNext())
|
||||
}
|
||||
} finally {
|
||||
cursor?.close()
|
||||
}
|
||||
return operations
|
||||
}
|
||||
|
||||
fun clearOperationsOf(eventId: Int) {
|
||||
val selection = "$COL_EVENT_ID = $eventId"
|
||||
mDb.delete(OPERATIONS_TABLE_NAME, selection, null)
|
||||
}
|
||||
|
||||
fun clearQueue() {
|
||||
mDb.delete(OPERATIONS_TABLE_NAME, null, null)
|
||||
}
|
||||
}
|
@ -1,5 +0,0 @@
|
||||
package com.simplemobiletools.calendar.interfaces
|
||||
|
||||
interface GoogleSyncListener {
|
||||
fun syncCompleted()
|
||||
}
|
@ -1,3 +0,0 @@
|
||||
package com.simplemobiletools.calendar.models
|
||||
|
||||
data class GoogleError(val message: String)
|
@ -1,7 +0,0 @@
|
||||
package com.simplemobiletools.calendar.models
|
||||
|
||||
import com.google.gson.JsonArray
|
||||
import com.google.gson.JsonObject
|
||||
|
||||
data class GoogleEvent(val summary: String?, val description: String?, val status: String, val start: GoogleEventDateTime, val end: GoogleEventDateTime,
|
||||
val reminders: JsonObject, val recurrence: JsonArray?, val id: String, val colorId: Int, val updated: String)
|
@ -1,3 +0,0 @@
|
||||
package com.simplemobiletools.calendar.models
|
||||
|
||||
data class GoogleEventDateTime(val date: String?, val dateTime: String?, val timeZone: String?)
|
@ -1,3 +0,0 @@
|
||||
package com.simplemobiletools.calendar.models
|
||||
|
||||
data class GoogleEventReminder(val method: String, val minutes: Int)
|
@ -1,3 +0,0 @@
|
||||
package com.simplemobiletools.calendar.models
|
||||
|
||||
data class GoogleOperation(val eventId: Int, val operation: Int, val importId: String)
|
@ -3,10 +3,8 @@ package com.simplemobiletools.calendar.receivers
|
||||
import android.content.BroadcastReceiver
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import com.simplemobiletools.calendar.extensions.isGoogleSyncActive
|
||||
import com.simplemobiletools.calendar.extensions.notifyRunningEvents
|
||||
import com.simplemobiletools.calendar.extensions.scheduleAllEvents
|
||||
import com.simplemobiletools.calendar.extensions.scheduleGoogleSync
|
||||
|
||||
class BootCompletedReceiver : BroadcastReceiver() {
|
||||
|
||||
@ -14,7 +12,6 @@ class BootCompletedReceiver : BroadcastReceiver() {
|
||||
context.apply {
|
||||
scheduleAllEvents()
|
||||
notifyRunningEvents()
|
||||
scheduleGoogleSync(isGoogleSyncActive())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,13 +0,0 @@
|
||||
package com.simplemobiletools.calendar.receivers
|
||||
|
||||
import android.content.BroadcastReceiver
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import com.simplemobiletools.calendar.asynctasks.FetchGoogleEventsTask
|
||||
|
||||
class GoogleSyncReceiver : BroadcastReceiver() {
|
||||
|
||||
override fun onReceive(context: Context, arg1: Intent) {
|
||||
FetchGoogleEventsTask(context).execute()
|
||||
}
|
||||
}
|
@ -109,26 +109,6 @@
|
||||
|
||||
</RelativeLayout>
|
||||
|
||||
<RelativeLayout
|
||||
android:id="@+id/settings_google_sync_holder"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="@dimen/medium_margin"
|
||||
android:background="?attr/selectableItemBackground"
|
||||
android:padding="@dimen/activity_margin">
|
||||
|
||||
<com.simplemobiletools.commons.views.MySwitchCompat
|
||||
android:id="@+id/settings_google_sync"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@null"
|
||||
android:clickable="false"
|
||||
android:paddingLeft="@dimen/medium_margin"
|
||||
android:paddingStart="@dimen/medium_margin"
|
||||
android:text="@string/google_sync"/>
|
||||
|
||||
</RelativeLayout>
|
||||
|
||||
<RelativeLayout
|
||||
android:id="@+id/settings_caldav_sync_holder"
|
||||
android:layout_width="match_parent"
|
||||
|
@ -186,21 +186,12 @@
|
||||
<string name="no_ringtone_picker">Keine App zum Setzen des Klingentons gefunden</string>
|
||||
<string name="no_ringtone_selected">Kein Klingelton gewählt</string>
|
||||
<string name="day_end_before_start">Terminbeginn kann nicht vor Terminende liegen</string>
|
||||
<string name="google_sync">Google Sync</string>
|
||||
<string name="caldav_sync">CalDAV sync</string>
|
||||
<string name="display_past_events">Display events from the past</string>
|
||||
<string name="snooze_delay">Postpone reminder with Snooze by</string>
|
||||
<string name="widgets">Widgets</string>
|
||||
<string name="cannot_while_offline">You cannot do that while offline.</string>
|
||||
|
||||
<!-- Google sync -->
|
||||
<string name="google_sync_testing">Google sync is in a testing mode, please be cautions when relying on it. Reporting any feedback at hello@simplemobiletools.com would be appreciated. Thanks!</string>
|
||||
<string name="google_sync_existing">Upload currently existing events to Google?</string>
|
||||
<string name="google_sync_disabling">Disabling Google sync will delete all synced events from your device, while leaving them intact in the cloud.</string>
|
||||
<string name="google_sync_error_insert">Error uploading event to Google: %1$s</string>
|
||||
<string name="google_sync_error_update">Error updating event at Google: %1$s</string>
|
||||
<string name="google_sync_error_fetch">Error fetching Google events: %1$s</string>
|
||||
|
||||
<plurals name="by_minutes">
|
||||
<item quantity="one">%1$d minute</item>
|
||||
<item quantity="other">%1$d minutes</item>
|
||||
|
@ -186,21 +186,12 @@
|
||||
<string name="no_ringtone_picker">No se ha encontrado ninguna aplicación capaz de establecer el tono de llamada</string>
|
||||
<string name="no_ringtone_selected">Ninguno</string>
|
||||
<string name="day_end_before_start">El día no puede terminar antes de que comience</string>
|
||||
<string name="google_sync">Sincronización de Google</string>
|
||||
<string name="caldav_sync">CalDAV sync</string>
|
||||
<string name="display_past_events">Display events from the past</string>
|
||||
<string name="snooze_delay">Postpone reminder with Snooze by</string>
|
||||
<string name="widgets">Widgets</string>
|
||||
<string name="cannot_while_offline">You cannot do that while offline.</string>
|
||||
|
||||
<!-- Google sync -->
|
||||
<string name="google_sync_testing">Google sync is in a testing mode, please be cautions when relying on it. Reporting any feedback at hello@simplemobiletools.com would be appreciated. Thanks!</string>
|
||||
<string name="google_sync_existing">Upload currently existing events to Google?</string>
|
||||
<string name="google_sync_disabling">Disabling Google sync will delete all synced events from your device, while leaving them intact in the cloud.</string>
|
||||
<string name="google_sync_error_insert">Error uploading event to Google: %1$s</string>
|
||||
<string name="google_sync_error_update">Error updating event at Google: %1$s</string>
|
||||
<string name="google_sync_error_fetch">Error fetching Google events: %1$s</string>
|
||||
|
||||
<plurals name="by_minutes">
|
||||
<item quantity="one">%1$d minute</item>
|
||||
<item quantity="other">%1$d minutes</item>
|
||||
|
@ -186,21 +186,12 @@
|
||||
<string name="no_ringtone_picker">Aucune application capable de configurer la sonnerie trouvée</string>
|
||||
<string name="no_ringtone_selected">Aucune</string>
|
||||
<string name="day_end_before_start">Le jour ne peut pas se terminer plus tôt qu\'il ne débute</string>
|
||||
<string name="google_sync">Synchronisation Google</string>
|
||||
<string name="caldav_sync">CalDAV sync</string>
|
||||
<string name="display_past_events">Display events from the past</string>
|
||||
<string name="snooze_delay">Postpone reminder with Snooze by</string>
|
||||
<string name="widgets">Widgets</string>
|
||||
<string name="cannot_while_offline">You cannot do that while offline.</string>
|
||||
|
||||
<!-- Google sync -->
|
||||
<string name="google_sync_testing">Google sync is in a testing mode, please be cautions when relying on it. Reporting any feedback at hello@simplemobiletools.com would be appreciated. Thanks!</string>
|
||||
<string name="google_sync_existing">Upload currently existing events to Google?</string>
|
||||
<string name="google_sync_disabling">Disabling Google sync will delete all synced events from your device, while leaving them intact in the cloud.</string>
|
||||
<string name="google_sync_error_insert">Error uploading event to Google: %1$s</string>
|
||||
<string name="google_sync_error_update">Error updating event at Google: %1$s</string>
|
||||
<string name="google_sync_error_fetch">Error fetching Google events: %1$s</string>
|
||||
|
||||
<plurals name="by_minutes">
|
||||
<item quantity="one">%1$d minute</item>
|
||||
<item quantity="other">%1$d minutes</item>
|
||||
|
@ -186,21 +186,12 @@
|
||||
<string name="no_ringtone_picker">No app capable of setting ringtone found</string>
|
||||
<string name="no_ringtone_selected">None</string>
|
||||
<string name="day_end_before_start">The day cannot end earlier than it starts</string>
|
||||
<string name="google_sync">Google sync</string>
|
||||
<string name="caldav_sync">CalDAV sync</string>
|
||||
<string name="display_past_events">Display events from the past</string>
|
||||
<string name="snooze_delay">Postpone reminder with Snooze by</string>
|
||||
<string name="widgets">Widgets</string>
|
||||
<string name="cannot_while_offline">You cannot do that while offline.</string>
|
||||
|
||||
<!-- Google sync -->
|
||||
<string name="google_sync_testing">Google sync is in a testing mode, please be cautions when relying on it. Reporting any feedback at hello@simplemobiletools.com would be appreciated. Thanks!</string>
|
||||
<string name="google_sync_existing">Upload currently existing events to Google?</string>
|
||||
<string name="google_sync_disabling">Disabling Google sync will delete all synced events from your device, while leaving them intact in the cloud.</string>
|
||||
<string name="google_sync_error_insert">Error uploading event to Google: %1$s</string>
|
||||
<string name="google_sync_error_update">Error updating event at Google: %1$s</string>
|
||||
<string name="google_sync_error_fetch">Error fetching Google events: %1$s</string>
|
||||
|
||||
<plurals name="by_minutes">
|
||||
<item quantity="one">%1$d minute</item>
|
||||
<item quantity="other">%1$d minutes</item>
|
||||
|
@ -186,21 +186,12 @@
|
||||
<string name="no_ringtone_picker">No app capable of setting ringtone found</string>
|
||||
<string name="no_ringtone_selected">None</string>
|
||||
<string name="day_end_before_start">The day cannot end earlier than it starts</string>
|
||||
<string name="google_sync">Google sync</string>
|
||||
<string name="caldav_sync">CalDAV sync</string>
|
||||
<string name="display_past_events">Display events from the past</string>
|
||||
<string name="snooze_delay">Postpone reminder with Snooze by</string>
|
||||
<string name="widgets">Widgets</string>
|
||||
<string name="cannot_while_offline">You cannot do that while offline.</string>
|
||||
|
||||
<!-- Google sync -->
|
||||
<string name="google_sync_testing">Google sync is in a testing mode, please be cautions when relying on it. Reporting any feedback at hello@simplemobiletools.com would be appreciated. Thanks!</string>
|
||||
<string name="google_sync_existing">Upload currently existing events to Google?</string>
|
||||
<string name="google_sync_disabling">Disabling Google sync will delete all synced events from your device, while leaving them intact in the cloud.</string>
|
||||
<string name="google_sync_error_insert">Error uploading event to Google: %1$s</string>
|
||||
<string name="google_sync_error_update">Error updating event at Google: %1$s</string>
|
||||
<string name="google_sync_error_fetch">Error fetching Google events: %1$s</string>
|
||||
|
||||
<plurals name="by_minutes">
|
||||
<item quantity="one">%1$d minute</item>
|
||||
<item quantity="other">%1$d minutes</item>
|
||||
|
@ -186,21 +186,12 @@
|
||||
<string name="no_ringtone_picker">No app capable of setting ringtone found</string>
|
||||
<string name="no_ringtone_selected">None</string>
|
||||
<string name="day_end_before_start">The day cannot end earlier than it starts</string>
|
||||
<string name="google_sync">Google sync</string>
|
||||
<string name="caldav_sync">CalDAV sync</string>
|
||||
<string name="display_past_events">Display events from the past</string>
|
||||
<string name="snooze_delay">Postpone reminder with Snooze by</string>
|
||||
<string name="widgets">Widgets</string>
|
||||
<string name="cannot_while_offline">You cannot do that while offline.</string>
|
||||
|
||||
<!-- Google sync -->
|
||||
<string name="google_sync_testing">Google sync is in a testing mode, please be cautions when relying on it. Reporting any feedback at hello@simplemobiletools.com would be appreciated. Thanks!</string>
|
||||
<string name="google_sync_existing">Upload currently existing events to Google?</string>
|
||||
<string name="google_sync_disabling">Disabling Google sync will delete all synced events from your device, while leaving them intact in the cloud.</string>
|
||||
<string name="google_sync_error_insert">Error uploading event to Google: %1$s</string>
|
||||
<string name="google_sync_error_update">Error updating event at Google: %1$s</string>
|
||||
<string name="google_sync_error_fetch">Error fetching Google events: %1$s</string>
|
||||
|
||||
<plurals name="by_minutes">
|
||||
<item quantity="one">%1$d minute</item>
|
||||
<item quantity="other">%1$d minutes</item>
|
||||
|
@ -186,21 +186,12 @@
|
||||
<string name="no_ringtone_picker">לא נמצאה אפליקציה להגדרת רינגטון</string>
|
||||
<string name="no_ringtone_selected">ללא</string>
|
||||
<string name="day_end_before_start">היום לא יכול להסתיים מוקדם משהוא מתחיל</string>
|
||||
<string name="google_sync">Google sync</string>
|
||||
<string name="caldav_sync">CalDAV sync</string>
|
||||
<string name="display_past_events">Display events from the past</string>
|
||||
<string name="snooze_delay">Postpone reminder with Snooze by</string>
|
||||
<string name="widgets">Widgets</string>
|
||||
<string name="cannot_while_offline">You cannot do that while offline.</string>
|
||||
|
||||
<!-- Google sync -->
|
||||
<string name="google_sync_testing">Google sync is in a testing mode, please be cautions when relying on it. Reporting any feedback at hello@simplemobiletools.com would be appreciated. Thanks!</string>
|
||||
<string name="google_sync_existing">Upload currently existing events to Google?</string>
|
||||
<string name="google_sync_disabling">Disabling Google sync will delete all synced events from your device, while leaving them intact in the cloud.</string>
|
||||
<string name="google_sync_error_insert">Error uploading event to Google: %1$s</string>
|
||||
<string name="google_sync_error_update">Error updating event at Google: %1$s</string>
|
||||
<string name="google_sync_error_fetch">Error fetching Google events: %1$s</string>
|
||||
|
||||
<plurals name="by_minutes">
|
||||
<item quantity="one">%1$d minute</item>
|
||||
<item quantity="other">%1$d minutes</item>
|
||||
|
@ -186,21 +186,12 @@
|
||||
<string name="no_ringtone_picker">No app capable of setting ringtone found</string>
|
||||
<string name="no_ringtone_selected">None</string>
|
||||
<string name="day_end_before_start">The day cannot end earlier than it starts</string>
|
||||
<string name="google_sync">Google sync</string>
|
||||
<string name="caldav_sync">CalDAV sync</string>
|
||||
<string name="display_past_events">Display events from the past</string>
|
||||
<string name="snooze_delay">Postpone reminder with Snooze by</string>
|
||||
<string name="widgets">Widgets</string>
|
||||
<string name="cannot_while_offline">You cannot do that while offline.</string>
|
||||
|
||||
<!-- Google sync -->
|
||||
<string name="google_sync_testing">Google sync is in a testing mode, please be cautions when relying on it. Reporting any feedback at hello@simplemobiletools.com would be appreciated. Thanks!</string>
|
||||
<string name="google_sync_existing">Upload currently existing events to Google?</string>
|
||||
<string name="google_sync_disabling">Disabling Google sync will delete all synced events from your device, while leaving them intact in the cloud.</string>
|
||||
<string name="google_sync_error_insert">Error uploading event to Google: %1$s</string>
|
||||
<string name="google_sync_error_update">Error updating event at Google: %1$s</string>
|
||||
<string name="google_sync_error_fetch">Error fetching Google events: %1$s</string>
|
||||
|
||||
<plurals name="by_minutes">
|
||||
<item quantity="one">%1$d minute</item>
|
||||
<item quantity="other">%1$d minutes</item>
|
||||
|
@ -191,21 +191,12 @@
|
||||
<string name="no_ringtone_picker">Nie znalazłem aplikacji mogącej ustawiać dzwonki</string>
|
||||
<string name="no_ringtone_selected">Żaden</string>
|
||||
<string name="day_end_before_start">Dzień nie może zakończyć się wcześniej niż się zaczyna</string>
|
||||
<string name="google_sync">Synchronizacja z Google</string>
|
||||
<string name="caldav_sync">CalDAV sync</string>
|
||||
<string name="display_past_events">Pokazuj wydarzenia z przeszłości</string>
|
||||
<string name="snooze_delay">Opóźnij przypomnienie o</string>
|
||||
<string name="widgets">Widżety</string>
|
||||
<string name="cannot_while_offline">Nie możesz tego zrobić bez dostępu do internetu.</string>
|
||||
|
||||
<!-- Google sync -->
|
||||
<string name="google_sync_testing">Synchronizacja z Google jest w fazie testów, sync is in a testing mode. Polegasz na niej na własną odpowiedzialność. Wszelkie raporty odnośnie tej funkcji pisane na adres hello@simplemobiletools.com są mile widziane.</string>
|
||||
<string name="google_sync_existing">Wysłać istniejące wydarzenia na Dysk Google?</string>
|
||||
<string name="google_sync_disabling">Wyłączenie synchronizacji z Google usunie wszelkie zsynchronizowane z Twoim urządzeniem wydarzenia, pozostwiając je nienaruszone w chmurze.</string>
|
||||
<string name="google_sync_error_insert">Wystąił błąd podczas wysyłania wydarzeń na Dysk Google: %1$s</string>
|
||||
<string name="google_sync_error_update">Wystąił błąd podczas aktualizacji wydarzeń na Dysku Google: %1$s</string>
|
||||
<string name="google_sync_error_fetch">Wystąił błąd podczas pobierania wydarzeń z Dysku Google: %1$s</string>
|
||||
|
||||
<plurals name="by_minutes">
|
||||
<item quantity="one">%1$d minutę</item>
|
||||
<item quantity="few">%1$d minuty</item>
|
||||
|
@ -186,21 +186,12 @@
|
||||
<string name="no_ringtone_picker">Não foi encontrado nenhum aplicativo capaz de definir o som</string>
|
||||
<string name="no_ringtone_selected">Nenhum</string>
|
||||
<string name="day_end_before_start">O dia final não pode ser antes do início</string>
|
||||
<string name="google_sync">Sincronização Google</string>
|
||||
<string name="caldav_sync">CalDAV sync</string>
|
||||
<string name="display_past_events">Display events from the past</string>
|
||||
<string name="snooze_delay">Postpone reminder with Snooze by</string>
|
||||
<string name="widgets">Widgets</string>
|
||||
<string name="cannot_while_offline">You cannot do that while offline.</string>
|
||||
|
||||
<!-- Google sync -->
|
||||
<string name="google_sync_testing">Google sync is in a testing mode, please be cautions when relying on it. Reporting any feedback at hello@simplemobiletools.com would be appreciated. Thanks!</string>
|
||||
<string name="google_sync_existing">Upload currently existing events to Google?</string>
|
||||
<string name="google_sync_disabling">Disabling Google sync will delete all synced events from your device, while leaving them intact in the cloud.</string>
|
||||
<string name="google_sync_error_insert">Error uploading event to Google: %1$s</string>
|
||||
<string name="google_sync_error_update">Error updating event at Google: %1$s</string>
|
||||
<string name="google_sync_error_fetch">Error fetching Google events: %1$s</string>
|
||||
|
||||
<plurals name="by_minutes">
|
||||
<item quantity="one">%1$d minute</item>
|
||||
<item quantity="other">%1$d minutes</item>
|
||||
|
@ -186,21 +186,12 @@
|
||||
<string name="no_ringtone_picker">Não foi encontrada uma aplicação capaz de definir o som</string>
|
||||
<string name="no_ringtone_selected">Nenhum</string>
|
||||
<string name="day_end_before_start">O dia final não pode ser antes do inicial</string>
|
||||
<string name="google_sync">Sincronização Google</string>
|
||||
<string name="caldav_sync">CalDAV sync</string>
|
||||
<string name="display_past_events">Mostrar eventos passados</string>
|
||||
<string name="snooze_delay">Adiar lembrete com a opção Snooze</string>
|
||||
<string name="widgets">Widgets</string>
|
||||
<string name="cannot_while_offline">You cannot do that while offline.</string>
|
||||
|
||||
<!-- Google sync -->
|
||||
<string name="google_sync_testing">A sincronização Google ainda não está terminada. Reporte os erros encontrados para hello@simplemobiletools.com. Obrigado!</string>
|
||||
<string name="google_sync_existing">Upload currently existing events to Google?</string>
|
||||
<string name="google_sync_disabling">Disabling Google sync will delete all synced events from your device, while leaving them intact in the cloud.</string>
|
||||
<string name="google_sync_error_insert">Error uploading event to Google: %1$s</string>
|
||||
<string name="google_sync_error_update">Error updating event at Google: %1$s</string>
|
||||
<string name="google_sync_error_fetch">Error fetching Google events: %1$s</string>
|
||||
|
||||
<plurals name="by_minutes">
|
||||
<item quantity="one">%1$d minuto</item>
|
||||
<item quantity="other">%1$d minutos</item>
|
||||
|
@ -200,21 +200,12 @@
|
||||
<string name="no_ringtone_picker">Не найдено приложение для выбора рингтона</string>
|
||||
<string name="no_ringtone_selected">Нет</string>
|
||||
<string name="day_end_before_start">Конец дня не может быть раньше начала</string>
|
||||
<string name="google_sync">Синхронизация с Google</string>
|
||||
<string name="caldav_sync">CalDAV sync</string>
|
||||
<string name="display_past_events">Показывать прошедшие события</string>
|
||||
<string name="snooze_delay">Postpone reminder with Snooze by</string>
|
||||
<string name="widgets">Widgets</string>
|
||||
<string name="cannot_while_offline">You cannot do that while offline.</string>
|
||||
|
||||
<!-- Google sync -->
|
||||
<string name="google_sync_testing">Google sync is in a testing mode, please be cautions when relying on it. Reporting any feedback at hello@simplemobiletools.com would be appreciated. Thanks!</string>
|
||||
<string name="google_sync_existing">Upload currently existing events to Google?</string>
|
||||
<string name="google_sync_disabling">Disabling Google sync will delete all synced events from your device, while leaving them intact in the cloud.</string>
|
||||
<string name="google_sync_error_insert">Error uploading event to Google: %1$s</string>
|
||||
<string name="google_sync_error_update">Error updating event at Google: %1$s</string>
|
||||
<string name="google_sync_error_fetch">Error fetching Google events: %1$s</string>
|
||||
|
||||
<plurals name="by_minutes">
|
||||
<item quantity="one">%1$d минута</item>
|
||||
<item quantity="few">%1$d минуты</item>
|
||||
|
@ -193,21 +193,12 @@
|
||||
<string name="no_ringtone_picker">Nenašla sa žiadna aplikácia na zmenu zvučky</string>
|
||||
<string name="no_ringtone_selected">Žiadna</string>
|
||||
<string name="day_end_before_start">Deň nemôže skončiť skôr než začne</string>
|
||||
<string name="google_sync">Google synchronizácia</string>
|
||||
<string name="caldav_sync">CalDAV synchronizácia</string>
|
||||
<string name="display_past_events">Zobraziť minulé udalosti spred</string>
|
||||
<string name="snooze_delay">Posunúť pripomienku s Odložiť o</string>
|
||||
<string name="widgets">Widgety</string>
|
||||
<string name="cannot_while_offline">Nemôžete to urobiť bez internetu.</string>
|
||||
|
||||
<!-- Google sync -->
|
||||
<string name="google_sync_testing">Google synchronizácia je v testovacej prevádzke, buďte opatrní pri spoliehaní sa na ňu. Nahlásenie akýchkoľvek ohlasov na hello@simplemobiletools.com je vítané. Vďaka!</string>
|
||||
<string name="google_sync_existing">Nahrať momentálne existujúce udalosti Googlu?</string>
|
||||
<string name="google_sync_disabling">Vypnutie Google synchonizácie odstráni všetky synchronizované udalosti zo zariadenia, no v oblakoch ostanú nedotknuté.</string>
|
||||
<string name="google_sync_error_insert">Chyba pri nahrávaní udalosti na Google: %1$s</string>
|
||||
<string name="google_sync_error_update">Chyba pri úprave udalosti na Googli: %1$s</string>
|
||||
<string name="google_sync_error_fetch">Chyba pri čítaní Google udalostí: %1$s</string>
|
||||
|
||||
<plurals name="by_minutes">
|
||||
<item quantity="one">%1$d minútu</item>
|
||||
<item quantity="few">%1$d minúty</item>
|
||||
|
@ -186,21 +186,12 @@
|
||||
<string name="no_ringtone_picker">Hittade ingen app som kan ställa in ljudet</string>
|
||||
<string name="no_ringtone_selected">Ingen</string>
|
||||
<string name="day_end_before_start">Dagen kan inte börja innan den tar slut</string>
|
||||
<string name="google_sync">Google Synk</string>
|
||||
<string name="caldav_sync">CalDAV sync</string>
|
||||
<string name="display_past_events">Visa tidigare händelser</string>
|
||||
<string name="snooze_delay">Skjut upp påminnelse med Snooza</string>
|
||||
<string name="widgets">Widgets</string>
|
||||
<string name="cannot_while_offline">You cannot do that while offline.</string>
|
||||
|
||||
<!-- Google sync -->
|
||||
<string name="google_sync_testing">Google sync is in a testing mode, please be cautions when relying on it. Reporting any feedback at hello@simplemobiletools.com would be appreciated. Thanks!</string>
|
||||
<string name="google_sync_existing">Upload currently existing events to Google?</string>
|
||||
<string name="google_sync_disabling">Disabling Google sync will delete all synced events from your device, while leaving them intact in the cloud.</string>
|
||||
<string name="google_sync_error_insert">Error uploading event to Google: %1$s</string>
|
||||
<string name="google_sync_error_update">Error updating event at Google: %1$s</string>
|
||||
<string name="google_sync_error_fetch">Error fetching Google events: %1$s</string>
|
||||
|
||||
<plurals name="by_minutes">
|
||||
<item quantity="one">%1$d minut</item>
|
||||
<item quantity="other">%1$d minuter</item>
|
||||
|
@ -186,21 +186,12 @@
|
||||
<string name="no_ringtone_picker">Zil sesi ayarlayabilen hiçbir uygulama bulunamadı</string>
|
||||
<string name="no_ringtone_selected">Boş</string>
|
||||
<string name="day_end_before_start">Gün başlamadan önce bitemez</string>
|
||||
<string name="google_sync">Google senkronizasyonu</string>
|
||||
<string name="caldav_sync">CalDAV sync</string>
|
||||
<string name="display_past_events">Display events from the past</string>
|
||||
<string name="snooze_delay">Postpone reminder with Snooze by</string>
|
||||
<string name="widgets">Widgets</string>
|
||||
<string name="cannot_while_offline">You cannot do that while offline.</string>
|
||||
|
||||
<!-- Google sync -->
|
||||
<string name="google_sync_testing">Google sync is in a testing mode, please be cautions when relying on it. Reporting any feedback at hello@simplemobiletools.com would be appreciated. Thanks!</string>
|
||||
<string name="google_sync_existing">Upload currently existing events to Google?</string>
|
||||
<string name="google_sync_disabling">Disabling Google sync will delete all synced events from your device, while leaving them intact in the cloud.</string>
|
||||
<string name="google_sync_error_insert">Error uploading event to Google: %1$s</string>
|
||||
<string name="google_sync_error_update">Error updating event at Google: %1$s</string>
|
||||
<string name="google_sync_error_fetch">Error fetching Google events: %1$s</string>
|
||||
|
||||
<plurals name="by_minutes">
|
||||
<item quantity="one">%1$d minute</item>
|
||||
<item quantity="other">%1$d minutes</item>
|
||||
|
@ -186,21 +186,12 @@
|
||||
<string name="no_ringtone_picker">No app capable of setting ringtone found</string>
|
||||
<string name="no_ringtone_selected">None</string>
|
||||
<string name="day_end_before_start">The day cannot end earlier than it starts</string>
|
||||
<string name="google_sync">Google sync</string>
|
||||
<string name="caldav_sync">CalDAV sync</string>
|
||||
<string name="display_past_events">Display events from the past</string>
|
||||
<string name="snooze_delay">Postpone reminder with Snooze by</string>
|
||||
<string name="widgets">Widgets</string>
|
||||
<string name="cannot_while_offline">You cannot do that while offline.</string>
|
||||
|
||||
<!-- Google sync -->
|
||||
<string name="google_sync_testing">Google sync is in a testing mode, please be cautions when relying on it. Reporting any feedback at hello@simplemobiletools.com would be appreciated. Thanks!</string>
|
||||
<string name="google_sync_existing">Upload currently existing events to Google?</string>
|
||||
<string name="google_sync_disabling">Disabling Google sync will delete all synced events from your device, while leaving them intact in the cloud.</string>
|
||||
<string name="google_sync_error_insert">Error uploading event to Google: %1$s</string>
|
||||
<string name="google_sync_error_update">Error updating event at Google: %1$s</string>
|
||||
<string name="google_sync_error_fetch">Error fetching Google events: %1$s</string>
|
||||
|
||||
<plurals name="by_minutes">
|
||||
<item quantity="one">%1$d minute</item>
|
||||
<item quantity="other">%1$d minutes</item>
|
||||
|
Loading…
x
Reference in New Issue
Block a user