乐趣区

关于android:京东金融客户端用户触达方式的探索与实践

一、对于用户触达
用户触达:能够简略了解为通过某种形式将消息传递给用户的行为;触达的特定音讯从性能上可分展现、疏导落地两层。用户触达作为一种产品经营形式,曾经融入咱们日常生产流动的方方面面。在挪动互联网的世界里,咱们的产品离不开触达,用户流动也离不开触达。

二、为什么做用户触达
以用户应用角度来看,用户在应用 App 的过程中会有一些与用户相干的零碎类的告诉,比方交易物流、客服音讯、账单信息,借还款揭示,实时资讯等音讯须要及时的给用户揭示;

以 APP 经营流动看,App 在日常经营过程中,依据以后的指标,联合流动向用户定向发送相干营销类信息,比方单品的流动信息或一些品类促销优惠等,疏导用户疾速进入流动页面;

因而触达在拉新、促活、留存、变现、自流传等经营流动中扮演者重要角色。这篇文章从 app 研发视角介绍下用户触达方面的一些实际。

三、触达用户的形式实际
从 APP 的存活状态辨别,实现触达有两种形式,一种是:APP 非沉闷状态时的站外触达,次要蕴含:短信、Push、桌面小组件等

另一种是:APP 沉闷状态时的站内触达,次要蕴含站内弹窗、页面固定经营位,feed 流举荐位等。

上面介绍下一下咱们实现的几种触达形式及遇到的一些问题。

触达形式一:短信

短信起初利用最宽泛的场景是作为咱们交换沟通的一种形式,随着时代的倒退微信、QQ 等即时通讯类的 app 逐步代替了短信作为人与人沟通工具,然而因为短信可能及时稳固的将音讯同步给用户的特点,它仍是咱们当初应用比拟宽泛的音讯触达形式。常见的利用场景如:验证码告诉、还款揭示、账户变动、营销流动告诉等。咱们晓得作为一种触达形式,它的使命不仅是将音讯告诉到用户,对于特定的音讯还要能便捷的疏导用户跳转到 APP 内的相应的落地页。

短信的音讯触达能力是毋庸置疑的,尽管短信文本中间接放入的链接咱们也能够关上,然而确存在一些局限性,这种形式仅反对关上 web 页面,无奈跳转到 APP 原生页面,另外点击链接会先弹窗,由用户抉择关上链接的 app,这种体验相比间接关上 APP 指定页面来说大打折扣。因而,如何通过短信间接达到 APP 内,相应的落地页就是咱们须要解决的问题。google 提供了一种能使 Android 零碎间接通过网站地址关上应用程序对应内容页面,而不须要用户抉择应用哪个利用来解决网站地址的形式,即 Android App Links;其工作流程如下:

要增加 Android App Links 到利用中,须要在利用里定义通过 Http (s) 地址关上利用的 intent filter,并验证你的确领有该利用和该网站。

如果零碎胜利验证到你领有该网站,那么零碎会间接把 URL 对应的 intent 路由到你的利用。

1. 在 AndroidManifest 里配置用于零碎进行验证的 IntentFilter:

当 android:autoVerify=”true” 呈现在你任意一个 intent filter 里,在 Android 6.0 及以上的零碎上装置利用的时候,会触发系统对 APP 里和 URL 无关的每一个域名的验证。验证过程设计以下步骤:

零碎会查看所有蕴含以下特色的 intent filter:Action 为
android.intent.action.VIEW、Category 为
android.intent.category.BROWSABLE 和
android.intent.category.DEFAULT、Data scheme 为 http 或 https

2. 配置一个数字资产链接的 Json 文件,申明你的网址和利用之间的关系;

对于在上述 intent filter 里找到的每一个惟一的域名,Android 零碎会到对应的域名下查找数字资产文件,地址是:https:// 域名
/.well-known/assetlinks.json

只有当零碎为 AndroidManifest 里找到的每一个域名找到对应的数字资产文件,零碎才会把你的利用设置为特定链接的默认处理器。

数字资产示例:

package_name:在 build.gradle 里定义的 application ID

