标签: DeepLink

DeepLink唤醒App的简单实现方法

DeepLink(深度链接技术),一般是通过Web页面调用原生App,并把需要的参数通过Uri的形式传递给App,主要使用方式有:两个App之间的广告、App的社交分享、页面跳转App、DSP广告投放、营销效果统计等。在App的运营推广中,DeepLink的意义十分重大。

使用DeepLink技术的App可以让用户在手机移动端点击广告或链接时,直接唤醒对应的手机App,并跳转到达App里对应的场景页面。

DeepLink技术目前也有比较成熟的第三方,这里重点介绍一下 openinstall 的“一键拉起”功能,这项功能集成scheme,universal link等技术,能快速实现一键拉起App、一键直达页面,近期已经免费开放给广大开发者。

%title插图%num

如上图所示,openinstall 这项功能的主要优势有:
1、同时兼容Android和iOS系统,两者都可以直达相应场景;
2、openinstall一键拉起功能适配大量主流社交平台和浏览器,如微信、QQ、钉钉、新浪微博、支付宝等;
3、目前该服务运行相当稳定,能完善用户安装全流程,大幅降低用户流失率;
4、openinstall能帮助开发者追踪渠道来源,统计用户是具体从哪篇文章、哪个链接点进来的,评估渠道广告和推广效果;
5、openinstall能实现点击链接安装后自动添加好友,让用户之间的关系链更加紧密;
6、11月份起,已经完全免费开放给开发者使用。

目前大多数App都能得到巧用。如:电商类App直达购物商品页面、游戏类App直达分享游戏房间、资讯类App直达对应新闻页面等,具体可以结合自身的App业务进行拓展。此外,openinstall提供的免填邀请码安装、广告效果统计等功能也能让这项技术的使用场景得到延伸。

%title插图%num

openinstall官网:https://www.openinstall.io

Deeplink(深度链接)拉起App,我是这样做到的

移动互联网时代,信息的分享传播无疑是 App 引流增长的关键,与其花费大量精力和成本找渠道、硬推广,不如从细节下手,用*快*简便的方法实现 Deeplink(深度链接)技术,打破信息孤岛、缩短分享路径、优化用户体验,*终提高流量转化率和留存率。

什么是 DeepLink(深度链接)技术
如果把 App 看成网站,那么 DeepLink 就是网站中的深入页面,比如商品购物页面、活动促销页面。简单理解,就是当用户点击手机中的某个链接时,可以帮他跳转到 App 内部中的目标页面,直接实现场景还原,而不是 App 首页,这是一种无障碍场景还原技术。

DeepLink 通常运用于App社交分享、App广告引流、App裂变活动、Web to App、分享效果统计、沉默用户唤醒等场景,对广告引流、活动推广、新闻类、电商类、游戏类、视频直播类App的引流推广和转化都有着奇效。

升级版 Deferred deeplink(延迟深度链接)技术
相比 Deeplink,Deferred deeplink 增加了一个判断,能在用户点击链接时判断设备是否安装了目标App,如果没有安装,则跳转应用市场或者浏览器中引导下载,用户安装后再次实现 Deeplink 的场景还原功能。

是否使用这两项技术的差别:

%title插图%num

可以看到,使用了深度链接后,用户操作成本明显降低了一至两步,做运营的小伙伴都知道,在用户转化的漏斗中,每多一个步骤,漏斗的路径就会多一层,用户流失率也就随之增加。

怎样为App快速实现这两项技术
我们以 openinstall 的一键拉起功能为例,这项功能集成了深度链接中的scheme,universal link等核心技术,能完美实现 Deeplink、Deferred deeplink 的所有技术场景效果,主要特点如下:

一键拉起功能同时兼容 Android、iOS 系统,不存在操作系统技术障碍;
适配了大量主流社交平台和浏览器,如微信、QQ、新浪微博、钉钉、支付宝等;
用户已安装该 App 的情况下,点击页面链接可直接拉起本地 App,并自动进入目标页面;
用户未安装该 App 的情况下,点击页面链接会引导到应用商店或默认浏览器下载,安装后首次打开将自动进入目标页面;
该功能目前以及免费开放给所有开发者,随时可以到 openinstall 官网访问集成 SDK 使用,*快十分钟即可集成体验。
openinstall:https://www.openinstall.io/pullUp.html

