-
Notifications
You must be signed in to change notification settings - Fork 12
Commit
* Kotlin SDK Android Example was added * Readme file was added * Update Readme.md * Update Readme.md * Unnecessary file was removed
- Loading branch information
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
# Kotlin SDK Android Example | ||
|
||
This is an Android app that uses Kotlin GrowthBook SDK | ||
|
||
# Overview | ||
|
||
If you have no Android Studio to build the application you can watch the app flow in [recorded video on YouTube Shorts](https://youtube.com/shorts/j1roM81QWc4?feature=share). | ||
|
||
|
||
![](./screenshots/Screenshot.png) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
/build |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
plugins { | ||
id 'com.android.application' | ||
id 'org.jetbrains.kotlin.android' | ||
id 'org.jetbrains.kotlin.plugin.serialization' | ||
} | ||
|
||
android { | ||
namespace 'com.example.growthbookdemoapp' | ||
compileSdk 34 | ||
|
||
defaultConfig { | ||
applicationId "com.example.growthbookdemoapp" | ||
minSdk 26 | ||
targetSdk 34 | ||
versionCode 1 | ||
versionName "1.0" | ||
|
||
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" | ||
|
||
} | ||
|
||
buildTypes { | ||
|
||
release { | ||
minifyEnabled true | ||
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' | ||
signingConfig signingConfigs.debug | ||
} | ||
debug { | ||
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' | ||
} | ||
} | ||
|
||
|
||
dependencies { | ||
implementation 'androidx.core:core-ktx:1.10.1' | ||
implementation 'androidx.appcompat:appcompat:1.6.1' | ||
implementation 'com.google.android.material:material:1.6.0' | ||
testImplementation 'junit:junit:4.13.2' | ||
androidTestImplementation 'androidx.test.ext:junit:1.1.5' | ||
androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1' | ||
|
||
String ktorVersion = '2.1.1' | ||
implementation("io.ktor:ktor-client-core:$ktorVersion") | ||
|
||
implementation 'io.growthbook.sdk:GrowthBook:1.1.36' | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
# 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 | ||
|
||
#-dontobfuscate | ||
|
||
-keep class kotlinx.serialization.json.** { *; } | ||
|
||
#-keep class ** { *; } | ||
|
||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
<?xml version="1.0" encoding="utf-8"?> | ||
<manifest xmlns:android="http://schemas.android.com/apk/res/android" | ||
xmlns:tools="http://schemas.android.com/tools"> | ||
|
||
<application | ||
android:allowBackup="true" | ||
android:dataExtractionRules="@xml/data_extraction_rules" | ||
android:fullBackupContent="@xml/backup_rules" | ||
android:icon="@mipmap/ic_launcher" | ||
android:label="@string/app_name" | ||
android:roundIcon="@mipmap/ic_launcher_round" | ||
android:supportsRtl="true" | ||
android:theme="@style/Theme.GrowthBookDemoApp" | ||
tools:targetApi="31" > | ||
|
||
<activity | ||
android:name="com.example.growthbookdemoapp.MainActivity" | ||
android:exported="true"> | ||
|
||
<intent-filter> | ||
<action android:name="android.intent.action.MAIN"/> | ||
<category android:name="android.intent.category.LAUNCHER"/> | ||
</intent-filter> | ||
</activity> | ||
</application> | ||
</manifest> |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
package com.example.growthbookdemoapp | ||
|
||
import android.os.Bundle | ||
import android.widget.Button | ||
import android.widget.TextView | ||
import androidx.appcompat.app.AppCompatActivity | ||
import com.sdk.growthbook.GBSDKBuilder | ||
import com.sdk.growthbook.GrowthBookSDK | ||
import com.sdk.growthbook.SDKBuilder | ||
import kotlinx.coroutines.DelicateCoroutinesApi | ||
|
||
class MainActivity: AppCompatActivity() { | ||
|
||
private var growthBookSDK: GrowthBookSDK? = null | ||
|
||
override fun onCreate(savedInstanceState: Bundle?) { | ||
super.onCreate(savedInstanceState) | ||
setContentView(R.layout.layout) | ||
|
||
findViewById<Button>(R.id.btn_initialize).setOnClickListener { | ||
onInitializeBtnClick() | ||
} | ||
|
||
findViewById<Button>(R.id.button).isEnabled = false | ||
findViewById<Button>(R.id.button).setOnClickListener { | ||
onBtnClick() | ||
} | ||
} | ||
|
||
@OptIn(DelicateCoroutinesApi::class) | ||
private fun onInitializeBtnClick() { | ||
// User attributes for targeting and assigning users to experiment variations | ||
val attrs = HashMap<String, Any>() | ||
attrs["appBuildNumber"] = 3432 | ||
|
||
val sdkBuilder: SDKBuilder = GBSDKBuilder( | ||
// Fetch and cache feature definitions from GrowthBook API | ||
// If self-hosting, we recommend using a CDN in production | ||
apiKey = "sdk-3e06aog6O1Mp6Ir", | ||
hostURL = "https://cdn.growthbook.io/", | ||
attributes = attrs, | ||
trackingCallback = { gbExperiment, gbExperimentResult -> | ||
// TODO: track in your analytics system | ||
print("Viewed Experiment") | ||
print("Experiment Id: " + gbExperiment.key) | ||
print("Variation Id: " + gbExperimentResult.variationId) | ||
}, | ||
// Provide the encryption key of type String if you intend to use data encryption, | ||
// otherwise you can pass null | ||
encryptionKey = null | ||
) | ||
|
||
growthBookSDK = sdkBuilder.initialize() | ||
findViewById<TextView>(R.id.textView).text = getString(R.string.check_if_feature_enabled) | ||
findViewById<Button>(R.id.button).isEnabled = true | ||
} | ||
|
||
private fun onBtnClick() { | ||
val gb = growthBookSDK | ||
val theText = when { | ||
gb == null -> "sdk is null" | ||
gb.feature("user576-feature").on -> "Feature is ON!" | ||
else -> "Feature is OFF" | ||
} | ||
|
||
findViewById<TextView>(R.id.textView).text = theText | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
<vector xmlns:android="http://schemas.android.com/apk/res/android" | ||
xmlns:aapt="http://schemas.android.com/aapt" | ||
android:width="108dp" | ||
android:height="108dp" | ||
android:viewportWidth="108" | ||
android:viewportHeight="108"> | ||
<path android:pathData="M31,63.928c0,0 6.4,-11 12.1,-13.1c7.2,-2.6 26,-1.4 26,-1.4l38.1,38.1L107,108.928l-32,-1L31,63.928z"> | ||
<aapt:attr name="android:fillColor"> | ||
<gradient | ||
android:endX="85.84757" | ||
android:endY="92.4963" | ||
android:startX="42.9492" | ||
android:startY="49.59793" | ||
android:type="linear"> | ||
<item | ||
android:color="#44000000" | ||
android:offset="0.0" /> | ||
<item | ||
android:color="#00000000" | ||
android:offset="1.0" /> | ||
</gradient> | ||
</aapt:attr> | ||
</path> | ||
<path | ||
android:fillColor="#FFFFFF" | ||
android:fillType="nonZero" | ||
android:pathData="M65.3,45.828l3.8,-6.6c0.2,-0.4 0.1,-0.9 -0.3,-1.1c-0.4,-0.2 -0.9,-0.1 -1.1,0.3l-3.9,6.7c-6.3,-2.8 -13.4,-2.8 -19.7,0l-3.9,-6.7c-0.2,-0.4 -0.7,-0.5 -1.1,-0.3C38.8,38.328 38.7,38.828 38.9,39.228l3.8,6.6C36.2,49.428 31.7,56.028 31,63.928h46C76.3,56.028 71.8,49.428 65.3,45.828zM43.4,57.328c-0.8,0 -1.5,-0.5 -1.8,-1.2c-0.3,-0.7 -0.1,-1.5 0.4,-2.1c0.5,-0.5 1.4,-0.7 2.1,-0.4c0.7,0.3 1.2,1 1.2,1.8C45.3,56.528 44.5,57.328 43.4,57.328L43.4,57.328zM64.6,57.328c-0.8,0 -1.5,-0.5 -1.8,-1.2s-0.1,-1.5 0.4,-2.1c0.5,-0.5 1.4,-0.7 2.1,-0.4c0.7,0.3 1.2,1 1.2,1.8C66.5,56.528 65.6,57.328 64.6,57.328L64.6,57.328z" | ||
android:strokeWidth="1" | ||
android:strokeColor="#00000000" /> | ||
</vector> |