sha256_cert_fingerprints:利用签名的 SHA256 指纹信息,这个字段反对多个指纹信息,能够用来反对不同的利用版本,如开发版本和公布版本而后将 assetlinks 公布到 https:// 域名
/.well-known/assetlinks.json

[
  {
    "relation": ["delegate_permission/common.handle_all_urls"],
    "target": {
      "namespace": "android_app",
      "package_name": "xxx.xxx.xx",
      "sha256_cert_fingerprints": ["xx:xx...."]
    }
  }
]

3. 跳转落地页

在配置了上述 intent filter 的 Activity 中解析 url,并执行跳转落地页等操作

4. 问题及排查办法

如果配置后点击短信的链接无奈失常跳转,能够一一排查相干配置是否正确

4.1 确认数字资产文件是否被正确地定义和公布:

https://digitalassetlinks.goo…

source.web.site=https:// 你的域名:可选的端口

&relation=delegate_permission/common.handle_all_urls

4.2 确认利用是否设置了正确链接解决形式:

adb shell am start -a android.intent.action.VIEW \

-c android.intent.category.BROWSABLE \

-d “http:// 你的域名:可选的端口 ”

4.3 查看链接策略

这一步须要在利用装置后,期待一段时间 10s 后再执行,因为利用装置后零碎会申请解析配置表

执行:adb shell dumpsys package domain-preferred-apps 或 adb shell dumpsys package d

该命令返回了设施上每一个利用配置的列表,这个列表表明利用和网站之间的关联

App linkages for user 0:

Package: com.android.demo 代表利用包名

Domains: play.google.com market.android.com 网站域名,多个网站之间用空格分隔

Status: always : xxxx 示意利用在 Manifest 文件里的配置了 android:autoVerify=”true” 状态为 always;前面的 xxxx 和验证是否胜利无关,和零碎中利用的配置记录无关;

4.4 解决机型兼容性适配问题

在实际过程中还发现各厂商的不同型号的设施上存在无奈跳转到落地页的状况,经剖析该机型上利用装置后零碎申请解析配置表 assetlinks 过程失败,此时会应用零碎默认浏览器关上落地页,落地页是 app 原生页面的无奈跳转到落地页,对于须要登录的 web 页面,如果未在登录核心注册的也会跳转失败,并会重定向到 m.jd.com。

解决方案:有问题的机型,应用对立下载页直达,下载页执行唤起 APP,APP 内解决跳转落地页逻辑。

触达形式二:Push 推送

1. 客户端推送计划

Google 为 Android 提供了 FCM 推送,然而因为网络服务等一些起因其可用性不佳;目前国内各厂商 rom 也都提供了收费的 push 推送接入能力,同短信比 push 因为其免费性极大地节约了触达老本。

同时国内也有一些三方推送服务供应商,咱们联合京东金融本身业务特点,为了保障数据的安全性以及推送音讯的服务质量,最终采取整合华为,小米,OPPO、ViVO、魅族各厂商推送能力与自建通道相结合的计划。

其中厂商推送特点:token 有效期内,用户杀死 app 能够接管到 push 音讯;自建通道特点:app 启动后建设连贯,接管 push 音讯,杀死 APP 后收不到 push 音讯,次要用于应用未适配的厂商设施如三星、努比亚等用户接管 push 音讯。

各厂商在 push 计划的实现上大体雷同(厂商 push 接入流程,下图以 MiPush 为例),在应用厂商推送的过程中咱们也遇到了很多问题,因而理解了各厂商的个性是制订出良好的触达策略前提。

2. 厂商推送遇到的问题

2.1 push 告诉音讯是否能够个性化展现

通常状况下告诉栏音讯展现成果次要内容包含音讯题目、摘要、利用图标和工夫。客户端能够自行定义具体展现内容。

不同厂商如华为、OPPO、vivo、小米、魅族等告诉栏款式存在一些不同综合比照如下表:

在告诉展现的款式上,综合比照来看华为反对 inBox 的款式,OPPO 小米反对大图款式,能够通过这些特点定制出更有特色的告诉展现模式来突出告诉主题。