%title插图%num

不仅如此,作为成熟的第三方供应商,openinstall 在深度链接的基础上,完善出了更多定制化场景需求,比如:

能够根据需求满足开发者业务逻辑,如:既可实现下载优先,也可以实现拉起优先;
在社交分享页面上,openinstall 还能同时实现携带参数安装,帮助开发者实现渠道来源统计,具体到用户是被哪篇文章吸引来的、哪个广告页面的转化率*高、哪件产品付费效果*好;
甚至可以在业务上结合 openinstall 实现【社交平台快速下载 App、免填邀请码、App 安装后自动加群加好友、下载 App 后自动登录账号】等功能,进一步完善用户体验和关系链。
哪些产品或场景非常适合深度链接

社交平台我们以微信为例,产品以电商类京东 App、资讯类今日头条 App 为例,可以参考他们的结合效果:

%title插图%num

显而易见,电商类、资讯类、旅游类、服务类 App 结合社交分享传播具有非常大的价值,此外,游戏类 App 甚至可以利用一键拉起功能点击分享链接直接进入 App 内的游戏房间。

常见使用场景如下:

 

电商类:在分享商品链接中点击,进入 App 内对应店铺或购物页面
资讯类:在分享新闻链接中点击,进入 App 内对应内容页面
游戏类:在分享邀请组队的链接中点击,进入 App 内对应的游戏房间或战队队伍中
广告:在社交平台点击相关广告,进入 App 内对应内容页面
拉新活动:例如老带新邀请、福利抽*等 H5 页面活动,参与者可以点击进入 App 内对应活动参与页面

App 间的自由跳转,解决的不仅仅是用户体验问题,更是拓展 App 的应用宽度问题,有了深度链接后,App 之间不再是独立的个体平台,开发者可以在移动端再现网页端的自由跳转,将广告、活动营销、裂变拉新、用户唤醒等业务结合其中,创造一个更加完整、精简的转化链,能给 App 的运营和推广带来更多想象空间。

Android应用开发中使用deeplink

一、DeepLink的应用场景
DeepLink简单理解就是通过在手机上点击一个链接后能实现如下功能:

如果目标App没有启动,那么就拉起App,并跳转到App内指定页面
如果目标App已经启动,那么就把App拉到前台并跳转到App内指定页面
二、DeepLink的实现思路
在Android开发中,可以通过在清单文件中配置scheme来实现页面跳转,所以可以通过scheme匹配的方式来实现DeepLink的功能。配置方式大概分为三种:

为每一个要跳转的Activity都指定一个对应的匹配条件,如果页面太多的话,这种方式管理起来不太方便,而且没有办法对App全局配置信息、用户状态等进行统一处理
配置闪屏页面为匹配页面,闪屏页一般都是App冷启动时才会出现,而且打开首页后,闪屏页就会关闭,这种方式在App没有启动的情况下可以很好的处理对应的Intent信息,但是如果App已经启动过了,在去拉起闪屏页就不合理了
配置首页为匹配页面,首页在App中一般都是常驻的,一般情况下首页关闭就意味着App的退出,所以可以在首页中统一处理匹配scheme得到的Intent信息,然后进行统一的跳转分发(需要将首页Activity的启动模式设置为singleTask以防止首页创建多个页面)
三、DeepLink的实现案例
下面使用上述的方式3写个Demo进行验证,实现步骤如下:

提前定义好自己的scheme、host等信息配置到清单文件里面,scheme是必须要有的,像host等信息可以配置也可以没有,我这里配置了scheme和host两个条件,其中sheme是“link”,host是“cn.znh.deeplinkdemo”,清单文件配置如下:
<?xml version=”1.0″ encoding=”utf-8″?>
<manifest xmlns:android=”http://schemas.android.com/apk/res/android”
package=”cn.znh.deeplinkdemo”>

