Skip to content
This repository was archived by the owner on Jun 9, 2025. It is now read-only.

Commit eeca011

Browse files
Add geofence radius x property (#97)
* Added geofence radius x-property * updated tests * Update JtxICalObjectTest.kt * Update JtxICalObjectTest.kt
1 parent 260cee1 commit eeca011

File tree

3 files changed

+38
-6
lines changed

3 files changed

+38
-6
lines changed

src/androidTest/java/at/bitfire/ical4android/JtxICalObjectTest.kt

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,9 @@ package at.bitfire.ical4android
66

77
import android.accounts.Account
88
import android.content.ContentProviderClient
9+
import android.content.ContentResolver
910
import android.content.ContentValues
11+
import android.content.Context
1012
import android.database.DatabaseUtils
1113
import android.os.ParcelFileDescriptor
1214
import androidx.test.platform.app.InstrumentationRegistry
@@ -38,14 +40,14 @@ class JtxICalObjectTest {
3840

3941
companion object {
4042

41-
val context = InstrumentationRegistry.getInstrumentation().targetContext
42-
val contentResolver = context.contentResolver
43+
private val context: Context = InstrumentationRegistry.getInstrumentation().targetContext
44+
private val contentResolver: ContentResolver = context.contentResolver
4345

4446
private lateinit var client: ContentProviderClient
4547

4648
@JvmField
4749
@ClassRule
48-
val permissionRule = GrantPermissionRule.grant(*TaskProvider.PERMISSIONS_JTX)
50+
val permissionRule: GrantPermissionRule = GrantPermissionRule.grant(*TaskProvider.PERMISSIONS_JTX)
4951

5052
@BeforeClass
5153
@JvmStatic
@@ -65,8 +67,8 @@ class JtxICalObjectTest {
6567
}
6668

6769
private val testAccount = Account("TEST", JtxContract.JtxCollection.TEST_ACCOUNT_TYPE)
68-
var collection: JtxCollection<at.bitfire.ical4android.JtxICalObject>? = null
69-
var sample: at.bitfire.ical4android.JtxICalObject? = null
70+
private var collection: JtxCollection<at.bitfire.ical4android.JtxICalObject>? = null
71+
private var sample: at.bitfire.ical4android.JtxICalObject? = null
7072

7173
private val url = "https://jtx.techbee.at"
7274
private val displayname = "jtxTest"
@@ -95,13 +97,15 @@ class JtxICalObjectTest {
9597
this.dtend = System.currentTimeMillis()
9698
this.dtendTimezone = "Europe/Paris"
9799
this.status = JtxICalObject.StatusJournal.FINAL.name
100+
this.xstatus = "my status"
98101
this.classification = JtxICalObject.Classification.PUBLIC.name
99102
this.url = "https://jtx.techbee.at"
100103
this.contact = "[email protected]"
101104
this.geoLat = 48.2082
102105
this.geoLong = 16.3738
103106
this.location = "Vienna"
104107
this.locationAltrep = "Wien"
108+
this.geofenceRadius = 10
105109
this.percent = 99
106110
this.priority = 1
107111
this.due = System.currentTimeMillis()
@@ -144,13 +148,25 @@ class JtxICalObjectTest {
144148
@Test fun check_DTEND() = insertRetrieveAssertLong(JtxICalObject.DTEND, sample?.dtend, Component.VJOURNAL.name)
145149
@Test fun check_DTEND_TIMEZONE() = insertRetrieveAssertString(JtxICalObject.DTEND_TIMEZONE, sample?.dtendTimezone, Component.VJOURNAL.name)
146150
@Test fun check_STATUS() = insertRetrieveAssertString(JtxICalObject.STATUS, sample?.status, Component.VJOURNAL.name)
151+
@Test fun check_XSTATUS() {
152+
val jtxVersionCode = context.packageManager.getPackageInfo("at.techbee.jtx", 0).longVersionCode
153+
Assume.assumeTrue(jtxVersionCode > 204020003)
154+
insertRetrieveAssertString(JtxICalObject.EXTENDED_STATUS, sample?.xstatus, Component.VJOURNAL.name)
155+
}
156+
147157
@Test fun check_CLASSIFICATION() = insertRetrieveAssertString(JtxICalObject.CLASSIFICATION, sample?.classification, Component.VJOURNAL.name)
148158
@Test fun check_URL() = insertRetrieveAssertString(JtxICalObject.URL, sample?.url, Component.VJOURNAL.name)
149159
@Test fun check_CONTACT() = insertRetrieveAssertString(JtxICalObject.CONTACT, sample?.contact, Component.VJOURNAL.name)
150160
@Test fun check_GEO_LAT() = insertRetrieveAssertDouble(JtxICalObject.GEO_LAT, sample?.geoLat, Component.VJOURNAL.name)
151161
@Test fun check_GEO_LONG() = insertRetrieveAssertDouble(JtxICalObject.GEO_LONG, sample?.geoLong, Component.VJOURNAL.name)
152162
@Test fun check_LOCATION() = insertRetrieveAssertString(JtxICalObject.LOCATION, sample?.location, Component.VJOURNAL.name)
153163
@Test fun check_LOCATION_ALTREP() = insertRetrieveAssertString(JtxICalObject.LOCATION_ALTREP, sample?.locationAltrep, Component.VJOURNAL.name)
164+
@Test fun check_GEOFENCE_RADIUS() {
165+
val jtxVersionCode = context.packageManager.getPackageInfo("at.techbee.jtx", 0).longVersionCode
166+
Assume.assumeTrue(jtxVersionCode > 204020003)
167+
insertRetrieveAssertInt(JtxICalObject.GEOFENCE_RADIUS, sample?.geofenceRadius, Component.VJOURNAL.name)
168+
}
169+
154170
@Test fun check_PERCENT() = insertRetrieveAssertInt(JtxICalObject.PERCENT, sample?.percent, Component.VJOURNAL.name)
155171
@Test fun check_PRIORITY() = insertRetrieveAssertInt(JtxICalObject.PRIORITY, sample?.priority, Component.VJOURNAL.name)
156172
@Test fun check_DUE() = insertRetrieveAssertLong(JtxICalObject.DUE, sample?.due, Component.VJOURNAL.name)

src/main/java/at/bitfire/ical4android/JtxICalObject.kt

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@ open class JtxICalObject(
9191
var geoLong: Double? = null
9292
var location: String? = null
9393
var locationAltrep: String? = null
94+
var geofenceRadius: Int? = null
9495

9596
var uid: String = UUID.randomUUID().toString()
9697

@@ -229,6 +230,7 @@ open class JtxICalObject(
229230
const val X_PARAM_ATTACH_LABEL = "X-LABEL" // used for filename in KOrganizer
230231
const val X_PARAM_FILENAME = "FILENAME" // used for filename in GNOME Evolution
231232
const val X_PROP_XSTATUS = "X-STATUS" // used to define an extended status (additionally to standard status)
233+
const val X_PROP_GEOFENCE_RADIUS = "X-GEOFENCE-RADIUS" // used to define a Geofence-Radius to notifiy the user when close
232234

233235
/**
234236
* Parses an iCalendar resource and extracts the VTODOs and/or VJOURNALS.
@@ -543,6 +545,7 @@ open class JtxICalObject(
543545
else -> when(prop.name) {
544546
X_PROP_COMPLETEDTIMEZONE -> iCalObject.completedTimezone = prop.value
545547
X_PROP_XSTATUS -> iCalObject.xstatus = prop.value
548+
X_PROP_GEOFENCE_RADIUS -> iCalObject.geofenceRadius = try { prop.value.toInt() } catch (e: NumberFormatException) { Ical4Android.log.warning("Wrong format for geofenceRadius: ${prop.value}"); null }
546549
else -> iCalObject.unknown.add(Unknown(value = UnknownProperty.toJsonString(prop))) // save the whole property for unknown properties
547550
}
548551
}
@@ -718,6 +721,9 @@ open class JtxICalObject(
718721
if (geoLat != null && geoLong != null) {
719722
props += Geo(geoLat!!.toBigDecimal(), geoLong!!.toBigDecimal())
720723
}
724+
geofenceRadius?.let { geofenceRadius ->
725+
props += XProperty(X_PROP_GEOFENCE_RADIUS, geofenceRadius.toString())
726+
}
721727
color?.let { props += Color(null, Css3Color.nearestMatch(it).name) }
722728
url?.let {
723729
try {
@@ -1398,6 +1404,7 @@ duration?.let(props::add)
13981404
this.locationAltrep = newData.locationAltrep
13991405
this.geoLat = newData.geoLat
14001406
this.geoLong = newData.geoLong
1407+
this.geofenceRadius = newData.geofenceRadius
14011408
this.percent = newData.percent
14021409
this.classification = newData.classification
14031410
this.status = newData.status
@@ -1457,6 +1464,7 @@ duration?.let(props::add)
14571464
values.getAsDouble(JtxContract.JtxICalObject.GEO_LONG)?.let { geoLong -> this.geoLong = geoLong }
14581465
values.getAsString(JtxContract.JtxICalObject.LOCATION)?.let { location -> this.location = location }
14591466
values.getAsString(JtxContract.JtxICalObject.LOCATION_ALTREP)?.let { locationAltrep -> this.locationAltrep = locationAltrep }
1467+
values.getAsInteger(JtxContract.JtxICalObject.GEOFENCE_RADIUS)?.let { geofenceRadius -> this.geofenceRadius = geofenceRadius }
14601468
values.getAsInteger(JtxContract.JtxICalObject.PERCENT)?.let { percent -> this.percent = percent }
14611469
values.getAsInteger(JtxContract.JtxICalObject.PRIORITY)?.let { priority -> this.priority = priority }
14621470
values.getAsLong(JtxContract.JtxICalObject.DUE)?.let { due -> this.due = due }
@@ -1682,6 +1690,7 @@ duration?.let(props::add)
16821690
put(JtxContract.JtxICalObject.GEO_LONG, geoLong)
16831691
put(JtxContract.JtxICalObject.LOCATION, location)
16841692
put(JtxContract.JtxICalObject.LOCATION_ALTREP, locationAltrep)
1693+
put(JtxContract.JtxICalObject.GEOFENCE_RADIUS, geofenceRadius)
16851694
put(JtxContract.JtxICalObject.PERCENT, percent)
16861695
put(JtxContract.JtxICalObject.DTSTAMP, dtstamp)
16871696
put(JtxContract.JtxICalObject.DTSTART, dtstart)

src/main/java/at/techbee/jtx/JtxContract.kt

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ object JtxContract {
4242
const val AUTHORITY = "at.techbee.jtx.provider"
4343

4444
/** The version of this SyncContentProviderContract */
45-
const val VERSION = 4
45+
const val VERSION = 5
4646

4747
/** Constructs an Uri for the Jtx Sync Adapter with the given Account
4848
* @param [account] The account that should be appended to the Base Uri
@@ -279,6 +279,13 @@ object JtxContract {
279279
*/
280280
const val EXTENDED_STATUS = "xstatus"
281281

282+
/**
283+
* Purpose: Defines the radius for a geofence in meters
284+
* This is put into an extended property in the iCalendar-file
285+
* Type: [String]
286+
*/
287+
const val GEOFENCE_RADIUS = "geofenceRadius"
288+
282289
/**
283290
* Purpose: This property defines the access classification for a calendar component.
284291
* The possible values of a status are defined in the enum [Classification].

0 commit comments

Comments
 (0)