华为 inBox 款式:Inbox 款式将每行内容都当作独立的单行文本去展现。文本内容最多可展现 5 行,每行内容展现不了时后边主动增加“…”

OPPO 小米反对大图款式:这种告诉能够将更有吸引力的图片展现给用户

2.2 App 有很多业务推送告诉,用户是否能够指定接管分类音讯

随着 APP 的业务越来越简单,利用的告诉越来越多,给用户造成显著打搅;

用户只能全局屏蔽这个利用的全副告诉,不能屏蔽局部,而后留下对本人有用的。

为了解决这个问题,Android 8.0 开始反对开发者给本人的告诉分成若干类,而后容许用户独自屏蔽这个类别的告诉。

须要进行 Channel 分类,增加新 Channel(以 MiPush 为例):

ChannelHelper channelHelper = new ChannelHelper(APP_SECRET);
ChannelInfo channelInfo = new ChannelInfo.Builder()
        .channelId("id") // 必填,告诉类别的 ID,长度不超过 200 字符
        .channelName("name") // 必填,告诉类别的名称,长度不超过 40 字符
        .channelDesc("desc") // 可选,告诉类别的形容,长度不超过 300 字符
        .notifyType(0) // 必填,告诉的成果类型,仅反对 0,即振动、提示音、led 灯三种成果都无
        .soundUrl("sound_url") // 可选,告诉的自定义铃声 uri,格局介绍请参见“4.1 自定义铃声”.build();
Result result = channelHelper.addNewChannel(channelInfo, 1)

不同的 channel 在零碎设置页告诉设置中展现如下:

通过细分 push 告诉的类别,减少通道数量可进步 push 音讯在告诉栏里的留存率;

同时用户可有更多抉择,设置本人比拟关注的类型音讯,防止过多打搅,以晋升用户体验。

2.3 如何指定推送形式或人群

各厂商推送形式反对形式如下:

2.3.1 基于 ReglD 的推送

RegID 为是推送 SDK 为每个设施上的每个 app 注册推送服务时生成的惟一标示。

当开发者须要给一个或多个具体的设施推送音讯时,能够应用基于 RegID 的推送,将个性化的信息推送给指定的设施。这种形式实用于须要为每个用户订制个性化推送的场景。

2.3.2 基于 Alias 的推送

alias 是推送提供的一种个性化设定,开发者能够将用户在利用内的账号或其它用户惟一标识设定为用户设施 RegID 的别名,在推送中能够间接基于别名进行推送。

别名不仅不便开发者将推送与自有的账号零碎进行关联,同时也防止了因须要保留设施 RegID 与自有帐号的对应关系而额定带来的开发和存储老本。

2.3.3 基于标签的推送

对利用下已订阅 push 的设置了标签的用户进行推送。在推送音讯时,开发者能够联合每条音讯的内容和指标用户人群,抉择所对应的标签,实现申请后,push 推送服务会向所有

打上这一标签的用户发送该音讯,从而满足定向推送的需要。并且提供标签治理性能。

2.3.4 小米通道 userAccount:最多可对应 20 台设施,单账号可登陆多台设施,给一个 userAccount 推送可同时有 20 台设施收到音讯。

总结:将特定的推送音讯通过特定的形式发送给比方不同的客户端版本、不同地区、男女等的用户群体,或者通过给不同的用户群体打不同的标签的形式实现个性音讯的推送,以达到更精密推送的目标。

2.4 OPPO、ViVO 触达成功率低,如何晋升

触达数据接入数据看板后,经比照各厂商触达成功率发现 OPPO、ViVO 的触达率根本在 83%~86% 而小米华为通道触达成功率根本在 94%~98% 因而晋升 OPPO、VIVO 通达的触达成功率是咱们面临的又一问题

OPPO: 经排查发现影响 OPPO 触达率的次要因素为告诉开关的状态:APP 仅在告诉开关开启的状况下能力收到厂商的 Push 音讯而 OPPO、一加告诉开关在用户装置后默认敞开,因而收不到 Push 音讯。

