在深度 Link 中使用 Ampersand 进行应用索引无法正常工作

App Indexing with Ampersand in Deep Link not working

我们正在尝试实现 Google's App Indexing 功能。我们已经使用以下格式的 rel-alternate 标签将深度 links 添加到我们的网站:

android-app://id.of.the.app/scheme/?screen=Product&product=123456

现在我们收到内容不匹配的抓取错误。如果我使用来自 here 的二维码进行测试,一切正常。但是如果我打开一个抓取错误,点击 "Open App Page" 并使用 adb 命令进行测试,我可以看到从 & 符号开始的所有内容都没有传递到应用程序,因此我的产品数据无法加载。我怀疑这就是爬虫检查应用程序内容的方式,也是我们收到内容不匹配错误的原因。

此外,如果我使用 Search Console 中的 "Fetch as Google",它看起来像和号中的所有内容都被截断了。

我查看了 eBay,因为它正在使用他们的应用程序,这就是他们正在使用的 link:

android-app://com.ebay.mobile/ebay/link/?nav=item.view&id=221559043026&referrer=http%3A%2F%2Frover.ebay.com%2Froverns%2F1%2F711-13271-9788-0%3Fmpcl%3Dhttp%253A%252F%252Fwww.ebay.com%252Fitm%252FRoxy-Fairness-Backpack-Womens-Red-RPM6-%252F221559043026%253Fpt%253DLH_DefaultDomain_0

他们用 & 编码了符号,但如果我这样做并用 "Fetch as Google" 函数测试它也不起作用。

这些用户似乎遇到了同样的问题,但他们没有分享解决方案(如果他们找到的话):

https://productforums.google.com/forum/#!msg/webmasters/5r7KdetlECY/enYknTVkYU4J https://productforums.google.com/forum/#!topic/webmasters/lswyXKlS-Ik

感谢您的任何想法。

更新 1

这就是我如何解释 Android 应用程序中的深层 link:

Uri data = getIntent().getData();
String scheme = data.getScheme();
if (scheme.equals("scheme")) {
    String screen = data.getQueryParameter("screen");
    if (screen.equals("Product")) {
        String product = data.getQueryParameter("product");
        // Open Product and give it product number as intent data
    }
}

更新 2

这是我们 Manifest.xml 的相关部分:

<activity
    android:name="id.of.the.app.StartActivity"
    android:configChanges="orientation|screenSize"
    android:label="@string/app_title"
    android:windowSoftInputMode="adjustPan|stateHidden">

        <intent-filter>
            <action android:name="android.intent.action.MAIN" />
            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>

        <intent-filter>
            <data android:scheme="scheme" />
            <action android:name="android.intent.action.VIEW" />
            <category android:name="android.intent.category.DEFAULT" />                
            <category android:name="android.intent.category.BROWSABLE" />
        </intent-filter>

</activity>

尝试用 %26

替换符号

问题是平台工具版本 21 中的错误

更新 3
我仍在尝试了解是否可以避免更改清单并重新提交应用程序。使用您发布的 AndroidManifest,您是否尝试过仅更改 rel-alternate 标记以包含主机(如果它未包含在清单中,则为事件)?例如,您是否尝试过 android-app://id.of.the.app/scheme/fakehost/?screen=Product&product=123456 其中 fakehost 是一个字符串?我想标签的语法必须是 android-app://{package_name}/{scheme}/{host_path},所以在网站上有一个主机是必要的(但可能不在应用程序上)。


更新 2
在您发布清单后,我猜您在 Intent-Filter 的数据标记中缺少强制性的“host”。

获取此作为参考:

<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:scheme="myapp" android:host="link"/>
    <data android:scheme="myapp" android:host="link/"/>
</intent-filter>

html 中的元应该是 (android-app://package-name/scheme/host)

<html>
<head>   
<link rel="alternate"
      href="android-app://it.test.testdeeplink/myapp/link/?p1=1&p2=2" />
...
</head>

您可能需要更新您的应用程序,因为您的清单必须修复。


首先,感谢您的所有澄清。我猜对 deep link(您正在实现的功能)和 Chrome Intent (the link that you provided as comment). So, I decided to implement a small project that you can download by my dropbox folder 存在一些混淆。该项目非常简单,只有一个 activity 为 Intent 数据接收到的每个 参数 打印一行(当然,如果您通过应用程序启动器启动应用程序,您将不会什么都看不到)。 Activity 支持两种 intent-filter 模式(my-android-app 和 http),在 MainActivity.java 的末尾你可以找到(作为评论)

  1. 针对 adb 和第一个模式
  2. 进行深度测试的一行 linking
  3. 针对 adb 和第二个模式
  4. 进行深度测试的一行 linking
  5. 使用浏览器测试深度 link 的简单 html 页面 - 最后两个 href 是由 Chrome.
  6. 正确管理的 Intent

由于我无权访问您的代码,而且我看不出是否存在任何问题,我想这是帮助您并让我的回答被接受的最佳方式:)

Uri 中使用查询参数进行应用索引对我来说效果很好。请检查您是否正确执行了所有步骤:

  • AndroidManifest.xml

    中声明id.of.the.app.StartActivity的方案

        <intent-filter>
            <action android:name="android.intent.action.MAIN" />
            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    
            <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:scheme="my_custom_scheme"/>
            </intent-filter>
    

  • 解析深层链接

假设我们有以下深层链接 my_custom_scheme://test_authority/product_screen/?product=123456&test_param=0000&utm_source=google&utm_medium=organic&utm_campaign=appindexing

    public void parseDeeplikUrl(Uri uri) {
        if (uri == null) {
           // fallback: open home screen
        }
        String autority = uri.getAuthority();
        String path = uri.getPath();
        String query = uri.getQuery();

        // authority = "test_authority"
        // path = "products_screen"
        // query = "product=123456&test_param=0000&utm_source=google&utm_medium=organic&utm_campaign=appindexing"
    }
  • 从命令行测试应用索引:

    adb shell 'am start -a android.intent.action.VIEW -c android.intent.category.BROWSABLE -d "my_custom_scheme://test_authority/product_screen/?product=123456&test_param=0000&utm_source=google&utm_medium=organic&utm_campaign=appindexing" -e android.intent.extra.REFERRER_NAME android-app://com.google.appcrawler/https/www.google.com id.of.the.app'
    

使用这个 adb 命令我们模拟 GoogleBot 调用。

  • 转到 Search console 中的 "Fetch as Google" 并检查 GoogleBot 是否也正常工作并呈现正确的应用程序屏幕。

    android-app://id.of.the.app/my_custom_scheme/test_authority/product_screen/?product=123456&test_param=0000&utm_source=google&utm_medium=organic&utm_campaign=appindexing
    

P.S.:有时 GoogleBot 无法正确呈现屏幕。我得到了几个空白屏幕,其中包含正确的深层链接。在这种情况下,尝试再次执行相同的深层链接。它对我有用。