Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 43 additions & 15 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,39 +62,67 @@ Then add the library to your dependencies. (Note: The + means it always uses the
dependencies {
implementation 'io.snabble.sdk:core:+'
implementation 'io.snabble.sdk:ui:+'
implementation 'io.snabble.sdk:ui-integration:+'
}
```

## Usage

You can initialize the SDK by specifying metadata in the AndroidManifest.xml

```
<meta-data
android:name="snabble_app_id"
android:value="YOUR_APP_ID" />

<meta-data
android:name="snabble_secret"
android:value="YOUR_SECRET" />
```

You also can initialize the SDK programmatically by specifying in the AndroidManifest.xml:

```
<meta-data
android:name="snabble_auto_initialization_disabled"
android:value="true" />
```

And then initialize the SDK via code.

```kotlin
val config = Config(
appId = YOUR_APP_ID,
secret = YOUR_SECRET,
)
Snabble.setup(application, config)
```

// you may enable debug logging
Snabble.setDebugLoggingEnabled(BuildConfig.DEBUG)

Snabble.setup(application, config, object : Snabble.SetupCompletionListener {
override fun onReady() {
// an application can have multiple projects, for example for
// multiple independent regions / countries
val project = Snabble.projects.first()
To observe the current initialization state of the SDK use:

// check in to the first shop - you can use CheckInManager if you want
// to use geofencing
Snabble.checkedInShop = project.shops.first()
```kotlin
Snabble.initializationState.observe(this) {
when(it) {
InitializationState.INITIALIZING -> {}
InitializationState.INITIALIZED -> {
val projects = Snabble.projects // access to projects
}
InitializationState.ERROR -> {
// error detailing why the initialization failed
val error = Snabble.error
// you can call setup again without arguments to retry the initialization
// e.g. on network failure
Snabble.setup()
}
}
})
}
```

## Light mode themes

If using a theme that is explicitly only light mode (and not a DayNight theme) you need to set

```
AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO);
```kotlin
AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO)
```

or else some resources may get grabbed from the "-night" folders when the device is set to night mode
Expand Down
11 changes: 11 additions & 0 deletions core/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -1,12 +1,23 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="io.snabble.sdk">
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.INTERNET" />

<application>
<activity android:name=".googlepay.GooglePayHelperActivity"
android:theme="@style/Snabble.Theme.GooglePayOverlay"/>

<provider
android:name="androidx.startup.InitializationProvider"
android:authorities="${applicationId}.androidx-startup"
android:exported="false"
tools:node="merge">

<meta-data android:name="io.snabble.sdk.SnabbleInitializer"
android:value="androidx.startup" />
</provider>
</application>

<queries>
Expand Down
70 changes: 69 additions & 1 deletion core/src/main/java/io/snabble/sdk/Config.kt
Original file line number Diff line number Diff line change
@@ -1,6 +1,14 @@
package io.snabble.sdk

import android.content.Context
import com.google.gson.*
import io.snabble.sdk.utils.Dispatch
import io.snabble.sdk.utils.GsonHolder
import io.snabble.sdk.utils.Logger
import okhttp3.Interceptor
import java.io.File
import java.lang.Exception
import java.lang.reflect.Type
import java.util.concurrent.TimeUnit

data class Config (
Expand Down Expand Up @@ -135,4 +143,64 @@ data class Config (
*/
@JvmField
var manualProductDatabaseUpdates: Boolean = false,
)
) {
fun save(context: Context) {
val file = File(context.filesDir, "snabble/${fileName}/")
val json = gson.toJson(this)
Dispatch.io {
try {
file.writeText(json)
} catch (e: Throwable) {
Logger.e("Failed to save config to ${file.path}: ${e.message}")
}
}
}

companion object {
const val fileName = "config.json"

private val gson = GsonHolder.get()
.newBuilder()
.registerTypeAdapter(Interceptor::class.java, InterceptorSerializer)
.create()

fun restore(context: Context): Config? {
val file = File(context.filesDir, "snabble/${fileName}/")
return try {
val text = file.readText()
val config = gson.fromJson(text, Config::class.java)
config
} catch (e: Throwable) {
Logger.e("Failed to load config to ${file.path}: ${e.message}")
null
}
}
}
}

object InterceptorSerializer : JsonSerializer<Interceptor?>, JsonDeserializer<Interceptor?> {
override fun serialize(src: Interceptor?,
typeOfSrc: Type?,
context: JsonSerializationContext?
): JsonElement {
val cls = src?.javaClass?.name
return if (cls != null) {
JsonPrimitive(cls)
} else {
JsonNull.INSTANCE
}
}

override fun deserialize(json: JsonElement?,
typeOfT: Type?,
context: JsonDeserializationContext?
): Interceptor? {
val cls = json?.asString
return if (cls != null) {
val clazz = Class.forName(cls)
clazz.newInstance() as Interceptor
} else {
null
}
}
}
1 change: 1 addition & 0 deletions core/src/main/java/io/snabble/sdk/InitializationState.kt
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package io.snabble.sdk

enum class InitializationState {
UNINITIALIZED,
INITIALIZING,
INITIALIZED,
ERROR,
Expand Down
4 changes: 2 additions & 2 deletions core/src/main/java/io/snabble/sdk/Project.kt
Original file line number Diff line number Diff line change
Expand Up @@ -502,7 +502,7 @@ class Project internal constructor(jsonObject: JsonObject) {
.map { it.paymentMethod }
.firstOrNull { it == PaymentMethod.GOOGLE_PAY }
?.let {
GooglePayHelper(this, instance.application)
GooglePayHelper(this, Snabble.application)
}

coupons = Coupons(this)
Expand All @@ -518,7 +518,7 @@ class Project internal constructor(jsonObject: JsonObject) {
.map { it.paymentMethod }
.firstOrNull { it == PaymentMethod.GOOGLE_PAY }
?.let {
GooglePayHelper(this, instance.application)
GooglePayHelper(this, Snabble.application)
}

/**
Expand Down
Loading