Xamarin Android
Google Play Services 17+版本
If you reference Google Play Services version 17 or higher, you MUST complete Google's update instructions here.
由于 Google Play Services 于2019年6月进行了重大更改,未完成更新步骤将导致 Branch 的 Android SDK(以及其他各种跨平台 SDK,例如 Unity)停止收集 Android AID,而我们需要使用该 ID 来确保准确的深度链接和归因。
如果您运行的 Google Play Services 版本低于17,则无需更新。
配置 Branch
- Complete your Branch Dashboard


安装 Branch
NuGet
Google 广告标识符(GAID)
Branch Xamarin SDK 8.0.0+ requires the Xamarin.GooglePlayServices.AdsIdentifier NuGet package to obtain the advertising id.
Note that version 117.0.1.5 does not work properly on Visual Studio for Mac 2019, use 117.0.1.3 instead.
The Branch Xamarin SDK is available as a NuGet package. The Branch NuGet package must be added to each of the Xamarin projects that will use Branch methods.
要将 Branch NuGet 包添加到项目中:
- Right-click on each project and select Add > Add NuGet Packages
- Find the Branch-Xamarin-Linking-SDK package and add it to the project
- Optional: Find the Xamarin.GooglePlayServices.AdsIdentifier package and add it to the Android project.
配置应用
请确保 Android 项目未使用 Shared Mono Runtime
- Right-click on the Android project and select: Options
- Select: Android Build
- On the General tab, un-check: Use Shared Mono Runtime
在应用的 Manifest(清单) 文件中添加应用功能
In the Required permissions section of AndroidManifest.xml, configure the following permissions:
- AccessNetworkState
- 互联网
关于 Android Manifest 的额外信息:
将应用的 Branch key 添加到 Strings.xml 文件
Add the Branch key to the Android project's Resources/values/Strings.xml file. This file contains values that can be accessed by the app's Application class.
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">TestXamarinFormsApp</string>
<string name="branch_key">key_live_liAnF8k7gZUEZv76Rt9a4bffAzlC5zVW</string>
</resources>
初始化 Branch
*Create the project's Application.cs* class
- Right-click on the .Droid project and select Add > New File...
- Select: General > Empty File
- Name the file: Application.cs
- 输入以下代码(将 “TestAndroidApp” 替换为应用的实际名称):
using System;
using Android.App;
using Android.Content;
using Android.Runtime;
using BranchXamarinSDK;
namespace TestAndroidApp.Droid
{
[Application(AllowBackup = true, Icon = "@mipmap/icon", Label = "@string/app_name")]
[MetaData("io.branch.sdk.auto_link_disable", Value = "false")]
[MetaData("io.branch.sdk.TestMode", Value = "true")]
[MetaData("io.branch.sdk.BranchKey", Value = "@string/branch_key")]
public class TestAndroidApp : Application
{
public TestAndroidApp(IntPtr javaReference, JniHandleOwnership transfer) : base(javaReference, transfer)
{
}
public override void OnCreate()
{
base.OnCreate();
BranchAndroid.GetAutoInstance(this.ApplicationContext);
}
}
}
Key | 值 |
---|---|
io.branch.sdk.TestMode | 将此参数设置为 true 启用 Debug Mode,这将导致卸载/重新安装应用来触发 install 事件。在发布到生产环境之前,请确保禁用此功能。请注意,如果已在项目中添加了该功能,则在 Android 上启用 Debug Mode 也会强制该应用使用 Branch Test 键。使用 Test 键运行的应用将无法从使用 Live 键创建的 Branch Link 接收数据。 |
io.branch.sdk.BranchKey | 应用的 Branch 键。可以将Live键和Test键都添加到 Strings.xml 文件中。启用TestMode 后,如果已指定,则应用将自动使用Test键。 |
创建一个活动来处理 Branch 事件:BranchActivity
- Right-click on the .Droid project and select Add > New File...
- Select: Android > Activity
- Rename the file: BranchActivity.cs
- 输入以下代码(将 “TestAndroidApp” 替换为应用的实际名称):
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Newtonsoft.Json;
using BranchXamarinSDK;
using Android.App;
using Android.Content;
using Android.OS;
using Android.Runtime;
using Android.Views;
using Android.Widget;
namespace TestAndroidApp.Droid
{
[Activity(Label = "BranchActivity")]
public class BranchActivity : Activity
{
private string logString = "";
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
LogMessage("Branch initialization completed: ");
Dictionary<string, object> data = JsonConvert.DeserializeObject<Dictionary<string, object>>(Intent.GetStringExtra("BranchData"));
foreach (var key in data.Keys)
{
LogMessage(key + " : " + data[key].ToString());
}
}
#region Utils
void LogMessage(string message)
{
Console.WriteLine(message);
logString += DateTime.Now.ToLongTimeString() + "> " + message + "\n";
}
#endregion
}
}
创建一个活动来处理 Branch 错误:BranchErrorActivity
- Right-click on the .Droid project and select Add > New File...
- Select: Android > Activity
- Rename the file: BranchErrorActivity.cs
- 输入以下代码(将 “TestAndroidApp” 替换为应用的实际名称):
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Android.App;
using Android.Content;
using Android.OS;
using Android.Runtime;
using Android.Views;
using Android.Widget;
namespace TestAndroidApp.Droid
{
[Activity(Label = "BranchErrorActivity")]
public class BranchErrorActivity : Activity
{
private string logString = "";
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
LogMessage("Branch initialization failed");
LogMessage("Error code: " + Intent.Extras.GetInt("ErrorCode").ToString());
LogMessage(Intent.Extras.GetString("ErrorMessage"));
}
#region Utils
void LogMessage(string message)
{
Console.WriteLine(message);
logString += DateTime.Now.ToLongTimeString() + "> " + message + "\n";
}
#endregion
}
}
初始化 Branch 并配置 Branch 会话管理
必须在 Application 类或应用启动的第一个 Activity 的 OnCreate 方法中初始化 Branch。当应用由于 Branch link 点击而激活时,必须添加 OnNewIntent 方法以获得最新的链接标识符。
如果初始化成功,则将调用 InitSessionComplete 方法。如果初始化失败,则将调用SessionRequestError 方法。深度链接路由逻辑应位于 InitSessionComplete 方法中。
在下面的代码示例中,以下 Branch初始化和会话管理步骤已添加到 MainActivity.cs中:
- 响应应用 URI Scheme 的 Activity
- An Activity is launched in
singleTask
mode - 覆盖 OnCreate 方法并初始化 Branch SDK
- 覆盖 OnNewIntent 方法
- 添加一个 InitSessionComplete 方法来处理 Branch Link 信息(这是深的链接路由代码所在的位置)
- 添加 SessionRequestError 方法以处理 Branch 未能初始化的情况
using Android.App;
using Android.Widget;
using Android.OS;
using BranchXamarinSDK;
using System;
using System.Collections.Generic;
using Android.Content;
using Newtonsoft.Json;
namespace TestAndroidApp.Droid
{
[Activity(Label = "TestAndroidApp", MainLauncher = true, Icon = "@mipmap/icon", LaunchMode = Android.Content.PM.LaunchMode.SingleTask)]
[IntentFilter(new[] { "android.intent.action.VIEW" },
Categories = new[] { "android.intent.category.DEFAULT", "android.intent.category.BROWSABLE" },
DataScheme = "testandroidapp",
DataHost = "open")]
[IntentFilter(new[] { "android.intent.action.VIEW" },
Categories = new[] { "android.intent.category.DEFAULT", "android.intent.category.BROWSABLE" },
DataScheme = "https",
DataHost = "testandroidapp.app.link")]
[IntentFilter(new[] { "android.intent.action.VIEW" },
Categories = new[] { "android.intent.category.DEFAULT", "android.intent.category.BROWSABLE" },
DataScheme = "https",
DataHost = "testandroidapp-alternate.app.link")]
public class MainActivity : Activity, IBranchSessionInterface
{
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
BranchAndroid.Init(this, Resources.GetString(Resource.String.branch_key), this);
}
// Ensure we get the updated link identifier when the app becomes active
// due to a Branch link click after having been in the background
protected override void OnNewIntent(Intent intent)
{
this.Intent = intent;
}
public void InitSessionComplete(Dictionary<string, object> data)
{
//Handle custom logic based on deep link data in InitSessionComplete
//View all the link data in the console
Console.WriteLine("My Link Data: " + JsonConvert.SerializeObject(data));
//Preferred method: use BranchActivity created previously to handle the link data
//Will need to update BranchActivity with desired custom logic, to open the correct page in the app
var intent = new Intent(this, typeof(BranchActivity));
intent.PutExtra("BranchData", JsonConvert.SerializeObject(data));
StartActivity(intent);var intent = new Intent
}
public void SessionRequestError(BranchError error)
{
Console.WriteLine("Branch session initialization error: " + error.ErrorCode);
Console.WriteLine(error.ErrorMessage);
var intent = new Intent(this, typeof(BranchErrorActivity));
intent.PutExtra("ErrorCode", error.ErrorCode);
intent.PutExtra("ErrorMessage", error.ErrorMessage);
StartActivity(intent);
}
}
}
使用 Xamarin 表单配置 Branch
创建用于 Branch 会话处理的类
Branch 异步初始化,通过对 Branch 的网络调用返回 Branch link 参数。如果初始化成功,则将调用 InitSessionComplete 方法。如果初始化失败,则将调用SessionRequestError 方法。深度链接路由逻辑应位于 InitSessionComplete 方法中。
- Right-click on the C# project and select Add > New File...
- Select: General > Empty Class
- Rename the file: TestXamarinFormsApp.cs
- 输入以下代码(将 “TestXamarinFormsApp” 替换为应用的实际名称):
using BranchXamarinSDK;
using System.Collections.Generic;
using System.ComponentModel;
using Xamarin.Forms;
namespace TestXamarinFormsApp
{
public class TestXamarinFormsApp : Application, IBranchSessionInterface
{
public TestXamarinFormsApp()
{
}
#region IBranchSessionInterface implementation
public void InitSessionComplete(Dictionary<string, object> data)
{
}
public void CloseSessionComplete()
{
}
public void SessionRequestError(BranchError error)
{
}
#endregion
}
}
创建一个用于处理链接数据的类
Branch stores link data in an object referred to as the Branch Universal Object, or BUO.
- Right-click on the C# project and select Add > New File...
- Select: General > Empty Class
- Rename the file: TestXamarinFormsAppBUO.cs
- 输入以下代码(将 “TestXamarinFormsApp” 替换为应用的实际名称):
using BranchXamarinSDK;
using System.Collections.Generic;
using System.ComponentModel;
using Xamarin.Forms;
namespace TestXamarinFormsApp
{
public class TestXamarinFormsAppBUO : Application, IBranchBUOSessionInterface
{
public TestXamarinFormsAppBUO()
{
}
#region IBranchBUOSessionInterface implementation
public void InitSessionComplete(BranchUniversalObject buo, BranchLinkProperties blp)
{
}
public void SessionRequestError(BranchError error)
{
}
#endregion
}
}
请确保 Android 项目未使用 Shared Mono Runtime
- Right-click on the Android project and select: Options
- Select: Android Build
- On the General tab, un-check: Use Shared Mono Runtime
在 Android Manifest.xml 文件中添加应用功能
In the Required permissions section of AndroidManifest.xml, configure the following permissions:
- AccessNetworkState
- 互联网
关于 Android Manifest 的更多阅读
将应用的 Branch key 添加到 Strings.xml 文件
Create a Resources/values/Strings.xml file that can be accessed by the app's Application class for the Android project and add the Branch key to this file.
- In the Android project, browse to Resources/values
- Right-click on the values folder and select: Add > New File...
- Select: XML > Empty XML File
- Name the file: Strings
- 输入以下值:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">TestXamarinFormsApp</string>
<string name="branch_key">key_live_liAnF8k7gZUEZv76Rt9a4bffAzlC5zVW</string>
</resources>
配置 .Droid 项目的 Application 类
在 .Droid 项目的 Application 类中:
- 设置 Branch SDK 的初始化参数
- Override the
OnCreate()
method to callBranchAndroid.GetAutoInstance
如果该项目尚不存在 Appplication 类,请创建一个:
- Right-click on the .Droid project and select: Add > New File...
- Select: General > Empty Class
- 命名文件: {app name} (例如 'TestXamarinFormsApp')
该文件应具有以下内容:
using System;
using Android.App;
using Android.Content;
using Android.Runtime;
using BranchXamarinSDK;
namespace TestXamarinFormsApp.Droid
{
[Application (AllowBackup = true, Icon = "@drawable/icon", Label = "@string/app_name")]
[MetaData("io.branch.sdk.auto_link_disable", Value = "false")]
[MetaData("io.branch.sdk.TestMode", Value = "true")]
[MetaData("io.branch.sdk.BranchKey", Value = "@string/branch_key")]
public class App : Application
{
public App(IntPtr javaReference, JniHandleOwnership transfer) : base(javaReference, transfer)
{
}
public override void OnCreate()
{
base.OnCreate();
BranchAndroid.GetAutoInstance(this.ApplicationContext);
}
}
}
Key | 值 |
---|---|
io.branch.sdk.TestMode | 将此参数设置为 true 启用 Debug Mode,这将导致卸载/重新安装应用来触发 install 事件。在发布到生产环境之前,请确保禁用此功能。请注意,如果已在项目中添加了该功能,则在 Android 上启用 Debug Mode 也会强制该应用使用 Branch Test 键。使用 Test 键运行的应用将无法从使用 Live 键创建的 Branch Link 接收数据。 |
io.branch.sdk.BranchKey | 应用的 Branch 键。可以将Live键和Test键都添加到 Strings.xml 文件中。启用TestMode 后,如果已指定,则应用将自动使用Test键。 |
初始化 Branch
Branch must be initialized in the OnCreate
method of either the Application class or the first Activity launched by the app. The OnNewIntent
method must be added to retrieve the latest link identifier when the app becomes active due to a Branch link click.
在下面的代码示例中,以下 Branch初始化和会话管理步骤已添加到 MainActivity.cs中:
- 注册 Activity 以响应应用的 URI scheme
- Ensure the Activity is launched in
singleTask
mode - Override the
OnCreate
method and initialize the Branch SDK - Override the
OnNewIntent
method
using System;
using Android.App;
using Android.Content;
using Android.Content.PM;
using Android.Runtime;
using Android.Views;
using Android.Widget;
using Android.OS;
using BranchXamarinSDK;
using TestXamarinFormsApp;
namespace TestXamarinFormsApp.Droid
{
[Activity(Label = "TestXamarinFormsApp.Droid", LaunchMode = LaunchMode.SingleTask, Icon = "@drawable/icon", Theme = "@style/MyTheme", MainLauncher = true, ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation)]
[IntentFilter(new[] { "android.intent.action.VIEW" },
Categories = new[] { "android.intent.category.DEFAULT", "android.intent.category.BROWSABLE" },
DataScheme = "testxamarinformsapp",
DataHost = "open")]
[IntentFilter(new[] { "android.intent.action.VIEW" },
Categories = new[] { "android.intent.category.DEFAULT", "android.intent.category.BROWSABLE" },
DataScheme = "https",
DataHost = "testxamarinformsapp.app.link")]
public class MainActivity : global::Xamarin.Forms.Platform.Android.FormsApplicationActivity
{
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
global::Xamarin.Forms.Forms.Init(this, savedInstanceState);
TestXamarinFormsAppBUO linkData = new TestXamarinFormsAppBUO();
BranchAndroid.Init(this, GetString(Resource.String.branch_key), linkData);
LoadApplication(linkData);
}
protected override void OnNewIntent(Intent intent)
{
this.Intent = intent;
}
}
}
实现功能
创建内容参考
- The Branch Universal Object encapsulates the thing you want to share
- Uses Universal Object properties
BranchUniversalObject universalObject = new BranchUniversalObject();
universalObject.canonicalIdentifier = "id12345";
universalObject.title = "id12345 title";
universalObject.contentDescription = "My awesome piece of content!";
universalObject.imageUrl = "https://s3-us-west-1.amazonaws.com/branchhost/mosaic_og.png";
universalObject.metadata.AddCustomMetadata("foo", "bar");
创建深度链接
- 在应用中生成深度链接
- Needs a Create content reference
- 需要创建链接参考
- Validate with the Branch Dashboard
BranchLinkProperties linkProperties = new BranchLinkProperties();
linkProperties.tags.Add("tag1");
linkProperties.tags.Add("tag2");
linkProperties.feature = "sharing";
linkProperties.channel = "facebook";
linkProperties.controlParams.Add("$desktop_url", "http://example.com");
Branch.GetInstance().GetShortURL(callback,
universalObject,
linkProperties);
分享深度链接
- 生成 Branch 深度链接,并通过用户选择的渠道对其进行标签
- Needs a Create content reference
- Needs a Create link reference
- Uses Deep Link Properties
Branch.GetInstance().ShareLink (callback,
universalObject,
linkProperties,
message)
读取深度链接
- 从深度链接中提取 Branch 数据
- 最佳做法是从
listener
(to prevent a race condition) - Returns deep link properties
// latest
Dictionary<string, object> sessionParams = Branch.GetInstance().GetLatestReferringParams();
// first
Dictionary<string, object> installParams = Branch.GetInstance().GetFirstReferringParams();
追踪用户
- Sets the identity of a user (ID, UUID, etc) for events, deep links, and referrals
- Validate with the Branch Dashboard
Branch branch = Branch.GetInstance ();
branch.SetIdentity("the user id", this); // Where this implements IBranchIdentityInterface
branch.Logout(this); // Where this implements IBranchIdentityInterface
追踪 Commerce Event
- Commerce Event 描述客户与您的产品进行交互并通过购买进行转化相关的事件。这些事件包括添加付款信息,购买,查看产品等。如果启用了 Branch Universal Ads(全域广告归因),这些事件将自动映射到部分广告合作伙伴。首先为与您重新追踪的事件相关联的每个产品创建一个 Branch Universal Object。
- 从那里,将 Branch Universal Object 添加到追踪的事件,并使用正确的预定义常量。例如,下面的代码片段用于追踪用户何时将其添加到购物车,但只需将该常量替换为另一个常量即可追踪不同的事件。
- 有关货币和汇率的说明:
如果您在没有货币的情况下追踪 Commerce Event,则我们假设它们是美元。如果您使用非美元的货币追踪 Commerce Event,我们将使用最近的汇率将指定的收入转化为美元。 - 由于所有单位均为美元,因此您可以轻松地在操作后台 (Dashboard)上查看许多国家和货币的收入。定期从 openexchangerates.org 提取汇率,并且通常在实时汇率的一小时内。如果通过 Webhooks 或 Exports查看原始的 Branch 事件,则可以看到所使用的汇率。
- Validate with the Branch Dashboard
BranchUniversalObject universalObject = new BranchUniversalObject();
universalObject.canonicalIdentifier = "id12345";
universalObject.canonicalUrl = "https://branch.io/item/id12345";
universalObject.title = "Item 12345";
universalObject.contentDescription = "My awesome piece of content!";
universalObject.imageUrl = "https://s3-us-west-1.amazonaws.com/branchhost/mosaic_og.png";
universalObject.metadata.price = (float)23.20;
universalObject.metadata.quantity = 1;
universalObject.metadata.sku = "1994329302";
universalObject.metadata.productName = "my_product_name1";
universalObject.metadata.productBrand = "my_product_brand1";
universalObject.metadata.productCategory = BranchProductCategory.APPAREL_AND_ACCESSORIES;
universalObject.metadata.productVariant = "XL";
universalObject.metadata.condition = BranchCondition.NEW;
universalObject.metadata.AddCustomMetadata("foo", "bar");
BranchEvent branchCommerceEvent = new BranchEvent(BranchEventType.PURCHASE);
branchCommerceEvent.SetAlias("new_user_purchase");
branchCommerceEvent.AddContentItem(universalObject);
branchCommerceEvent.SetRevenue((float)1.5);
branchCommerceEvent.SetShipping((float)10.5);
branchCommerceEvent.SetCurrency(BranchCurrencyType.USD);
branchCommerceEvent.SetTax((float)12.3);
Branch.GetInstance().SendEvent(branchCommerceEvent);
追踪 Content Event
- Content Event 是用户与您的应用内内容互动时发生的事件。例如,如果您有应用内文章,则希望追踪与用户搜索,查看内容,对内容进行评级和分享有关的事件。这可以应用于多种应用内内容,例如博客文章,音乐,视频,图片和电子商务目录项。
- Validate with the Branch Dashboard
BranchEvent branchContentEvent = new BranchEvent(BranchEventType.SEARCH);
branchContentEvent.SetAlias("my_custom_alias");
branchContentEvent.SetDescription("Product Search");
branchContentEvent.SetSearchQuery("user search query terms for product xyz");
branchContentEvent.AddCustomData("content_event_property_key1", "content_event_property_val1");
Branch.GetInstance().SendEvent(branchContentEvent);
追踪 Lifecycle Event
- Lifecycle Event 事件可以描述为继续操作,用户在应用内产生的事件。当用户完成用户个人资料,注册或完成教程时,这些事件可以应用于游戏应用以及非游戏应用。
- Validate with the Branch Dashboard
BranchEvent branchLifecycleEvent = new BranchEvent(BranchEventType.COMPLETE_REGISTRATION);
branchLifecycleEvent.SetAlias("registration_flow_xyz"); branchLifecycleEvent.SetDescription("Existing User Registration");
branchLifecycleEvent.AddCustomData("lifeycle_event_property_key1", "lifecycle_event_property_val1");
Branch.GetInstance().SendEvent(branchLifecycleEvent);
追踪自定义事件
- 如果要追踪非预定义的事件,只需进行以下操作:
- 强烈建议使用不超过40个字符,仅包含字母,数字,连字符,空格和下划线且不要以连字符开头的自定义事件名称。 Facebook 将不接受违反这些规则的事件,如果您启用 Facebook 集成,Branch 可能会清理您的事件名称以通过验证。
- Validate with the Branch Dashboard
BranchEvent branchCustomEvent = new BranchEvent("custom_event");
branchCustomEvent.SetAlias("custom_event_alias");
branchCustomEvent.SetDescription("Custom Event Description");
branchCustomEvent.AddCustomData("custom_event_property_key1", "custom_event_property_val1");
branchCustomEvent.AddCustomData("custom_event_property_key2", "custom_event_property_val2");
Branch.GetInstance().SendEvent(branchCustomEvent);
示例测试应用
此存储库中包含四个功能齐全的演示应用:适用于 iOS 和 Android 平台的Xamarin Native 和 Xamarin Forms 应用。将这些应用用作集成 Branch SDK 的参考模型。
排查问题
测试深度链接 Android
- Create a deep link from the Branch Marketing Dashboard
- 从设备中删除您的应用
- 使用 Android Studio 编译您的应用
- Paste deep link in Google Hangouts
- 点击深度链接打开您的应用
在存在链接错误的情况下,无法构建 Android 应用
添加 Branch Xamarin SDK NuGet 包后,Newtonsoft JSON NuGet 包将自动添加到项目中。此软件包存在一个已知问题,导致在构建项目时的链接错误。
错误 XA0009:加载程序集时出错:/Users/david/Projects/TestXamarinFormsApp/Droid/obj/Debug/android/assets/mscorlib.dll
要使用 Newtonsoft JSON NuGet 包解决此问题,请执行以下操作:
- 右键点击项目,然后选择选项
- Go to Android Build and select the Linker tab
- Select: Release
- Go to the Ignore assemblies box
- Add: System.Core
- 重建应用
Updated 4 months ago