VenueNext Android SDK Setup
System Requirements
- Minimum SDK Version 21 - Android 5.0 “Lollipop”
Getting the SDK
VenueNext Android SDK is served via JFrog. Follow the guide below using your provided credentials to obtain the SDK.
Step 1. Configure your JFrog Repository and Set Up Gradle
Add the following dependencies to your project’s build.gradle
file:
buildscript {
ext {
gradle_version = '3.4.2'
kotlin_version = '1.3.41'
kotlin_coroutines_version = '1.2.2'
serialization_version = '0.11.1'
}
repositories {
google()
jcenter()
}
dependencies {
classpath "com.android.tools.build:gradle:$gradle_version"
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
classpath "org.jetbrains.kotlin:kotlin-serialization:$kotlin_version"
classpath "org.jfrog.buildinfo:build-info-extractor-gradle:4.7.3"
classpath "android.arch.navigation:navigation-safe-args-gradle-plugin:1.0.0"
classpath 'com.google.gms:google-services:4.3.0'
classpath 'io.fabric.tools:gradle:1.31.0'
}
}
allprojects {
repositories {
google()
jcenter()
maven { url "https://kotlin.bintray.com/kotlinx" }
}
}
Add the following plugin and repository to your app’s build.gradle
file:
apply plugin: 'maven-publish'
repositories {
maven {
url "https://venuenext.jfrog.io/venuenext/venuenextsdk-android"
credentials {
username = XXXXXXXXXXXXXXXXX
password = XXXXXXXXXXXXXXXXX
}
}
}
Apply the following plugins to your app’s build.gradle
file:
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
apply plugin: 'kotlin-kapt'
apply plugin: 'kotlinx-serialization'
apply plugin: 'androidx.navigation.safeargs'
apply plugin: 'io.fabric'
// Add this plugin to the bottom of your Gradle file (per Google documentation)
apply plugin: 'com.google.gms.google-services'
Enable databinding in your app’s build.gradle
file:
android {
dataBinding {
enabled = true
}
}
Add the following VenueNext dependencies to your app’s build.gradle
file (UI dependencies can be omitted if not using VenueNext views):
// VenueNext
implementation 'com.venuenext:vncore:0.11.0'
implementation 'com.venuenext:vncoreui:0.11.0'
implementation 'com.venuenext:vnanalytics:0.11.0'
implementation 'com.venuenext:vnlocalytics:0.11.0'
implementation 'com.venuenext:vnlegacy:0.11.0'
implementation 'com.venuenext:vnorder:0.11.0'
implementation 'com.venuenext:vnorderui:0.11.0'
implementation 'com.venuenext:vnpayment:0.11.0'
implementation 'com.venuenext:vnticket:0.11.0'
Add the following additional dependencies to your app’s build.gradle
file:
// Kotlin
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
implementation "org.jetbrains.kotlin:kotlin-reflect:$kotlin_version"
implementation "org.jetbrains.kotlinx:kotlinx-serialization-runtime:$serialization_version"
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:$kotlin_coroutines_version"
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:$kotlin_coroutines_version"
// UI
implementation 'com.google.android.material:material:1.0.0'
implementation 'androidx.appcompat:appcompat:1.0.2'
implementation 'androidx.core:core-ktx:1.0.2'
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
implementation 'androidx.legacy:legacy-support-v4:1.0.0'
implementation 'com.android.support:cardview-v7:28.0.0'
implementation 'com.android.support:cardview-v7:28.0.0'
implementation 'com.android.support:appcompat-v7:28.0.0'
implementation 'com.google.android:flexbox:2.0.1'
// Lifecycle
implementation "androidx.lifecycle:lifecycle-extensions:2.2.0"
implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.2.0"
// Navigation
implementation "androidx.navigation:navigation-ui-ktx:2.3.0"
implementation "androidx.navigation:navigation-fragment:2.3.0"
implementation "androidx.navigation:navigation-fragment-ktx:2.3.0"
// Room
implementation "androidx.room:room-runtime:2.1.0"
kapt "androidx.room:room-compiler:2.1.0"
// Firebase
implementation 'com.google.firebase:firebase-core:17.0.1'
implementation 'com.google.firebase:firebase-analytics:17.0.1'
implementation 'com.google.firebase:firebase-messaging:19.0.1'
implementation 'com.google.android.gms:play-services-tagmanager:17.0.0'
// Crashlytics
implementation 'com.crashlytics.sdk.android:crashlytics:2.10.1'
// Braintree
implementation 'com.braintreepayments.api:braintree:3.0.0'
implementation 'com.braintreepayments.api:drop-in:4.1.0'
// Facebook Shimmer
implementation 'com.facebook.shimmer:shimmer:0.4.0'
// QR codes
implementation 'com.journeyapps:zxing-android-embedded:3.6.0'
implementation 'com.google.zxing:core:3.3.3'
// Image Loading
implementation "com.github.bumptech.glide:glide:4.9.0"
// Localytics
implementation 'com.android.support:support-compat:28.0.0'
implementation "com.google.android.gms:play-services-gcm:17.0.0"
implementation "com.google.android.gms:play-services-location:17.0.0"
implementation 'com.localytics.android:library:5.5+'
// Compat
implementation 'androidx.localbroadcastmanager:localbroadcastmanager:1.0.0'
implementation 'com.android.support:multidex:1.0.3'
Step 2. Initialize the SDK
Have you been provided a config file from VenueNext? Skip to Step 2b. Initialize with a Config file.
Are you using a JSON Web Token to identify your users? See Step 2a. Initialization With a JWT Token.
To initialize the SDK, pass in your SDK key and secret.
This could potentially go in the onViewCreated
handler of a Fragment class.
Initialization is also where we configure Crash Reporting, Analytics, & Payment Processing for plugging in a specific framework.
GlobalScope.async {
// Note: We removed calls to add Firebase and Localytics analytics implementations.
// You can add your own analytics implementation to receive events from the VenueNext SDK
// as shown below.
val analytics = VNAnalyticsInterface(applicationContext)
VenueNext.configureAnalytics(analytics)
// Note: This is the default implementation of payment method processing to use if you don't want to configure your own
// payment method capturing. You can add your own payment method capturing by following the instructions on the
// "Configuring Payment" page of these docs.
VNPayment.configurePaymentProcessing(BraintreePaymentProcessableFragment())
VenueNext.initialize("SDK_KEY", "SECRET_KEY", self.context!!).await()
// Initialize modules to handle deep links
VenueNext.registerDeepLinkable(VNOrderUI)
withContext(Dispatchers.Main) {
// Start navigation
Navigation.findNavController(view).navigate(R.id.start_main)
}
}
Please treat your SDK key and secret with care. Do not check them into source repositories or pass them around in the clear.
Initialization Variations
Step 2a. Initialization With a JWT Token
Use this if you have an external user ID at the time of initializing the VenueNext SDK Please see the example below and ensure the JWT has the correct payload.
val jwt = "xxxxxxxxxxxxxxxx.xxxxxxxxxxxxxxxxxxx.xxxxxxxxxxxxxxx"
VenueNext.initialize("SDK_KEY", "SECRET_KEY", self.context!!, jwt).await()
When using a JWT please ensure the following payload structure is included:
{
"sub": "1234567890",
"iat": 1516239022,
"email": "email@example.org",
"sth": true,
"name": "Sam Smith"
}
Step 2b. Initialize with a Config file
If VenueNext has provided you with a configuration file, store the file in a place where it is accessible via code when you initialize the SDK. We recommend storing the file in the res/raw
directory or in the assets
directory. You’ll be reading the contents of the config file into a String
and passing the String
to the initialize
function. The example below assumes the file has been stored in the res/raw
directory:
val configStream = resources.openRawResource(
resources.getIdentifier("<configFileNameWithoutExtension>", "raw", packageName)
)
var configString = ""
try {
configStream.bufferedReader().use { configString = it.readText() }
} catch (e: Exception) {
Log.e(TAG, "Error reading the config file")
}
// Note: We removed calls to add Firebase and Localytics analytics implementations
// You can add your own analytics implementation to receive events from the VenueNext SDK
// as shown below.
val analytics = VNAnalyticsInterface(applicationContext)
VenueNext.configureAnalytics(analytics)
VenueNext.initialize(
sdkKey = sdkKey,
sdkSecret = sdkSecret,
context = this,
jwt = null,
configJsonString = configString,
onSuccess = this::completeInitialize,
onError = this::handleInitializationError
)
VNOrderUI.initialize()
VNPayment.configurePaymentProcessing(BraintreePaymentProcessableFragment())
fun completeInitialize() { }
fun handleInitializationError(e: Throwable) { }
Notes:
- If you are logging users in via a JSON Web Token, you can pass it here instead of passing
null
as shown above - You no longer need to call
VenueNext.registerDeeplinkable(VNOrderUI)
- this has instead been replaced withVNOrderUI.initialize()
- You no longer need to dispatch the initialization to another thread - you can instead pass in callback functions for success or error that will be called when initialization has completed
Step 2c. Initialize Wallet
If you intend to use VenueNext Wallet functionality, please see additional initialization documentation in the Wallet Configuration section
Step 3. Setup Fragments and Navigation
a. Add the following fragment to your MainActivity layout:
<fragment
android:id="@+id/fragment_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:navGraph="@navigation/app_navigation"
android:name="androidx.navigation.fragment.NavHostFragment"
app:defaultNavHost="true"/>
b. Add an app_navigation.xml
file to your navigation
resource folder:
- Add the contents of our sample app_navigation.xml
- If you want to change the text that displays at the top of views in the Action Bar,
update the
vnActionBarTitle
argument in the actions below. See Setting the Action Bar Title Text - If you wish to start directly to a navigation flow without a placeholder fragment, you will need to ensure the SDK has been initialized
- If you want to change the text that displays at the top of views in the Action Bar,
update the
c. Add a placeholder fragment as a starting point for your navigation graph
The purpose of this fragment is to give the navigation graph a starting point outside of the SDK flow. If the SDK is not initialized before navigating to a VenueNext flow you will encounter errors. This can be replaced with any fragment in your app_navigation
and is optional only in this case or your start destination is a VenueNext flow (e.g. @id/food_and_bev_flow
) and the SDK has been initialized.
Fragment:
class MainFragment : Fragment() {
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
return inflater.inflate(R.layout.fragment_main, container, false)
}
}
XML:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainFragment">
<!-- This placeholder layout can be blank, this ProgressBar is provided as an example if you
wish to show a loading state
-->
<ProgressBar
style="?android:attr/progressBarStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/progressBar"
android:indeterminate="true"
android:indeterminateTint="@color/colorAccent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"/>
</androidx.constraintlayout.widget.ConstraintLayout>
Step 4. Setup Deep Linking
- Add the following intent filter to your project’s current
AndroidManifest.xml
file:<intent-filter> <data android:scheme="[yourAppSchemeHere]" /> <action android:name="android.intent.action.VIEW" /> <category android:name="android.intent.category.DEFAULT" /> <category android:name="android.intent.category.BROWSABLE" /> </intent-filter>
- To add VenueNext Deep Link handling to your project’s current deep link implementation, ensure the following steps are performed in
onNewIntent
and after initial launch of your application:- Initialize the VenueNext SDK (
VenueNext::initialize
) - Register Deep Linkable objects with VenueNext (
VenueNext::registerDeepLinkable
) - Call
VenueNext::canHandleDeepLink
andVenueNext::handleDeepLink
as seen below:private fun handleIntent(intent: Intent?) { if (intent?.action == Intent.ACTION_VIEW) { intent.data?.let { if (VenueNext.canHandleDeepLink(it)) { // IMPORTANT: If your Activity does not include the VenueNext navigation graphs, // start an Activity that does include the VenueNext navigation graphs with this // Intent instead of handling the deep link here. // The View that will be used to locate the NavController associated with the view. // In practice, this will likely be fragment_main from Step 3a VenueNext.handleDeepLink(view, it) } else { // This is a deep link for your app! } } } }
- Initialize the VenueNext SDK (
For setting up deep linking for virtual currency transfers, see deep linking setup.
If the above steps have been properly completed, you should be able to navigate into VenueNext views.