解决办法:后期次要是制订疏导策略,在适合的机会检测告诉开关状态,疏导用户被动去设置页开启,起初经调研发现 OPPO 的 ColorOS 零碎提供了一键开启告诉开关的能力,前期应用疏导一键开启计划,将 OPPO 通道的触达率晋升到了 94% 左右;

VIVO: 与 OPPO 不同,VIVO 设施装置利用后告诉开关是开启的,咱们依据数仓提供的数据与厂商反馈的错误码剖析,导致 VIVO 触达偏低次要因素为音讯未进行分类而被限额。

vivo 通道音讯类型分为两类 —— 按音讯类型是否与用户强相干将音讯分为“经营音讯”和“零碎音讯”,未接音讯分类性能将导致所有音讯默认为经营音讯而受到频控限度,从而导致重要音讯可能无奈触达。

vivo 用户单利用每日经营音讯接管条数下限 5 条,零碎音讯无限度。vivo 用户单利用接管条数限度以“达到量”是否超过 5 条为准,在发送时校验单用户是否达到 5 条,超限则计入管控量。

除 VIVO 外,华为、OPPO、小米对告诉音讯的数量 都有肯定的限度,对于存在限额的厂商通道,将点击率高的个性化推送策略尽量安顿在上午推送,能够保障优质推送内容的达到率;通过进步音讯推送的额度,进步 push 音讯的触达率。

2.5 如何加强未读音讯揭示

能够在 App 桌面角标显示未读音讯数,厂商 lunch app 和 push sdk 对此提供了相应的能力反对,用于加强揭示,各厂商的实现细节上有差别:

华为:角标未读数由服务端下发的 push 音讯管制,凋谢了 api 供第三方利用设置角标未读数,移除告诉栏音讯角标数量不会变动。

小米:角标未读数等于厂商 push 通道(零碎告诉栏)收到的该 app 的未读告诉数,凋谢 api 供第三方利用设置角标未读数。移除零碎告诉栏音讯,角标数量相应缩小。

oppo:反对红点,数字角标,角标未读数等于厂商 push 通道(零碎告诉栏)收到的该 app 的未读告诉数。

vivo:桌面角标未读数开关默认敞开,须要用户手动开启能力应用,提供设置角标未读数的能力。

角标适配的问题及解决办法:

2.5.1 在小米零碎上能展现告诉数,但无奈更新站内信数量。

解决方案:站内信和 push 买通,进入 app 时同步更新未读数。

2.5.2 在华为零碎上无奈显示 Push 数量,站内信数显示失常。

解决方案:华为推送服务提供了在服务端设置桌面角标 API 接口,第三方 app 能够在音讯中封装角标参数。

2.5.3 vivo 手机上不反对显示角标未读数。

解决方案:更新 SDK 版本,接入角标能力

2.5.4 在 oppo 角标展现仅站内信数量。

push 性能在开明时能够申请圆点角标或数字角标、无角标三种模式,用户能够在告诉设置中自主抉择。

oppo push 反对的零碎版本,目前反对 ColorOS3.1 及以上的零碎的 OPPO 的机型,一加 5/5t 及以上机型,realme 所有机型(Android 8.0 当前的设施)。

2.5.5 其余:魅族手机未凋谢桌面角标设置。

触达形式三:站内横幅

1. 站内横幅计划介绍

已有的触达形式对用户实时行为产生的场景笼罩不够,而且这类场景较离线场景相比实时性更高,对用户来说绝对更重要。针对这个状况,咱们减少了对实时场景笼罩。

目标是将用户行为形象成关系模型,当关系一侧的用户行为产生变更后触发对另一侧的触达,这种状况实时性更强而且和用户强相干,触达的音讯点击和转化都比拟高,也有利于加强用户粘性。

数据服务层:各业务模块负责采集用户行为数据,由 molo 侧将用户行为形象关系模型,用户进入指定场景,触发对应场景触达策略,再经对立频控量控进行核验

传输层:基于 MQTT 协定的长链接实现的鹰眼自建通道,将通过核验的触达信号传递给下一流程

APP 根底能力层:为触达音讯传输,流程监控提供根底能力

数据解析层:将传递过去的触达音讯体解析,合法性校验,监控异样数据

