diff --git a/Sample-App/app/build.gradle b/Sample-App/app/build.gradle index 355c23f..04ab6df 100644 --- a/Sample-App/app/build.gradle +++ b/Sample-App/app/build.gradle @@ -6,6 +6,7 @@ android { defaultConfig { applicationId "com.adobe.marketing.mobile.sampleapp" minSdkVersion 19 + buildToolsVersion '30.0.2' targetSdkVersion 31 versionCode 1 versionName "1.0" @@ -37,17 +38,21 @@ dependencies { implementation 'com.adobe.marketing.mobile:userprofile:1.+' implementation 'com.adobe.marketing.mobile:sdk-core:1.+' implementation 'com.adobe.marketing.mobile:assurance:1.+' + implementation 'com.adobe.marketing.mobile:optimize:1.+' implementation 'com.adobe.marketing.mobile:analytics:1.+' implementation 'com.adobe.marketing.mobile:edge:1.+' implementation 'com.adobe.marketing.mobile:edgeconsent:1.+' implementation 'com.adobe.marketing.mobile:edgeidentity:1.+' - implementation 'com.adobe.marketing.mobile:messaging:1.+' + implementation 'com.adobe.marketing.mobile:messaging:1.2.0-beta-2-SNAPSHOT' implementation platform('com.google.firebase:firebase-bom:27.1.0') implementation 'com.google.firebase:firebase-messaging' // Image loading implementation 'com.github.bumptech.glide:glide:4.12.0' + implementation 'androidx.lifecycle:lifecycle-livedata-ktx:2.2.0' + implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.2.0' + implementation 'androidx.recyclerview:recyclerview:1.1.0' annotationProcessor 'com.github.bumptech.glide:compiler:4.12.0' // For complete instructions on how to enable ad ID features, please see ./Documentation/README.md#advertising-identifier diff --git a/Sample-App/app/lib/messaging-phone-debug.aar b/Sample-App/app/lib/messaging-phone-debug.aar new file mode 100644 index 0000000..abaaf61 Binary files /dev/null and b/Sample-App/app/lib/messaging-phone-debug.aar differ diff --git a/Sample-App/app/src/main/java/com/adobe/marketing/mobile/sampleapp/AppConstants.java b/Sample-App/app/src/main/java/com/adobe/marketing/mobile/sampleapp/AppConstants.java index 6248d34..f90e2f9 100644 --- a/Sample-App/app/src/main/java/com/adobe/marketing/mobile/sampleapp/AppConstants.java +++ b/Sample-App/app/src/main/java/com/adobe/marketing/mobile/sampleapp/AppConstants.java @@ -2,8 +2,8 @@ public class AppConstants { public static final String INTENT_TAB_KEY = "TAB"; - public static final int TAB_CORE = 1; public static final int TAB_ASSURANCE = 0; + public static final int TAB_CORE = 1; public static final int TAB_EDGE = 2; public static final String INTENT_FROM_PUSH= "from_push"; diff --git a/Sample-App/app/src/main/java/com/adobe/marketing/mobile/sampleapp/MainApp.java b/Sample-App/app/src/main/java/com/adobe/marketing/mobile/sampleapp/MainApp.java index 942ddaa..69f0181 100644 --- a/Sample-App/app/src/main/java/com/adobe/marketing/mobile/sampleapp/MainApp.java +++ b/Sample-App/app/src/main/java/com/adobe/marketing/mobile/sampleapp/MainApp.java @@ -8,26 +8,26 @@ */ package com.adobe.marketing.mobile.sampleapp; -import com.adobe.marketing.mobile.AdobeCallback; +import android.app.Application; +import android.content.Context; +import android.util.Log; +import com.adobe.marketing.mobile.AdobeCallback; import com.adobe.marketing.mobile.Assurance; import com.adobe.marketing.mobile.Edge; +import com.adobe.marketing.mobile.InvalidInitException; +import com.adobe.marketing.mobile.Lifecycle; +import com.adobe.marketing.mobile.LoggingMode; import com.adobe.marketing.mobile.Messaging; import com.adobe.marketing.mobile.MobileCore; -import com.adobe.marketing.mobile.Lifecycle; import com.adobe.marketing.mobile.Signal; import com.adobe.marketing.mobile.UserProfile; -import com.adobe.marketing.mobile.InvalidInitException; -import com.adobe.marketing.mobile.LoggingMode; import com.adobe.marketing.mobile.edge.consent.Consent; +import com.adobe.marketing.mobile.optimize.Optimize; import com.google.android.gms.tasks.OnCompleteListener; import com.google.android.gms.tasks.Task; import com.google.firebase.messaging.FirebaseMessaging; -import android.app.Application; -import android.content.Context; -import android.util.Log; - import androidx.annotation.NonNull; import androidx.multidex.MultiDex; @@ -60,18 +60,21 @@ public void onCreate() { com.adobe.marketing.mobile.edge.identity.Identity.registerExtension(); Lifecycle.registerExtension(); Signal.registerExtension(); + Messaging.registerExtension(); Edge.registerExtension(); Assurance.registerExtension(); - Messaging.registerExtension(); + Optimize.registerExtension(); + + MobileCore.start(new AdobeCallback() { @Override public void call(Object o) { Log.d(LOG_TAG, "AEP Mobile SDK is initialized"); - } }); + } catch (InvalidInitException e) { e.printStackTrace(); } @@ -94,6 +97,8 @@ public void onComplete(@NonNull Task task) { } catch (IllegalArgumentException e) { Log.e(LOG_TAG, "IllegalArgumentException - Check if google-services.json is added and is correctly configured. \nError message: " + e.getLocalizedMessage()); } + + } @Override diff --git a/Sample-App/app/src/main/java/com/adobe/marketing/mobile/sampleapp/MenuActivity.java b/Sample-App/app/src/main/java/com/adobe/marketing/mobile/sampleapp/MenuActivity.java index 6db4c62..22ab0cf 100644 --- a/Sample-App/app/src/main/java/com/adobe/marketing/mobile/sampleapp/MenuActivity.java +++ b/Sample-App/app/src/main/java/com/adobe/marketing/mobile/sampleapp/MenuActivity.java @@ -1,7 +1,5 @@ package com.adobe.marketing.mobile.sampleapp; -import androidx.appcompat.app.AppCompatActivity; - import android.content.Intent; import android.net.Uri; import android.os.Bundle; @@ -9,6 +7,8 @@ import android.view.View; import android.widget.Button; +import androidx.appcompat.app.AppCompatActivity; + public class MenuActivity extends AppCompatActivity implements View.OnClickListener { private static final String LOG_TAG = "MenuActivity"; @@ -19,6 +19,7 @@ public class MenuActivity extends AppCompatActivity implements View.OnClickListe Button btnConsent; Button btnAssurance; Button btnMessaging; + Button btnOptimize; @Override protected void onCreate(Bundle savedInstanceState) { @@ -39,6 +40,8 @@ protected void onCreate(Bundle savedInstanceState) { btnEdgeIdentity = findViewById(R.id.btn_edgeidentity); btnConsent = findViewById(R.id.btn_consent); btnMessaging = findViewById(R.id.btn_messaging); + btnOptimize = findViewById(R.id.btn_optimize); + btnCore.setOnClickListener(this); btnEdge.setOnClickListener(this); @@ -46,6 +49,7 @@ protected void onCreate(Bundle savedInstanceState) { btnEdgeIdentity.setOnClickListener(this); btnConsent.setOnClickListener(this); btnMessaging.setOnClickListener(this); + btnOptimize.setOnClickListener(this); } private void openMainActivity(int tab) { @@ -69,6 +73,8 @@ public void onClick(View v) { break; case R.id.btn_messaging: openMainActivity(5); break; + case R.id.btn_optimize: openMainActivity(6); + break; default: break; } diff --git a/Sample-App/app/src/main/java/com/adobe/marketing/mobile/sampleapp/MessageTab.java b/Sample-App/app/src/main/java/com/adobe/marketing/mobile/sampleapp/MessageTab.java index 38bb8e1..9d3cebe 100644 --- a/Sample-App/app/src/main/java/com/adobe/marketing/mobile/sampleapp/MessageTab.java +++ b/Sample-App/app/src/main/java/com/adobe/marketing/mobile/sampleapp/MessageTab.java @@ -2,36 +2,23 @@ import android.app.Activity; import android.os.Bundle; -import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; -import android.view.inputmethod.InputMethodManager; -import android.widget.Button; -import android.widget.EditText; import android.widget.TextView; -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import androidx.fragment.app.Fragment; - import com.adobe.marketing.mobile.AdobeCallback; -import com.adobe.marketing.mobile.Edge; -import com.adobe.marketing.mobile.EdgeCallback; -import com.adobe.marketing.mobile.EdgeEventHandle; -import com.adobe.marketing.mobile.ExperienceEvent; +import com.adobe.marketing.mobile.Messaging; import com.adobe.marketing.mobile.edge.identity.Identity; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.fragment.app.Fragment; public class MessageTab extends Fragment { TextView tvECID; - private static final String LOG_TAG = "Assurance Tab"; + private static final String LOG_TAG = "Message Tab"; @Override public void onCreate(@Nullable Bundle savedInstanceState) { @@ -47,6 +34,18 @@ public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup c @Override public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { super.onViewCreated(view, savedInstanceState); + + final TextView tv_version = getView().findViewById(R.id.tv_messaging_version); + view.post(new Runnable() { + @Override + public void run() { + if (tv_version != null) { + tv_version.setText("Messaging v" + Messaging.extensionVersion()); + } + } + }); + + tvECID = view.findViewById(R.id.tv_lbl_ecidLabel); } diff --git a/Sample-App/app/src/main/java/com/adobe/marketing/mobile/sampleapp/OptimizeTab.java b/Sample-App/app/src/main/java/com/adobe/marketing/mobile/sampleapp/OptimizeTab.java new file mode 100644 index 0000000..a6c55ff --- /dev/null +++ b/Sample-App/app/src/main/java/com/adobe/marketing/mobile/sampleapp/OptimizeTab.java @@ -0,0 +1,149 @@ +package com.adobe.marketing.mobile.sampleapp; + +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.webkit.WebView; +import android.widget.Button; +import android.widget.EditText; +import android.widget.TextView; + +import com.adobe.marketing.mobile.AdobeCallbackWithError; +import com.adobe.marketing.mobile.AdobeError; +import com.adobe.marketing.mobile.Edge; +import com.adobe.marketing.mobile.ExperienceEvent; +import com.adobe.marketing.mobile.optimize.DecisionScope; +import com.adobe.marketing.mobile.optimize.Offer; +import com.adobe.marketing.mobile.optimize.Optimize; +import com.adobe.marketing.mobile.optimize.Proposition; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Map; + +import androidx.fragment.app.Fragment; + +/** + * A simple {@link Fragment} subclass. + * Use the {@link OptimizeTab#newInstance} factory method to + * create an instance of this fragment. + */ +public class OptimizeTab extends Fragment { + + boolean userIsViewingThisFragment = true; + final ArrayList htmlOfferList = new ArrayList(); + + + public OptimizeTab() { + // Required empty public constructor + } + + + public static OptimizeTab newInstance() { + OptimizeTab fragment = new OptimizeTab(); + return fragment; + } + + public void ShowExperience() { + + String htmlString ; + + if(!htmlOfferList.isEmpty()) { + + htmlString = htmlOfferList.get(0).getContent(); + + WebView mywebview = (WebView) getView().findViewById(R.id.viewMbox); + mywebview.clearCache(false); + mywebview.loadData(htmlString, "text/html", "UTF-8"); + + // Emit the displayed event when the HTML offer is clicked + htmlOfferList.get(0).displayed(); + } + + } + + public void FetchTargetPropositions() { + + // The following code is a sample showing how a custom parameter 'myAnimal' is used to fetch the right experience to show to the users + // Please modify this code for your specific Target activity and parameters + + // Step 1: Add mbox parameters + final Map data = new HashMap<>(); + final Map targetParameters = new HashMap<>(); + EditText textFieldAnimal = getView().findViewById(R.id.txtAnimalChoice); + targetParameters.put("myAnimal", textFieldAnimal.getText().toString()); + data.put("__adobe", new HashMap() { + { put("target", targetParameters); } + }); + + // Step 2: Define a decisionScope which matches the hardcoded location. + DecisionScope decisionScope = new DecisionScope("_TargetPoweredLoc"); + final ArrayList decisionScopeList = new ArrayList(); + decisionScopeList.add(decisionScope); + + // Step 3: Call the API method updatePropositions to fetch the experiences from Target + Optimize.updatePropositions(decisionScopeList, null, data); + + // Step 4: Implement the callback method which will be called when the propositions are returned + Proposition proposition; + Optimize.onPropositionsUpdate(new AdobeCallbackWithError>() { + @Override + public void fail(final AdobeError adobeError) { + // handle error + } + + @Override + public void call(final Map propositionsMap) { + + if (propositionsMap != null && !propositionsMap.isEmpty()) { + // handle propositions + for (Proposition prop : propositionsMap.values()) { + htmlOfferList.addAll(prop.getOffers()); + } + } + } + }); + } + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + } + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + // Inflate the layout for this fragment + return inflater.inflate(R.layout.fragment_optimize_tab, container, false); + } + + @Override + public void onViewCreated(View view, Bundle savedInstanceState) { + final TextView tv_version = getView().findViewById(R.id.tv_optimize_version); + view.post(new Runnable() { + @Override + public void run() { + if (tv_version != null) { + tv_version.setText("Optimize v" + Optimize.extensionVersion()); + } + } + }); + + Button buttonFetchPropositions = view.findViewById(R.id.btnFetchExperience); + buttonFetchPropositions.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + FetchTargetPropositions(); + } + }); + + Button buttonShowPropositions = view.findViewById(R.id.btnShowExperience); + buttonShowPropositions.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + ShowExperience(); + } + }); + } +} diff --git a/Sample-App/app/src/main/java/com/adobe/marketing/mobile/sampleapp/PageAdapter.java b/Sample-App/app/src/main/java/com/adobe/marketing/mobile/sampleapp/PageAdapter.java index fcdf9f2..2d37015 100644 --- a/Sample-App/app/src/main/java/com/adobe/marketing/mobile/sampleapp/PageAdapter.java +++ b/Sample-App/app/src/main/java/com/adobe/marketing/mobile/sampleapp/PageAdapter.java @@ -27,7 +27,8 @@ public class PageAdapter extends FragmentStatePagerAdapter { new EdgeIdentityTab(), new ConsentTab(), new AssuranceTab(), - new MessageTab() + new MessageTab(), + new OptimizeTab() }; public PageAdapter(FragmentManager fm, final Context context, int numOfTabs) { @@ -39,7 +40,8 @@ public PageAdapter(FragmentManager fm, final Context context, int numOfTabs) { context.getString(R.string.tab_EdgeIdentity), context.getString(R.string.tab_Consent), context.getString(R.string.tab_Assurance), - context.getString(R.string.tab_Messaging) + context.getString(R.string.tab_Messaging), + "Optimize" }; } diff --git a/Sample-App/app/src/main/res/layout/activity_main.xml b/Sample-App/app/src/main/res/layout/activity_main.xml index d7f3842..3325e91 100644 --- a/Sample-App/app/src/main/res/layout/activity_main.xml +++ b/Sample-App/app/src/main/res/layout/activity_main.xml @@ -60,6 +60,12 @@ android:layout_height="wrap_content" android:text="@string/tab_Messaging" /> + + diff --git a/Sample-App/app/src/main/res/layout/activity_menu.xml b/Sample-App/app/src/main/res/layout/activity_menu.xml index 4641974..726b43c 100644 --- a/Sample-App/app/src/main/res/layout/activity_menu.xml +++ b/Sample-App/app/src/main/res/layout/activity_menu.xml @@ -26,9 +26,10 @@ android:id="@+id/tv_core" android:layout_width="match_parent" android:layout_height="wrap_content" - android:layout_marginTop="25dp" + android:layout_marginTop="12dp" android:text="@string/home_tv_core" app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintHorizontal_bias="0.39" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@+id/tv_header" /> @@ -39,6 +40,7 @@ android:layout_marginTop="10dp" android:text="@string/home_btn_core" app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintHorizontal_bias="0.39" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@+id/tv_core" /> @@ -46,10 +48,10 @@ android:id="@+id/tv_edge" android:layout_width="match_parent" android:layout_height="wrap_content" - android:layout_marginTop="20dp" + android:layout_marginTop="8dp" android:text="@string/home_tv_edge" app:layout_constraintEnd_toEndOf="parent" - app:layout_constraintHorizontal_bias="1.0" + app:layout_constraintHorizontal_bias="0.487" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@+id/btn_core" /> @@ -87,16 +89,17 @@ android:id="@+id/tv_validation" android:layout_width="match_parent" android:layout_height="wrap_content" - android:layout_marginTop="20dp" + android:layout_marginTop="12dp" android:text="@string/home_tv_validation" app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintHorizontal_bias="0.609" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@+id/btn_consent" />