From 2199b1fc420470084ddc438770214f5e650cb42b Mon Sep 17 00:00:00 2001 From: Karen Tamayo Date: Wed, 12 Feb 2020 14:58:50 -0800 Subject: [PATCH] Release 5.7.0 (#75) --- CHANGELOG.md | 13 +- Modules/Location/.gitignore | 5 + Modules/Location/LocationSample/.gitignore | 13 + .../Location/LocationSample/app/.gitignore | 1 + .../Location/LocationSample/app/build.gradle | 40 ++++ .../LocationSample/app/google-services.json | 3 + .../LocationSample/app/proguard-rules.pro | 25 ++ .../app/src/main/AndroidManifest.xml | 37 +++ .../app/src/main/Assets/geofences.json | 22 ++ .../example/tealiumlocationdemoapp/App.java | 11 + .../LocationAssets.java | 102 ++++++++ .../LocationConfig.java | 110 +++++++++ .../LocationGeofencing.java | 115 +++++++++ .../LocationTracking.java | 90 +++++++ .../tealiumlocationdemoapp/LocationUrl.java | 105 ++++++++ .../tealiumlocationdemoapp/MainActivity.java | 97 ++++++++ .../TealiumFirebaseMessagingService.java | 36 +++ .../tealiumlocationdemoapp/TealiumHelper.java | 168 +++++++++++++ .../drawable-v24/ic_launcher_foreground.xml | 34 +++ .../res/drawable/ic_launcher_background.xml | 170 +++++++++++++ .../drawable/tealium_logo_rgb_600x278px.png | Bin 0 -> 5025 bytes .../tealium_logo_white_rgb_600x278px.png | Bin 0 -> 4900 bytes .../src/main/res/layout/activity_assets.xml | 93 ++++++++ .../src/main/res/layout/activity_config.xml | 93 ++++++++ .../main/res/layout/activity_geofencing.xml | 94 ++++++++ .../src/main/res/layout/activity_location.xml | 79 ++++++ .../app/src/main/res/layout/activity_main.xml | 92 +++++++ .../app/src/main/res/layout/activity_url.xml | 94 ++++++++ .../res/mipmap-anydpi-v26/ic_launcher.xml | 5 + .../mipmap-anydpi-v26/ic_launcher_round.xml | 5 + .../src/main/res/mipmap-hdpi/ic_launcher.png | Bin 0 -> 2963 bytes .../res/mipmap-hdpi/ic_launcher_round.png | Bin 0 -> 4905 bytes .../src/main/res/mipmap-mdpi/ic_launcher.png | Bin 0 -> 2060 bytes .../res/mipmap-mdpi/ic_launcher_round.png | Bin 0 -> 2783 bytes .../src/main/res/mipmap-xhdpi/ic_launcher.png | Bin 0 -> 4490 bytes .../res/mipmap-xhdpi/ic_launcher_round.png | Bin 0 -> 6895 bytes .../main/res/mipmap-xxhdpi/ic_launcher.png | Bin 0 -> 6387 bytes .../res/mipmap-xxhdpi/ic_launcher_round.png | Bin 0 -> 10413 bytes .../main/res/mipmap-xxxhdpi/ic_launcher.png | Bin 0 -> 9128 bytes .../res/mipmap-xxxhdpi/ic_launcher_round.png | Bin 0 -> 15132 bytes .../app/src/main/res/values/colors.xml | 6 + .../app/src/main/res/values/strings.xml | 3 + .../app/src/main/res/values/styles.xml | 11 + .../main/res/xml/network_security_config.xml | 9 + Modules/Location/LocationSample/build.gradle | 31 +++ .../Location/LocationSample/gradle.properties | 20 ++ .../gradle/wrapper/gradle-wrapper.jar | Bin 0 -> 54329 bytes .../gradle/wrapper/gradle-wrapper.properties | 6 + Modules/Location/LocationSample/gradlew | 172 ++++++++++++++ Modules/Location/LocationSample/gradlew.bat | 84 +++++++ .../Location/LocationSample/settings.gradle | 1 + Modules/Location/README.md | 4 + Modules/Location/tealium.location-1.0.0.aar | Bin 0 -> 20175 bytes Samples/AndroidTVSample/.gitignore | 224 +----------------- Samples/AndroidTVSample/app/build.gradle | 2 +- Samples/BlankApp+Tealium/app/build.gradle | 2 +- Samples/ConsentManagerDemoApp/.gitignore | 2 +- .../.idea/caches/build_file_checksums.ser | Bin 540 -> 0 bytes .../ConsentManagerDemoApp/.idea/gradle.xml | 22 -- Samples/ConsentManagerDemoApp/.idea/misc.xml | 48 ---- .../.idea/runConfigurations.xml | 12 - .../ConsentManagerDemoApp/app/build.gradle | 2 +- Samples/ExampleApp+Tealium/app/build.gradle | 2 +- tealium-5.6.2.aar | Bin 155464 -> 0 bytes tealium-5.7.0.aar | Bin 0 -> 170273 bytes 65 files changed, 2106 insertions(+), 309 deletions(-) create mode 100644 Modules/Location/.gitignore create mode 100644 Modules/Location/LocationSample/.gitignore create mode 100644 Modules/Location/LocationSample/app/.gitignore create mode 100644 Modules/Location/LocationSample/app/build.gradle create mode 100644 Modules/Location/LocationSample/app/google-services.json create mode 100644 Modules/Location/LocationSample/app/proguard-rules.pro create mode 100644 Modules/Location/LocationSample/app/src/main/AndroidManifest.xml create mode 100644 Modules/Location/LocationSample/app/src/main/Assets/geofences.json create mode 100644 Modules/Location/LocationSample/app/src/main/java/com/example/tealiumlocationdemoapp/App.java create mode 100644 Modules/Location/LocationSample/app/src/main/java/com/example/tealiumlocationdemoapp/LocationAssets.java create mode 100644 Modules/Location/LocationSample/app/src/main/java/com/example/tealiumlocationdemoapp/LocationConfig.java create mode 100644 Modules/Location/LocationSample/app/src/main/java/com/example/tealiumlocationdemoapp/LocationGeofencing.java create mode 100644 Modules/Location/LocationSample/app/src/main/java/com/example/tealiumlocationdemoapp/LocationTracking.java create mode 100644 Modules/Location/LocationSample/app/src/main/java/com/example/tealiumlocationdemoapp/LocationUrl.java create mode 100644 Modules/Location/LocationSample/app/src/main/java/com/example/tealiumlocationdemoapp/MainActivity.java create mode 100644 Modules/Location/LocationSample/app/src/main/java/com/example/tealiumlocationdemoapp/TealiumFirebaseMessagingService.java create mode 100644 Modules/Location/LocationSample/app/src/main/java/com/example/tealiumlocationdemoapp/TealiumHelper.java create mode 100644 Modules/Location/LocationSample/app/src/main/res/drawable-v24/ic_launcher_foreground.xml create mode 100644 Modules/Location/LocationSample/app/src/main/res/drawable/ic_launcher_background.xml create mode 100644 Modules/Location/LocationSample/app/src/main/res/drawable/tealium_logo_rgb_600x278px.png create mode 100644 Modules/Location/LocationSample/app/src/main/res/drawable/tealium_logo_white_rgb_600x278px.png create mode 100644 Modules/Location/LocationSample/app/src/main/res/layout/activity_assets.xml create mode 100644 Modules/Location/LocationSample/app/src/main/res/layout/activity_config.xml create mode 100644 Modules/Location/LocationSample/app/src/main/res/layout/activity_geofencing.xml create mode 100644 Modules/Location/LocationSample/app/src/main/res/layout/activity_location.xml create mode 100644 Modules/Location/LocationSample/app/src/main/res/layout/activity_main.xml create mode 100644 Modules/Location/LocationSample/app/src/main/res/layout/activity_url.xml create mode 100644 Modules/Location/LocationSample/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml create mode 100644 Modules/Location/LocationSample/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml create mode 100644 Modules/Location/LocationSample/app/src/main/res/mipmap-hdpi/ic_launcher.png create mode 100644 Modules/Location/LocationSample/app/src/main/res/mipmap-hdpi/ic_launcher_round.png create mode 100644 Modules/Location/LocationSample/app/src/main/res/mipmap-mdpi/ic_launcher.png create mode 100644 Modules/Location/LocationSample/app/src/main/res/mipmap-mdpi/ic_launcher_round.png create mode 100644 Modules/Location/LocationSample/app/src/main/res/mipmap-xhdpi/ic_launcher.png create mode 100644 Modules/Location/LocationSample/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png create mode 100644 Modules/Location/LocationSample/app/src/main/res/mipmap-xxhdpi/ic_launcher.png create mode 100644 Modules/Location/LocationSample/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png create mode 100644 Modules/Location/LocationSample/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png create mode 100644 Modules/Location/LocationSample/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png create mode 100644 Modules/Location/LocationSample/app/src/main/res/values/colors.xml create mode 100644 Modules/Location/LocationSample/app/src/main/res/values/strings.xml create mode 100644 Modules/Location/LocationSample/app/src/main/res/values/styles.xml create mode 100644 Modules/Location/LocationSample/app/src/main/res/xml/network_security_config.xml create mode 100644 Modules/Location/LocationSample/build.gradle create mode 100644 Modules/Location/LocationSample/gradle.properties create mode 100644 Modules/Location/LocationSample/gradle/wrapper/gradle-wrapper.jar create mode 100644 Modules/Location/LocationSample/gradle/wrapper/gradle-wrapper.properties create mode 100755 Modules/Location/LocationSample/gradlew create mode 100644 Modules/Location/LocationSample/gradlew.bat create mode 100644 Modules/Location/LocationSample/settings.gradle create mode 100644 Modules/Location/README.md create mode 100644 Modules/Location/tealium.location-1.0.0.aar delete mode 100644 Samples/ConsentManagerDemoApp/.idea/caches/build_file_checksums.ser delete mode 100644 Samples/ConsentManagerDemoApp/.idea/gradle.xml delete mode 100644 Samples/ConsentManagerDemoApp/.idea/misc.xml delete mode 100644 Samples/ConsentManagerDemoApp/.idea/runConfigurations.xml delete mode 100644 tealium-5.6.2.aar create mode 100644 tealium-5.7.0.aar diff --git a/CHANGELOG.md b/CHANGELOG.md index 98ccca4..fca50ca 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,14 @@ # Change Log - +- 5.7.0 + - Update Gradle to latest version to fix Proguard issues + - Location 1.0.0 + - Location tracking based on defined geofence + - New Event Attributes: + - `geofence_name` + - `geofence_transition_type` + - `location_accuracy` + - `device_last_latitude` + - `device_last_longitude` - 5.6.2 - Embed proguard-rules - All Modules - proguard-rules are now embedded in each module @@ -20,7 +29,7 @@ - 5.5.5 - Webview bug fix: disable Hardware Acceleration for Tealium webview - Install Referrer 1.1.2 - - Placement of endconnection() to more appropriate location + - Bug fix: resolve referrerClient NPE by adding `endConnection()` after establishing connection - 5.5.4 - Fixed VisitorProfile URL to default to profile provided in Tealium.Config - 5.5.3 diff --git a/Modules/Location/.gitignore b/Modules/Location/.gitignore new file mode 100644 index 0000000..1bcf832 --- /dev/null +++ b/Modules/Location/.gitignore @@ -0,0 +1,5 @@ +.idea +.gradle +*.iml +build +local.properties \ No newline at end of file diff --git a/Modules/Location/LocationSample/.gitignore b/Modules/Location/LocationSample/.gitignore new file mode 100644 index 0000000..2b75303 --- /dev/null +++ b/Modules/Location/LocationSample/.gitignore @@ -0,0 +1,13 @@ +*.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 diff --git a/Modules/Location/LocationSample/app/.gitignore b/Modules/Location/LocationSample/app/.gitignore new file mode 100644 index 0000000..796b96d --- /dev/null +++ b/Modules/Location/LocationSample/app/.gitignore @@ -0,0 +1 @@ +/build diff --git a/Modules/Location/LocationSample/app/build.gradle b/Modules/Location/LocationSample/app/build.gradle new file mode 100644 index 0000000..d549014 --- /dev/null +++ b/Modules/Location/LocationSample/app/build.gradle @@ -0,0 +1,40 @@ +apply plugin: 'com.android.application' +apply plugin: 'com.google.gms.google-services' + +android { + compileSdkVersion 29 + buildToolsVersion "29.0.1" + defaultConfig { + applicationId "com.example.tealiumlocationdemoapp" + minSdkVersion 19 + targetSdkVersion 29 + versionCode 1 + versionName "1.0" + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + } + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + } + } +} + +dependencies { + implementation 'androidx.appcompat:appcompat:1.0.2' + implementation 'androidx.constraintlayout:constraintlayout:1.1.3' + + // Tealium dependencies + implementation 'com.tealium:library:5.7.0' + implementation 'com.tealium:location:1.0.0' + + // Other required dependencies + runtimeOnly 'com.google.android.gms:play-services-location:17.0.0' + implementation 'com.google.firebase:firebase-messaging:20.0.0' + implementation 'com.optimizely.ab:android-sdk:2.1.0' + + // Testing dependencies + testImplementation 'junit:junit:4.12' + androidTestImplementation 'androidx.test:runner:1.2.0' + androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0' +} diff --git a/Modules/Location/LocationSample/app/google-services.json b/Modules/Location/LocationSample/app/google-services.json new file mode 100644 index 0000000..fb49f8d --- /dev/null +++ b/Modules/Location/LocationSample/app/google-services.json @@ -0,0 +1,3 @@ +{ + "_comment": "INSERT YOUR GOOGLE-SERVICES.JSON CONFIGURATION HERE" +} \ No newline at end of file diff --git a/Modules/Location/LocationSample/app/proguard-rules.pro b/Modules/Location/LocationSample/app/proguard-rules.pro new file mode 100644 index 0000000..6299c0b --- /dev/null +++ b/Modules/Location/LocationSample/app/proguard-rules.pro @@ -0,0 +1,25 @@ +# 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 + +-keep com.tealium.internal.** { + *; +} \ No newline at end of file diff --git a/Modules/Location/LocationSample/app/src/main/AndroidManifest.xml b/Modules/Location/LocationSample/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000..71393a7 --- /dev/null +++ b/Modules/Location/LocationSample/app/src/main/AndroidManifest.xml @@ -0,0 +1,37 @@ + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Modules/Location/LocationSample/app/src/main/Assets/geofences.json b/Modules/Location/LocationSample/app/src/main/Assets/geofences.json new file mode 100644 index 0000000..98c9519 --- /dev/null +++ b/Modules/Location/LocationSample/app/src/main/Assets/geofences.json @@ -0,0 +1,22 @@ +[ + { + "name": "Tealium_asset1", + "latitude": 59.4610304, + "longitude": -9.9707625, + "radius": 100, + "expire_after": -1, + "trigger_on_enter": true, + "trigger_on_exit": true, + "minimum_dwell_time": 0 + }, + { + "name": "Tealium_asset2", + "latitude": 39.9061189, + "longitude": -142.2379163, + "radius": 100, + "expire_after": -1, + "trigger_on_enter": true, + "trigger_on_exit": true, + "minimum_dwell_time": 0 + } +] \ No newline at end of file diff --git a/Modules/Location/LocationSample/app/src/main/java/com/example/tealiumlocationdemoapp/App.java b/Modules/Location/LocationSample/app/src/main/java/com/example/tealiumlocationdemoapp/App.java new file mode 100644 index 0000000..1a4c568 --- /dev/null +++ b/Modules/Location/LocationSample/app/src/main/java/com/example/tealiumlocationdemoapp/App.java @@ -0,0 +1,11 @@ +package com.example.tealiumlocationdemoapp; + +import android.app.Application; + +public class App extends Application { + @Override + public void onCreate() { + super.onCreate(); + TealiumHelper.initialize(this); + } +} diff --git a/Modules/Location/LocationSample/app/src/main/java/com/example/tealiumlocationdemoapp/LocationAssets.java b/Modules/Location/LocationSample/app/src/main/java/com/example/tealiumlocationdemoapp/LocationAssets.java new file mode 100644 index 0000000..0f592ba --- /dev/null +++ b/Modules/Location/LocationSample/app/src/main/java/com/example/tealiumlocationdemoapp/LocationAssets.java @@ -0,0 +1,102 @@ +package com.example.tealiumlocationdemoapp; + +import android.app.Activity; +import android.os.Bundle; +import android.view.View; +import android.widget.TextView; +import android.widget.Toast; + +import com.tealium.location.TealiumLocation; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +public class LocationAssets extends Activity { + + private boolean mLocationShowcaseStarted = false; + private TealiumLocation mInstance; + private final String mGeofenceJsonFile = "geofences.json"; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_assets); + + findViewById(R.id.location_assets_button_update) + .setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + if (mLocationShowcaseStarted) { + drawActiveGeofences(); + drawUsedAssets(); + } else { + showToast("Please press Start first!"); + } + } + }); + + findViewById(R.id.location_assets_button_start) + .setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + if (!mLocationShowcaseStarted) { + startLocationShowcase(); + } else { + showToast("Showcase Already Started!"); + } + } + }); + + findViewById(R.id.location_assets_button_stop).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + if (!mLocationShowcaseStarted) { + showToast("Please press Start first!"); + } + } + }); + } + + private void startLocationShowcase() { + mLocationShowcaseStarted = true; + + Set tealiumInstances = new HashSet<>(); + tealiumInstances.add(TealiumHelper.TEALIUM_MAIN); + + mInstance = TealiumLocation.setupInstanceWithFile(this, tealiumInstances, mGeofenceJsonFile); + mInstance.startLocationUpdates(true, 5000); + drawUsedAssets(); + drawActiveGeofences(); + } + + private void drawActiveGeofences() { + List activeGeofences = mInstance.getAllGeofenceNames(); + String geofenceNames = ""; + + for (String name : activeGeofences) { + geofenceNames = geofenceNames + name + "\n"; + } + + TextView geofenceNameData = findViewById(R.id.location_assets_geofencesdata); + geofenceNameData.setText(geofenceNames); + } + + private void drawUsedAssets() { + TextView urlData = findViewById(R.id.location_assets_assetsdata); + urlData.setText(mGeofenceJsonFile); + } + + private void showToast(String message) { + Toast.makeText(getApplicationContext(), message, Toast.LENGTH_LONG).show(); + } + + @Override + public void onDestroy() { + super.onDestroy(); + if (mLocationShowcaseStarted) { + TealiumLocation.destroyInstance(); + } + } +} diff --git a/Modules/Location/LocationSample/app/src/main/java/com/example/tealiumlocationdemoapp/LocationConfig.java b/Modules/Location/LocationSample/app/src/main/java/com/example/tealiumlocationdemoapp/LocationConfig.java new file mode 100644 index 0000000..22ad52d --- /dev/null +++ b/Modules/Location/LocationSample/app/src/main/java/com/example/tealiumlocationdemoapp/LocationConfig.java @@ -0,0 +1,110 @@ +package com.example.tealiumlocationdemoapp; + +import android.app.Activity; +import android.os.Bundle; +import android.view.View; +import android.widget.TextView; +import android.widget.Toast; + +import com.tealium.library.Tealium; +import com.tealium.location.TealiumLocation; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +public class LocationConfig extends Activity { + + private Tealium.Config mTealiumConfig; + private boolean mLocationShowcaseStarted = false; + private TealiumLocation mInstance; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_config); + + findViewById(R.id.location_config_button_update) + .setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + if (mLocationShowcaseStarted) { + drawActiveGeofences(); + drawUsedConfig(); + } else { + showToast("Please press Start first!"); + } + } + }); + + findViewById(R.id.location_config_button_start) + .setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + if (!mLocationShowcaseStarted) { + startLocationShowcase(); + } else { + showToast("Showcase Already Started!"); + } + } + }); + + findViewById(R.id.location_config_button_stop) + .setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + if (!mLocationShowcaseStarted) { + showToast("Please press Start first!"); + } + } + }); + } + + private void startLocationShowcase() { + mLocationShowcaseStarted = true; + + mTealiumConfig = TealiumHelper.getConfig(); + + Set tealiumInstances = new HashSet<>(); + tealiumInstances.add(TealiumHelper.TEALIUM_MAIN); + + if (mTealiumConfig != null) { + mInstance = TealiumLocation.setupInstanceWithConfig(this, tealiumInstances, mTealiumConfig); + mInstance.startLocationUpdates(true, 5000); + drawActiveGeofences(); + drawUsedConfig(); + } else { + showToast("Error with config"); + } + } + + private void drawActiveGeofences() { + List activeGeofences = mInstance.getAllGeofenceNames(); + String geofenceNames = ""; + + for (String name : activeGeofences) { + geofenceNames = geofenceNames + name + "\n"; + } + + TextView geofenceNameData = findViewById(R.id.location_config_geofencesdata); + geofenceNameData.setText(geofenceNames); + } + + private void drawUsedConfig() { + TextView urlData = findViewById(R.id.location_config_configdata); + urlData.setText(mTealiumConfig.getAccountName()); + } + + private void showToast(String message) { + Toast.makeText(getApplicationContext(), message, Toast.LENGTH_LONG).show(); + } + + @Override + public void onDestroy() { + super.onDestroy(); + if (mLocationShowcaseStarted) { + TealiumLocation.destroyInstance(); + } + } +} diff --git a/Modules/Location/LocationSample/app/src/main/java/com/example/tealiumlocationdemoapp/LocationGeofencing.java b/Modules/Location/LocationSample/app/src/main/java/com/example/tealiumlocationdemoapp/LocationGeofencing.java new file mode 100644 index 0000000..2ec8c9d --- /dev/null +++ b/Modules/Location/LocationSample/app/src/main/java/com/example/tealiumlocationdemoapp/LocationGeofencing.java @@ -0,0 +1,115 @@ +package com.example.tealiumlocationdemoapp; + +import android.app.Activity; +import android.location.Location; +import android.os.Bundle; +import android.view.View; +import android.widget.TextView; +import android.widget.Toast; + +import com.tealium.location.TealiumLocation; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +public class LocationGeofencing extends Activity { + + private boolean mLocationShowcaseStarted = false; + private Location mLastLocation; + private TealiumLocation mInstance; + private static final String GEOFENCES_URL = "https://tags.tiqcdn.com/dle/tealiummobile/location/geofences.json"; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_geofencing); + + findViewById(R.id.location_geofencing_button_update) + .setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + if (mLocationShowcaseStarted) { + mLastLocation = mInstance.getLastLocation(); + drawLastLocation(); + drawActiveGeofences(); + } else { + showToast("Please press Start first!"); + } + } + }); + + findViewById(R.id.location_geofencing_button_start) + .setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + if (!mLocationShowcaseStarted) { + startLocationShowcase(); + } else { + showToast("Showcase Already Started!"); + } + } + }); + + findViewById(R.id.location_geofencing_button_stop) + .setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + if (mLocationShowcaseStarted) { + mInstance.stopLocationUpdates(); + showToast("Showcase Stopped."); + } else { + showToast("Please press Start first!"); + } + } + }); + } + + private void startLocationShowcase() { + mLocationShowcaseStarted = true; + + Set tealiumInstances = new HashSet<>(); + tealiumInstances.add(TealiumHelper.TEALIUM_MAIN); + + mInstance = TealiumLocation.setupInstanceWithUrl(this, tealiumInstances, GEOFENCES_URL); + mInstance.startLocationUpdates(true, 5000); + drawLastLocation(); + drawActiveGeofences(); + } + + private void drawLastLocation() { + TextView locationData = findViewById(R.id.location_geofencing_locationdata); + + if (mLastLocation != null) { + locationData.setText("Latitude: " + mLastLocation.getLatitude() + "\nLongitude: " + mLastLocation.getLongitude()); + } else { + locationData.setText("Please Update UI"); + Toast.makeText(getApplicationContext(), "Location Updates Every 5 Seconds, Please wait a bit!", Toast.LENGTH_SHORT).show(); + } + } + + private void drawActiveGeofences() { + List activeGeofences = mInstance.getActiveGeofenceNames(); + String geofenceNames = ""; + + for (String geofence : activeGeofences) { + geofenceNames = geofenceNames + geofence + "\n"; + } + + TextView geofenceNameData = findViewById(R.id.location_geofencing_geofencesdata); + geofenceNameData.setText(geofenceNames); + } + + private void showToast(String message) { + Toast.makeText(getApplicationContext(), message, Toast.LENGTH_LONG).show(); + } + + @Override + public void onDestroy() { + super.onDestroy(); + if (mLocationShowcaseStarted) { + TealiumLocation.destroyInstance(); + } + } +} diff --git a/Modules/Location/LocationSample/app/src/main/java/com/example/tealiumlocationdemoapp/LocationTracking.java b/Modules/Location/LocationSample/app/src/main/java/com/example/tealiumlocationdemoapp/LocationTracking.java new file mode 100644 index 0000000..daf296b --- /dev/null +++ b/Modules/Location/LocationSample/app/src/main/java/com/example/tealiumlocationdemoapp/LocationTracking.java @@ -0,0 +1,90 @@ +package com.example.tealiumlocationdemoapp; + +import android.app.Activity; +import android.location.Location; +import android.os.Bundle; +import android.view.View; +import android.widget.TextView; +import android.widget.Toast; + +import com.tealium.location.TealiumLocation; + +import java.util.HashSet; +import java.util.Set; + +public class LocationTracking extends Activity { + + private boolean mLocationShowcaseStarted = false; + private Location mLastLocation; + private TealiumLocation mInstance; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_location); + + findViewById(R.id.location_tracking_button_update) + .setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + if (mLocationShowcaseStarted) { + mLastLocation = mInstance.getLastLocation(); + drawLastLocation(); + } else { + showToast("Please press Start first!"); + } + } + }); + + findViewById(R.id.location_tracking_button_start) + .setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + if (!mLocationShowcaseStarted) { + startLocationShowcase(); + } else { + showToast("Showcase Already Started!"); + } + } + }); + + findViewById(R.id.location_tracking_button_stop) + .setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + if (mLocationShowcaseStarted) { + mInstance.stopLocationUpdates(); + showToast("Showcase Stopped."); + } else { + showToast("Please press Start first!"); + } + } + }); + } + + private void startLocationShowcase() { + mLocationShowcaseStarted = true; + + Set tealiumInstances = new HashSet<>(); + tealiumInstances.add(TealiumHelper.TEALIUM_MAIN); + + mInstance = TealiumLocation.setupInstance(this, tealiumInstances); + mInstance.startLocationUpdates(true, 5000); + drawLastLocation(); + } + + private void drawLastLocation() { + TextView locationData = findViewById(R.id.location_tracking_locationdata); + + if (mLastLocation != null) { + locationData.setText("Latitude: " + mLastLocation.getLatitude() + "\nLongitude: " + mLastLocation.getLongitude()); + } else { + locationData.setText("Please Update UI"); + showToast("Location Updates Every 5 Seconds, Please wait a bit!"); + } + } + + private void showToast(String message) { + Toast.makeText(getApplicationContext(), message, Toast.LENGTH_LONG).show(); + } +} diff --git a/Modules/Location/LocationSample/app/src/main/java/com/example/tealiumlocationdemoapp/LocationUrl.java b/Modules/Location/LocationSample/app/src/main/java/com/example/tealiumlocationdemoapp/LocationUrl.java new file mode 100644 index 0000000..3f93579 --- /dev/null +++ b/Modules/Location/LocationSample/app/src/main/java/com/example/tealiumlocationdemoapp/LocationUrl.java @@ -0,0 +1,105 @@ +package com.example.tealiumlocationdemoapp; + +import android.app.Activity; +import android.os.Bundle; +import android.view.View; +import android.widget.TextView; +import android.widget.Toast; + +import com.tealium.location.TealiumLocation; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +public class LocationUrl extends Activity { + + private boolean mLocationShowcaseStarted = false; + private TealiumLocation mInstance; + private final String mGeofenceJsonUrl = "https://tags.tiqcdn.com/dle/tealiummobile/location/geofences.json"; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_url); + + findViewById(R.id.location_url_button_update) + .setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + if (mLocationShowcaseStarted) { + drawActiveGeofences(); + drawUsedUrl(); + } else { + showToast("Please press Start first!"); + } + } + }); + + findViewById(R.id.location_url_button_start) + .setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + if (!mLocationShowcaseStarted) { + startLocationShowcase(); + } else { + showToast("Showcase Already Started!"); + } + } + }); + + findViewById(R.id.location_url_button_stop) + .setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + if (!mLocationShowcaseStarted) { + showToast("Please press Start first!"); + } + } + }); + } + + private void startLocationShowcase() { + mLocationShowcaseStarted = true; + + Set tealiumInstances = new HashSet<>(); + tealiumInstances.add(TealiumHelper.TEALIUM_MAIN); + + mInstance = TealiumLocation.setupInstanceWithUrl(this, tealiumInstances, mGeofenceJsonUrl); + mInstance.startLocationUpdates(true, 5000); + drawActiveGeofences(); + drawUsedUrl(); + } + + private void drawActiveGeofences() { + List activeGeofences = mInstance.getAllGeofenceNames(); + String geofenceNames = ""; + + for (String name : activeGeofences) { + geofenceNames = geofenceNames + name + "\n"; + } + + TextView geofenceNameData = findViewById(R.id.location_url_geofencesdata); + geofenceNameData.setText(geofenceNames); + } + + private void drawUsedUrl() { + TextView urlData = findViewById(R.id.location_url_urldata); + urlData.setText(mGeofenceJsonUrl); + } + + private void showToast(String message) { + Toast.makeText(getApplicationContext(), message, Toast.LENGTH_LONG).show(); + } + + @Override + public void onDestroy() { + super.onDestroy(); + if (mLocationShowcaseStarted) { + TealiumLocation.destroyInstance(); + } + } +} + + diff --git a/Modules/Location/LocationSample/app/src/main/java/com/example/tealiumlocationdemoapp/MainActivity.java b/Modules/Location/LocationSample/app/src/main/java/com/example/tealiumlocationdemoapp/MainActivity.java new file mode 100644 index 0000000..87db7b6 --- /dev/null +++ b/Modules/Location/LocationSample/app/src/main/java/com/example/tealiumlocationdemoapp/MainActivity.java @@ -0,0 +1,97 @@ +package com.example.tealiumlocationdemoapp; + +import android.Manifest; +import android.content.Intent; +import android.content.pm.PackageManager; +import android.os.Bundle; +import android.view.View; +import android.widget.Toast; + +import androidx.appcompat.app.AppCompatActivity; +import androidx.core.app.ActivityCompat; +import androidx.core.content.ContextCompat; + +public class MainActivity extends AppCompatActivity { + + public static final int LOCATION_REQUEST_CODE = 101; + private static final String TAG = "MainActivity"; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_main); + + if ((ContextCompat.checkSelfPermission(getApplicationContext(), Manifest.permission.ACCESS_FINE_LOCATION) + != PackageManager.PERMISSION_GRANTED) && ContextCompat.checkSelfPermission(getApplicationContext(), + Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) { + requestLocationPermission(); + } + + findViewById(R.id.main_button_url_demo) + .setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + startActivity(new Intent(v.getContext(), LocationUrl.class)); + } + }); + + findViewById(R.id.main_button_assets_demo) + .setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + startActivity(new Intent(v.getContext(), LocationAssets.class)); + } + }); + + findViewById(R.id.main_button_config_demo) + .setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + startActivity(new Intent(v.getContext(), LocationConfig.class)); + } + }); + + findViewById(R.id.main_button_location_demo) + .setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + startActivity(new Intent(v.getContext(), LocationTracking.class)); + } + }); + + findViewById(R.id.main_button_geofencing_demo) + .setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + startActivity(new Intent(v.getContext(), LocationGeofencing.class)); + } + }); + } + + public void requestLocationPermission() { + if (ContextCompat.checkSelfPermission(getApplicationContext(), Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) { + ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION}, LOCATION_REQUEST_CODE); + } + } + + @Override + public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) { + String message; + if (requestCode == LOCATION_REQUEST_CODE) { + // If request is cancelled, the result arrays are empty. + if ((grantResults.length > 0) && (grantResults[0] == PackageManager.PERMISSION_GRANTED)) { + message = "Location Permission Granted"; + } else { + message = "Location Permission Not Granted"; + } + } else { + message = "Location Permission Not Granted"; + } + showToast(message); + } + + private void showToast(String message) { + Toast.makeText(getApplicationContext(), message, Toast.LENGTH_LONG).show(); + } + +} diff --git a/Modules/Location/LocationSample/app/src/main/java/com/example/tealiumlocationdemoapp/TealiumFirebaseMessagingService.java b/Modules/Location/LocationSample/app/src/main/java/com/example/tealiumlocationdemoapp/TealiumFirebaseMessagingService.java new file mode 100644 index 0000000..1a4d9d6 --- /dev/null +++ b/Modules/Location/LocationSample/app/src/main/java/com/example/tealiumlocationdemoapp/TealiumFirebaseMessagingService.java @@ -0,0 +1,36 @@ +package com.example.tealiumlocationdemoapp; + +import android.util.Log; + +import com.google.firebase.messaging.FirebaseMessagingService; +import com.google.firebase.messaging.RemoteMessage; + +public class TealiumFirebaseMessagingService extends FirebaseMessagingService { + + public static final String TAG = "TealiumFirebaseMsgSvc"; + + public TealiumFirebaseMessagingService() { + } + + @Override + public void onMessageReceived(RemoteMessage remoteMessage) { + Log.d(TAG, "From: " + remoteMessage.getFrom()); + + if (remoteMessage.getNotification() != null) { + Log.d(TAG, "Message Notification Title: " + remoteMessage.getNotification().getTitle()); + Log.d(TAG, "Message Notification Body: " + remoteMessage.getNotification().getBody()); + } + } + + /** + * Called if InstanceID token is updated. This may occur if the security of + * the previous token had been compromised. Note that this is called when the InstanceID token + * is initially generated so this is where you would retrieve the token. + */ + @Override + public void onNewToken(String token) { + Log.d(TAG, "Refreshed token: " + token); + + TealiumHelper.updatePushToken(token); + } +} diff --git a/Modules/Location/LocationSample/app/src/main/java/com/example/tealiumlocationdemoapp/TealiumHelper.java b/Modules/Location/LocationSample/app/src/main/java/com/example/tealiumlocationdemoapp/TealiumHelper.java new file mode 100644 index 0000000..d957699 --- /dev/null +++ b/Modules/Location/LocationSample/app/src/main/java/com/example/tealiumlocationdemoapp/TealiumHelper.java @@ -0,0 +1,168 @@ +package com.example.tealiumlocationdemoapp; + +import android.app.Application; +import android.content.SharedPreferences; +import android.util.Log; +import android.webkit.WebView; + +import com.tealium.internal.data.Dispatch; +import com.tealium.internal.listeners.WebViewLoadedListener; +import com.tealium.internal.tagbridge.RemoteCommand; +import com.tealium.library.DispatchValidator; +import com.tealium.library.Tealium; + +import java.util.HashMap; +import java.util.Locale; +import java.util.Map; + +/** + * This class abstracts interaction with the Tealium library and simplifies comprehension + */ +public final class TealiumHelper { + + static { + Log.i("TagBridge", " --- START --- "); + } + + private final static String KEY_TEALIUM_INIT_COUNT = "tealium_init_count"; + private final static String KEY_TEALIUM_INITIALIZED = "tealium_initialized"; + private final static String TAG = "TealiumHelper"; + private static Tealium.Config sConfig; + + // Identifier for the main Tealium instance + public static final String TEALIUM_MAIN = "main"; + + // Not instantiatable. + private TealiumHelper() { + } + + public static void initialize(Application application) { + + Log.i(TAG, "initialize(" + application.getClass().getSimpleName() + ")"); + + WebView.setWebContentsDebuggingEnabled(true); + + final Tealium.Config config = Tealium.Config.create(application, "tealiummobile", "location", "dev"); + + // (OPTIONAL) Update console logs verbosity + config.setForceOverrideLogLevel("dev"); + + // (OPTIONAL) Get the WebView with UTag loaded + config.getEventListeners().add(createWebViewLoadedListener()); + + // (OPTIONAL) Control how the library treats views/links + config.getDispatchValidators().add(createDispatchValidator()); + + sConfig = config; + + final Tealium instance = Tealium.createInstance(TEALIUM_MAIN, sConfig); + + // (OPTIONAL) Enhanced integrations + instance.addRemoteCommand(createLoggerRemoteCommand()); + + // (OPTIONAL) Use tealium.getDataSources().getPersistentDataSources() to set/modify lifetime values + SharedPreferences sp = instance.getDataSources().getPersistentDataSources(); + sp.edit().putInt(KEY_TEALIUM_INIT_COUNT, sp.getInt(KEY_TEALIUM_INIT_COUNT, 0) + 1).commit(); + + // (OPTIONAL) Use tealium.getDataSources().getVolatileDataSources() to set/modify runtime only values + instance.getDataSources().getVolatileDataSources() + .put(KEY_TEALIUM_INITIALIZED, System.currentTimeMillis()); + + // (OPTIONAL) tracking initialization + final Map data = new HashMap<>(2); + data.put("logged_in", false); + data.put("visitor_status", new String[]{"new_user", "unregistered"}); + TealiumHelper.trackEvent("initialization", data); + } + + public static void trackView(String viewName, Map data) { + final Tealium instance = Tealium.getInstance(TEALIUM_MAIN); + + // Instance can be remotely destroyed through publish settings + if (instance != null) { + instance.trackView(viewName, data); + } + } + + public static void trackEvent(String eventName, Map data) { + final Tealium instance = Tealium.getInstance(TEALIUM_MAIN); + + // Instance can be remotely destroyed through publish settings + if (instance != null) { + instance.trackEvent(eventName, data); + } + } + + private static WebViewLoadedListener createWebViewLoadedListener() { + return new WebViewLoadedListener() { + @Override + public void onWebViewLoad(WebView webView, boolean success) { + Log.d(TAG, "WebView " + webView + + (success ? " loaded successfully" : "failed to load")); + } + + @Override + public String toString() { + return "LoggingWebViewLoadListener"; + } + }; + } + + private static DispatchValidator createDispatchValidator() { + return new DispatchValidator() { + @Override + protected boolean shouldDrop(Dispatch dispatch) { + + // Drop any desired dispatches here by returning true. (Never queued nor sent) + return super.shouldDrop(dispatch); + } + + @Override + protected boolean shouldQueue(Dispatch dispatch, boolean shouldQueue) { + + Log.d(TAG, String.format( + Locale.ROOT, + "%s dispatch: %s", + (shouldQueue ? "Queueing" : "Sending"), + dispatch)); + + return super.shouldQueue(dispatch, shouldQueue); + } + + @Override + public String toString() { + return "CustomDispatchValidator"; + } + }; + } + + private static RemoteCommand createLoggerRemoteCommand() { + return new RemoteCommand("logger", "Logs dispatches") { + @Override + protected void onInvoke(Response response) throws Exception { + final String message = response.getRequestPayload() + .optString("message", "no_message"); + Log.i(TAG, "RemoteCommand Message: " + message); + } + + @Override + public String toString() { + return "LoggerRemoteCommand"; + } + }; + } + + public static Tealium.Config getConfig() { + return sConfig; + } + + public static void updatePushToken(String token) { + + if (Tealium.getInstance(TealiumHelper.TEALIUM_MAIN) == null || token == null) { + return; + } + + Tealium.getInstance(TealiumHelper.TEALIUM_MAIN).getDataSources().getPersistentDataSources().edit().putString("push_token", token).apply(); + } + +} \ No newline at end of file diff --git a/Modules/Location/LocationSample/app/src/main/res/drawable-v24/ic_launcher_foreground.xml b/Modules/Location/LocationSample/app/src/main/res/drawable-v24/ic_launcher_foreground.xml new file mode 100644 index 0000000..1f6bb29 --- /dev/null +++ b/Modules/Location/LocationSample/app/src/main/res/drawable-v24/ic_launcher_foreground.xml @@ -0,0 +1,34 @@ + + + + + + + + + + + diff --git a/Modules/Location/LocationSample/app/src/main/res/drawable/ic_launcher_background.xml b/Modules/Location/LocationSample/app/src/main/res/drawable/ic_launcher_background.xml new file mode 100644 index 0000000..0d025f9 --- /dev/null +++ b/Modules/Location/LocationSample/app/src/main/res/drawable/ic_launcher_background.xml @@ -0,0 +1,170 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Modules/Location/LocationSample/app/src/main/res/drawable/tealium_logo_rgb_600x278px.png b/Modules/Location/LocationSample/app/src/main/res/drawable/tealium_logo_rgb_600x278px.png new file mode 100644 index 0000000000000000000000000000000000000000..b26670d5d630b115436cc3bf87c3bf94c94e50df GIT binary patch literal 5025 zcmds5_dgrl_YZ0`tx+0kSNrG)rLDbJTh-QS5Q0zd!=IY_yFCqa3~~kNxcED{UN-P`bayp#b##dc>~&QK0QmF_?&(;B z&rs%#p|js-*ng6!bF?q8;X$CTqV^ATsiJA&bnfbwMt&Ouof41DN>@MeIclH2 zP_Dl_g6|UdF;Gs%^j8ac{I9D1p4{cXg3O0-gNTD^h!OesYlW8yuLv{DwKrqc&tg}`%#BAHDjSyJ%kYVXfww2|uE9KKF{0Cd`c9BWDV#=0+y@zUfLMXi2D$FPGFi5YkvzJS!y{1^a@2-K4{Y<8{i8^?V`*f2 z_5I73oe@B6?Cz!Y1e)P9rKIW$;`@$9Xw`DvnWx`{FYe>^qiN3H!T}DRIUE>ALLO>&+1@E?_`82r6a zhKB~z2j@1d=hR^dr4bU8R&-m=g(?DyM_;gie@6cdV11a~J37J9NMY^uB6s5Q=_w-- z@jf>UnXsQOI=rtp{ThtzHrkC8xPPEpxQ(FR&GILP4(h=qnAOErSdBI@SNC?0h5Ek! zx7!RtiDjgyFp;CK*hCjZJ=xrze@I>7+AL|oubXTtL~>@CG3fvjvrWoi5ysdEd-$=buS*r^0u30@%E-~sCX|aIYvLGE0gxD(>YT3AgqBV z$$NT|&NifewoYc%V{(u!TG3b5n-ofGdmiJQ?iz{xc9_y1GQEYkquIOQc>r7_M(NwY zdPZ|iLd{jq?!qd^cnx37n}kgSy%Bs;gj`UFS||d#4=1>Gu5ADtaV_Z-Rb%&)Mhb>r z0kp57;uBS_(<)+tP^Izp3bjCN=Tsh=uoB?bMS6d%!<88xA7W7xel+VSeEnn1%($D} zX6>;XF(z@&_A)M~%)xhXdR%pIAyE?u{q53AL^{=^@y*ox*35S_`TQOWl5iMt%<6vN z7!P@l@F*P`PRcM~@BD70@F7^(t_l5G!r{)Bfs*DDi8bWwe?eYSmpG%|qCS`2Y8%{w zv1H}XvfsL8Jftt>Fd}{N6|cSb)Qz8&at}*MX((G_Pi(71SX%0r0e5$5VY-%)uMRs-hAj~ zQtm{O5Cz4j#QBidsHW_f9# zuBW}nN@IA=!2uQvmmhu{Wix+=wy~SzpIC-Rjz>F{lE&g=aqpEJL+vZJdp(1awLztW zG~~gemYzxyQ7iD>@4~o==>;UKJ9Lxc6XS?ZhJF9W0~w50{t)PptR+6TV4qOQA}%2} zI7}CuJw*p)TbbeoQf$hO-=FY}VmL(a`C?SRL)F{KY8X;%v2>ZtTd-h2nPY? zie8q(e?8*7yqxUS$NKO&TSl=CVOa)2xmrd)lmC$$y01HtK6NAz_Qz|ZGZ0Oh%&Vb7 zKYGM~U2q+l2sVp^&pKUN5@H_Rc)3Q)>8E*zuA!<816(OYZoYQu9h{Q_6Y`?oglXq8 zx2{!FYR!20ByD_aoHn38Cklp(a$2P?mA^9+O^&W*d$owp8;C~zB5;>aI%2*kE^-nr z%y)60)`!KBPdqb9Fur#ivj2p12Yqw)kzIP5g+Cj#6V}i4PQm2s3;=Q;nRW1|>xW#~ zrqSZL^<7Vun|9PF!cT4N;slS#11VbSXuI|*ds!&cXH65a)k@uT_Q>-h9;?BAokzD_|9su9ekQe9exYS!@x_r3JYB}DtT9lnn{MLo%$SLV(S!Jc0B z6e5TbcBjtxT2yb8vv<9*dlhnDBE+ova-P^vCAR$f!Hr$BTwd9dz4*M2@om#{aP_0? znS;l73QQX`5PfObJJvT#BQt`a1v3Ij_a};0K(XSofMC8+wr2|lQ*7+L^qwJkJ|O(5 zwjbOI&vnzmH(e143$yntE=tBlzSggcJ5BsX6q}%k-|SiKSGg`;Hm_Mg|BqD~dcEm1 zVNHPmk+P_kT|$)K(LFzPFv+uyzKAvatv_f0JBg_p?)TCck-$ZrTvXva~_Ln*bo zZ;*3={<@gx8b7aYWv3b{?(o?x?Td7~x}CfFa=%cfS1B;s-}gZ!eLn#UBc0Wrf4L@* z)Uzb8w9(h41Fs6EA1`~&cxT@&Ws$!SdL6!gvB@8IdSW?8XpaGD8AB_L^rHECQ5?=h zPJyM`6|J?=(iTvfu9ED#@JjJVnWlv0LvNcB#hy{`;-r8%CQVmcLnFZagKdYIt(DU@ z4!HHwcIxv<(+jnJ`aD(Tmh^MF(78=Jnaz`%Ofq=GhwWP_h8gy4R;7WUlu(ulzX?#p zKvU(VDzimm$!bH8uH&Ov17FEY7S#F2R;Sx)O-g6s(Yf`p_YX#-m8m|yCUY?s@fGM` zjdS}*y=7$Wp72gvj=G$1!=+@S0X;OR#i|Xc1!gaYt6aZdwov)hpl?W;s6o=zk2HBq zZVD@CJyysK3wYZuH{m?wc8uEjN=j%kJ20R;2eDW{dLy%&(|60C>)X=k(VGXQj?F56 z2L0_5dn#w~$UD(BqsFKzIaL$!3ZIRht?*sRU$0iip&czoHn6q)`7Gh)Hrm}xLK22= zp8azio-^bsb=4;RuBHj@`A>V?Db9MjiF`mRB)7j3xR3XaCF(SRo>)winl`%{x+j2uR}$^SB%XqrH; zyGjp?+DSRNu7($cP=tB9hI3UU$cBNZlO}uT$dVg7)iw%fNyXwwh30`KTU_$-8*HUI z<;ScR%>4uHOB7F^*F*?Nnb5BEkzy=wb*ZFp`B5t_IU*+M_U$K!t)oXuG+XDGvSp;H zhx_+RMXw5<81d>S9qkE#wtqn;kr@&y6vKv$QdL= z`R2rNq`suqEM0Q*Eu;6`4X++_eCQn)VViGKA9A6`C_FF!rPd2K0k$LcM-h=69?sch zBQ`Us56wL_DX60#OlA4ArCD;WbTaE1=}|6H;Elu=X%v-=_;8aWsK|>wB7*jQ$spEg z>zq`Gu$rysfs7Q#O(yR-Ppj=+LaZqAYMK3lZ9u_reWtmfuxtD278Ci?*I=_ObG{{( zF?OV|pVgdWP*2)4ClU*O+4IZxVWnN=C%&Dhmmg9^)B_-pcS^#wc}hwBExFAaD}FKk zY5S8d;=Rr9Q2y!ss76~g^H1`N*=%^U9Lj@Eir+zgno!`f8l->VXwj7a=5|^IJ9I+N z82fA)ijG801z5^t9;nF(bGfIF2`(DM$2RPm4aGf>vSEWr&j4>AtL^5iuYAU4fuS?1 z8q|RALXf5M^$P>~oRjz!-ky~d$q5~>=sau1`k&1)oK7IU6n!jfl)^{1z%9a@t?>mq zuZY)d-Y%?9Dc*jpgoGI`7=xrVT-Fo)UKL+Vd>xT_q3RQYuzX_Y)SRD29*0j3|r2x+HRT_mFnY_3tlyCk!y@vmP>KJPs&hlR~XpJytgmL+Fk?Gkb81~-tF zlic+em$ShIb6nPMgC#u{h^;?r>U#GOHNPV7T>lu0gDZ#{`FD3~6?g~0>xxSTV;X)4 zmLlLk=%0lC(LDUPT4aHx_ku@-!Dy}_S{UElgTrlO^kQ@|=sEmW8FIyRP2;Hhd zJm6%Wi8x2TiA(!8RD4ht`gMjGs`dVA`4BJhf(R5}p=@|BCemGc!C+5wFMYCkM z!?Uh^zZ=LcwU3q!zgG3(as^_qQv*>g5?mjYE4tA$vT@J~{?`AvtORh>;K9%wF8=Va zZk9KMlisN>Am%U&)WqkKIMA_`+Di{h(yM{+HgWcPOMHp)qQmyt-2Hq5=8mA9uU3UE zirWZ7Gzr3VE1@)n8bAQ}79pI4a~IJKDZDRdn31ep=XNT>2b^y!7!H;PxbrSfP0Vpfao!w0v3 z+HI+mrx83j`qjHVZ!b8EV z0BJ*3GLuDdt#PP!dzIi5`LHWy!9Zq4xET^silA;cjI!ZiT}~pAD}T5tf$8Ux#}!Ik zPx~JjmVMNrf@%QZRRi7dEa{%sptVrR7cucwZ(f&|j6`TB!00Y^(WGf8f ziO-7bh_Bp1ZchqX7&>cLyGt#?%Jq3CtLik+tM6P4ra*4Da}z(CROsAuVA{F;04mC` z`>}thA8c=#5h=)TEF@|R_XS*b@WtH!_hteTqiMB*k54JVCbh@-XZ($MJwaiAQCzwH zyk#JzVyvtvM6l1(f2W-}mffY|vy3uU6}V!;nQ{bHX7Cgyj4ts0PE}~-H3p)72;ur_ zB2aq>y~uF+i{=1gz}Wk_gL?@dv2|(;k8jr?|A{XH|5`%#aFGhc1#c+^FY(+_sO9$o zm`nOlWp2PU-1bGaJM=ujhYeIAqdJ=cyQq0~W$yWAqyLxxEjH-?vytCDWj+s3qMu2n U%n=xL8USE$-{@YIu0!1a0qN^MC;$Ke literal 0 HcmV?d00001 diff --git a/Modules/Location/LocationSample/app/src/main/res/drawable/tealium_logo_white_rgb_600x278px.png b/Modules/Location/LocationSample/app/src/main/res/drawable/tealium_logo_white_rgb_600x278px.png new file mode 100644 index 0000000000000000000000000000000000000000..2346da5497718b99c6edf2e1949fa6b69132bb29 GIT binary patch literal 4900 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 C$eOtT literal 0 HcmV?d00001 diff --git a/Modules/Location/LocationSample/app/src/main/res/layout/activity_assets.xml b/Modules/Location/LocationSample/app/src/main/res/layout/activity_assets.xml new file mode 100644 index 0000000..87eb026 --- /dev/null +++ b/Modules/Location/LocationSample/app/src/main/res/layout/activity_assets.xml @@ -0,0 +1,93 @@ + + + + + + + + + + + + + + + + +