视图管制层:进行触达音讯模板视图创立,弹出形式辨认,通过 ViewCore 给触达音讯视图注入生命周期,出入场动画,声音触动揭示、展现动效等各种定制化属性

2. 京东金融 App 站内横栏利用场景

站内横栏性能上线后,为一批业务提供了无效的触达策略

3. 遇到的问题及解决思路

3.1 如何让横栏实现在 App 站内全局

全局弹窗这个实现起来绝对容易,次要依赖注册的页面生命周期监听,利用 WindowManager 在来到页面时移除 view,在进入新页面从新增加;

3.2 指定页面显示或指定页面不显示问题

指定页面的前提是能辨别是哪个页面,分两种状况:

Web 页面,首先获取经营在鹰眼平台配置的指定的 Web 链接,再通过 APP 的 web 容器获取以后正在加的 web 页面的链接地址,两个地址进行匹配,须要留神本地取到的 url 里参数存在比经营配置多的状况,因而匹配时咱们认为只有本地取到的参数蕴含配置的地址中的各参数即是匹配胜利;

原生页面,形式一,路由地址匹配:咱们首先取原生页面的路由信息,本地有路由信息依据路由地址去匹配,若原生页面无路由地址,须要进行适配

形式二,popClass 匹配:须要将原生页面的类门路录入到后盾页面配置表进行保护,匹配时依据页面的类门路进行匹配

3.3 如何防止多个横栏音讯时失落问题

同时反对多个横栏,这里须要留神的是横栏信息同步问题,咱们在创立横栏的时候给横栏创立了一个属性信息对象,每个横栏属性信息都有惟一的 key, 将横栏属性缓存起来,并给缓存设置最大阈值,达到阈值时最初一个横栏隐没革除缓存信息

总结:站内横栏触达计划是咱们在智能化触达形式中的一项摸索,性能上线后,为白条,保险,财产,基金,分期等业务提供了一种更智能化的经营形式,触达音讯触达成功率 98%,点击率达到 12%~16%,助力相干业务晋升 40% 以上

触达形式四:桌面小组件

AppWidget 又称小部件、小插件或微件。它是显示在 Launcher 上,能在 Logo 以外提供更多信息的一种特地的设计;它不便用户免于关上 App 即可间接查看信息和进行简略的交互。

Android 初期曾经提供这种能力,但利用比拟少,常见的利用如:时钟、天气、日历等;
iOS 10 引入小组件,直到 iOS 14 的全面反对,可能是受此影响,Android 12 改良了 widgetAPI,晋升了用户及开发者体验

1. 创立 AppWidget

总的来说分以下几个局部:

1.1 定义 AppWidgetProvider

创立一个 AppWidgetProvider 子类,并创立对应的 AppWidgetProviderInfo 配置文件
example_appwidget_info.xml,并在 manifest 申明

1.2 设置 appWidget 的根本属性

AppWidgetProviderInfo 定义了 widget 的根本个性,如利用微件的最小布局尺寸、利用微件的初始布局资源、利用微件的更新频率,以及(可选)在利用微件创立时启动的配置 Activity。您能够应用单个 <appwidget-provider> 元素在 XML 资源中定义 AppWidgetProviderInfo 对象,并将其保留在我的项目的 res/xml/ 文件夹中

1.3 绘制 widget 的布局

AppWidget 能够反对的布局如下(因为其底层是基于 RemoteViews 实现,反对的视图较少):

FrameLayout、LinearLayout、RelativeLayout、GridLayout
反对应用的 View 如下(不反对自定义 View):

AnalogClock、Button、Chronometer、ImageButton、ImageView、ProgressBar、TextView、ViewFlipper、ListView、GridView、StackView、AdapterViewFlipper
1.4 配置 Configuration Activity

当利用 widget 应用配置 Activity 时,由该 Activity 负责在配置实现后对 app 的 widget 进行初始化

1.4.1 获取 widget id

1.4.2 执行利用微件配置

1.4.3 配置实现后,通过调用 getInstance(Context) 来获取 AppWidgetManager 的实例

1.4.4 通过调用 updateAppWidget(int, RemoteViews) 来应用 RemoteViews 布局更新利用微件

