初探 Google App Indexing

导语

Firebase App Indexing 可以将您的应用纳入 Google 搜索中。如果用户安装了您的应用,他们就可以启动您的应用,并直接转到他们正在搜索的内容。App Indexing 可帮助您的应用用户在其设备上查找公开和个人内容,甚至提供查询自动填充功能以帮助他们更快速地找到所需的内容,从而重新吸引这些用户的关注。

1.介绍

如今随着Android手机的普及以及谷歌强大的搜索引擎,谷歌搜索相关市场份额在互联网占有率非常高,这为它打造它独有的搜索生态圈提供了强大的支撑,如google inc、google map、google assistant,google chrome等系列应用都整合搜索信息,可以很方便应用其google app相关应用搜索所需信息,如你可以通过google map搜索附近餐厅,google assistant搜索joox音乐软件,既然人家“朋友圈”那么广,那么是不是通过人家广交朋友来打造自己的”朋友圈”哈哈,为了向大家开放它独有的“朋友圈”,谷歌在2016年IO大会开放了Firabase App Indexing功能,其可以让用户利用谷歌搜索生态来打开app的指定内容(deep link一样),详情可以点击:https://firebase.google.com/docs/app-indexing/ , 比如我直接在google assistant搜搜etsy电商平台上的smile相关商品,点击其信息,就直接打开我的etsy应用了(手机已安装该应用),并跳转到指定应用,如图所示:

图:1.1搜索

图: 1.2跳转页面

不过我发现有几个关键点哈,如果你的应用没有安装,则不会打开你的应用,而是直接打开website页面,如果手机已经安装了esty应用,在chrome搜索esty应用,则web页面会显示“已安装”。

那么joox可以应用google的app indexing做什么呢?

  • 在谷歌应用搜索中,显示指向应用内容的链接,方便用户点击链接直接打开joox应用并直接跳转到指定应用,这有利于提升joox的A1指标。
  • 在搜索中搜索joox应用安装,其安装按钮会显示在首页搜索结果旁边,以便用户能够方便地安装joox应用。
  • 可以通过Search Console统计后台,分析用户搜索joox 行为以及页面搜索占比,这有利于结合AdMob定位投放广告,提高广告收入。

2.开发入门

2.1环境搭建

添加 Firebase 和 App Indexing 库

1.添加Firebase至Android项目中,具体链接:https://firebase.google.com/docs/android/setup

2.要将App Indexing库添加至你的项目,请转到应用的build.gradle 脚本并添加一下依赖项:

dependencies {
  ...
  // To avoid errors, use the same Firebase SDK version across your app.
  compile 'com.google.firebase:firebase-appindexing:11.2.0'
  ...
}

合理安排应用内容的链接

恰当组织您的网站和应用的结构,使指向您的网站网页的网址与指向您的 Android 应用视图的网址相同。Google 搜索会抓取您的这些网站链接,然后利用它们将用户直接导向至您的应用。

3.在Firebase平台创建项目并注册其应用信息,以获取google_service.json 配置文件,如图:

图: 下载配置文件

图: 加载配置文件

当Google搜索显示爬取的公开内容信息时,用户点击其信息,将会交给匹配的Activity处理。

4.在AndroidManifest.xml添加处理url的Activity配置:

<activity
   android:name=".client.RecipeActivity"
   android:label="@string/app_name"
   android:exported="true"
   android:launchMode="singleTop"
   android:theme="@android:style/Theme.Holo.NoActionBar">
   <intent-filter android:label="@string/app_name" android:autoVerify="true">
       <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://recipe-app.com/recipe" -->
       <data android:scheme="http"
           android:host="recipe-app.com"
           android:pathPrefix="/recipe" />
   </intent-filter>
</activity>

启用个人内容索引,这样方便在自己设备上看到相关内容搜索,类似于搜索历史,出于隐私保护,该个人内容索引只存在于用户设备上,不会上传到google服务器。

5.建立个人搜索内容索引,核心代码如下:

public class AppIndexingService extends IntentService {
   @Override
   protected void onHandleIntent(Intent intent) {
       ArrayList<Indexable> indexableNotes = new ArrayList<>();

       for (Recipe recipe : getAllRecipes()) {
           Note note = recipe.getNote();
           if (note != null) {
               Indexable noteToIndex = Indexables.noteDigitalDocumentBuilder()
                       .setName(recipe.getTitle() + " Note")
                       .setText(note.getText())
                       .setUrl(recipe.getNoteUrl())
                       .build();

               indexableNotes.add(noteToIndex);
           }
       }

       if (indexableNotes.size() > 0) {
           Indexable[] notesArr = new Indexable[indexableNotes.size()];
           notesArr = indexableNotes.toArray(notesArr);

           // batch insert indexable notes into index
           FirebaseAppIndex.getInstance().update(notesArr);
       }
   }
}

AndroidManifest配置:

<service android:name=".client.AppIndexingService"
  android:exported="true"
  android:permission="com.google.android.gms.permission.APPINDEXING">
   <intent-filter>
       <action android:name="com.google.firebase.appindexing.UPDATE_INDEX" />
   </intent-filter>
</service>

当然为了解用户需求,需要采集用户搜索公开内容行为来提升产品用户体验以及满足用户更多需求,因此可以用API采统计用户行为,也可以采集用户搜索个人内容行为(这里有兴趣可以去官网看,不太代码了)。

6.记录用户搜索公开内容行为核心代码:

    @Override
    public void onStart() {
       super.onStart();
       if (recipe != null) {
          indexRecipe();
          FirebaseUserActions.getInstance().start(getRecipeViewAction());
       }
    }

    private void indexRecipe() {
        Indexable recipeToIndex = new Indexable.Builder()
               .setName(mRecipe.getTitle())
               .setUrl(mRecipe.getRecipeUrl())
               .setImage(mRecipe.getPhoto())
               .setDescription(mRecipe.getDescription())
               .build();

        FirebaseAppIndex.getInstance().update(recipeToIndex);
    }

    private Action getRecipeViewAction() {
       return Actions.newView(mRecipe.getTitle(),mRecipe.getRecipeUrl());
    }