<application
android:allowBackup=”true”
android:icon=”@mipmap/ic_launcher”
android:label=”@string/app_name”
android:roundIcon=”@mipmap/ic_launcher_round”
android:supportsRtl=”true”
android:theme=”@style/AppTheme”>

<!–闪屏页设置为启动页–>
<activity android:name=”.SplashActivity”>
<intent-filter>
<action android:name=”android.intent.action.MAIN” />
<category android:name=”android.intent.category.LAUNCHER” />
</intent-filter>
</activity>

<!–配置首页–>
<activity
android:name=”.MainActivity”
android:launchMode=”singleTask”>
<intent-filter>
<action android:name=”android.intent.action.VIEW” />
<category android:name=”android.intent.category.DEFAULT” />
<category android:name=”android.intent.category.BROWSABLE” />

<data
android:host=”cn.znh.deeplinkdemo”
android:scheme=”link” />
</intent-filter>
</activity>

<!–普通的Activity–>
<activity android:name=”.Link1Activity” />
<activity android:name=”.Link2Activity” />
<activity android:name=”.Link3Activity” />
</application>

</manifest>

在首页Activity的onCreate方法和onNewIntent方法里面,接收Intent参数进行相应的跳转处理,首页代码如下:
package cn.znh.deeplinkdemo;

import android.content.Intent;
import android.net.Uri;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;

/**
* Created by znh on 2018/12/23.
* <p>
* 首页
*/
public class MainActivity extends AppCompatActivity {

//定义的scheme
private static final String SCHEME_VALUE = “link”;

//定义的host
private static final String HOST_VAULE = “cn.znh.deeplinkdemo”;

/**
* 首次启动MainActivity调用该方法
*
* @param savedInstanceState
*/
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
schemeIntent(getIntent());
}

/**
* 启动已经存在的MainActivity调用该方法(singleTask启动模式)
*
* @param intent
*/
@Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
schemeIntent(intent);
}

/**
* 处理intent事件
*
* @param intent
*/
private void schemeIntent(Intent intent) {
if (intent == null || intent.getData() == null) {
return;
}

//获取Uri
Uri uri = intent.getData();

//打印出uri里取出的Scheme和Host
Log.e(“schemeIntent”, “getScheme:” + uri.getScheme());
Log.e(“schemeIntent”, “getHost:” + uri.getHost());

//判断取出的Scheme和Host是否和自己配置的一样,如果一样进行相应的处理,否则不处理
if (!SCHEME_VALUE.equals(uri.getScheme()) || !HOST_VAULE.equals(uri.getHost())) {
return;
}

//如果Scheme和Host匹配成功,取出uri中的参数并进行相应的业务处理
String type = uri.getQueryParameter(“type”);
String id = uri.getQueryParameter(“id”);

//打印uri里取出的参数
Log.e(“schemeIntent”, “type:” + type);
Log.e(“schemeIntent”, “id:” + id);

//进行统一的跳转分发
if (“1”.equals(type)) {
Intent intent1 = new Intent(this, Link1Activity.class);
startActivity(intent1);
} else if (“2”.equals(type)) {
Intent intent2 = new Intent(this, Link2Activity.class);
startActivity(intent2);
} else if (“3”.equals(type)) {
Intent intent3 = new Intent(this, Link3Activity.class);
startActivity(intent3);
}
}
}

上述两个步骤就可以实现deeplink的效果了,可以在AndroidStudio里输入如下命令进行测试:

adb shell am start -a android.intent.action.VIEW -d “link://cn.znh.deeplinkdemo?’type=2&id=335′”
1
观察结果发现页面跳转到Link2Activity了,log打印结果如下:

E/schemeIntent: getScheme:link
E/schemeIntent: getHost:cn.znh.deeplinkdemo
E/schemeIntent: type:2
E/schemeIntent: id:335