1.4.5. 最初,创立返回 Intent,为其设置 Activity 后果,而后完结该 Activity

1.4.6 设置预览图片

在抉择创立 appWidget 时,展现给用户的描述利用微件是什么样子的一张图片,未配置时默认展现 APP logo

1.4.7 配置 Service

申请汇合中的特定我的项目时,RemoteViewsFactory 会为汇合创立相应我的项目并将其作为 RemoteViews 对象返回。要在 appWidget 中增加汇合视图,您必须实现 RemoteViewsService 和 RemoteViewsFactory。

具体参见官网 demo:
https://android.googlesource….

1.4.8 设置点击事件

通常应用 setOnClickPendingIntent() 来设置对象的点击行为 – 例如,让按钮启动 Activity。然而,不容许对各个汇合我的项目中的子视图应用此办法。如果要向汇合中的各个我的项目增加点击行为,应改用 setOnClickFillInIntent()。这须要为汇合视图设置待定 Intent 模板,而后通过 RemoteViewsFactory 在汇合中的每个我的项目上设置填充 Intent。

2. 常见 App 的实现

金融 APP 的实现:

3. 小组件实际中的问题

3.1 如何裁剪图片圆角

个别在开发过程中应用 Glide 对图片进行裁剪,这里须要留神小组件里应用 Glide 与平时略有不同,因为拿不到对应的 View 视图,AppWidgetTarget 更实用于小组件加载图片场景,配合 MultiTransformation 可简便的实现图片圆角的剪裁

AppWidgetTarget appWidgetTarget = new AppWidgetTarget(context, ivViewId, views, mAppWidgetIds);
RequestOptions option = new RequestOptions()
                .transform(new MultiTransformation<>(new CenterCrop(),
                        new RoundedCorners(ToolUnit.dipToPx(mContext, connerDp))));
GlideApp.with(AppEnvironment.getApplication().getApplicationContext())
                    .asBitmap()
                    .load(bgUrl)
                    .apply(option)
                    .diskCacheStrategy(DiskCacheStrategy.NONE)
                    .into(appWidgetTarget);

3.2 如何实现自定义字体

小组件自身是不反对自定义 view 的,若要实现反对自定义字体,能够通过 Canvas draw text 形式 给 text 设置字体款式,粗细、色彩、背景等属性

3.3 解决点击响应提早问题

通过播送模式 PendingIntent.getBroadcast 解决点击事件,在局部机型上存在延时,最长约 7s;能够应用 setOnClickPendingIntent 形式代替,须要在 app 的跳转核心解决对应的事件,如跳转落地页、埋点等

3.4 如何制订更新策略

零碎为了防止小组件过多的占用资源,默认回绝频繁更新,设置了最短更新工夫为 30 分钟;这种默认的刷新形式不太适宜交互类型的小组件,存在用户操作完当前页面状态不同步的问题,那这个问题如何解决呢?首先依据业务场景须要咱们也能够把刷新分为两类:

实时性有肯定要求的业务场景:比方新闻资讯类的

通过创立 Service 开启定时工作的形式,制订更新的工夫距离,比方 5 分钟执行一次更新工作;

用户交互类型的业务场景:比方签到,收积分、能量等;此类场景不要求频繁刷新数据,但须要配置正当的主动刷新工夫,同时在用户操作后须要刷新页面;能够在 App 启动时注册 APP 内页面生命周期监听 ActivityLifecycleCallbacks,实现判断 APP 前后台监听能力,监听利用进入后盾时发送刷新小组件的播送,触发小组件的刷新;或者封装对立办法,提供给业务被动触发刷新对应的小组件的接口

小结

本文次要分享了京东金融客户端技术团队对短信、push、站内横幅、小组件几种触达形式的摸索实际过程以及遇到的问题和解决方案。心愿能给在摸索用户触达实现计划的同学提供一些思路;为了让用户在应用咱们的产品的时候能有更好的体验,产品在经营过程中能高效的触达用户,京东科技技术团队在继续打磨已有计划的同时将持续摸索和实际更加智能高效的触达计划。

退出移动版