diff --git a/.gitignore b/.gitignore index 71f9913..45b2fa1 100644 --- a/.gitignore +++ b/.gitignore @@ -2,6 +2,7 @@ g*.iml .gradle .idea .kotlin +libs local.properties diff --git a/DemoApp/DemoAppJava/app/build.gradle b/DemoApp/DemoAppJava/app/build.gradle index 44e2c9b..498bbfa 100644 --- a/DemoApp/DemoAppJava/app/build.gradle +++ b/DemoApp/DemoAppJava/app/build.gradle @@ -41,11 +41,18 @@ android { dependencies { // Optable SDK - implementation "com.github.Optable:optable-android-sdk:" + versioning.getVersionName(false) + if (useReleaseSdk == "true") { + implementation "com.github.Optable:optable-android-sdk:" + versioning.getVersionName(false) + } else { + implementation "co.optable:local-sdk" + } // Google Mobile Ads implementation 'com.google.android.gms:play-services-ads:24.6.0' + // Prebid Ads + implementation "org.prebid:prebid-mobile-sdk:3.0.2" + // Base Android implementation "org.jetbrains.kotlin:kotlin-stdlib:2.0.21" implementation 'com.android.support:multidex:1.0.3' diff --git a/DemoApp/DemoAppJava/app/src/main/AndroidManifest.xml b/DemoApp/DemoAppJava/app/src/main/AndroidManifest.xml index 6757516..a228588 100644 --- a/DemoApp/DemoAppJava/app/src/main/AndroidManifest.xml +++ b/DemoApp/DemoAppJava/app/src/main/AndroidManifest.xml @@ -6,6 +6,7 @@ diff --git a/DemoApp/DemoAppJava/app/src/main/java/co/optable/demoappjava/MainActivity.java b/DemoApp/DemoAppJava/app/src/main/java/co/optable/demoappjava/MainActivity.java index ef7ce31..1e9d150 100644 --- a/DemoApp/DemoAppJava/app/src/main/java/co/optable/demoappjava/MainActivity.java +++ b/DemoApp/DemoAppJava/app/src/main/java/co/optable/demoappjava/MainActivity.java @@ -1,32 +1,55 @@ package co.optable.demoappjava; import android.os.Bundle; +import android.util.Log; import androidx.appcompat.app.AppCompatActivity; import androidx.navigation.NavController; import androidx.navigation.Navigation; import androidx.navigation.ui.AppBarConfiguration; import androidx.navigation.ui.NavigationUI; -import co.optable.android_sdk.OptableSDK; +import com.google.android.gms.ads.MobileAds; import com.google.android.material.bottomnavigation.BottomNavigationView; +import org.prebid.mobile.PrebidMobile; +import org.prebid.mobile.api.data.InitializationStatus; public class MainActivity extends AppCompatActivity { - public static OptableSDK OPTABLE; + private static final String TAG = "MainActivity"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); - MainActivity.OPTABLE = new OptableSDK(this.getApplicationContext(), "sandbox.optable.co", "ios-sdk-demo"); - + initGoogleAds(); + initPrebidSdk(); initUi(); } + private void initGoogleAds() { + MobileAds.initialize(this, initializationStatus -> { + }); + } + + private void initPrebidSdk() { + PrebidMobile.setPrebidServerAccountId("0689a263-318d-448b-a3d4-b02e8a709d9d"); + PrebidMobile.initializeSdk(getApplicationContext(), "https://prebid-server-test-j.prebid.org/openrtb2/auction", status -> { + if (status == InitializationStatus.SUCCEEDED) { + Log.d(TAG, "SDK initialized successfully!"); + } else { + Log.e(TAG, "SDK initialization error: " + status.getDescription()); + } + }); + } + private void initUi() { BottomNavigationView navView = findViewById(R.id.nav_view); NavController navController = Navigation.findNavController(this, R.id.nav_host_fragment); - AppBarConfiguration appBarConfiguration = new AppBarConfiguration.Builder(R.id.navigation_identify, R.id.navigation_gambanner).build(); + AppBarConfiguration appBarConfiguration = new AppBarConfiguration.Builder( + R.id.navigation_identify, + R.id.navigation_gambanner, + R.id.navigation_prebid + ).build(); NavigationUI.setupActionBarWithNavController(this, navController, appBarConfiguration); NavigationUI.setupWithNavController(navView, navController); } diff --git a/DemoApp/DemoAppJava/app/src/main/java/co/optable/demoappjava/TheApplication.java b/DemoApp/DemoAppJava/app/src/main/java/co/optable/demoappjava/TheApplication.java new file mode 100644 index 0000000..0f84c6b --- /dev/null +++ b/DemoApp/DemoAppJava/app/src/main/java/co/optable/demoappjava/TheApplication.java @@ -0,0 +1,19 @@ +package co.optable.demoappjava; + +import android.app.Application; +import co.optable.android_sdk.OptableConfig; +import co.optable.android_sdk.OptableSDK; + +public class TheApplication extends Application { + + public static OptableSDK optable; + + @Override + public void onCreate() { + super.onCreate(); + + OptableConfig config = new OptableConfig(this, "prebidtest", "js-sdk", "ca.edge.optable.co"); + optable = new OptableSDK(config); + } + +} diff --git a/DemoApp/DemoAppJava/app/src/main/java/co/optable/demoappjava/ui/GAMBanner/GAMBannerFragment.java b/DemoApp/DemoAppJava/app/src/main/java/co/optable/demoappjava/ui/GAMBanner/GAMBannerFragment.java deleted file mode 100644 index d717c4f..0000000 --- a/DemoApp/DemoAppJava/app/src/main/java/co/optable/demoappjava/ui/GAMBanner/GAMBannerFragment.java +++ /dev/null @@ -1,161 +0,0 @@ -package co.optable.demoappjava.ui.GAMBanner; - -import android.os.Bundle; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.TextView; -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import androidx.fragment.app.Fragment; -import co.optable.android_sdk.OptableSDK; -import co.optable.demoappjava.MainActivity; -import co.optable.demoappjava.R; -import com.google.android.gms.ads.AdRequest; -import com.google.android.gms.ads.admanager.AdManagerAdRequest; -import com.google.android.gms.ads.admanager.AdManagerAdView; - -import java.util.Collection; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -public class GAMBannerFragment extends Fragment { - - private AdManagerAdView mAdView; - private TextView statusTextView; - - @Override - public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { - View root = inflater.inflate(R.layout.fragment_gambanner, container, false); - initUi(root); - return root; - } - - private void initUi(View root) { - mAdView = root.findViewById(R.id.publisherAdView); - statusTextView = root.findViewById(R.id.targetingDataView); - - root.findViewById(R.id.btnLoadBanner).setOnClickListener(view -> onClickLoadAd()); - root.findViewById(R.id.btnCachedBanner).setOnClickListener(view -> onClickCachedBanner()); - root.findViewById(R.id.btnClearCache).setOnClickListener(view -> onClickClearCache()); - } - - /** - * Loads targeting data and then the GAM banner - */ - private void onClickLoadAd() { - statusTextView.setText(""); - - MainActivity.OPTABLE - .targeting() - .observe(getViewLifecycleOwner(), result -> { - AdManagerAdRequest.Builder adRequest = new AdManagerAdRequest.Builder(); - - if (result.getStatus() == OptableSDK.Status.SUCCESS) { - HashMap> data = result.getData(); - changeStatusText("Loading GAM ad with targeting data", data); - - if (data != null) { - for (String key : data.keySet()) { - List values = data.get(key); - if (values == null) continue; - adRequest.addCustomTargeting(key, values); - } - } - } else { - changeStatusText("Error getting targeting data: " + result.getMessage(), null); - } - - mAdView.loadAd(adRequest.build()); - profile(); - witness(); - }); - } - - /** - * Loads targeting data from cache and then the GAM banner - */ - private void onClickCachedBanner() { - statusTextView.setText(""); - - AdRequest.Builder adRequest = new AdRequest.Builder(); - HashMap> data = MainActivity.OPTABLE.targetingFromCache(); - - if (data != null) { - changeStatusText("Loading GAM ad with cached targeting data", data); - for (String key : data.keySet()) { - List values = data.get(key); - if (values == null) continue; - adRequest.addCustomTargeting(key, values); - } - } else { - changeStatusText("Targeting data cache empty.", null); - } - - mAdView.loadAd(adRequest.build()); - profile(); - witness(); - } - - /** - * Clears targeting data cache. - */ - private void onClickClearCache() { - statusTextView.setText("Clearing targeting data cache.\n\n"); - MainActivity.OPTABLE.targetingClearCache(); - } - - private void profile() { - HashMap traits = new HashMap<>(); - traits.put("gender", "F"); - traits.put("age", 38); - traits.put("hasAccount", true); - - MainActivity.OPTABLE - .profile(traits) - .observe(getViewLifecycleOwner(), result -> { - if (result.getStatus() == OptableSDK.Status.SUCCESS) { - appendStatusText("Success calling profile API to set traits on user."); - } else { - appendStatusText("Error during sending profile: " + result.getMessage()); - } - }); - } - - private void witness() { - HashMap eventProperties = new HashMap<>(); - eventProperties.put("exampleKey", "exampleValue"); - eventProperties.put("exampleKey2", 123); - eventProperties.put("exampleKey3", false); - - MainActivity.OPTABLE - .witness("GAMBannerFragment.loadAdButtonClicked", eventProperties) - .observe(getViewLifecycleOwner(), result -> { - if (result.getStatus() == OptableSDK.Status.SUCCESS) { - appendStatusText("Success calling witness API to log loadAdButtonClicked event."); - } else { - appendStatusText("Error during sending witness: " + result.getMessage()); - } - }); - } - - private void changeStatusText(@NonNull String message, @Nullable HashMap> optableResponse) { - StringBuilder formattedMessage = new StringBuilder(message); - if (optableResponse != null) { - formattedMessage.append("\n\nTargeting data: "); - for (Map.Entry> entry : optableResponse.entrySet()) { - formattedMessage.append(entry.getKey()) - .append(" = ") - .append(entry.getValue()) - .append("\n"); - } - } - statusTextView.setText(formattedMessage.toString()); - } - - private void appendStatusText(@NonNull String message) { - statusTextView.append("\n\n" + message); - } - -} \ No newline at end of file diff --git a/DemoApp/DemoAppJava/app/src/main/java/co/optable/demoappjava/ui/GamBannerFragment.java b/DemoApp/DemoAppJava/app/src/main/java/co/optable/demoappjava/ui/GamBannerFragment.java new file mode 100644 index 0000000..c9fceaf --- /dev/null +++ b/DemoApp/DemoAppJava/app/src/main/java/co/optable/demoappjava/ui/GamBannerFragment.java @@ -0,0 +1,150 @@ +package co.optable.demoappjava.ui; + +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.TextView; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.fragment.app.Fragment; +import co.optable.android_sdk.OptableIdentifiers; +import co.optable.android_sdk.OptableResult; +import co.optable.android_sdk.OptableSDK; +import co.optable.android_sdk.OptableTargeting; +import co.optable.demoappjava.R; +import co.optable.demoappjava.TheApplication; +import com.google.android.gms.ads.admanager.AdManagerAdRequest; +import com.google.android.gms.ads.admanager.AdManagerAdView; +import kotlin.Unit; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class GamBannerFragment extends Fragment { + + private AdManagerAdView mAdView; + private TextView statusTextView; + + private OptableSDK optable; + + @Override + public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { + View root = inflater.inflate(R.layout.fragment_gambanner, container, false); + initUi(root); + optable = TheApplication.optable; + return root; + } + + private void initUi(View root) { + mAdView = root.findViewById(R.id.publisherAdView); + statusTextView = root.findViewById(R.id.statusTextView); + + root.findViewById(R.id.btnLoadBanner).setOnClickListener(view -> onClickLoadAd()); + root.findViewById(R.id.btnCachedBanner).setOnClickListener(view -> onClickCachedBanner()); + root.findViewById(R.id.btnClearCache).setOnClickListener(view -> onClickClearCache()); + } + + /** + * Loads targeting data and then the GAM banner + */ + private void onClickLoadAd() { + statusTextView.setText(""); + + OptableIdentifiers ids = new OptableIdentifiers.Builder().email("test@test.com").build(); + optable.targeting(ids, result -> { + AdManagerAdRequest.Builder requestBuilder = new AdManagerAdRequest.Builder(); + + if (result instanceof OptableResult.Success success) { + applyOptableToGam(requestBuilder, success.getData()); + changeStatusText("Targeting success: " + success.getData().getAudiences()); + } else if (result instanceof OptableResult.Error error) { + changeStatusText("Targeting error: " + error.getMessage()); + } + + mAdView.loadAd(requestBuilder.build()); + profile(); + witness(); + }); + } + + /** + * Loads targeting data from cache and then the GAM banner + */ + private void onClickCachedBanner() { + statusTextView.setText(""); + + AdManagerAdRequest.Builder requestBuilder = new AdManagerAdRequest.Builder(); + + OptableTargeting optableTargeting = optable.targetingFromCache(); + if (optableTargeting != null) { + changeStatusText("Targeting from cache: " + optableTargeting.getAudiences()); + applyOptableToGam(requestBuilder, optableTargeting); + } else { + changeStatusText("Targeting cache is empty"); + } + + mAdView.loadAd(requestBuilder.build()); + profile(); + witness(); + } + + private void applyOptableToGam(AdManagerAdRequest.Builder builder, @Nullable OptableTargeting targeting) { + if (targeting == null) return; + + Map> audiences = targeting.getAudiences(); + if (audiences != null) { + for (Map.Entry> entry : audiences.entrySet()) { + builder.addCustomTargeting(entry.getKey(), entry.getValue()); + } + } + } + + /** + * Clears targeting data cache. + */ + private void onClickClearCache() { + statusTextView.setText("Clearing targeting data cache."); + optable.targetingClearCache(); + } + + private void profile() { + HashMap traits = new HashMap<>(); + traits.put("gender", "F"); + traits.put("age", 38); + traits.put("hasAccount", true); + + optable.profile(traits, result -> { + if (result instanceof OptableResult.Success) { + appendStatusText("Profile success"); + } else if (result instanceof OptableResult.Error error) { + appendStatusText("Profile error: " + error.getMessage()); + } + }); + } + + private void witness() { + HashMap eventProperties = new HashMap<>(); + eventProperties.put("exampleKey", "exampleValue"); + eventProperties.put("exampleKey2", 123); + eventProperties.put("exampleKey3", false); + + optable.witness("GAMBannerFragment.loadAdButtonClicked", eventProperties, result -> { + if (result instanceof OptableResult.Success) { + appendStatusText("Witness success"); + } else if (result instanceof OptableResult.Error error) { + appendStatusText("Witness error: " + error.getMessage()); + } + }); + } + + private void changeStatusText(@NonNull String message) { + statusTextView.setText(message); + } + + private void appendStatusText(@NonNull String message) { + statusTextView.append("\n\n" + message); + } + +} \ No newline at end of file diff --git a/DemoApp/DemoAppJava/app/src/main/java/co/optable/demoappjava/ui/Identify/IdentifyFragment.java b/DemoApp/DemoAppJava/app/src/main/java/co/optable/demoappjava/ui/IdentifyFragment.java similarity index 65% rename from DemoApp/DemoAppJava/app/src/main/java/co/optable/demoappjava/ui/Identify/IdentifyFragment.java rename to DemoApp/DemoAppJava/app/src/main/java/co/optable/demoappjava/ui/IdentifyFragment.java index b73e02c..78a9287 100644 --- a/DemoApp/DemoAppJava/app/src/main/java/co/optable/demoappjava/ui/Identify/IdentifyFragment.java +++ b/DemoApp/DemoAppJava/app/src/main/java/co/optable/demoappjava/ui/IdentifyFragment.java @@ -1,4 +1,4 @@ -package co.optable.demoappjava.ui.Identify; +package co.optable.demoappjava.ui; import android.os.Bundle; import android.view.LayoutInflater; @@ -9,9 +9,11 @@ import android.widget.TextView; import androidx.annotation.NonNull; import androidx.fragment.app.Fragment; +import co.optable.android_sdk.OptableResult; import co.optable.android_sdk.OptableSDK; -import co.optable.demoappjava.MainActivity; import co.optable.demoappjava.R; +import co.optable.demoappjava.TheApplication; +import kotlin.Unit; public class IdentifyFragment extends Fragment { @@ -19,10 +21,13 @@ public class IdentifyFragment extends Fragment { private EditText emailText; private Switch gaidSwitch; + private OptableSDK optable; + @Override public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View root = inflater.inflate(R.layout.fragment_identify, container, false); initUi(root); + optable = TheApplication.optable; return root; } @@ -37,19 +42,13 @@ private void initUi(View root) { private void onClickIdentify() { identifyView.setText(""); - MainActivity.OPTABLE - .identify(emailText.getText().toString(), gaidSwitch.isChecked()) - .observe(getViewLifecycleOwner(), result -> { - String msg = "Calling identify API... "; - - if (result.getStatus() == OptableSDK.Status.SUCCESS) { - msg += "Success"; - } else { - msg += "\n\nOptableSDK Error: " + result.getMessage(); - } - - identifyView.setText(msg); - }); + optable.identify(emailText.getText().toString(), gaidSwitch.isChecked(), result -> { + if (result instanceof OptableResult.Success) { + identifyView.setText("Identify success"); + } else if (result instanceof OptableResult.Error error) { + identifyView.setText("Identify error: " + error.getMessage()); + } + }); } } diff --git a/DemoApp/DemoAppJava/app/src/main/java/co/optable/demoappjava/ui/PrebidBannerFragment.java b/DemoApp/DemoAppJava/app/src/main/java/co/optable/demoappjava/ui/PrebidBannerFragment.java new file mode 100644 index 0000000..eeb6619 --- /dev/null +++ b/DemoApp/DemoAppJava/app/src/main/java/co/optable/demoappjava/ui/PrebidBannerFragment.java @@ -0,0 +1,205 @@ +package co.optable.demoappjava.ui; + +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.TextView; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.fragment.app.Fragment; +import co.optable.android_sdk.OptableIdentifiers; +import co.optable.android_sdk.OptableResult; +import co.optable.android_sdk.OptableSDK; +import co.optable.android_sdk.OptableTargeting; +import co.optable.demoappjava.R; +import co.optable.demoappjava.TheApplication; +import com.google.android.gms.ads.AdListener; +import com.google.android.gms.ads.LoadAdError; +import com.google.android.gms.ads.admanager.AdManagerAdRequest; +import com.google.android.gms.ads.admanager.AdManagerAdView; +import kotlin.Unit; +import org.jetbrains.annotations.NotNull; +import org.prebid.mobile.BannerAdUnit; +import org.prebid.mobile.TargetingParams; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class PrebidBannerFragment extends Fragment { + + private static final String GAM_AD_UNIT_ID = "/21808260008/prebid_demo_app_original_api_banner"; + private static final String PREBID_CONFIG_ID = "prebid-demo-banner-320-50"; + private static final int WIDTH = 320; + private static final int HEIGHT = 50; + + private AdManagerAdView adView; + private BannerAdUnit prebidAdUnit; + + private ViewGroup adContainer; + private TextView statusTextView; + + private OptableSDK optable; + + @Override + public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { + View root = inflater.inflate(R.layout.fragment_prebid, container, false); + initUi(root); + optable = TheApplication.optable; + return root; + } + + private void initUi(View root) { + statusTextView = root.findViewById(R.id.statusTextView); + adContainer = root.findViewById(R.id.adContainer); + + root.findViewById(R.id.btnLoadBanner).setOnClickListener(view -> onClickLoadAd()); + root.findViewById(R.id.btnCachedBanner).setOnClickListener(view -> onClickCachedBanner()); + root.findViewById(R.id.btnClearCache).setOnClickListener(view -> onClickClearCache()); + } + + /** + * Loads targeting data and then the GAM banner + */ + private void onClickLoadAd() { + statusTextView.setText(""); + + OptableIdentifiers ids = new OptableIdentifiers.Builder().email("test@test.com").build(); + optable.targeting(ids, optableResult -> { + OptableTargeting optableTargeting = null; + if (optableResult instanceof OptableResult.Success success) { + changeStatusText("Targeting success: " + success.getData().getAudiences()); + optableTargeting = success.getData(); + } else if (optableResult instanceof OptableResult.Error error) { + changeStatusText("Targeting error: " + error.getMessage()); + } + + loadPrebidAd(optableTargeting); + profile(); + witness(); + }); + } + + private void loadPrebidAd(@Nullable OptableTargeting optableTargeting) { + AdManagerAdRequest.Builder adRequestBuilder = new AdManagerAdRequest.Builder(); + + prebidAdUnit = new BannerAdUnit(PREBID_CONFIG_ID, WIDTH, HEIGHT); + applyOptableToPrebid(optableTargeting); + prebidAdUnit.fetchDemand(adRequestBuilder, resultCode -> { + appendStatusText("Prebid ads loading status: " + resultCode.toString()); + loadGamAd(adRequestBuilder, optableTargeting); + }); + } + + private void loadGamAd(AdManagerAdRequest.Builder requestBuilder, @Nullable OptableTargeting optableTargeting) { + applyOptableToGam(requestBuilder, optableTargeting); + + adContainer.removeAllViews(); + + adView = new AdManagerAdView(requireContext()); + adView.setAdUnitId(GAM_AD_UNIT_ID); + adView.setAdSizes(new com.google.android.gms.ads.AdSize(WIDTH, HEIGHT)); + adView.setAdListener(new AdListener() { + @Override + public void onAdLoaded() { + super.onAdLoaded(); + appendStatusText("Google ad loaded"); + } + + @Override + public void onAdFailedToLoad(@NonNull @NotNull LoadAdError loadAdError) { + appendStatusText("Google ad failed to load: " + loadAdError.getMessage()); + } + }); + adView.loadAd(requestBuilder.build()); + + adContainer.addView(adView); + } + + /** + * Loads targeting data from cache and then the GAM banner + */ + private void onClickCachedBanner() { + OptableTargeting targeting = optable.targetingFromCache(); + if (targeting != null) { + changeStatusText("Targeting from cache: " + targeting.getAudiences()); + } else { + changeStatusText("Targeting data cache empty."); + } + + loadPrebidAd(targeting); + profile(); + witness(); + } + + /** + * Clears targeting data cache. + */ + private void onClickClearCache() { + statusTextView.setText("Clearing targeting data cache.\n\n"); + optable.targetingClearCache(); + } + + private void applyOptableToPrebid(@Nullable OptableTargeting optableResult) { + if (optableResult == null) { + TargetingParams.setGlobalOrtbConfig(null); + return; + } + + String openRtbJson = optableResult.getOpenRtbJson(); + if (openRtbJson != null) { + TargetingParams.setGlobalOrtbConfig(openRtbJson); + } + } + + private void applyOptableToGam(AdManagerAdRequest.Builder builder, @Nullable OptableTargeting targeting) { + if (targeting == null) return; + + Map> audiences = targeting.getAudiences(); + if (audiences != null) { + for (Map.Entry> entry : audiences.entrySet()) { + builder.addCustomTargeting(entry.getKey(), entry.getValue()); + } + } + } + + private void profile() { + HashMap traits = new HashMap<>(); + traits.put("gender", "F"); + traits.put("age", 38); + traits.put("hasAccount", true); + + optable.profile(traits, result -> { + if (result instanceof OptableResult.Success) { + appendStatusText("Profile Success"); + } else if (result instanceof OptableResult.Error error) { + appendStatusText("Profile Error: " + error.getMessage()); + } + }); + } + + private void witness() { + HashMap eventProperties = new HashMap<>(); + eventProperties.put("exampleKey", "exampleValue"); + eventProperties.put("exampleKey2", 123); + eventProperties.put("exampleKey3", false); + + optable.witness("GAMBannerFragment.loadAdButtonClicked", eventProperties, result -> { + if (result instanceof OptableResult.Success) { + appendStatusText("Witness Success"); + } else if (result instanceof OptableResult.Error error) { + appendStatusText("Witness Error: " + error.getMessage()); + } + }); + } + + private void changeStatusText(@NonNull String message) { + statusTextView.setText(message); + } + + private void appendStatusText(@NonNull String message) { + statusTextView.append("\n\n" + message); + } + +} \ No newline at end of file diff --git a/DemoApp/DemoAppJava/app/src/main/res/layout/activity_main.xml b/DemoApp/DemoAppJava/app/src/main/res/layout/activity_main.xml index 38c0aa8..472e2b8 100644 --- a/DemoApp/DemoAppJava/app/src/main/res/layout/activity_main.xml +++ b/DemoApp/DemoAppJava/app/src/main/res/layout/activity_main.xml @@ -1,33 +1,25 @@ - - - + android:orientation="vertical" + android:layout_height="match_parent"> - \ No newline at end of file + + + \ No newline at end of file diff --git a/DemoApp/DemoAppJava/app/src/main/res/layout/fragment_gambanner.xml b/DemoApp/DemoAppJava/app/src/main/res/layout/fragment_gambanner.xml index 2fe5cbc..4ef0fcd 100644 --- a/DemoApp/DemoAppJava/app/src/main/res/layout/fragment_gambanner.xml +++ b/DemoApp/DemoAppJava/app/src/main/res/layout/fragment_gambanner.xml @@ -1,10 +1,45 @@ - + android:orientation="vertical" + tools:context=".ui.GamBannerFragment"> + + + +