四、闪屏页的问题处理
经过上面两个步骤,确实已经可以实现deeplink的功能了,但是还有个问题,那就是如果App还没有启动的情况下,由于直接拉起的是首页页面,并没有经过闪屏页(如果App已经启动过了,不需要走闪屏页,直接走首页然后进行对应页面跳转是没有问题的),那么怎么解决这个问题呢,这里想到的一个解决方案是记录一个是否是经闪屏页启动的一个标志位,如果是就正常处理,如果不是就重新开启闪屏页。具体实现如下:

在闪屏页面跳转到首页时,在Intent中传递过去一个标志位参数isSplashLanuch,以标识闪屏页已经启动过了
//跳转到首页
Intent intent = new Intent(SplashActivity.this, MainActivity.class);
intent.putExtra(“isSplashLanuch”, true);
startActivity(intent);
finish();

在首页页面中获取isSplashLanuch的值来判断闪屏页面是否已经启动过(需要注意,在onNewIntent方法中要将isSplashLanuch的值永远设置为true),如果为true不进行特殊处理,如果为false就关闭首页并开启闪屏页,还要传递给闪屏页uri数据,方便跳转场景还原,首页处理Intent的方法如下:
/**
* 处理intent事件
*
* @param intent
*/
private void schemeIntent(Intent intent) {
if (intent == null || intent.getData() == null) {
return;
}

//获取Uri
Uri uri = intent.getData();

//打印出uri里取出的Scheme和Host
Log.e(“schemeIntent”, “getScheme:” + uri.getScheme());
Log.e(“schemeIntent”, “getHost:” + uri.getHost());

//判断取出的Scheme和Host是否和自己配置的一样,如果一样进行相应的处理,否则不处理
if (!SCHEME_VALUE.equals(uri.getScheme()) || !HOST_VAULE.equals(uri.getHost())) {
return;
}

//如果闪屏页启动过了,就不处理,否则关闭首页打开闪屏页
if (!isSplashLanuch) {
Intent intentSplash = new Intent(this, SplashActivity.class);
intentSplash.setData(uri);//设置uri数据,方便场景还原
startActivity(intentSplash);
finish();
return;
}

//如果Scheme和Host匹配成功,取出uri中的参数并进行相应的业务处理
String type = uri.getQueryParameter(“type”);
String id = uri.getQueryParameter(“id”);

//打印uri里取出的参数
Log.e(“schemeIntent”, “type:” + type);
Log.e(“schemeIntent”, “id:” + id);

//进行统一的跳转分发
if (“1”.equals(type)) {
Intent intent1 = new Intent(this, Link1Activity.class);
startActivity(intent1);
} else if (“2”.equals(type)) {
Intent intent2 = new Intent(this, Link2Activity.class);
startActivity(intent2);
} else if (“3”.equals(type)) {
Intent intent3 = new Intent(this, Link3Activity.class);
startActivity(intent3);
}
}

在闪屏页执行结束跳转到首页时,将uri数据带到首页进行场景还原,跳转到首页的代码如下:
//跳转到首页,并重新设置拿到的uri数据
Intent intent = new Intent(SplashActivity.this, MainActivity.class);
if (getIntent() != null && getIntent().getData() != null) {
intent.setData(getIntent().getData());
}
intent.putExtra(“isSplashLanuch”, true);
startActivity(intent);
finish();

在次输入命令进行测试,观察结果,冷启动时可以走闪屏页面了,跳转逻辑页正常。

五、闪屏页和首页的完整代码
闪屏页完整代码:
package cn.znh.deeplinkdemo;

import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;

/**
* Created by znh on 2018/12/23.
* <p>
* 闪屏页
*/
public class SplashActivity extends AppCompatActivity {

@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_splash);

//延迟3秒跳转到首页
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
//跳转到首页,并重新设置拿到的uri数据
Intent intent = new Intent(SplashActivity.this, MainActivity.class);
if (getIntent() != null && getIntent().getData() != null) {
intent.setData(getIntent().getData());
}
intent.putExtra(“isSplashLanuch”, true);
startActivity(intent);
finish();
}
}, 3000);
}
}

首页的完整代码:
package cn.znh.deeplinkdemo;

