diff --git a/app/build.gradle b/app/build.gradle index 8a04613..233c775 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -1,6 +1,6 @@ buildscript { ext.flutterEngine = "1.0.0-c08d7d5efc9aa6eb3c30cfb3be6dc09bca5e7631" - ext.sdkVersion = "0.0.24" + ext.sdkVersion = "0.0.25" repositories { mavenCentral() } @@ -20,8 +20,8 @@ android { compileSdk 33 defaultConfig { minSdk 21 - versionCode 3 - versionName "0.0.6" + versionCode 4 + versionName "0.0.7" multiDexEnabled true testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" } diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index ba59963..4248388 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -1,4 +1,7 @@ - + - \ No newline at end of file + \ No newline at end of file diff --git a/app/src/main/kotlin/com/mytiki/tiki_sdk_android/TikiSdk.kt b/app/src/main/kotlin/com/mytiki/tiki_sdk_android/TikiSdk.kt index bd2ee81..c6837fe 100644 --- a/app/src/main/kotlin/com/mytiki/tiki_sdk_android/TikiSdk.kt +++ b/app/src/main/kotlin/com/mytiki/tiki_sdk_android/TikiSdk.kt @@ -1,3 +1,8 @@ +/* + * Copyright (c) TIKI Inc. + * MIT license. See LICENSE file in root directory. + */ + package com.mytiki.tiki_sdk_android import android.content.Context diff --git a/app/src/main/kotlin/com/mytiki/tiki_sdk_android/TikiSdkConsent.kt b/app/src/main/kotlin/com/mytiki/tiki_sdk_android/TikiSdkConsent.kt index 434b09d..4ef2d24 100644 --- a/app/src/main/kotlin/com/mytiki/tiki_sdk_android/TikiSdkConsent.kt +++ b/app/src/main/kotlin/com/mytiki/tiki_sdk_android/TikiSdkConsent.kt @@ -1,3 +1,8 @@ +/* + * Copyright (c) TIKI Inc. + * MIT license. See LICENSE file in root directory. + */ + package com.mytiki.tiki_sdk_android import com.squareup.moshi.JsonClass diff --git a/app/src/main/kotlin/com/mytiki/tiki_sdk_android/TikiSdkDataTypeEnum.kt b/app/src/main/kotlin/com/mytiki/tiki_sdk_android/TikiSdkDataTypeEnum.kt index 2a2442c..1f0f308 100644 --- a/app/src/main/kotlin/com/mytiki/tiki_sdk_android/TikiSdkDataTypeEnum.kt +++ b/app/src/main/kotlin/com/mytiki/tiki_sdk_android/TikiSdkDataTypeEnum.kt @@ -1,3 +1,8 @@ +/* + * Copyright (c) TIKI Inc. + * MIT license. See LICENSE file in root directory. + */ + package com.mytiki.tiki_sdk_android import com.squareup.moshi.JsonClass @@ -10,5 +15,4 @@ enum class TikiSdkDataTypeEnum { data_point, data_stream, data_pool; - } \ No newline at end of file diff --git a/app/src/main/kotlin/com/mytiki/tiki_sdk_android/TikiSdkDestination.kt b/app/src/main/kotlin/com/mytiki/tiki_sdk_android/TikiSdkDestination.kt index ec3114c..f63e19e 100644 --- a/app/src/main/kotlin/com/mytiki/tiki_sdk_android/TikiSdkDestination.kt +++ b/app/src/main/kotlin/com/mytiki/tiki_sdk_android/TikiSdkDestination.kt @@ -1,3 +1,8 @@ +/* + * Copyright (c) TIKI Inc. + * MIT license. See LICENSE file in root directory. + */ + package com.mytiki.tiki_sdk_android import com.squareup.moshi.JsonClass diff --git a/app/src/main/kotlin/com/mytiki/tiki_sdk_android/TikiSdkOwnership.kt b/app/src/main/kotlin/com/mytiki/tiki_sdk_android/TikiSdkOwnership.kt index 6989e7c..da1d416 100644 --- a/app/src/main/kotlin/com/mytiki/tiki_sdk_android/TikiSdkOwnership.kt +++ b/app/src/main/kotlin/com/mytiki/tiki_sdk_android/TikiSdkOwnership.kt @@ -1,3 +1,8 @@ +/* + * Copyright (c) TIKI Inc. + * MIT license. See LICENSE file in root directory. + */ + package com.mytiki.tiki_sdk_android import com.squareup.moshi.JsonClass diff --git a/app/src/main/kotlin/com/mytiki/tiki_sdk_android/tiki_platform_channel/MethodEnum.kt b/app/src/main/kotlin/com/mytiki/tiki_sdk_android/tiki_platform_channel/MethodEnum.kt index d4309ea..e4c6b92 100644 --- a/app/src/main/kotlin/com/mytiki/tiki_sdk_android/tiki_platform_channel/MethodEnum.kt +++ b/app/src/main/kotlin/com/mytiki/tiki_sdk_android/tiki_platform_channel/MethodEnum.kt @@ -1,3 +1,8 @@ +/* + * Copyright (c) TIKI Inc. + * MIT license. See LICENSE file in root directory. + */ + package com.mytiki.tiki_sdk_android.tiki_platform_channel /** diff --git a/app/src/main/kotlin/com/mytiki/tiki_sdk_android/tiki_platform_channel/TikiPlatformChannel.kt b/app/src/main/kotlin/com/mytiki/tiki_sdk_android/tiki_platform_channel/TikiPlatformChannel.kt index 5232ad7..bff49e1 100644 --- a/app/src/main/kotlin/com/mytiki/tiki_sdk_android/tiki_platform_channel/TikiPlatformChannel.kt +++ b/app/src/main/kotlin/com/mytiki/tiki_sdk_android/tiki_platform_channel/TikiPlatformChannel.kt @@ -2,6 +2,7 @@ * Copyright (c) TIKI Inc. * MIT license. See LICENSE file in root directory. */ + package com.mytiki.tiki_sdk_android.tiki_platform_channel import android.util.Log diff --git a/app/src/main/kotlin/com/mytiki/tiki_sdk_android/tiki_platform_channel/req/ReqBuild.kt b/app/src/main/kotlin/com/mytiki/tiki_sdk_android/tiki_platform_channel/req/ReqBuild.kt index 23b6066..569782b 100644 --- a/app/src/main/kotlin/com/mytiki/tiki_sdk_android/tiki_platform_channel/req/ReqBuild.kt +++ b/app/src/main/kotlin/com/mytiki/tiki_sdk_android/tiki_platform_channel/req/ReqBuild.kt @@ -2,6 +2,7 @@ * Copyright (c) TIKI Inc. * MIT license. See LICENSE file in root directory. */ + package com.mytiki.tiki_sdk_android.tiki_platform_channel.req import com.squareup.moshi.JsonClass diff --git a/app/src/main/kotlin/com/mytiki/tiki_sdk_android/tiki_platform_channel/req/ReqConsentApply.kt b/app/src/main/kotlin/com/mytiki/tiki_sdk_android/tiki_platform_channel/req/ReqConsentApply.kt index 132a9a1..46fc59f 100644 --- a/app/src/main/kotlin/com/mytiki/tiki_sdk_android/tiki_platform_channel/req/ReqConsentApply.kt +++ b/app/src/main/kotlin/com/mytiki/tiki_sdk_android/tiki_platform_channel/req/ReqConsentApply.kt @@ -2,6 +2,7 @@ * Copyright (c) TIKI Inc. * MIT license. See LICENSE file in root directory. */ + package com.mytiki.tiki_sdk_android.tiki_platform_channel.req import com.mytiki.tiki_sdk_android.TikiSdkDestination diff --git a/app/src/main/kotlin/com/mytiki/tiki_sdk_android/tiki_platform_channel/req/ReqConsentGet.kt b/app/src/main/kotlin/com/mytiki/tiki_sdk_android/tiki_platform_channel/req/ReqConsentGet.kt index c74d4d9..87d00d9 100644 --- a/app/src/main/kotlin/com/mytiki/tiki_sdk_android/tiki_platform_channel/req/ReqConsentGet.kt +++ b/app/src/main/kotlin/com/mytiki/tiki_sdk_android/tiki_platform_channel/req/ReqConsentGet.kt @@ -2,6 +2,7 @@ * Copyright (c) TIKI Inc. * MIT license. See LICENSE file in root directory. */ + package com.mytiki.tiki_sdk_android.tiki_platform_channel.req import com.squareup.moshi.JsonClass diff --git a/app/src/main/kotlin/com/mytiki/tiki_sdk_android/tiki_platform_channel/req/ReqConsentModify.kt b/app/src/main/kotlin/com/mytiki/tiki_sdk_android/tiki_platform_channel/req/ReqConsentModify.kt index 92d3c64..2523075 100644 --- a/app/src/main/kotlin/com/mytiki/tiki_sdk_android/tiki_platform_channel/req/ReqConsentModify.kt +++ b/app/src/main/kotlin/com/mytiki/tiki_sdk_android/tiki_platform_channel/req/ReqConsentModify.kt @@ -2,6 +2,7 @@ * Copyright (c) TIKI Inc. * MIT license. See LICENSE file in root directory. */ + package com.mytiki.tiki_sdk_android.tiki_platform_channel.req import com.mytiki.tiki_sdk_android.TikiSdkDestination diff --git a/app/src/main/kotlin/com/mytiki/tiki_sdk_android/tiki_platform_channel/req/ReqOwnershipAssign.kt b/app/src/main/kotlin/com/mytiki/tiki_sdk_android/tiki_platform_channel/req/ReqOwnershipAssign.kt index 42dc42d..413f751 100644 --- a/app/src/main/kotlin/com/mytiki/tiki_sdk_android/tiki_platform_channel/req/ReqOwnershipAssign.kt +++ b/app/src/main/kotlin/com/mytiki/tiki_sdk_android/tiki_platform_channel/req/ReqOwnershipAssign.kt @@ -2,6 +2,7 @@ * Copyright (c) TIKI Inc. * MIT license. See LICENSE file in root directory. */ + package com.mytiki.tiki_sdk_android.tiki_platform_channel.req import com.mytiki.tiki_sdk_android.TikiSdkDataTypeEnum diff --git a/app/src/main/kotlin/com/mytiki/tiki_sdk_android/tiki_platform_channel/req/ReqOwnershipGet.kt b/app/src/main/kotlin/com/mytiki/tiki_sdk_android/tiki_platform_channel/req/ReqOwnershipGet.kt index 1cab451..e5bf1a4 100644 --- a/app/src/main/kotlin/com/mytiki/tiki_sdk_android/tiki_platform_channel/req/ReqOwnershipGet.kt +++ b/app/src/main/kotlin/com/mytiki/tiki_sdk_android/tiki_platform_channel/req/ReqOwnershipGet.kt @@ -2,6 +2,7 @@ * Copyright (c) TIKI Inc. * MIT license. See LICENSE file in root directory. */ + package com.mytiki.tiki_sdk_android.tiki_platform_channel.req import com.squareup.moshi.JsonClass diff --git a/app/src/main/kotlin/com/mytiki/tiki_sdk_android/tiki_platform_channel/rsp/RspBuild.kt b/app/src/main/kotlin/com/mytiki/tiki_sdk_android/tiki_platform_channel/rsp/RspBuild.kt index 101ccd4..240ad5f 100644 --- a/app/src/main/kotlin/com/mytiki/tiki_sdk_android/tiki_platform_channel/rsp/RspBuild.kt +++ b/app/src/main/kotlin/com/mytiki/tiki_sdk_android/tiki_platform_channel/rsp/RspBuild.kt @@ -2,6 +2,7 @@ * Copyright (c) TIKI Inc. * MIT license. See LICENSE file in root directory. */ + package com.mytiki.tiki_sdk_android.tiki_platform_channel.rsp import com.squareup.moshi.JsonClass diff --git a/app/src/main/kotlin/com/mytiki/tiki_sdk_android/tiki_platform_channel/rsp/RspConsentApply.kt b/app/src/main/kotlin/com/mytiki/tiki_sdk_android/tiki_platform_channel/rsp/RspConsentApply.kt index 0efcca8..3ad089b 100644 --- a/app/src/main/kotlin/com/mytiki/tiki_sdk_android/tiki_platform_channel/rsp/RspConsentApply.kt +++ b/app/src/main/kotlin/com/mytiki/tiki_sdk_android/tiki_platform_channel/rsp/RspConsentApply.kt @@ -2,6 +2,7 @@ * Copyright (c) TIKI Inc. * MIT license. See LICENSE file in root directory. */ + package com.mytiki.tiki_sdk_android.tiki_platform_channel.rsp import com.squareup.moshi.JsonClass diff --git a/app/src/main/kotlin/com/mytiki/tiki_sdk_android/tiki_platform_channel/rsp/RspConsentGet.kt b/app/src/main/kotlin/com/mytiki/tiki_sdk_android/tiki_platform_channel/rsp/RspConsentGet.kt index afd2d0f..0a01fda 100644 --- a/app/src/main/kotlin/com/mytiki/tiki_sdk_android/tiki_platform_channel/rsp/RspConsentGet.kt +++ b/app/src/main/kotlin/com/mytiki/tiki_sdk_android/tiki_platform_channel/rsp/RspConsentGet.kt @@ -2,6 +2,7 @@ * Copyright (c) TIKI Inc. * MIT license. See LICENSE file in root directory. */ + package com.mytiki.tiki_sdk_android.tiki_platform_channel.rsp import com.mytiki.tiki_sdk_android.TikiSdkConsent diff --git a/app/src/main/kotlin/com/mytiki/tiki_sdk_android/tiki_platform_channel/rsp/RspError.kt b/app/src/main/kotlin/com/mytiki/tiki_sdk_android/tiki_platform_channel/rsp/RspError.kt index 78bc182..b4a7193 100644 --- a/app/src/main/kotlin/com/mytiki/tiki_sdk_android/tiki_platform_channel/rsp/RspError.kt +++ b/app/src/main/kotlin/com/mytiki/tiki_sdk_android/tiki_platform_channel/rsp/RspError.kt @@ -2,6 +2,7 @@ * Copyright (c) TIKI Inc. * MIT license. See LICENSE file in root directory. */ + package com.mytiki.tiki_sdk_android.tiki_platform_channel.rsp import com.squareup.moshi.JsonClass diff --git a/app/src/main/kotlin/com/mytiki/tiki_sdk_android/tiki_platform_channel/rsp/RspOwnership.kt b/app/src/main/kotlin/com/mytiki/tiki_sdk_android/tiki_platform_channel/rsp/RspOwnership.kt index 109f098..e920b35 100644 --- a/app/src/main/kotlin/com/mytiki/tiki_sdk_android/tiki_platform_channel/rsp/RspOwnership.kt +++ b/app/src/main/kotlin/com/mytiki/tiki_sdk_android/tiki_platform_channel/rsp/RspOwnership.kt @@ -2,6 +2,7 @@ * Copyright (c) TIKI Inc. * MIT license. See LICENSE file in root directory. */ + package com.mytiki.tiki_sdk_android.tiki_platform_channel.rsp import com.mytiki.tiki_sdk_android.TikiSdkOwnership diff --git a/app/src/main/kotlin/com/mytiki/tiki_sdk_android/util/TimeStampToDateAdapter.kt b/app/src/main/kotlin/com/mytiki/tiki_sdk_android/util/TimeStampToDateAdapter.kt index 105272f..d4724ad 100644 --- a/app/src/main/kotlin/com/mytiki/tiki_sdk_android/util/TimeStampToDateAdapter.kt +++ b/app/src/main/kotlin/com/mytiki/tiki_sdk_android/util/TimeStampToDateAdapter.kt @@ -1,3 +1,8 @@ +/* + * Copyright (c) TIKI Inc. + * MIT license. See LICENSE file in root directory. + */ + package com.mytiki.tiki_sdk_android.util import com.squareup.moshi.* diff --git a/app/src/test/java/com/mytiki/tiki_sdk_android/TikiSdkConsentTest.kt b/app/src/test/java/com/mytiki/tiki_sdk_android/TikiSdkConsentTest.kt index 023030a..5e03240 100644 --- a/app/src/test/java/com/mytiki/tiki_sdk_android/TikiSdkConsentTest.kt +++ b/app/src/test/java/com/mytiki/tiki_sdk_android/TikiSdkConsentTest.kt @@ -1,3 +1,8 @@ +/* + * Copyright (c) TIKI Inc. + * MIT license. See LICENSE file in root directory. + */ + package com.mytiki.tiki_sdk_android import com.mytiki.tiki_sdk_android.util.TimeStampToDateAdapter diff --git a/app/src/test/java/com/mytiki/tiki_sdk_android/TikiSdkDataTypeEnumTest.kt b/app/src/test/java/com/mytiki/tiki_sdk_android/TikiSdkDataTypeEnumTest.kt index d2c28c3..376c2f4 100644 --- a/app/src/test/java/com/mytiki/tiki_sdk_android/TikiSdkDataTypeEnumTest.kt +++ b/app/src/test/java/com/mytiki/tiki_sdk_android/TikiSdkDataTypeEnumTest.kt @@ -1,3 +1,8 @@ +/* + * Copyright (c) TIKI Inc. + * MIT license. See LICENSE file in root directory. + */ + package com.mytiki.tiki_sdk_android import com.squareup.moshi.JsonAdapter diff --git a/app/src/test/java/com/mytiki/tiki_sdk_android/TikiSdkDestinationTest.kt b/app/src/test/java/com/mytiki/tiki_sdk_android/TikiSdkDestinationTest.kt index ca94f8e..aa735ea 100644 --- a/app/src/test/java/com/mytiki/tiki_sdk_android/TikiSdkDestinationTest.kt +++ b/app/src/test/java/com/mytiki/tiki_sdk_android/TikiSdkDestinationTest.kt @@ -1,3 +1,8 @@ +/* + * Copyright (c) TIKI Inc. + * MIT license. See LICENSE file in root directory. + */ + package com.mytiki.tiki_sdk_android import com.squareup.moshi.JsonAdapter diff --git a/app/src/test/java/com/mytiki/tiki_sdk_android/TikiSdkOwnershipTest.kt b/app/src/test/java/com/mytiki/tiki_sdk_android/TikiSdkOwnershipTest.kt index 142b9e0..2736990 100644 --- a/app/src/test/java/com/mytiki/tiki_sdk_android/TikiSdkOwnershipTest.kt +++ b/app/src/test/java/com/mytiki/tiki_sdk_android/TikiSdkOwnershipTest.kt @@ -1,3 +1,8 @@ +/* + * Copyright (c) TIKI Inc. + * MIT license. See LICENSE file in root directory. + */ + package com.mytiki.tiki_sdk_android import com.squareup.moshi.JsonAdapter diff --git a/app/src/test/java/com/mytiki/tiki_sdk_android/tiki_platform_channel/rsp/RspBuildTest.kt b/app/src/test/java/com/mytiki/tiki_sdk_android/tiki_platform_channel/rsp/RspBuildTest.kt index 036b6c5..62bb319 100644 --- a/app/src/test/java/com/mytiki/tiki_sdk_android/tiki_platform_channel/rsp/RspBuildTest.kt +++ b/app/src/test/java/com/mytiki/tiki_sdk_android/tiki_platform_channel/rsp/RspBuildTest.kt @@ -2,8 +2,8 @@ * Copyright (c) TIKI Inc. * MIT license. See LICENSE file in root directory. */ -package com.mytiki.tiki_sdk_android.tiki_platform_channel.rsp +package com.mytiki.tiki_sdk_android.tiki_platform_channel.rsp import com.squareup.moshi.JsonAdapter import com.squareup.moshi.Moshi diff --git a/doc/guide/GettingStarted.md b/doc/guide/GettingStarted.md index 22f9e61..892eba6 100644 --- a/doc/guide/GettingStarted.md +++ b/doc/guide/GettingStarted.md @@ -26,14 +26,16 @@ repositories { Add the dependency in your App's `build.gradle` file (`PROJECT_ROOT/app/build.gradle`) ``` -implementation("com.mytiki:tiki-sdk-android:0.0.5") +implementation("com.mytiki:tiki-sdk-android:1.0.0") ``` ### Usage #### 1. [Sign up](https://console.mytiki.com) (free) for a TIKI developer account to get an API ID. -#### 2. Construct the [TIKI SDK](tiki-sdk-android-tiki-sdk) +#### 2. Initialize the [TIKI SDK](tiki-sdk-android-tiki-sdk) + +_Note: Must be called from the main UI thread_ Configuration parameters: @@ -56,7 +58,9 @@ Configuration parameters: Example: ``` -val tiki = TikiSdk().init("565b3268-cdc0-4e5c-94c8-5d8f53d4577c", "com.mycompany.myproduct", context) +MainScope().launch { + val tiki = TikiSdk().init("565b3268-cdc0-4e5c-94c8-5d8f53d4577c", "com.mycompany.myproduct", applicationContext).await() +} ``` #### 3. Assign ownership @@ -67,7 +71,7 @@ Parameters: An identifier in your system corresponding to the raw data. _i.e. a user_id_ -- **type → String** +- **type → [TikiSdkDataTypeEnum](tiki-sdk-android-tiki-sdk-data-type-enum)** `"data_point"`, `"data_pool"`, or `"data_stream"` @@ -91,7 +95,10 @@ Returns: Example: ``` -val oid = tiki.assignOwnership("12345", TikiSdkDataTypeEnum.data_point, listOf("email_address")) +MainScope().launch { + ... + val oid = tiki.assignOwnership("12345", TikiSdkDataTypeEnum.data_point, listOf("email_address")) +} ``` #### 4. Modify consent @@ -114,7 +121,7 @@ Parameters: An optional definition of a reward promised to the user in exchange for consent. -- **expiry → [LocalDateTime](https://kotlinlang.org/api/kotlinx-datetime/kotlinx-datetime/kotlinx.datetime/-local-date-time/-local-date-time.html)? = null** +- **expiry → Date? = null** The date upon which the consent is no longer valid. If not set, consent is perpetual. Returns: @@ -124,7 +131,10 @@ Returns: Example: ``` -val consent = tiki.modifyConsent(oid, TikiSdkDestination(listOf("*"), listOf("*"))) +MainScope().launch { + ... + val consent = tiki.modifyConsent(oid, TikiSdkDestination(listOf("*"), listOf("*"))) +} ``` #### 5. Apply consent @@ -154,7 +164,10 @@ Parameters: Example: ``` -applyConsent("12345", TikiSdkDestination(listOf("*"), listOf("*")), { - print("Consent Approved. Send data to backend.") -}); +MainScope().launch { + ... + tiki.applyConsent("12345", TikiSdkDestination(listOf("*"), listOf("*")), { + print("Consent Approved. Send data to backend.") + }); +} ``` \ No newline at end of file diff --git a/doc/ref/KotlinDocs.md b/doc/ref/KotlinDocs.md index 7c98789..f9d0fec 100644 --- a/doc/ref/KotlinDocs.md +++ b/doc/ref/KotlinDocs.md @@ -3,7 +3,7 @@ title: Kotlin Docs category: 6386a02f5b7bf00510590f34 slug: tiki-sdk-android-docs hidden: false -order: 6 +order: 7 type: link link_url: https://tiki-sdk-android.docs.mytiki.com/ --- \ No newline at end of file diff --git a/doc/ref/Source.md b/doc/ref/Source.md index 9a80ce2..6528c2f 100644 --- a/doc/ref/Source.md +++ b/doc/ref/Source.md @@ -1,4 +1,9 @@ --- -title: Source Code category: 6386a02f5b7bf00510590f34 slug: tiki-sdk-android-source hidden: false -order: 5 type: link link_url: https://github.com/tiki/tiki-sdk-android +title: Source Code +category: 6386a02f5b7bf00510590f34 +slug: tiki-sdk-android-source +hidden: false +order: 6 +type: link +link_url: https://github.com/tiki/tiki-sdk-android --- diff --git a/doc/ref/TikiSdk.md b/doc/ref/TikiSdk.md index dd30d1a..c42d257 100644 --- a/doc/ref/TikiSdk.md +++ b/doc/ref/TikiSdk.md @@ -1,49 +1,61 @@ --- -title: TikiSdk excerpt: The primary object for interacting with the TIKI infrastructure. -Use `TikiSdk` to assign ownership, modify, and apply consent. category: 6386a02f5b7bf00510590f34 -slug: tiki-sdk-android-tiki-sdk hidden: false order: 1 +title: TikiSdk +excerpt: The primary object for interacting with the TIKI infrastructure. Use `TikiSdk` to assign ownership, modify, and apply consent. +category: 6386a02f5b7bf00510590f34 +slug: tiki-sdk-android-tiki-sdk +hidden: false +order: 1 --- ## Constructors -##### TikiSdk (...) +##### TikiSdk () -Creates an empty TikiSdk. +Construct the TikiSdk object. `init(...)` must be called before use. ## Methods -##### init(...) → String +##### init(...) → Deferred<TikiSdk> -Initializes the TIKI SDK. It should be called before any other method. It sets up Flutter Engine and -Platform Channel and builds the core of the TIKI SDK, calling TIKI SDK Dart through the Flutter -Platform Channel. +Initializes the TIKI SDK. It should be called before any other method. It sets up Flutter Engine and Platform Channel and builds the core of the TIKI SDK, calling TIKI SDK Dart through the Flutter Platform Channel. **Must be called from the main UI thread.** Read about [coroutines](https://kotlinlang.org/docs/coroutines-overview.html) for Android [here](https://developer.android.com/topic/libraries/architecture/coroutines). Parameters: - **apiId → String** - A unique identifier for your account. Create, revoke, and cycle Ids (not a secret but try and - treat it with care) at [console.mytiki.com](https://console.mytiki.com). + A unique identifier for your account. Create, revoke, and cycle Ids (not a secret but try and treat it with care) at [console.mytiki.com](https://console.mytiki.com). - **origin → String** - Included in the on-chain transaction to denote the application of origination (can be overridden - in individual requests). It should follow a reversed FQDN syntax. i.e. com.mycompany.myproduct + Included in the on-chain transaction to denote the application of origination (can be overridden in individual requests). It should follow a reversed FQDN syntax. i.e. com.mycompany.myproduct - **context → [Context](https://developer.android.com/reference/android/content/Context)** - Set the application context. Required for - the [MethodChannel](https://api.flutter.dev/flutter/services/MethodChannel-class.html) which - communicates with the [Dart SDK](https://github.com/tiki/tiki-sdk-dart) binaries + Set the application context. Required for the [MethodChannel](https://api.flutter.dev/flutter/services/MethodChannel-class.html) which communicates with the [Dart SDK](https://github.com/tiki/tiki-sdk-dart) binaries - **address → String? = null** - Set the user address (primarily for restoring the state on launch). If not set, a new key pair and - address will be generated for the user. + Set the user address (primarily for restoring the state on launch). If not set, a new key pair and address will be generated for the user. + +Returns: + +- **Deferred<TikiSdk>** + `this` initialized + + +Example: + +``` +MainScope().launch { + val tiki = TikiSdk().init("YOUR_API_ID", "com.mycompany.myproduct", applicationContext).await() +} +``` ##### assignOwnership(...) → String -Data ownership can be assigned to any data point, pool, or stream, creating an immutable, on-chain -record. +Data ownership can be assigned to any data point, pool, or stream, creating an immutable, on-chain record. + +**suspend function** +_must be called from within a coroutine_ Parameters: @@ -52,8 +64,8 @@ Parameters: _i.e. a user_id_ -- **type → String** - One of `"point"`, `"pool"`, or `"stream"` +- **type → [TikiSdkDataTypeEnum](tiki-sdk-android-tiki-sdk-data-type-enum)** + One of `"data_point"`, `"data_pool"`, or `"data_stream"` - **contains → List<String>** @@ -83,8 +95,10 @@ val tid = tiki.assignOwnership("12345", TikiSdkDataTypeEnum.data_point, listOf(" ##### modifyConsent(...) → [TikiSdkConsent](tiki-sdk-android-tiki-sdk-consent) -Consent is given (or revoked) for data ownership records. Consent defines "who" the data owner has -given utilization rights. +Consent is given (or revoked) for data ownership records. Consent defines "who" the data owner has given utilization rights. + +**suspend function** +_must be called from within a coroutine_ Parameters: @@ -97,17 +111,14 @@ Parameters: - **about → String? = null** - An optional description to provide additional context to the transaction. Most typically as - human-readable text. + An optional description to provide additional context to the transaction. Most typically as human-readable text. - **reward → String? = null** An optional definition of a reward promised to the user in exchange for consent. -- **expiry - → [LocalDateTime](https://kotlinlang.org/api/kotlinx-datetime/kotlinx-datetime/kotlinx.datetime/-local-date-time/-local-date-time.html) - ? = null** +- **expiry → Date ? = null** The date upon which the consent is no longer valid. If not set, consent is perpetual. Returns: @@ -123,10 +134,12 @@ val consent = tiki.modifyConsent(oid, TikiSdkDestination(listOf("*"), listOf("*   -##### getOwnership(source: String, origin: String?) → [TikiSdkOwnership](tiki-sdk-android-tiki-sdk-ownership)? +##### getOwnership(source: String, origin: String? = null) → [TikiSdkOwnership](tiki-sdk-android-tiki-sdk-ownership)? + +Get the `TikiSdkOwnership` for a `source` and `origin`. If `origin` is unset, the default set during construction is used. -Get the `TikiSdkOwnership` for a `source` and `origin`. If `origin` is unset, the default set during -construction is used. +**suspend function** +_must be called from within a coroutine_ Parameters: @@ -152,8 +165,10 @@ val ownership = tiki.getOwnership("12345") ##### getConsent(source: String, origin: String?) → [TikiSdkConsent](tiki-sdk-android-tiki-sdk-consent)? -Get the latest `TikiSdkConsent` for a `source` and `origin`. If `origin` is unset, the default set -during construction is used. +Get the latest `TikiSdkConsent` for a `source` and `origin`. If `origin` is unset, the default set during construction is used. + +**suspend function** +_must be called from within a coroutine_ Parameters: @@ -179,8 +194,10 @@ val consent = tiki.getConsent("12345") ##### applyConsent(...) -Apply consent to a data transaction. If consent is granted for the `source` and `destination` and -has not expired, the request is executed. +Apply consent to a data transaction. If consent is granted for the `source` and `destination` and has not expired, the request is executed. + +**suspend function** +_must be called from within a coroutine_ Parameters: @@ -207,7 +224,7 @@ Parameters: Example: ``` -applyConsent("12345", TikiSdkDestination(listOf("*"), listOf("*")), { +tiki.applyConsent("12345", TikiSdkDestination(listOf("*"), listOf("*")), { print("Consent Approved. Send data to backend.") }) ``` \ No newline at end of file diff --git a/doc/ref/TikiSdkConsent.md b/doc/ref/TikiSdkConsent.md index 4ddaa9a..ed186fb 100644 --- a/doc/ref/TikiSdkConsent.md +++ b/doc/ref/TikiSdkConsent.md @@ -1,14 +1,24 @@ --- -title: TikiSdkConsent excerpt: A Consent Object. Representative of the NFT created on-chain. -Requires a corresponding Data Ownership NFT (see [TikiSdk](tiki-sdk-android-tiki-sdk)). category: -6386a02f5b7bf00510590f34 slug: tiki-sdk-android-tiki-sdk-consent hidden: false order: 3 +title: TikiSdkConsent +excerpt: A Consent Object. Representative of the NFT created on-chain. Requires a corresponding Data Ownership NFT (see [TikiSdkOwnership](tiki-sdk-android-tiki-sdk-ownership)). +category: 6386a02f5b7bf00510590f34 +slug: tiki-sdk-android-tiki-sdk-consent +hidden: false +order: 5 --- ## Constructors -##### TikiSdkConsent(ownershipId: String, destination: [TikiSdkDestination](tiki-sdk-android-tiki-sdk-destination), about: String, reward: String, transactionId: String, expiry: [Calendar](https://developer.android.com/reference/kotlin/java/util/Calendar.html)}) +##### TikiSdkConsent(...) -Builds a TikiSdkConsent for the data identified by `ownershipId`. +Parameters: + +- **ownershipId → String** +- **destination → [TikiSdkDestination](tiki-sdk-android-tiki-sdk-destination)** +- **transactionId → String** +- **about → String? = null** +- **reward → String? = null** +- **expiry → Int? = null** ## Properties diff --git a/doc/ref/TikiSdkDataTypeEnum.md b/doc/ref/TikiSdkDataTypeEnum.md index 6f12d43..79b19a1 100644 --- a/doc/ref/TikiSdkDataTypeEnum.md +++ b/doc/ref/TikiSdkDataTypeEnum.md @@ -1,7 +1,10 @@ --- -title: TikiSdkDataTypeEnum excerpt: An enumeration of the supported data aggregation types. -category: 6386a02f5b7bf00510590f34 slug: tiki-sdk-android-tiki-sdk-data-type-enum hidden: false -order: 4 +title: TikiSdkDataTypeEnum +excerpt: An enumeration of the supported data aggregation types. +category: 6386a02f5b7bf00510590f34 +slug: tiki-sdk-android-tiki-sdk-data-type-enum +hidden: false +order: 2 --- ## Entries diff --git a/doc/ref/TikiSdkDestination.md b/doc/ref/TikiSdkDestination.md index e880838..19077cb 100644 --- a/doc/ref/TikiSdkDestination.md +++ b/doc/ref/TikiSdkDestination.md @@ -1,7 +1,10 @@ --- -title: TikiSdkDestination excerpt: Defines destinations and use cases (optional) allowed or -disallowed. Serializable for inclusion in transactions. category: 6386a02f5b7bf00510590f34 slug: -tiki-sdk-android-tiki-sdk-destination hidden: false order: 2 +title: TikiSdkDestination +excerpt: Defines destinations and use cases (optional) allowed or disallowed. Serializable for inclusion in transactions. +category: 6386a02f5b7bf00510590f34 +slug: tiki-sdk-android-tiki-sdk-destination +hidden: false +order: 3 --- ## Constructors diff --git a/doc/ref/TikiSdkOwnership.md b/doc/ref/TikiSdkOwnership.md new file mode 100644 index 0000000..4334ff4 --- /dev/null +++ b/doc/ref/TikiSdkOwnership.md @@ -0,0 +1,54 @@ +--- +title: TikiSdkOwnership +excerpt: A Ownership Object. Representative of the NFT created on-chain. +category: 6386a02f5b7bf00510590f34 +slug: tiki-sdk-android-tiki-sdk-ownership +hidden: false +order: 4 +--- + +## Constructors + +##### TikiSdkOwnership(...) + +Parameters: + +- **source → String** +- **type → [TikiSdkDataTypeEnum](tiki-sdk-android-tiki-sdk-data-type-enum)** +- **origin → String** +- **transactionId → String** +- **contains → List<String> = listOf()** +- **about → String? = null** + +## Properties + +##### source ↔ String + +An identifier in your system corresponding to the raw data. +_i.e. a user_id_ +_read / write_ + +##### type ↔ [TikiSdkDataTypeEnum](tiki-sdk-android-tiki-sdk-data-type-enum) + +`data_point`, `data_pool`, or `data_stream` +_read / write_ + +##### origin ↔ String + +The origin from which the data was generated. +_read / write_ + +##### transactionId ↔ String + +The transaction id for `this` +_read / write_ + +##### contains ↔ List<String> = listOf() + +A list of metadata tags describing the represented data. +_read / write_ + +##### about ↔ String? = null + +An optional description to provide additional context to the transaction, typically as human-readable text. +_read / write_ \ No newline at end of file diff --git a/example_app/.gitignore b/example_app/.gitignore new file mode 100644 index 0000000..aa724b7 --- /dev/null +++ b/example_app/.gitignore @@ -0,0 +1,15 @@ +*.iml +.gradle +/local.properties +/.idea/caches +/.idea/libraries +/.idea/modules.xml +/.idea/workspace.xml +/.idea/navEditor.xml +/.idea/assetWizardSettings.xml +.DS_Store +/build +/captures +.externalNativeBuild +.cxx +local.properties diff --git a/example_app/app/.gitignore b/example_app/app/.gitignore new file mode 100644 index 0000000..42afabf --- /dev/null +++ b/example_app/app/.gitignore @@ -0,0 +1 @@ +/build \ No newline at end of file diff --git a/example_app/app/build.gradle b/example_app/app/build.gradle new file mode 100644 index 0000000..a7bcdea --- /dev/null +++ b/example_app/app/build.gradle @@ -0,0 +1,63 @@ +plugins { + id 'com.android.application' + id 'org.jetbrains.kotlin.android' +} + +android { + compileSdk 33 + + defaultConfig { + applicationId "com.mytiki.tiki_sdk_android.example_app" + + minSdk 21 + targetSdk 33 + versionCode 1 + versionName "1.0" + + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + + vectorDrawables.useSupportLibrary = true + } + + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + } + } + + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } + + kotlinOptions { + jvmTarget = '1.8' + } + + buildFeatures { + viewBinding true + dataBinding true + } +} + +dependencies { + implementation 'androidx.core:core-ktx:1.9.0' + implementation 'androidx.appcompat:appcompat:1.6.0' + implementation 'com.google.android.material:material:1.7.0' + implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:1.6.4" + implementation 'androidx.fragment:fragment-ktx:1.5.5' + implementation 'androidx.lifecycle:lifecycle-livedata-ktx:2.5.1' + implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.5.1' + implementation 'androidx.navigation:navigation-fragment-ktx:2.5.3' + implementation 'androidx.navigation:navigation-ui-ktx:2.5.3' + implementation 'androidx.databinding:databinding-runtime:7.4.0' + + implementation fileTree(include: ["app-debug.aar"], dir: '../../app/build/outputs/aar/') + + testImplementation 'junit:junit:4.13.2' + + androidTestImplementation "org.jetbrains.kotlinx:kotlinx-coroutines-test:1.6.4" + androidTestImplementation 'androidx.test.ext:junit:1.1.5' + androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1' +} \ No newline at end of file diff --git a/example_app/app/proguard-rules.pro b/example_app/app/proguard-rules.pro new file mode 100644 index 0000000..481bb43 --- /dev/null +++ b/example_app/app/proguard-rules.pro @@ -0,0 +1,21 @@ +# Add project specific ProGuard rules here. +# You can control the set of applied configuration files using the +# proguardFiles setting in build.gradle. +# +# For more details, see +# http://developer.android.com/guide/developing/tools/proguard.html + +# If your project uses WebView with JS, uncomment the following +# and specify the fully qualified class name to the JavaScript interface +# class: +#-keepclassmembers class fqcn.of.javascript.interface.for.webview { +# public *; +#} + +# Uncomment this to preserve the line number information for +# debugging stack traces. +#-keepattributes SourceFile,LineNumberTable + +# If you keep the line number information, uncomment this to +# hide the original source file name. +#-renamesourcefileattribute SourceFile \ No newline at end of file diff --git a/example_app/app/src/main/AndroidManifest.xml b/example_app/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000..35f2c04 --- /dev/null +++ b/example_app/app/src/main/AndroidManifest.xml @@ -0,0 +1,18 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/example_app/app/src/main/java/com/mytiki/tiki_sdk_android/example_app/MainActivity.kt b/example_app/app/src/main/java/com/mytiki/tiki_sdk_android/example_app/MainActivity.kt new file mode 100644 index 0000000..18a9d56 --- /dev/null +++ b/example_app/app/src/main/java/com/mytiki/tiki_sdk_android/example_app/MainActivity.kt @@ -0,0 +1,30 @@ +package com.mytiki.tiki_sdk_android.example_app + +import android.os.Bundle +import androidx.activity.viewModels +import androidx.appcompat.app.AppCompatActivity +import androidx.navigation.findNavController +import androidx.navigation.ui.AppBarConfiguration +import androidx.navigation.ui.navigateUp +import com.mytiki.tiki_sdk_android.example_app.databinding.MainActivityBinding +import com.mytiki.tiki_sdk_android.example_app.try_it_out.TryItOutViewModel + +class MainActivity : AppCompatActivity() { + + private lateinit var appBarConfiguration: AppBarConfiguration + private lateinit var binding: MainActivityBinding + + private val viewModel by viewModels() + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + binding = MainActivityBinding.inflate(layoutInflater) + setContentView(binding.root) + } + + override fun onSupportNavigateUp(): Boolean { + val navController = findNavController(R.id.nav_host_fragment_content_main) + return navController.navigateUp(appBarConfiguration) + || super.onSupportNavigateUp() + } +} \ No newline at end of file diff --git a/example_app/app/src/main/java/com/mytiki/tiki_sdk_android/example_app/body/BodyFragment.kt b/example_app/app/src/main/java/com/mytiki/tiki_sdk_android/example_app/body/BodyFragment.kt new file mode 100644 index 0000000..791fb70 --- /dev/null +++ b/example_app/app/src/main/java/com/mytiki/tiki_sdk_android/example_app/body/BodyFragment.kt @@ -0,0 +1,45 @@ +package com.mytiki.tiki_sdk_android.example_app.body + +import android.os.Bundle +import android.text.Editable +import android.text.TextWatcher +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import androidx.fragment.app.Fragment +import androidx.fragment.app.activityViewModels +import com.mytiki.tiki_sdk_android.example_app.databinding.BodyFragmentBinding +import com.mytiki.tiki_sdk_android.example_app.try_it_out.TryItOutViewModel +import java.util.* + +class BodyFragment : Fragment() { + + private val viewModel by activityViewModels() + + private var _binding: BodyFragmentBinding? = null + private val binding get() = _binding!! + + private var timer: Timer? = null + + override fun onCreateView( + inflater: LayoutInflater, container: ViewGroup?, + savedInstanceState: Bundle? + ): View { + _binding = BodyFragmentBinding.inflate(inflater, container, false) + return binding.root + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + binding.bodyTex.setText(viewModel.destination.value?.body) + binding.bodyTex.addTextChangedListener(object : TextWatcher { + override fun afterTextChanged(s: Editable?) {} + + override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {} + + override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) { + viewModel.destination.value?.body = s.toString() + } + }) + } +} \ No newline at end of file diff --git a/example_app/app/src/main/java/com/mytiki/tiki_sdk_android/example_app/consent/ConsentFragment.kt b/example_app/app/src/main/java/com/mytiki/tiki_sdk_android/example_app/consent/ConsentFragment.kt new file mode 100644 index 0000000..102ed58 --- /dev/null +++ b/example_app/app/src/main/java/com/mytiki/tiki_sdk_android/example_app/consent/ConsentFragment.kt @@ -0,0 +1,40 @@ +package com.mytiki.tiki_sdk_android.example_app.consent + +import android.os.Bundle +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import androidx.fragment.app.Fragment +import androidx.fragment.app.activityViewModels +import com.mytiki.tiki_sdk_android.example_app.databinding.ConsentFragmentBinding +import com.mytiki.tiki_sdk_android.example_app.try_it_out.TryItOutViewModel +import java.text.DateFormat +import java.util.* + +class ConsentFragment : Fragment() { + + private val viewModel by activityViewModels() + + private var _binding: ConsentFragmentBinding? = null + private val binding get() = _binding!! + + private var timer: Timer? = null + + override fun onCreateView( + inflater: LayoutInflater, container: ViewGroup?, + savedInstanceState: Bundle? + ): View { + _binding = ConsentFragmentBinding.inflate(inflater, container, false) + return binding.root + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + binding.hash.text = viewModel.consent!!.transactionId + binding.paths.text = viewModel.consent!!.destination.paths.joinToString(", ") + binding.uses.text = viewModel.consent!!.destination.uses.joinToString(", ") + binding.about.text = viewModel.consent!!.about + binding.reward.text = viewModel.consent!!.reward + binding.expiry.text = DateFormat.getDateTimeInstance().format(viewModel.consent!!.expiry!!) + } +} \ No newline at end of file diff --git a/example_app/app/src/main/java/com/mytiki/tiki_sdk_android/example_app/destination/Destination.kt b/example_app/app/src/main/java/com/mytiki/tiki_sdk_android/example_app/destination/Destination.kt new file mode 100644 index 0000000..27ded91 --- /dev/null +++ b/example_app/app/src/main/java/com/mytiki/tiki_sdk_android/example_app/destination/Destination.kt @@ -0,0 +1,9 @@ +package com.mytiki.tiki_sdk_android.example_app.destination + +data class Destination( + val source: String, + var body: String = "{\"message\" : \"Hello Tiki!\"}", + var httpMethod: String = "POST", + var interval: Int = 15, + var url: String = "https://postman-echo.com/post" +) \ No newline at end of file diff --git a/example_app/app/src/main/java/com/mytiki/tiki_sdk_android/example_app/destination/DestinationFragment.kt b/example_app/app/src/main/java/com/mytiki/tiki_sdk_android/example_app/destination/DestinationFragment.kt new file mode 100644 index 0000000..bb60080 --- /dev/null +++ b/example_app/app/src/main/java/com/mytiki/tiki_sdk_android/example_app/destination/DestinationFragment.kt @@ -0,0 +1,92 @@ +package com.mytiki.tiki_sdk_android.example_app.destination + +import android.os.Bundle +import android.text.Editable +import android.text.TextWatcher +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.AdapterView +import android.widget.ArrayAdapter +import android.widget.Spinner +import androidx.fragment.app.Fragment +import androidx.fragment.app.activityViewModels +import com.mytiki.tiki_sdk_android.example_app.R +import com.mytiki.tiki_sdk_android.example_app.databinding.DestinationFragmentBinding +import com.mytiki.tiki_sdk_android.example_app.try_it_out.TryItOutViewModel +import java.util.* + +class DestinationFragment : Fragment() { + + private val viewModel by activityViewModels() + + private var _binding: DestinationFragmentBinding? = null + private val binding get() = _binding!! + + private var timer: Timer? = null + + override fun onCreateView( + inflater: LayoutInflater, container: ViewGroup?, + savedInstanceState: Bundle? + ): View { + _binding = DestinationFragmentBinding.inflate(inflater, container, false) + return binding.root + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + initMethodSpinner() + initIntervalSpinner() + binding.url.setText(viewModel.destination.value?.url) + binding.url.addTextChangedListener(object : TextWatcher { + override fun afterTextChanged(s: Editable?) {} + + override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {} + + override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) { + viewModel.destination.value?.url = s.toString() + } + }) + } + + private fun initIntervalSpinner() { + val intervalSpinner: Spinner = binding.interval + val adapter = ArrayAdapter.createFromResource( + requireContext(), + R.array.interval, + android.R.layout.simple_spinner_item + ).also { adapter -> + adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item) + intervalSpinner.adapter = adapter + intervalSpinner.setSelection(adapter.getPosition(viewModel.destination.value?.interval.toString())) + } + intervalSpinner.onItemSelectedListener = object : AdapterView.OnItemSelectedListener { + override fun onItemSelected(p0: AdapterView<*>?, p1: View?, p2: Int, p3: Long) { + viewModel.destination.value?.interval = Integer.valueOf(adapter.getItem(p2).toString()) + } + + override fun onNothingSelected(p0: AdapterView<*>?) {} + } + } + + private fun initMethodSpinner() { + val methodSpinner: Spinner = binding.method + val adapter = ArrayAdapter.createFromResource( + requireContext(), + R.array.http_methods, + android.R.layout.simple_spinner_item + ).also { adapter -> + adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item) + methodSpinner.adapter = adapter + methodSpinner.setSelection(adapter.getPosition(viewModel.destination.value?.httpMethod)) + } + methodSpinner.onItemSelectedListener = object : AdapterView.OnItemSelectedListener { + override fun onItemSelected(p0: AdapterView<*>?, p1: View?, p2: Int, p3: Long) { + viewModel.destination.value?.httpMethod = adapter.getItem(p2).toString() + } + + override fun onNothingSelected(p0: AdapterView<*>?) {} + } + } + +} \ No newline at end of file diff --git a/example_app/app/src/main/java/com/mytiki/tiki_sdk_android/example_app/ownership/OwnershipFragment.kt b/example_app/app/src/main/java/com/mytiki/tiki_sdk_android/example_app/ownership/OwnershipFragment.kt new file mode 100644 index 0000000..719854a --- /dev/null +++ b/example_app/app/src/main/java/com/mytiki/tiki_sdk_android/example_app/ownership/OwnershipFragment.kt @@ -0,0 +1,42 @@ +package com.mytiki.tiki_sdk_android.example_app.ownership + +import android.os.Bundle +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import androidx.fragment.app.Fragment +import androidx.fragment.app.activityViewModels +import com.mytiki.tiki_sdk_android.example_app.databinding.OwnershipFragmentBinding +import com.mytiki.tiki_sdk_android.example_app.try_it_out.TryItOutViewModel +import java.util.* + +class OwnershipFragment : Fragment() { + + private val viewModel by activityViewModels() + + private var _binding: OwnershipFragmentBinding? = null + private val binding get() = _binding!! + + private var timer: Timer? = null + + override fun onCreateView( + inflater: LayoutInflater, container: ViewGroup?, + savedInstanceState: Bundle? + ): View { + _binding = OwnershipFragmentBinding.inflate(inflater, container, false) + return binding.root + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + binding.hash.text = viewModel.ownership!!.transactionId + + binding.source.text = viewModel.ownership!!.source + + binding.contains.text = viewModel.ownership!!.contains.joinToString(", ") + + binding.about.text = viewModel.ownership!!.about + + binding.origin.text = viewModel.ownership!!.origin + } +} \ No newline at end of file diff --git a/example_app/app/src/main/java/com/mytiki/tiki_sdk_android/example_app/try_it_out/TryItOutAdapter.kt b/example_app/app/src/main/java/com/mytiki/tiki_sdk_android/example_app/try_it_out/TryItOutAdapter.kt new file mode 100644 index 0000000..9601342 --- /dev/null +++ b/example_app/app/src/main/java/com/mytiki/tiki_sdk_android/example_app/try_it_out/TryItOutAdapter.kt @@ -0,0 +1,26 @@ +package com.mytiki.tiki_sdk_android.example_app.wallet + +import android.view.LayoutInflater +import android.view.ViewGroup +import androidx.recyclerview.widget.RecyclerView +import com.mytiki.tiki_sdk_android.example_app.databinding.RequestItemBinding +import com.mytiki.tiki_sdk_android.example_app.try_it_out.TryItOutViewModel + +class TryItOutAdapter(private val viewModel: TryItOutViewModel) : + RecyclerView.Adapter() { + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): TryItOutViewHolder { + val binding: RequestItemBinding = RequestItemBinding.inflate( + LayoutInflater.from(parent.context), parent, false + ) + return TryItOutViewHolder(binding) + } + + override fun getItemCount(): Int { + return viewModel.log.value!!.size + } + + override fun onBindViewHolder(holder: TryItOutViewHolder, position: Int) { + holder.bind(viewModel.log.value!![position], holder.itemView.context) + } +} diff --git a/example_app/app/src/main/java/com/mytiki/tiki_sdk_android/example_app/try_it_out/TryItOutFragment.kt b/example_app/app/src/main/java/com/mytiki/tiki_sdk_android/example_app/try_it_out/TryItOutFragment.kt new file mode 100644 index 0000000..943e35a --- /dev/null +++ b/example_app/app/src/main/java/com/mytiki/tiki_sdk_android/example_app/try_it_out/TryItOutFragment.kt @@ -0,0 +1,96 @@ +package com.mytiki.tiki_sdk_android.example_app.try_it_out + +import android.os.Bundle +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import androidx.fragment.app.Fragment +import androidx.fragment.app.activityViewModels +import androidx.navigation.Navigation +import androidx.recyclerview.widget.LinearLayoutManager +import com.mytiki.tiki_sdk_android.example_app.R +import com.mytiki.tiki_sdk_android.example_app.databinding.TryItOutFragmentBinding +import com.mytiki.tiki_sdk_android.example_app.wallet.TryItOutAdapter +import java.util.* +import kotlin.concurrent.schedule + +class TryItOutFragment : Fragment() { + + private val viewModel by activityViewModels() + + private var _binding: TryItOutFragmentBinding? = null + private val binding get() = _binding!! + + private var timer: Timer? = null + + override fun onCreateView( + inflater: LayoutInflater, container: ViewGroup?, + savedInstanceState: Bundle? + ): View { + _binding = TryItOutFragmentBinding.inflate(inflater, container, false) + setClickListeners() + return binding.root + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + val adapter = TryItOutAdapter(viewModel) + binding.requestsView.adapter = adapter + binding.requestsView.layoutManager = LinearLayoutManager(requireContext()) + viewModel.log.observe(viewLifecycleOwner) { + adapter.notifyItemInserted(it.size - 1) + } + } + + private fun setClickListeners() { + binding.walletCard.setOnClickListener { + Navigation.findNavController(binding.root) + .navigate(R.id.action_try_it_out_to_walletListFragment) + } + binding.toggleConsent.setOnClickListener { + viewModel.toggleConsent() + } + binding.ownershipCard.setOnClickListener { + Navigation.findNavController(binding.root) + .navigate(R.id.action_try_it_out_to_ownershipFragment) + } + binding.consenCard.setOnClickListener { + Navigation.findNavController(binding.root) + .navigate(R.id.action_try_it_out_to_consentFragment) + } + binding.destinationCard.setOnClickListener { + Navigation.findNavController(binding.root) + .navigate(R.id.action_try_it_out_to_destinationFragment) + } + binding.bodyCard.setOnClickListener { + Navigation.findNavController(binding.root) + .navigate(R.id.action_try_it_out_to_bodyFragment) + } + } + + override fun onResume() { + super.onResume() + val stream = viewModel.destination.value!! + binding.destinationTitle.text = stream.httpMethod + " " + stream.url + binding.bodyTitle.text = stream.body + if (viewModel.selectedWalletAddress.value != null) { + binding.walletAddress.text = viewModel.selectedWalletAddress.value + binding.ownershipAndConsent.visibility = View.VISIBLE + binding.ownershipId.text = viewModel.ownership!!.transactionId + binding.consentId.text = viewModel.consent?.transactionId + binding.toggleConsent.isChecked = viewModel.isConsentGiven.value == true + timer = Timer() + timer!!.schedule( + delay = 0L, + period = stream.interval * 1000L + ) { + viewModel.makeRequest() + } + } + } + + override fun onPause() { + super.onPause() + timer?.cancel() + } +} \ No newline at end of file diff --git a/example_app/app/src/main/java/com/mytiki/tiki_sdk_android/example_app/try_it_out/TryItOutReq.kt b/example_app/app/src/main/java/com/mytiki/tiki_sdk_android/example_app/try_it_out/TryItOutReq.kt new file mode 100644 index 0000000..fdff224 --- /dev/null +++ b/example_app/app/src/main/java/com/mytiki/tiki_sdk_android/example_app/try_it_out/TryItOutReq.kt @@ -0,0 +1,10 @@ +package com.mytiki.tiki_sdk_android.example_app.try_it_out + +import java.text.DateFormat +import java.text.DateFormat.getTimeInstance +import java.util.* + +data class TryItOutReq(val icon: String, val message: String) { + private val dateFormat: DateFormat = getTimeInstance() + val timestamp: String = dateFormat.format(Date()) +} \ No newline at end of file diff --git a/example_app/app/src/main/java/com/mytiki/tiki_sdk_android/example_app/try_it_out/TryItOutViewHolder.kt b/example_app/app/src/main/java/com/mytiki/tiki_sdk_android/example_app/try_it_out/TryItOutViewHolder.kt new file mode 100644 index 0000000..d7949dc --- /dev/null +++ b/example_app/app/src/main/java/com/mytiki/tiki_sdk_android/example_app/try_it_out/TryItOutViewHolder.kt @@ -0,0 +1,23 @@ +package com.mytiki.tiki_sdk_android.example_app.wallet + +import android.content.Context +import android.widget.TextView +import androidx.appcompat.app.AlertDialog +import androidx.recyclerview.widget.RecyclerView +import com.mytiki.tiki_sdk_android.example_app.R +import com.mytiki.tiki_sdk_android.example_app.databinding.RequestItemBinding +import com.mytiki.tiki_sdk_android.example_app.try_it_out.TryItOutReq + +class TryItOutViewHolder(private val binding: RequestItemBinding?) : + RecyclerView.ViewHolder(binding!!.root) { + fun bind(req: TryItOutReq, context: Context) { + itemView.findViewById(R.id.req).text = req.icon + " " + req.message + itemView.findViewById(R.id.timestamp).text = req.timestamp + itemView.setOnClickListener { + val builder = AlertDialog.Builder(context) + builder.setTitle("Response Body") + builder.setMessage(req.message) + builder.show() + } + } +} \ No newline at end of file diff --git a/example_app/app/src/main/java/com/mytiki/tiki_sdk_android/example_app/try_it_out/TryItOutViewModel.kt b/example_app/app/src/main/java/com/mytiki/tiki_sdk_android/example_app/try_it_out/TryItOutViewModel.kt new file mode 100644 index 0000000..0d0320f --- /dev/null +++ b/example_app/app/src/main/java/com/mytiki/tiki_sdk_android/example_app/try_it_out/TryItOutViewModel.kt @@ -0,0 +1,207 @@ +package com.mytiki.tiki_sdk_android.example_app.try_it_out + +import android.content.Context +import androidx.lifecycle.LiveData +import androidx.lifecycle.MutableLiveData +import androidx.lifecycle.ViewModel +import androidx.lifecycle.viewModelScope +import com.mytiki.tiki_sdk_android.* +import com.mytiki.tiki_sdk_android.example_app.destination.Destination +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.launch +import java.io.BufferedReader +import java.io.DataOutputStream +import java.io.InputStreamReader +import java.net.HttpURLConnection +import java.net.URL +import java.util.* + +class TryItOutViewModel : ViewModel() { + + private var _wallets: MutableLiveData> = + MutableLiveData(mutableMapOf()) + val wallets: LiveData> + get() = _wallets + + private var _ownerships: MutableLiveData> = + MutableLiveData(mutableMapOf()) + val ownerships: LiveData> + get() = _ownerships + + private var _consents: MutableLiveData> = + MutableLiveData(mutableMapOf()) + val consents: LiveData> + get() = _consents + + private var _destination: MutableLiveData = + MutableLiveData(Destination(UUID.randomUUID().toString())) + val destination: LiveData = _destination + + private var _isConsentGiven: MutableLiveData = MutableLiveData(false) + val isConsentGiven: LiveData = _isConsentGiven + + private var _selectedWalletAddress: MutableLiveData = MutableLiveData() + val selectedWalletAddress: LiveData = _selectedWalletAddress + + private var _log: MutableLiveData> = MutableLiveData(mutableListOf()) + val log: LiveData> + get() = _log + + val tikiSdk: TikiSdk? + get() = wallets.value?.get(selectedWalletAddress.value) + + val ownership: TikiSdkOwnership? + get() = ownerships.value?.get(selectedWalletAddress.value) + + val consent: TikiSdkConsent? + get() = consents.value?.get(ownership?.transactionId) + + private val _isLoading: MutableLiveData = MutableLiveData(false) + val isLoading: LiveData = _isLoading + + fun loadTikiSdk(context: Context, address: String? = null) { + if (address != null && wallets.value?.containsKey(address) == true) { + _selectedWalletAddress.postValue(address) + } else { + viewModelScope.launch { + val apiId = "2b8de004-cbe0-4bd5-bda6-b266d54f5c90" + val origin = "com.mytiki.tiki_sdk_android.test" + val tikiSdk = TikiSdk().init(apiId, origin, context, address).await() + _wallets.value!!.put(tikiSdk.address, tikiSdk).apply { + _wallets.postValue(_wallets.value) + } + _selectedWalletAddress.postValue(tikiSdk.address) + tikiSdk.assignOwnership( + destination.value!!.source, + TikiSdkDataTypeEnum.data_stream, + listOf("generic data"), + "Data destination created with TIKI SDK Sample App" + ) + val ownership = tikiSdk.getOwnership(destination.value!!.source) + _ownerships.value!!.toMutableMap().apply { + this.put(tikiSdk.address, ownership!!) + _ownerships.postValue(this) + } + val path: String = URL(destination.value?.url).host!! + val use: String = destination.value!!.httpMethod + val destination = TikiSdkDestination(listOf(path), listOf(use)) + val expiry: Calendar = Calendar.getInstance().apply { + this.add(Calendar.YEAR, 10) + } + val consent: TikiSdkConsent = tikiSdk.modifyConsent( + ownership!!.transactionId, + destination, + "Consent given to echo data in remote server", + "Test the SDK", + expiry.time + ) + _consents.value!!.toMutableMap().apply { + this.put(ownership.transactionId, consent) + _consents.postValue(this) + } + _isConsentGiven.value = true + _isLoading.value = false + } + } + } + + fun toggleConsent() { + val path: String = URL(destination.value!!.url).host + val use: String = destination.value!!.httpMethod + val destination = if (isConsentGiven.value!!) { + TikiSdkDestination.NONE + } else { + TikiSdkDestination(listOf(path), listOf(use)) + } + viewModelScope.launch { + val consent: TikiSdkConsent = tikiSdk!!.modifyConsent( + ownership!!.transactionId, + destination, + "Consent given to echo data in remote server", + "Test the SDK", + Calendar.getInstance().apply { + add(Calendar.YEAR, 10) + }.time + ) + _consents.value!!.toMutableMap().apply { + this.put(consent.ownershipId, consent) + _consents.postValue(this) + } + isConsentGiven.value.apply { + _isConsentGiven.postValue(!isConsentGiven.value!!) + } + } + } + + fun makeRequest() { + var logToAppend: TryItOutReq? = null + if (tikiSdk == null) { + logToAppend = TryItOutReq("🔴", "ERROR: Create a Wallet") + _log.value!!.toMutableList().apply { + this.add(logToAppend!!) + _log.postValue(this) + } + } else { + viewModelScope.launch { + try { + val url = URL(destination.value!!.url) + val path: String = url.host + val use: String = destination.value!!.httpMethod + val destination = TikiSdkDestination(listOf(path), listOf(use)) + tikiSdk!!.applyConsent(this@TryItOutViewModel.destination.value!!.source, destination, { + viewModelScope.launch(Dispatchers.IO) { + val con = url.openConnection() as HttpURLConnection + con.requestMethod = use + val postData = this@TryItOutViewModel.destination.value!!.body.toByteArray() + con.doOutput = true + val wr = DataOutputStream(con.outputStream) + wr.write(postData) + wr.flush() + wr.close() + val responseCode = con.responseCode + val income = BufferedReader(InputStreamReader(con.inputStream)) + val response = StringBuilder() + var inputLine = income.readLine() + while (inputLine != null) { + response.append(inputLine) + inputLine = income.readLine() + } + income.close() + if (responseCode in 200..299) { + logToAppend = TryItOutReq( + "🟢", + "${responseCode}: $response" + ) + _log.value!!.toMutableList().apply { + this.add(logToAppend!!) + _log.postValue(this) + } + } else { + logToAppend = TryItOutReq( + "🔴", + "${responseCode}: $response" + ) + _log.value!!.toMutableList().apply { + this.add(logToAppend!!) + _log.postValue(this) + } + } + } + }, { + logToAppend = TryItOutReq("🔴", "Blocked: consent required") + _log.value!!.toMutableList().apply { + this.add(logToAppend!!) + _log.postValue(this) + } + }) + } catch (e: Exception) { + logToAppend = TryItOutReq("🔴", e.message.toString()) + _log.value!!.toMutableList().apply { + this.add(logToAppend!!) + _log.postValue(this) + } + } + } + } + } +} \ No newline at end of file diff --git a/example_app/app/src/main/java/com/mytiki/tiki_sdk_android/example_app/wallet/WalletListAdapter.kt b/example_app/app/src/main/java/com/mytiki/tiki_sdk_android/example_app/wallet/WalletListAdapter.kt new file mode 100644 index 0000000..36e789c --- /dev/null +++ b/example_app/app/src/main/java/com/mytiki/tiki_sdk_android/example_app/wallet/WalletListAdapter.kt @@ -0,0 +1,28 @@ +package com.mytiki.tiki_sdk_android.example_app.wallet + +import android.view.LayoutInflater +import android.view.ViewGroup +import androidx.recyclerview.widget.RecyclerView +import com.mytiki.tiki_sdk_android.example_app.databinding.WalletItemBinding +import com.mytiki.tiki_sdk_android.example_app.try_it_out.TryItOutViewModel + +class WalletListAdapter(private val viewModel: TryItOutViewModel) : + RecyclerView.Adapter() { + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): WalletListViewHolder { + val binding: WalletItemBinding = WalletItemBinding.inflate( + LayoutInflater.from(parent.context), parent, false + ) + return WalletListViewHolder(binding, viewModel) + } + + override fun getItemCount(): Int { + val size = viewModel.wallets.value!!.size + return size + } + + override fun onBindViewHolder(holder: WalletListViewHolder, position: Int) { + val address = viewModel.wallets.value?.keys?.toList()?.get(position) + holder.bind(address!!) + } +} diff --git a/example_app/app/src/main/java/com/mytiki/tiki_sdk_android/example_app/wallet/WalletListFragment.kt b/example_app/app/src/main/java/com/mytiki/tiki_sdk_android/example_app/wallet/WalletListFragment.kt new file mode 100644 index 0000000..0ff962d --- /dev/null +++ b/example_app/app/src/main/java/com/mytiki/tiki_sdk_android/example_app/wallet/WalletListFragment.kt @@ -0,0 +1,47 @@ +package com.mytiki.tiki_sdk_android.example_app.wallet + +import android.annotation.SuppressLint +import android.os.Bundle +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import androidx.fragment.app.Fragment +import androidx.fragment.app.activityViewModels +import androidx.lifecycle.Observer +import androidx.recyclerview.widget.LinearLayoutManager +import com.mytiki.tiki_sdk_android.example_app.databinding.WalletFragmentBinding +import com.mytiki.tiki_sdk_android.example_app.try_it_out.TryItOutViewModel + +class WalletListFragment : Fragment() { + private val viewModel by activityViewModels() + + private var _binding: WalletFragmentBinding? = null + private val binding get() = _binding!! + + override fun onCreateView( + inflater: LayoutInflater, container: ViewGroup?, + savedInstanceState: Bundle? + ): View { + _binding = WalletFragmentBinding.inflate(inflater, container, false) + return binding.root + } + + @SuppressLint("NotifyDataSetChanged") + override fun onViewCreated(itemView: View, savedInstanceState: Bundle?) { + super.onViewCreated(itemView, savedInstanceState) + val adapter = WalletListAdapter(viewModel) + binding.recyclerView.adapter = adapter + binding.recyclerView.layoutManager = LinearLayoutManager(requireContext()) + viewModel.wallets.observe(viewLifecycleOwner, Observer { + binding.recyclerView.adapter = adapter + }) + viewModel.isLoading.observe(viewLifecycleOwner, Observer { + binding.button.isEnabled = !it + }) + binding.button.setOnClickListener { + viewModel.loadTikiSdk(requireContext()) + } + } +} + + diff --git a/example_app/app/src/main/java/com/mytiki/tiki_sdk_android/example_app/wallet/WalletListViewHolder.kt b/example_app/app/src/main/java/com/mytiki/tiki_sdk_android/example_app/wallet/WalletListViewHolder.kt new file mode 100644 index 0000000..13f74f7 --- /dev/null +++ b/example_app/app/src/main/java/com/mytiki/tiki_sdk_android/example_app/wallet/WalletListViewHolder.kt @@ -0,0 +1,24 @@ +package com.mytiki.tiki_sdk_android.example_app.wallet + +import android.graphics.Typeface +import android.view.View +import androidx.navigation.Navigation +import androidx.recyclerview.widget.RecyclerView +import com.mytiki.tiki_sdk_android.example_app.databinding.WalletItemBinding +import com.mytiki.tiki_sdk_android.example_app.try_it_out.TryItOutViewModel + +class WalletListViewHolder( + private val binding: WalletItemBinding?, + private val viewModel: TryItOutViewModel +) : RecyclerView.ViewHolder(binding!!.root) { + fun bind(tikiSdkAddress: String) { + binding!!.addressTextView.text = tikiSdkAddress + if(tikiSdkAddress == viewModel.selectedWalletAddress.value){ + binding.addressTextView.setTypeface(null, Typeface.BOLD); + } + itemView.setOnClickListener { + viewModel.loadTikiSdk(itemView.context, tikiSdkAddress) + Navigation.findNavController(itemView).popBackStack() + } + } +} \ No newline at end of file diff --git a/example_app/app/src/main/res/drawable-v24/ic_launcher_foreground.xml b/example_app/app/src/main/res/drawable-v24/ic_launcher_foreground.xml new file mode 100644 index 0000000..2b068d1 --- /dev/null +++ b/example_app/app/src/main/res/drawable-v24/ic_launcher_foreground.xml @@ -0,0 +1,30 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/example_app/app/src/main/res/drawable/arrow_back.xml b/example_app/app/src/main/res/drawable/arrow_back.xml new file mode 100644 index 0000000..0629b0e --- /dev/null +++ b/example_app/app/src/main/res/drawable/arrow_back.xml @@ -0,0 +1,5 @@ + + + diff --git a/example_app/app/src/main/res/drawable/arrow_forward.xml b/example_app/app/src/main/res/drawable/arrow_forward.xml new file mode 100644 index 0000000..18d16ca --- /dev/null +++ b/example_app/app/src/main/res/drawable/arrow_forward.xml @@ -0,0 +1,10 @@ + + + diff --git a/example_app/app/src/main/res/drawable/ic_launcher_background.xml b/example_app/app/src/main/res/drawable/ic_launcher_background.xml new file mode 100644 index 0000000..07d5da9 --- /dev/null +++ b/example_app/app/src/main/res/drawable/ic_launcher_background.xml @@ -0,0 +1,170 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/example_app/app/src/main/res/layout/body_fragment.xml b/example_app/app/src/main/res/layout/body_fragment.xml new file mode 100644 index 0000000..1f0cde4 --- /dev/null +++ b/example_app/app/src/main/res/layout/body_fragment.xml @@ -0,0 +1,44 @@ + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/example_app/app/src/main/res/layout/consent_fragment.xml b/example_app/app/src/main/res/layout/consent_fragment.xml new file mode 100644 index 0000000..1008910 --- /dev/null +++ b/example_app/app/src/main/res/layout/consent_fragment.xml @@ -0,0 +1,141 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/example_app/app/src/main/res/layout/destination_fragment.xml b/example_app/app/src/main/res/layout/destination_fragment.xml new file mode 100644 index 0000000..d9edc10 --- /dev/null +++ b/example_app/app/src/main/res/layout/destination_fragment.xml @@ -0,0 +1,118 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/example_app/app/src/main/res/layout/main_activity.xml b/example_app/app/src/main/res/layout/main_activity.xml new file mode 100644 index 0000000..ff667f9 --- /dev/null +++ b/example_app/app/src/main/res/layout/main_activity.xml @@ -0,0 +1,10 @@ + + + + + + \ No newline at end of file diff --git a/example_app/app/src/main/res/layout/main_content.xml b/example_app/app/src/main/res/layout/main_content.xml new file mode 100644 index 0000000..e1b25df --- /dev/null +++ b/example_app/app/src/main/res/layout/main_content.xml @@ -0,0 +1,20 @@ + + + + + + \ No newline at end of file diff --git a/example_app/app/src/main/res/layout/ownership_fragment.xml b/example_app/app/src/main/res/layout/ownership_fragment.xml new file mode 100644 index 0000000..1031cf1 --- /dev/null +++ b/example_app/app/src/main/res/layout/ownership_fragment.xml @@ -0,0 +1,136 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/example_app/app/src/main/res/layout/request_item.xml b/example_app/app/src/main/res/layout/request_item.xml new file mode 100644 index 0000000..1624d78 --- /dev/null +++ b/example_app/app/src/main/res/layout/request_item.xml @@ -0,0 +1,23 @@ + + + + + + + + diff --git a/example_app/app/src/main/res/layout/try_it_out_fragment.xml b/example_app/app/src/main/res/layout/try_it_out_fragment.xml new file mode 100644 index 0000000..6db605d --- /dev/null +++ b/example_app/app/src/main/res/layout/try_it_out_fragment.xml @@ -0,0 +1,230 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/example_app/app/src/main/res/layout/wallet_fragment.xml b/example_app/app/src/main/res/layout/wallet_fragment.xml new file mode 100644 index 0000000..5958dfd --- /dev/null +++ b/example_app/app/src/main/res/layout/wallet_fragment.xml @@ -0,0 +1,52 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/example_app/app/src/main/res/layout/wallet_item.xml b/example_app/app/src/main/res/layout/wallet_item.xml new file mode 100644 index 0000000..0627385 --- /dev/null +++ b/example_app/app/src/main/res/layout/wallet_item.xml @@ -0,0 +1,19 @@ + + + + + + \ No newline at end of file diff --git a/example_app/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml b/example_app/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml new file mode 100644 index 0000000..eca70cf --- /dev/null +++ b/example_app/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/example_app/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml b/example_app/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml new file mode 100644 index 0000000..eca70cf --- /dev/null +++ b/example_app/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/example_app/app/src/main/res/mipmap-hdpi/ic_launcher.webp b/example_app/app/src/main/res/mipmap-hdpi/ic_launcher.webp new file mode 100644 index 0000000..c209e78 Binary files /dev/null and b/example_app/app/src/main/res/mipmap-hdpi/ic_launcher.webp differ diff --git a/example_app/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp b/example_app/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp new file mode 100644 index 0000000..b2dfe3d Binary files /dev/null and b/example_app/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp differ diff --git a/example_app/app/src/main/res/mipmap-mdpi/ic_launcher.webp b/example_app/app/src/main/res/mipmap-mdpi/ic_launcher.webp new file mode 100644 index 0000000..4f0f1d6 Binary files /dev/null and b/example_app/app/src/main/res/mipmap-mdpi/ic_launcher.webp differ diff --git a/example_app/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp b/example_app/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp new file mode 100644 index 0000000..62b611d Binary files /dev/null and b/example_app/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp differ diff --git a/example_app/app/src/main/res/mipmap-xhdpi/ic_launcher.webp b/example_app/app/src/main/res/mipmap-xhdpi/ic_launcher.webp new file mode 100644 index 0000000..948a307 Binary files /dev/null and b/example_app/app/src/main/res/mipmap-xhdpi/ic_launcher.webp differ diff --git a/example_app/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp b/example_app/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp new file mode 100644 index 0000000..1b9a695 Binary files /dev/null and b/example_app/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp differ diff --git a/example_app/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp b/example_app/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp new file mode 100644 index 0000000..28d4b77 Binary files /dev/null and b/example_app/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp differ diff --git a/example_app/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp b/example_app/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp new file mode 100644 index 0000000..9287f50 Binary files /dev/null and b/example_app/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp differ diff --git a/example_app/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp b/example_app/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp new file mode 100644 index 0000000..aa7d642 Binary files /dev/null and b/example_app/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp differ diff --git a/example_app/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp b/example_app/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp new file mode 100644 index 0000000..9126ae3 Binary files /dev/null and b/example_app/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp differ diff --git a/example_app/app/src/main/res/navigation/nav_graph.xml b/example_app/app/src/main/res/navigation/nav_graph.xml new file mode 100644 index 0000000..2bb8d75 --- /dev/null +++ b/example_app/app/src/main/res/navigation/nav_graph.xml @@ -0,0 +1,54 @@ + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/example_app/app/src/main/res/values-land/dimens.xml b/example_app/app/src/main/res/values-land/dimens.xml new file mode 100644 index 0000000..22d7f00 --- /dev/null +++ b/example_app/app/src/main/res/values-land/dimens.xml @@ -0,0 +1,3 @@ + + 48dp + \ No newline at end of file diff --git a/example_app/app/src/main/res/values-night/themes.xml b/example_app/app/src/main/res/values-night/themes.xml new file mode 100644 index 0000000..8d2b58c --- /dev/null +++ b/example_app/app/src/main/res/values-night/themes.xml @@ -0,0 +1,16 @@ + + + + \ No newline at end of file diff --git a/example_app/app/src/main/res/values-w1240dp/dimens.xml b/example_app/app/src/main/res/values-w1240dp/dimens.xml new file mode 100644 index 0000000..d73f4a3 --- /dev/null +++ b/example_app/app/src/main/res/values-w1240dp/dimens.xml @@ -0,0 +1,3 @@ + + 200dp + \ No newline at end of file diff --git a/example_app/app/src/main/res/values-w600dp/dimens.xml b/example_app/app/src/main/res/values-w600dp/dimens.xml new file mode 100644 index 0000000..22d7f00 --- /dev/null +++ b/example_app/app/src/main/res/values-w600dp/dimens.xml @@ -0,0 +1,3 @@ + + 48dp + \ No newline at end of file diff --git a/example_app/app/src/main/res/values/colors.xml b/example_app/app/src/main/res/values/colors.xml new file mode 100644 index 0000000..f8c6127 --- /dev/null +++ b/example_app/app/src/main/res/values/colors.xml @@ -0,0 +1,10 @@ + + + #FFBB86FC + #FF6200EE + #FF3700B3 + #FF03DAC5 + #FF018786 + #FF000000 + #FFFFFFFF + \ No newline at end of file diff --git a/example_app/app/src/main/res/values/dimens.xml b/example_app/app/src/main/res/values/dimens.xml new file mode 100644 index 0000000..125df87 --- /dev/null +++ b/example_app/app/src/main/res/values/dimens.xml @@ -0,0 +1,3 @@ + + 16dp + \ No newline at end of file diff --git a/example_app/app/src/main/res/values/strings.xml b/example_app/app/src/main/res/values/strings.xml new file mode 100644 index 0000000..7fc1281 --- /dev/null +++ b/example_app/app/src/main/res/values/strings.xml @@ -0,0 +1,14 @@ + + ExampleApp + ExampleApp + + POST + GET + + + 1 + 15 + 30 + 60 + + \ No newline at end of file diff --git a/example_app/app/src/main/res/values/themes.xml b/example_app/app/src/main/res/values/themes.xml new file mode 100644 index 0000000..bc6fd4e --- /dev/null +++ b/example_app/app/src/main/res/values/themes.xml @@ -0,0 +1,25 @@ + + + + + + +