在深度 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 的末尾你可以找到(作为评论)
- 针对 adb 和第一个模式
进行深度测试的一行 linking
- 针对 adb 和第二个模式
进行深度测试的一行 linking
- 使用浏览器测试深度 link 的简单 html 页面 - 最后两个 href 是由 Chrome.
正确管理的 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
无法正确呈现屏幕。我得到了几个空白屏幕,其中包含正确的深层链接。在这种情况下,尝试再次执行相同的深层链接。它对我有用。
我们正在尝试实现 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 的末尾你可以找到(作为评论)
- 针对 adb 和第一个模式 进行深度测试的一行 linking
- 针对 adb 和第二个模式 进行深度测试的一行 linking
- 使用浏览器测试深度 link 的简单 html 页面 - 最后两个 href 是由 Chrome. 正确管理的 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
无法正确呈现屏幕。我得到了几个空白屏幕,其中包含正确的深层链接。在这种情况下,尝试再次执行相同的深层链接。它对我有用。