import android.content.Intent;
import android.net.Uri;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;

/**
* Created by znh on 2018/12/23.
* <p>
* 首页
*/
public class MainActivity extends AppCompatActivity {

//定义的scheme
private static final String SCHEME_VALUE = “link”;

//定义的host
private static final String HOST_VAULE = “cn.znh.deeplinkdemo”;

//闪屏页是否启动过了
private boolean isSplashLanuch = false;

/**
* 首次启动MainActivity调用该方法
*
* @param savedInstanceState
*/
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
isSplashLanuch = getIntent().getBooleanExtra(“isSplashLanuch”, false);
schemeIntent(getIntent());
}

/**
* 启动已经存在的MainActivity调用该方法(singleTask启动模式)
*
* @param intent
*/
@Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
isSplashLanuch = true;
schemeIntent(intent);
}

/**
* 处理intent事件
*
* @param intent
*/
private void schemeIntent(Intent intent) {
if (intent == null || intent.getData() == null) {
return;
}

//获取Uri
Uri uri = intent.getData();

//打印出uri里取出的Scheme和Host
Log.e(“schemeIntent”, “getScheme:” + uri.getScheme());
Log.e(“schemeIntent”, “getHost:” + uri.getHost());

//判断取出的Scheme和Host是否和自己配置的一样,如果一样进行相应的处理,否则不处理
if (!SCHEME_VALUE.equals(uri.getScheme()) || !HOST_VAULE.equals(uri.getHost())) {
return;
}

//如果闪屏页启动过了,就不处理,否则关闭首页打开闪屏页
if (!isSplashLanuch) {
Intent intentSplash = new Intent(this, SplashActivity.class);
intentSplash.setData(uri);//设置uri数据,方便场景还原
startActivity(intentSplash);
finish();
return;
}

//如果Scheme和Host匹配成功,取出uri中的参数并进行相应的业务处理
String type = uri.getQueryParameter(“type”);
String id = uri.getQueryParameter(“id”);

//打印uri里取出的参数
Log.e(“schemeIntent”, “type:” + type);
Log.e(“schemeIntent”, “id:” + id);

//进行统一的跳转分发
if (“1”.equals(type)) {
Intent intent1 = new Intent(this, Link1Activity.class);
startActivity(intent1);
} else if (“2”.equals(type)) {
Intent intent2 = new Intent(this, Link2Activity.class);
startActivity(intent2);
} else if (“3”.equals(type)) {
Intent intent3 = new Intent(this, Link3Activity.class);
startActivity(intent3);
}
}
}

 

【Android】DeepLink跳转简介

一、DeepLink的概念
DeepLink是将用户直接带到应用中特定内容的网址。在Android中,可以通过添加intent filters 并从传入的intent中提取数据来设置DeepLink,从而将 用户引导向正确的Activity。

当单击的链接或编程请求调用Web URI的intent时,Android系统将按顺序尝试以下每个操作,直到请求成功为止:

1.打开用户首选的可以处理URI的App(如果已指定)。

2.打开唯一可以处理URI的可用App。

3.允许用户从对话框中选择App。

即:用户通过点击或者其他的操作发送url请求,系统会对该url进行解析,然后调起注册过相应scheme的应用,如果有多个注册,会弹出对话框让用户选择。

二、DeepLink的作用
实现了网页与App之间的跳转。每个App不再是一个个独立的孤岛。交互非常的方便,将App连接到了整个网络世界,用过浏览器就能随意的跳转。
2. 通过DeepLink方式App之间可以相互拉活,相互跳转。

三、使用
1.创建指向应用内容的链接,需要在应用的AndroidManifest.xml中配置包含如下元素和属性的intent filter
<action> 中指定ACTION_VIEW,以便可以从Google搜索访问意图过滤器

<data> 添加一个或多个<data> 标记,每个标记表示解析为活动的URI格式。<data>标签必须至少 包含该android:scheme 属性。

<category> 包括BROWSABLE 类别。为了从Web浏览器访问intent过滤器,需要它。没有它,单击浏览器中的链接无法解析为您的应用程序。

