Skip to content
This repository was archived by the owner on Oct 2, 2023. It is now read-only.

Commit 83509d8

Browse files
authored
Merge pull request #26 from timkimadobe/edge-identity-ad-id
Implementation for Edge Identity ad ID + getUrlVariables features
2 parents 96e60f3 + 1ae324c commit 83509d8

File tree

12 files changed

+297
-15
lines changed

12 files changed

+297
-15
lines changed

Documentation/README.md

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,3 +9,58 @@ Before using messaging feature in the sample app you need to follow the below st
99
1. Setup [Journey Optimizer](https://aep-sdks.gitbook.io/docs/beta/adobe-journey-optimizer)
1010
1. Update the `LAUNCH_ENVIRONMENT_FILE_ID` constant value in `Sample-App/app/src/java/com/adobe/marketing/mobile/sampleapp/MainApp.Java` file with the config app id of the property.
1111
For more information on how to get the config app id from launch check this [document](https://experienceleague.adobe.com/docs/launch/using/publish/environments/environments.html?lang=en#mobile-configuration)
12+
13+
14+
# Advertising identifier
15+
16+
## Configuration
17+
To enable advertising identifier features in the sample app, follow these steps:
18+
1. Update the value for key `gms_ads_app_id` located in the `secrets.xml` at [aepsdk-sample-app-android/Sample-App/app/src/main/res/values](../Sample-App/app/src/main/res/values/secrets.xml) with a valid Google AdMob app ID.
19+
- See Google's [quick start reference](https://developers.google.com/admob/android/quick-start) on how to get your AdMob app ID. See step 3 of the [Configure your app](https://developers.google.com/admob/android/quick-start#import_the_mobile_ads_sdk) section for a free public test app ID from Google.
20+
- Any real key values in the `secrets.xml` file should **not** be committed to the repository.
21+
2. By default, the ad ID features are commented out in the sample app. To enable these features, uncomment the implemention code using [find and replace all](https://www.jetbrains.com/help/idea/finding-and-replacing-text-in-project.html#replace_search_string_in_project) to replace all instances of:
22+
```java
23+
/* Ad ID implementation
24+
```
25+
with:
26+
```java
27+
//* Ad ID implementation
28+
```
29+
Each code block has a pair of block comments wrapped around it to enable this behavior:
30+
```java
31+
/* Ad ID implementation (pt. 1/4)
32+
<commented implementation code...>
33+
/* Ad ID implementation (pt. 1/4) */
34+
```
35+
36+
After replacement it will become:
37+
```java
38+
//* Ad ID implementation (pt. 1/4)
39+
<active implementation code!>
40+
//* Ad ID implementation (pt. 1/4) */
41+
```
42+
43+
For convenience, these are the default find and replace shortcuts in Android Studio:
44+
[<img src="./assets/find-and-replace-shortcuts.png" alt="Default shortcuts for find and replace" width="500"/>](./assets/find-and-replace-shortcuts.png)
45+
46+
The shortcut should open a window that looks like the following:
47+
[<img src="./assets/find-and-replace-all-example.png" alt="Example of find and replace" width="500"/>](./assets/find-and-replace-all-example.png)
48+
There should be 4 pairs of special comment blocks (8 total matches) across two files:
49+
`EdgeIdentityTab.java` and `app/build.gradle`
50+
51+
3. With the implementation code and gradle files uncommented with new dependencies, sync the project with the Gradle file changes using: File -> Sync Project with Gradle Files
52+
53+
[<img src="./assets/sync-project-gradle-example.png" alt="Example of find and replace" width="500"/>](./assets/sync-project-gradle-example.png)
54+
55+
The app should now be properly configured to use advertising identifier features.
56+
57+
To **disable** these features, follow these steps:
58+
1. [Find and replace](https://www.jetbrains.com/help/idea/finding-and-replacing-text-in-project.html#replace_search_string_in_project) all instances of:
59+
```java
60+
//* Ad ID implementation
61+
```
62+
with:
63+
```java
64+
/* Ad ID implementation
65+
```
66+
2. Sync Project with Gradle files using: File -> Sync Project with Gradle Files
453 KB
Loading
53.2 KB
Loading
538 KB
Loading

README.md

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,14 @@ This repository contains the Android sample app for the AEP SDK.
1212

1313
## Installation
1414

15-
- Open Android Studio and select `Open an existing project` from the main screen or click `File -> Open...` .
16-
- Import the Sample-App/settings.gradle file into Android Studio.
17-
- Run Android `app` on the emulator or on real device.
15+
1. Open Android Studio and select `Open an existing project` from the main screen or click `File -> Open...` .
16+
2. Import the Sample-App/settings.gradle file into Android Studio.
17+
3. Set your `ENVIRONMENT_FILE_ID` in MainApp.java.
18+
4. Run Android `app` on the emulator or on real device.
1819

1920
## Documentation
20-
### Launch Edge Extensions Prerequisites
21-
App needs to be configured with the following edge extensions in Launch before it can be used:
21+
### Edge Extensions Prerequisites
22+
The app needs to be configured with the following Edge extensions in the Data Collection UI before it can be used:
2223
- [Edge](https://aep-sdks.gitbook.io/docs/foundation-extensions/experience-platform-extension)
2324
- [Edge Identity](https://aep-sdks.gitbook.io/docs/foundation-extensions/identity-for-edge-network)
2425
- [Consent](https://aep-sdks.gitbook.io/docs/foundation-extensions/consent-for-edge-network)
@@ -30,6 +31,9 @@ Follow the [documentation](https://aep-sdks.gitbook.io/docs/foundation-extension
3031
### Messaging
3132
Follow the [documentation](Documentation/README.md) for using the messaging features.
3233

34+
### Advertising Identifier
35+
Follow the [documentation](Documentation/README.md#advertising-identifier) for enabling advertising identifier features.
36+
3337
## Contributing
3438

3539
Contributions are welcomed! Read the [Contributing Guide](./.github/CONTRIBUTING.md) for more information.

Sample-App/app/build.gradle

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,22 +2,26 @@ apply plugin: 'com.android.application'
22
apply plugin: 'com.google.gms.google-services'
33

44
android {
5-
compileSdkVersion 29
6-
buildToolsVersion "29.0.2"
5+
compileSdkVersion 31
76
defaultConfig {
87
applicationId "com.adobe.marketing.mobile.sampleapp"
98
minSdkVersion 19
10-
targetSdkVersion 29
9+
targetSdkVersion 31
1110
versionCode 1
1211
versionName "1.0"
1312
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
13+
multiDexEnabled true
1414
}
1515
buildTypes {
1616
release {
1717
minifyEnabled false
1818
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
1919
}
2020
}
21+
compileOptions {
22+
sourceCompatibility JavaVersion.VERSION_1_8
23+
targetCompatibility JavaVersion.VERSION_1_8
24+
}
2125
}
2226

2327
dependencies {
@@ -45,4 +49,15 @@ dependencies {
4549
// Image loading
4650
implementation 'com.github.bumptech.glide:glide:4.12.0'
4751
annotationProcessor 'com.github.bumptech.glide:compiler:4.12.0'
52+
53+
// For complete instructions on how to enable ad ID features, please see ./Documentation/README.md#advertising-identifier
54+
/* Ad ID implementation (pt. 1/4)
55+
// GAID Advertising Tracking
56+
implementation("com.google.android.gms:play-services-ads-lite:20.6.0")
57+
implementation("com.google.guava:guava:31.1-android")
58+
/* Ad ID implementation (pt. 1/4) */
59+
60+
// Multidex support
61+
def multidex_version = "2.0.1"
62+
implementation "androidx.multidex:multidex:$multidex_version"
4863
}

Sample-App/app/src/main/AndroidManifest.xml

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,8 @@
2424
android:supportsRtl="true"
2525
android:theme="@style/AppTheme"
2626
tools:replace="android:icon,android:roundIcon">
27-
<activity android:name=".MenuActivity">
27+
<activity android:name=".MenuActivity"
28+
android:exported="true">
2829
<intent-filter>
2930
<action android:name="android.intent.action.MAIN" />
3031

@@ -65,7 +66,10 @@
6566
<action android:name="com.google.firebase.MESSAGING_EVENT" />
6667
</intent-filter>
6768
</service>
68-
69+
<!-- Google Ads -->
70+
<meta-data
71+
android:name="com.google.android.gms.ads.APPLICATION_ID"
72+
android:value="@string/gms_ads_app_id"/>
6973
</application>
7074

7175
</manifest>

Sample-App/app/src/main/java/com/adobe/marketing/mobile/sampleapp/EdgeIdentityTab.java

Lines changed: 122 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,15 +24,30 @@
2424
import com.adobe.marketing.mobile.edge.identity.Identity;
2525
import com.adobe.marketing.mobile.edge.identity.IdentityItem;
2626
import com.adobe.marketing.mobile.edge.identity.IdentityMap;
27+
2728
import com.google.gson.Gson;
2829
import com.google.gson.GsonBuilder;
2930

31+
// For complete instructions on how to enable ad ID features, please see ./Documentation/README.md#advertising-identifier
32+
/* Ad ID implementation (pt. 2/4)
33+
import android.os.Handler;
34+
import android.os.Looper;
35+
import com.adobe.marketing.mobile.MobileCore;
36+
import com.google.android.gms.ads.identifier.AdvertisingIdClient;
37+
import com.google.android.gms.common.GooglePlayServicesNotAvailableException;
38+
import com.google.android.gms.common.GooglePlayServicesRepairableException;
39+
import java.io.IOException;
40+
import java.util.concurrent.ExecutorService;
41+
import java.util.concurrent.Executors;
42+
/* Ad ID implementation (pt. 2/4) */
43+
3044
/**
3145
* A simple {@link Fragment} subclass.
3246
* create an instance of this fragment.
3347
*/
3448
public class EdgeIdentityTab extends Fragment implements NavigationAware {
3549
private static final String LOG_TAG = "EdgeIdentityTab";
50+
private static final String ZERO_ADVERTISING_ID = "00000000-0000-0000-0000-000000000000";
3651

3752
@Override
3853
public void onCreate(Bundle savedInstanceState) {
@@ -105,6 +120,75 @@ public void call(String ecid) {
105120
});
106121
}
107122
});
123+
124+
// Default hint for how to enable ad ID features; overwritten by actual implementation when ad ID features are enabled.
125+
Button btnUpdateAdId = getView().findViewById(R.id.btn_edge_identity_get_gaid);
126+
btnUpdateAdId.setOnClickListener(new View.OnClickListener() {
127+
@Override
128+
public void onClick(final View v) {
129+
Log.d(LOG_TAG,"For complete instructions on how to enable ad ID features, please see ./Documentation/README.md#advertising-identifier");
130+
}
131+
});
132+
133+
// Edge Identity Advertising Identifier
134+
/* Ad ID implementation (pt. 3/4)
135+
btnUpdateAdId.setOnClickListener(new View.OnClickListener() {
136+
@Override
137+
public void onClick(final View v) {
138+
getAdvertisingIdClientInfo(new AdobeCallback<AdvertisingIdClient.Info>() {
139+
@Override
140+
public void call(AdvertisingIdClient.Info info) {
141+
Handler handler = new Handler(Looper.getMainLooper());
142+
143+
String adIdText = "Unable to get valid AdvertisingIdClient.Info";
144+
String trackingAuthorizationText = "See console for error logs";
145+
146+
if (info != null) {
147+
if (info.isLimitAdTrackingEnabled()) {
148+
adIdText = "";
149+
trackingAuthorizationText = "Ad tracking disabled";
150+
} else {
151+
adIdText = info.getId();
152+
trackingAuthorizationText = "Ad tracking enabled";
153+
}
154+
// Update ad ID through MobileCore only when a valid Info instance is available
155+
// to fetch the latest state
156+
MobileCore.setAdvertisingIdentifier(adIdText);
157+
}
158+
159+
final String finalAdId = adIdText;
160+
final String finalTrackingAuthorizationText = trackingAuthorizationText;
161+
handler.post(new Runnable() {
162+
@Override
163+
public void run() {
164+
TextView gaidTextView = getView().findViewById(R.id.label_edge_identity_gaid_placeholder);
165+
gaidTextView.setText(finalAdId);
166+
TextView adTrackingTextView = getView().findViewById(R.id.label_edge_identity_ad_tracking_enabled);
167+
adTrackingTextView.setText(finalTrackingAuthorizationText);
168+
}
169+
});
170+
}
171+
});
172+
}
173+
});
174+
/* Ad ID implementation (pt. 3/4) */
175+
176+
// getURLVariables API's
177+
Button btnGetUrlVariables = getView().findViewById(R.id.btn_edge_identity_get_urlvariables);
178+
btnGetUrlVariables.setOnClickListener(new View.OnClickListener() {
179+
@Override
180+
public void onClick(final View v) {
181+
182+
Identity.getUrlVariables(new AdobeCallback<String>() {
183+
@Override
184+
public void call(String urlVariablesString) {
185+
Log.i(LOG_TAG, String.format("Received URLVariables from API = %s", urlVariablesString));
186+
TextView getUrlVariablesTextView = getView().findViewById(R.id.label_edge_identity_get_urlvariables_placeholder);
187+
getUrlVariablesTextView.setText(urlVariablesString);
188+
}
189+
});
190+
}
191+
});
108192
}
109193

110194
@Override
@@ -136,4 +220,41 @@ public void run() {
136220
}
137221
});
138222
}
139-
}
223+
224+
/**
225+
* Async method that retrieves the {@link AdvertisingIdClient.Info} (using Google's gms.ads SDK).
226+
* Callers <strong>MUST</strong> verify that the result of the callback is not null before using any of its properties.
227+
*
228+
* @param callback receives the {@link AdvertisingIdClient.Info} if a valid value can be retrieved, {@code null} otherwise.
229+
*/
230+
/* Ad ID implementation (pt. 4/4)
231+
private void getAdvertisingIdClientInfo(final AdobeCallback<AdvertisingIdClient.Info> callback) {
232+
if (callback == null) {
233+
Log.d(LOG_TAG, "Unexpected null callback, provide a callback to retrieve AdvertisingIdClientInfo.");
234+
return;
235+
}
236+
ExecutorService executor = Executors.newSingleThreadExecutor();
237+
executor.execute(new Runnable() {
238+
@Override
239+
public void run() {
240+
try {
241+
AdvertisingIdClient.Info idInfo = AdvertisingIdClient.getAdvertisingIdInfo(getContext());
242+
callback.call(idInfo);
243+
return;
244+
} catch (GooglePlayServicesNotAvailableException e) {
245+
Log.w(LOG_TAG, "GooglePlayServicesNotAvailableException while retrieving the advertising identifier ${e.localizedMessage}");
246+
} catch (GooglePlayServicesRepairableException e) {
247+
Log.w(LOG_TAG, "GooglePlayServicesRepairableException while retrieving the advertising identifier ${e.localizedMessage}");
248+
} catch (IOException e) {
249+
Log.w(LOG_TAG, "IOException while retrieving the advertising identifier ${e.localizedMessage}");
250+
}
251+
callback.call(null);
252+
}
253+
});
254+
}
255+
/* Ad ID implementation (pt. 4/4) */
256+
257+
}
258+
259+
260+

Sample-App/app/src/main/java/com/adobe/marketing/mobile/sampleapp/MainApp.java

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,11 +29,13 @@
2929
import android.util.Log;
3030

3131
import androidx.annotation.NonNull;
32+
import androidx.multidex.MultiDex;
3233

3334
public class MainApp extends Application {
3435

3536
private static final String LOG_TAG = "MainApp";
36-
private static final String LAUNCH_ENVIRONMENT_FILE_ID = "";
37+
// TODO: Set up the preferred Environment File ID from your mobile property configured in Data Collection UI
38+
private static final String ENVIRONMENT_FILE_ID = "";
3739
private static Context context;
3840

3941
public static Context getAppContext() {
@@ -49,7 +51,7 @@ public void onCreate() {
4951
MobileCore.setLogLevel(LoggingMode.VERBOSE);
5052
MobileCore.setSmallIconResourceID(R.mipmap.ic_launcher_round);
5153
MobileCore.setLargeIconResourceID(R.mipmap.ic_launcher_round);
52-
MobileCore.configureWithAppID(LAUNCH_ENVIRONMENT_FILE_ID);
54+
MobileCore.configureWithAppID(ENVIRONMENT_FILE_ID);
5355

5456
try {
5557
UserProfile.registerExtension();
@@ -93,4 +95,10 @@ public void onComplete(@NonNull Task<String> task) {
9395
Log.e(LOG_TAG, "IllegalArgumentException - Check if google-services.json is added and is correctly configured. \nError message: " + e.getLocalizedMessage());
9496
}
9597
}
98+
99+
@Override
100+
protected void attachBaseContext(Context base) {
101+
super.attachBaseContext(base);
102+
MultiDex.install(this);
103+
}
96104
}

0 commit comments

Comments
 (0)