public void onStop() {
   if (recipe != null) {
       FirebaseUserActions.getInstance().end(getRecipeViewAction());
   }
   super.onStop();
}

那么如何调试你的应用支不支持搜索链接跳转呢?这里可以用多种方法,其具体链接:https://firebase.google.com/docs/app-indexing/android/test

7.可以用类似命令行测试:

$ adb shell am start -a android.intent.action.VIEW \
-d "http://recipe-app.com/recipe/pierogi-poutine" com.recipe_app

3.实践

那么joox引入了app indxing,再结合阿里开源框架的ARouter(https://github.com/alibaba/ARouter),那么可以很好的管理页面跳转,同时可以通过降级或拦截器来处理跳转失败问题,其假设其跳转url协议为//协议格式:joox域名/跳转页url?参数。

具体处理流程如图:

图:处理流程

当然这些需要建立规范的路由映射表,如图:

图:路由映射表

定义路由映射:

@Route(path = RouterConsts.MAINTABACTIVITY)
public class MainTabActivity
//要求处于登录状态
@Route(path =RouterConsts.PERSONALINFOACTIVITY,extras = RouterConsts.REQUIRE_LOGIN)
public class PersonalInfoActivity

定义统一处理app indexing的Activit核心代码:

protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //处理app indexing url
        onNewIntent(getIntent());
        finish();
    }

    protected void onNewIntent(Intent intent) {
        String action = intent.getAction();
        String data = intent.getDataString();
        if (Intent.ACTION_VIEW.equals(action) && data != null) {
                //获取url参数
                Map<String,String> params=getQueryMap(uri.getQuery());
                //页面跳转
                if(pageUrl.equals(RouterConsts.MAINTABACTIVITY)&&params!=null){
                    //携带参数跳转
                    ARouter.getInstance().build(pageUrl).withInt("index",Integer.valueOf(params.get("index"))).navigation();
                }else {
                    ARouter.getInstance().build(pageUrl).navigation(null,new NavigationCallback() {

                        @Override
                        public void onLost(Postcard postcard) {
                            //找不到做降级处理
                        }

                    });
                }
        }
    }

定义拦截器:

//做页面跳转拦截操作
@Interceptor(priority = 7)
public class JooxInterceptor implements IInterceptor {
    @Override
    public void process(Postcard postcard, InterceptorCallback callback) {
        //拦截,检测条件
        if(postcard.getExtra()==RouterConsts.REQUIRE_LOGIN&&!AppCore.getUserManager().isLoginOK()){
            ARouter.getInstance().build(RouterConsts.WELCOMEPAGEACTIVITY).navigation();
        }else {
            callback.onContinue(postcard);
        }
    }

    @Override
    public void init(Context context) {

    }
}

总结

joox引入了app indexing功能,需要产品梳理每个模块对应的页面,以便能规范建立页面映射路由表,这有利于后面维护和修改,同时此功能有助于产品了解用户的需求,这有利于产品进一步提升和改进,还有一点,就是谷歌应用会对相关搜索页面进行排名,对热点搜索可以适当投放广告,增加广告的曝光率,从而进一步提高广告收入。

参考文献

1https://firebase.google.com/docs/app-indexing/

2https://github.com/alibaba/ARouter

3https://codelabs.developers.google.com/codelabs/app-indexing/#0

4https://www.youtube.com/watch?v=CwgWOHgHHJE&t=759s

原创声明,本文系作者授权云+社区发表,未经许可,不得转载。

如有侵权,请联系 yunjia_community@tencent.com 删除。

编辑于

徐国立的专栏

1 篇文章1 人订阅

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏Ceph对象存储方案

Luminous版本PG 分布调优

Luminous版本开始新增的balancer模块在PG分布优化方面效果非常明显,操作也非常简便,强烈推荐各位在集群上线之前进行这一操作,能够极大的提升整个集群...

3645
来自专栏pangguoming

Spring Boot集成JasperReports生成PDF文档

由于工作需要,要实现后端根据模板动态填充数据生成PDF文档,通过技术选型,使用Ireport5.6来设计模板,结合JasperReports5.6工具库来调用渲...

1.4K7
来自专栏大内老A

The .NET of Tomorrow

Ed Charbeneau(http://developer.telerik.com/featured/the-net-of-tomorrow/) Exciti...

38110
来自专栏跟着阿笨一起玩NET

c#实现打印功能

3602
来自专栏我和未来有约会

Kit 3D 更新

Kit3D is a 3D graphics engine written for Microsoft Silverlight. Kit3D was inita...

2906
来自专栏魂祭心

原 canvas绘制clock

5004
来自专栏张善友的专栏

Miguel de Icaza 细说 Mix 07大会上的Silverlight和DLR

Mono之父Miguel de Icaza 详细报道微软Mix 07大会上的Silverlight和DLR ,上面还谈到了Mono and Silverligh...

2997
来自专栏陈仁松博客

ASP.NET Core 'Microsoft.Win32.Registry' 错误修复

今天在发布Asp.net Core应用到Azure的时候出现错误InvalidOperationException: Cannot find compilati...

5208
来自专栏一个会写诗的程序员的博客

Spring Reactor 项目核心库Reactor Core

Non-Blocking Reactive Streams Foundation for the JVM both implementing a Reactiv...

2732
来自专栏落花落雨不落叶

canvas画简单电路图

81711

扫码关注云+社区