To attribute pre-loaded apps, the TUNE SDK provides a setter method for sending (or “hard-coding”) the partner info for attribution and subsequent postbacks. If multiple partners are pre-loading your mobile app, then you can create a partner-specific build of your app for distribution to each publishing partner (where each build includes different partner settings, respective to the particular partner). The partner-specific build is what the partner pre-loads onto the desired devices.
For information about more custom setter methods, please visit the Custom SDK Settings.
Setter Method
Use the regular TUNE implementation but after initialization, call this setter to enable pre-loaded attribution:
// Required setter
void setPreloadedApp(TunePreloadData preloadData);
+ (void)setPreloadData:(TunePreloadData *)preloadData;
public static void SetPreloadedApp(MATPreloadData preloadData)
Select a preferred platform.
public class MyApplication extends TuneApplication {
@Override
public void onCreate() {
super.onCreate();
// Initialize TUNE
Tune tune = Tune.init(getApplicationContext(), "your_advertiser_ID", "your_conversion_key");
// On first app open, set pre-loaded values
// You will need to determine some criteria for this
if (firstAppOpen) {
TunePreloadData preloadData = new TunePreloadData("your_publisher_id") // Required
.withOfferId("your_offer_id") // Rest are optional
.withAgencyId("your_agency_id")
.withPublisherReferenceId("your_publisher_ref_id")
.withPublisherSub1("your_pub_sub1")
.withPublisherSub2("your_pub_sub2")
.withPublisherSub3("your_pub_sub3")
.withPublisherSub4("your_pub_sub4")
.withPublisherSub5("your_pub_sub5")
.withPublisherSubAd("your_pub_sub_ad")
.withPublisherSubAdgroup("your_pub_sub_adgroup")
.withPublisherSubCampaign("your_pub_sub_campaign")
.withPublisherSubKeyword("your_pub_sub_keyword")
.withPublisherSubPublisher("your_pub_sub_publisher")
.withPublisherSubSite("your_pub_sub_site")
.withAdvertiserSubAd("your_ad_sub_ad")
.withAdvertiserSubAdgroup("your_ad_sub_adgroup")
.withAdvertiserSubCampaign("your_ad_sub_campaign")
.withAdvertiserSubKeyword("your_ad_sub_keyword")
.withAdvertiserSubPublisher("your_ad_sub_publisher")
.withAdvertiserSubSite("your_ad_sub_site");
tune.setPreloadedApp(preloadData);
}
}
}
TunePreloadData *pd = [TunePreloadData preloadDataWithPublisherId:@"112233"];
pd.offerId = @"offer_id";
pd.agencyId = @"agency_id";
pd.publisherReferenceId = @"publisher_ref_id";
pd.publisherSub1 = @"pub_sub1";
pd.publisherSub2 = @"pub_sub2";
pd.publisherSub3 = @"pub_sub3";
pd.publisherSub4 = @"pub_sub4";
pd.publisherSub5 = @"pub_sub5";
pd.publisherSubAd = @"pub_sub_ad";
pd.publisherSubAdgroup = @"pub_sub_adgroup";
pd.publisherSubCampaign = @"pub_sub_campaign";
pd.publisherSubKeyword = @"pub_sub_keyword";
pd.publisherSubPublisher = @"pub_sub_publisher";
pd.publisherSubSite = @"pub_sub_site";
pd.advertiserSubAd = @"ad_sub_ad";
pd.advertiserSubAdgroup = @"ad_sub_adgroup";
pd.advertiserSubCampaign = @"ad_sub_campaign";
pd.advertiserSubKeyword = @"ad_sub_keyword";
pd.advertiserSubPublisher = @"ad_sub_publisher";
pd.advertiserSubSite = @"ad_sub_site";
[Tune setPreloadData:pd];
[Tune measureSession];
MATPreloadData pd = new MATPreloadData("112233");
pd.offerId = @"offer_id";
pd.agencyId = @"agency_id";
pd.publisherReferenceId = @"publisher_ref_id";
pd.publisherSub1 = @"pub_sub1";
pd.publisherSub2 = @"pub_sub2";
pd.publisherSub3 = @"pub_sub3";
pd.publisherSub4 = @"pub_sub4";
pd.publisherSub5 = @"pub_sub5";
pd.publisherSubAd = @"pub_sub_ad";
pd.publisherSubAdgroup = @"pub_sub_adgroup";
pd.publisherSubCampaign = @"pub_sub_campaign";
pd.publisherSubKeyword = @"pub_sub_keyword";
pd.publisherSubPublisher = @"pub_sub_publisher";
pd.publisherSubSite = @"pub_sub_site";
pd.advertiserSubAd = @"ad_sub_ad";
pd.advertiserSubAdgroup = @"ad_sub_adgroup";
pd.advertiserSubCampaign = @"ad_sub_campaign";
pd.advertiserSubKeyword = @"ad_sub_keyword";
pd.advertiserSubPublisher = @"ad_sub_publisher";
pd.advertiserSubSite = @"ad_sub_site";
Tune.SetPreloadedApp(pd);
Tune.MeasureSession();
Select a preferred platform.
Make sure you use the setter ONLY for the first app open event, and not subsequent events/requests and MUST be excluded in the build for Google Play Store submission.
If you include the hard-coded attribution parameters for all measure sessions or other requests, then all requests are attributed accordingly (to the same hard-coded partner, such as AT&T). Therefore re-engagement does not work because the attribution information is already present/set, which prevents the SDK from collecting new attribution data.
For more conceptual information about how to attribute pre-installed apps, please visit Attributing Pre-Loaded Apps.
System Properties Method
Copy the below code in your app into a new file TunePreloadSystemData.java
:
class TunePreloadSystemData {
private static final String SYSTEM_PROPERTIES_CLASS_KEY = "android.os.SystemProperties";
private static final String TUNE_BRANCH_PREINSTALL_PROP_KEY = "io.branch.tune.preinstall.apps.path";
public static void getPreinstallSystemData(TuneInternal sTuneInstance) {
if (sTuneInstance != null) {
// check if the SystemProperties has the tune<>branch file path added
String tuneFilePath = checkForTunePreloadInSystem();
if (!TextUtils.isEmpty(tuneFilePath)) {
// after getting the file path get the file contents
readTuneFile(tuneFilePath, sTuneInstance);
}
}
}
private static String checkForTunePreloadInSystem() {
String path = null;
try {
path = (String) Class.forName(SYSTEM_PROPERTIES_CLASS_KEY)
.getMethod("get", String.class).invoke(null, TUNE_BRANCH_PREINSTALL_PROP_KEY);
} catch (Exception e) {
return null;
}
return path;
}
static void readTuneFile(final String tuneFilePath, final TuneInternal sTuneInstance) {
new Thread(new Runnable() {
@Override
public void run() {
try {
final StringBuilder tuneFileContent = new StringBuilder();
JSONObject tuneFileContentJson;
File tuneFile = new File(tuneFilePath);
BufferedReader br = new BufferedReader(new FileReader(tuneFile));
String line;
while ((line = br.readLine()) != null) {
tuneFileContent.append(line);
}
br.close();
tuneFileContentJson = new JSONObject(tuneFileContent.toString().trim());
if (!TextUtils.isEmpty(tuneFileContentJson.toString())) {
getTuneFileContent(tuneFileContentJson, sTuneInstance);
} else {
throw new FileNotFoundException();
}
} catch (FileNotFoundException ignore) {
} catch (IOException ignore) {
} catch (JSONException ignore) {
}
}
}).start();
}
public static void getTuneFileContent(JSONObject tuneFileContentJson,
TuneInternal sTuneInstance) {
// check if the current app package exists in the json
Iterator<String> keys = tuneFileContentJson.keys();
while (keys.hasNext()) {
String key = keys.next();
try {
if (key.equals("apps") && tuneFileContentJson
.get(key) instanceof JSONObject) {
if (tuneFileContentJson.getJSONObject(key)
.get(sTuneInstance.getPackageName()) != null) {
JSONObject tunePreinstallData = tuneFileContentJson
.getJSONObject(key)
.getJSONObject(sTuneInstance.getPackageName());
// find the preinstalls keys and any custom data
Iterator<String> preinstallDataKeys = tunePreinstallData
.keys();
TunePreloadData updatedTunePreloadData = null;
if (!TextUtils
.isEmpty(tunePreinstallData.getString(TuneUrlKeys.PUBLISHER_ID))) {
updatedTunePreloadData = new TunePreloadData(
tunePreinstallData.getString(
TuneUrlKeys.PUBLISHER_ID));
while (preinstallDataKeys.hasNext()) {
String datakey = preinstallDataKeys.next();
if (datakey.equals(TuneUrlKeys.OFFER_ID) && !TextUtils
.isEmpty(tunePreinstallData.get(datakey)
.toString())) {
updatedTunePreloadData
.withOfferId(tunePreinstallData.get(datakey)
.toString());
} else if (datakey.equals(TuneUrlKeys.AGENCY_ID) && !TextUtils
.isEmpty(tunePreinstallData.get(datakey)
.toString())) {
updatedTunePreloadData
.withAgencyId(tunePreinstallData.get(datakey)
.toString());
} else if (datakey.equals(TuneUrlKeys.PUBLISHER_REF_ID)
&& !TextUtils.isEmpty(tunePreinstallData.get(datakey)
.toString())) {
updatedTunePreloadData.withPublisherReferenceId(
tunePreinstallData.get(datakey)
.toString());
} else if (datakey.equals(TuneUrlKeys.PUBLISHER_SUB1) && !TextUtils
.isEmpty(tunePreinstallData.get(datakey)
.toString())) {
updatedTunePreloadData
.withPublisherSub1(tunePreinstallData.get(datakey)
.toString());
} else if (datakey.equals(TuneUrlKeys.PUBLISHER_SUB2) && !TextUtils
.isEmpty(tunePreinstallData.get(datakey)
.toString())) {
updatedTunePreloadData
.withPublisherSub2(tunePreinstallData.get(datakey)
.toString());
} else if (datakey.equals(TuneUrlKeys.PUBLISHER_SUB3) && !TextUtils
.isEmpty(tunePreinstallData.get(datakey)
.toString())) {
updatedTunePreloadData
.withPublisherSub3(tunePreinstallData.get(datakey)
.toString());
} else if (datakey.equals(TuneUrlKeys.PUBLISHER_SUB4) && !TextUtils
.isEmpty(tunePreinstallData.get(datakey)
.toString())) {
updatedTunePreloadData
.withPublisherSub4(tunePreinstallData.get(datakey)
.toString());
} else if (datakey.equals(TuneUrlKeys.PUBLISHER_SUB5) && !TextUtils
.isEmpty(tunePreinstallData.get(datakey)
.toString())) {
updatedTunePreloadData
.withPublisherSub5(tunePreinstallData.get(datakey)
.toString());
} else if (datakey.equals(TuneUrlKeys.PUBLISHER_SUB_AD)
&& !TextUtils.isEmpty(tunePreinstallData.get(datakey)
.toString())) {
updatedTunePreloadData
.withAdvertiserSubAd(tunePreinstallData.get(datakey)
.toString());
} else if (datakey.equals(TuneUrlKeys.PUBLISHER_SUB_ADGROUP)
&& !TextUtils.isEmpty(tunePreinstallData.get(datakey)
.toString())) {
updatedTunePreloadData
.withPublisherSubAdgroup(tunePreinstallData.get(datakey)
.toString());
} else if (datakey.equals(TuneUrlKeys.PUBLISHER_SUB_CAMPAIGN)
&& !TextUtils.isEmpty(tunePreinstallData.get(datakey)
.toString())) {
updatedTunePreloadData.withPublisherSubCampaign(
tunePreinstallData.get(datakey)
.toString());
} else if (datakey.equals(TuneUrlKeys.PUBLISHER_SUB_KEYWORD)
&& !TextUtils.isEmpty(tunePreinstallData.get(datakey)
.toString())) {
updatedTunePreloadData
.withPublisherSubKeyword(tunePreinstallData.get(datakey)
.toString());
} else if (datakey.equals(TuneUrlKeys.PUBLISHER_SUB_PUBLISHER)
&& !TextUtils.isEmpty(tunePreinstallData.get(datakey)
.toString())) {
updatedTunePreloadData.withPublisherSubPublisher(
tunePreinstallData.get(datakey)
.toString());
} else if (datakey.equals(TuneUrlKeys.ADVERTISER_SUB_AD)
&& !TextUtils.isEmpty(tunePreinstallData.get(datakey)
.toString())) {
updatedTunePreloadData
.withAdvertiserSubAd(tunePreinstallData.get(datakey)
.toString());
} else if (datakey.equals(TuneUrlKeys.ADVERTISER_SUB_ADGROUP)
&& !TextUtils.isEmpty(tunePreinstallData.get(datakey)
.toString())) {
updatedTunePreloadData.withAdvertiserSubAdgroup(
tunePreinstallData.get(datakey)
.toString());
} else if (datakey.equals(TuneUrlKeys.ADVERTISER_SUB_CAMPAIGN)
&& !TextUtils.isEmpty(tunePreinstallData.get(datakey)
.toString())) {
updatedTunePreloadData.withAdvertiserSubCampaign(
tunePreinstallData.get(datakey)
.toString());
} else if (datakey.equals(TuneUrlKeys.ADVERTISER_SUB_CAMPAIGN)
&& !TextUtils.isEmpty(tunePreinstallData.get(datakey)
.toString())) {
updatedTunePreloadData.withAdvertiserSubCampaign(
tunePreinstallData.get(datakey)
.toString());
} else if (datakey.equals(TuneUrlKeys.ADVERTISER_SUB_KEYWORD)
&& !TextUtils.isEmpty(tunePreinstallData.get(datakey)
.toString())) {
updatedTunePreloadData.withAdvertiserSubKeyword(
tunePreinstallData.get(datakey)
.toString());
} else if (datakey.equals(TuneUrlKeys.ADVERTISER_SUB_PUBLISHER)
&& !TextUtils.isEmpty(tunePreinstallData.get(datakey)
.toString())) {
updatedTunePreloadData.withAdvertiserSubPublisher(
tunePreinstallData.get(datakey)
.toString());
} else if (datakey.equals(TuneUrlKeys.ADVERTISER_SUB_SITE)
&& !TextUtils.isEmpty(tunePreinstallData.get(datakey)
.toString())) {
updatedTunePreloadData
.withAdvertiserSubSite(tunePreinstallData.get(datakey)
.toString());
}
}
// set the final TunePreloadData
sTuneInstance.setPreloadedAppData(updatedTunePreloadData);
}
}
}
} catch (Exception ignore) {
ignore.printStackTrace();
}
}
}
}
Select a preferred platform.
Once added, then call the below method in place of the #setPreloadedAppData()
:
TunePreloadSystemData.getPreinstallSystemData(TuneInternal.getInstance());
Select a preferred platform.
OEM Side Setup
{ "apps": { "com.tune.test": { "publisher_id": "test_publisher_id", "publisher_sub_campaign": "test_publisher_sub_campaign" } } }
The supported keys are:
- "publisher_id"
- "offer_id"
- "agency_id"
- "publisher_ref_id"
- "publisher_sub_publisher"
- "publisher_sub_site"
- "publisher_sub_campaign"
- "publisher_sub_adgroup"
- "publisher_sub_ad"
- "publisher_sub_keyword"
- "publisher_sub1"
- "publisher_sub2"
- "publisher_sub3"
- "publisher_sub4"
- "publisher_sub5"
- "advertiser_sub_publisher"
- "advertiser_sub_site"
- "advertiser_sub_campaign"
- "advertiser_sub_adgroup"
- "advertiser_sub_ad"
- "advertiser_sub_keyword";
The file path format can be seen in the Branch SDK documentation here: https://docs.branch.io/activity-reports-analytics/ads-pre-install-analytics/#read-pre-loaded-data-from-the-android-system-properties