以下XML代码段显示了如何在清单中为深度链接指定intent过滤器。URI “example://gizmos”和“http://www.example.com/gizmos”两者都解析为此活动。

<activity
android:name=”com.example.android.GizmosActivity”
android:label=”@string/title_gizmos” >
<intent-filter android:label=”@string/filter_view_http_gizmos”>
<action android:name=”android.intent.action.VIEW” />
<category android:name=”android.intent.category.DEFAULT” />
<category android:name=”android.intent.category.BROWSABLE” />
<!– Accepts URIs that begin with “http://www.example.com/gizmos” –>
<data android:scheme=”http”
android:host=”www.example.com”
android:pathPrefix=”/gizmos” />
<!– note that the leading “/” is required for pathPrefix–>
</intent-filter>
<intent-filter android:label=”@string/filter_view_example_gizmos”>
<action android:name=”android.intent.action.VIEW” />
<category android:name=”android.intent.category.DEFAULT” />
<category android:name=”android.intent.category.BROWSABLE” />
<!– Accepts URIs that begin with “example://gizmos” –>
<data android:scheme=”example”
android:host=”gizmos” />
</intent-filter>
</activity>

注意:两个intent-filter仅元素不同。同一个intent-filter可以包括多个,创建intent-filter的目的是要申报的唯一URL(如特定的组合是非常重要的scheme和host),因此多个在同一个intent-filter实际上合并在一起考虑其组合属性的所有变体。例如,请考虑以下事项

<intent-filter>

<data android:scheme=”https” android:host=”www.example.com” />
<data android:scheme=”app” android:host=”open.my.app” />
</intent-filter>

2.从传入的intent中读取数据
一旦系统通过intent filter启动Activity,就可以使用它提供的数据Intent来确定您需要呈现的内容。调用getData()和 getAction()方法来检索与传入相关的数据和操作Intent。可以在活动的生命周期中随时调用这些方法,但通常应该在早期回调期间执行此操作,例如 onCreate()或 onStart()。

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);

Intent intent = getIntent();
String action = intent.getAction();
Uri data = intent.getData();
}

参考网站:https://developer.android.google.cn/training/app-links/deep-linking

友情链接: SITEMAP | 旋风加速器官网 | 旋风软件中心 | textarea | 黑洞加速器 | jiaohess | 老王加速器 | 烧饼哥加速器 | 小蓝鸟 | tiktok加速器 | 旋风加速度器 | 旋风加速 | quickq加速器 | 飞驰加速器 | 飞鸟加速器 | 狗急加速器 | hammer加速器 | trafficace | 原子加速器 | 葫芦加速器 | 麦旋风 | 油管加速器 | anycastly | INS加速器 | INS加速器免费版 | 免费vqn加速外网 | 旋风加速器 | 快橙加速器 | 啊哈加速器 | 迷雾通 | 优途加速器 | 海外播 | 坚果加速器 | 海外vqn加速 | 蘑菇加速器 | 毛豆加速器 | 接码平台 | 接码S | 西柚加速器 | 快柠檬加速器 | 黑洞加速 | falemon | 快橙加速器 | anycast加速器 | ibaidu | moneytreeblog | 坚果加速器 | 派币加速器 | 飞鸟加速器 | 毛豆APP | PIKPAK | 安卓vqn免费 | 一元机场加速器 | 一元机场 | 老王加速器 | 黑洞加速器 | 白石山 | 小牛加速器 | 黑洞加速 | 迷雾通官网 | 迷雾通 | 迷雾通加速器 | 十大免费加速神器 | 猎豹加速器 | 蚂蚁加速器 | 坚果加速器 | 黑洞加速 | 银河加速器 | 猎豹加速器 | 海鸥加速器 | 芒果加速器 | 小牛加速器 | 极光加速器 | 黑洞加速 | movabletype中文网 | 猎豹加速器官网 | 烧饼哥加速器官网 | 旋风加速器度器 | 哔咔漫画 | PicACG | 雷霆加速