我的应用定义了意图过滤器,用于处理
定义的网站中的网址<intent-filter android:autoVerify="true">
<action android:name="android.intent.action.VIEW"/>
<category android:name="android.intent.category.DEFAULT"/>
<category android:name="android.intent.category.BROWSABLE"/>
<data android:host="www.host.com" android:scheme="http"/>
</intent-filter>
<intent-filter android:autoVerify="true">
<action android:name="android.intent.action.VIEW"/>
<category android:name="android.intent.category.DEFAULT"/>
<category android:name="android.intent.category.BROWSABLE"/>
<data android:host="www.host.com" android:scheme="https"/>
</intent-filter>
该应用正确检测到正确主机的网址,但会询问用户是否在应用或浏览器中打开它们。我尝试使用此处指定的应用链接验证。 https://developer.android.com/training/app-links/index.html
如我的服务器日志中所示,安装时,应用设备会查询/well-known/assetlinks.json,并以200状态响应。使用
测试数字资产文件https:// digitalassetlinks.googleapis.com/v1/statements:list?source.web.site= https://&lt;域1&GT;:其中端口&GT;&安培;关系= delegate_permission / common.handle_all_urls
API,它没有发现任何错误。
assetlinks.json文件中的SHA256是使用
获得的keytool -list -v -keystore my-release-key.keystore
应用程序签名的.keystore。
运行adb shell dumpsys package d
会返回链接验证状态为&#34;问&#34;意味着验证失败。为什么验证会失败?
答案 0 :(得分:11)
对我们来说,它是Windows行结尾!
使用“https://digitalassetlinks.googleapis.com/v1/statements:list?source.web.site=https://domain1:port&relation=delegate_permission/common.handle_all_urls”进行测试证明是非常宝贵的,因为它给我们提供了“无法解析语句列表(无效JSON)”错误,这导致我们遇到问题。
提示:最好使用Android Studio App Links Assistant中的“保存文件”按钮,而不是像我们一样复制和粘贴 - 这样就可以自行生成文件并保证不会出现此问题。
答案 1 :(得分:8)
对我而言,它归结为检查所有基础知识:
答案 2 :(得分:6)
看着j__m条评论,我发现了这一点。
在AndroidManifest
中这样写:
<intent-filter android:autoVerify="true">
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<!-- Write <data> tags with one attribute, if you use several domains. -->
<data android:scheme="https" />
<data android:host="example.com" />
</intent-filter>
<!-- Other domains-->
<intent-filter android:autoVerify="true">
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="https" />
<data android:host="server.com" />
</intent-filter>
android:autoVerify="true"
是应用程序链接所必需的。
使用assetlinks.json
创建Tools > App Links Assistant
。然后按Open Digital Asset Links File Generator
,输入域,应用程序ID,选择release
签名配置,然后按Generate Digital Asset Links File
。然后,您可以保存文件或将其复制到剪贴板。
您可以创建多个assetlinks.json
文件(用于多个应用程序)并将它们加入一个JSON中。在我看来,它不依赖于Windows行尾(我使用记事本来连接JSON)。第一次,我使用Ctrl + Alt + L对其进行自动格式化,并且在将其上传到域后,App Link无法正常工作(可能是由于AndroidManifest
中的以后错误),因此在第二次尝试中,我没有格式化JSON 。我为应用程序的assetlinks.json
和release
构建了debug
。
将assetlinks.json
上载到https://example.com/.well-known/assetlinks.json
。使用https://digitalassetlinks.googleapis.com/v1/statements:list?source.web.site=https://example.com&relation=delegate_permission/common.handle_all_urls
进行检查。该文件和域具有一些restrictions。就我而言,一切都很简单,我们没有更改设置。
在DeepLinkActivity
中,您可以使用正则表达式解析URL。使用JUnit
创建测试。从onCreate()
调用此方法:
private fun processDeepLink() {
if (intent?.data?.isHierarchical == true) {
val data = intent?.dataString
if (intent?.action == Intent.ACTION_VIEW && data != null) {
when {
REGEX.matches(data) -> // Get id and open some screen.
else -> // Either open MainActivity or skip this URL (open web browser instead).
}
finish()
}
}
}
companion object {
val REGEX = "^https://example.com/some_request/(\\d+).*".toRegex()
}
警告!!如果您从应用程序打开网络浏览器,则会陷入循环。在应用程序中单击指向您的域的链接时,不会出现浏览器,但是您的应用程序将自动打开!真是惊喜!因此,在processDeepLink
中,您应该检查URL并在URL与您的掩码之一匹配时打开MainActivity
。跳过其他人。现在,用户将看到一个对话框,其中包含浏览器和您的应用程序的列表(例如在Deep Link中)。发生这种情况是因为您的应用程序还处理了到域的链接,例如浏览器。
您也可以使用WebView
代替浏览器(不是一个好的解决方案),打开Chrome Custom Tabs
或Chrome
。
在Android 6或更高版本上使用设备。
如果https://digitalassetlinks.googleapis.com/v1/statements:list?source.web.site=https://example.com&relation=delegate_permission/common.handle_all_urls
没有返回错误,请构建应用程序。创建电子邮件,SMS,QR码或带有指向您的域的链接的其他应用程序。单击它,App Link将打开您的应用程序,或者Deep Link将显示一个对话框以选择一个应用程序。
如果App Link无效,请稍后阅读。
在LogCat
中,选择No Filters
,然后在搜索框中键入IntentFilter
。应该是:
I/IntentFilterIntentOp: Verifying IntentFilter. verificationId:2 scheme:"https" hosts:"example.com" package:"com.my_package".
I/IntentFilterIntentOp: Verification 0 complete. Success:true. Failed hosts:.
可能您会得到:
I/IntentFilterIntentOp: Verifying IntentFilter. verificationId:0 scheme:"https" hosts:"example.com server.com" package:"com.my_package".
I/IntentFilterIntentOp: Verification 0 complete. Success:false. Failed hosts:server.com.
稍后,您将尝试修复应用程序中的域,因此有时可以启动全新安装:
adb shell pm clear com.android.statementservice
启动adb shell dumpsys package d
并找到您的域。应该是:
Package Name: com.my_package
Domains: example.com server.com
Status: always : 200000000
但可能是:
Package Name: com.my_package
Domains: example.com server.com
Status: ask
另请参阅https://chris.orr.me.uk/android-app-linking-how-it-works/。很奇怪,但是在仿真器中它写了:always
,而App Link无法正常工作。
我还尝试adb shell am start -a android.intent.action.VIEW -c android.intent.category.BROWSABLE -d "https://example.com"
在没有浏览器的情况下测试App Link,但后来却无法正常工作。
如果您有多个域,请注释(或删除)AndroidManifest
中的其他域(仅保留一个域,例如“ example.com”)。然后单击URL https://example.com/something,并检查它是否使用App Link。
就我而言,我检查了应用程序的release
和debug
构建。尽管debug
构建与App Link一起使用,但release
却没有(有时反之亦然)。我使用了rekire的解决方案:
<meta-data
android:name="asset_statements"
android:resource="@string/asset_statements"/>
,它为2个域提供了帮助,但后来停止了,因此我将其删除。最后,我在AndroidManifest
<data>
标签中写了一个带有j__m所说的属性。
即使只有一个域发生故障,App Link也不适用于其他域。您可以在AndroidManifest
中一次只检查一个域,一次只检查一个域。
另请参见http://androidideas.com/handling-app-links-in-android/,https://willowtreeapps.com/ideas/a-better-user-experience-for-deep-linking-on-android,https://developer.android.com/training/app-links/verify-site-associations,
答案 3 :(得分:5)
有一些常见的陷阱你应该检查两次(我不是说你做错了。它只是一个检查清单):
assetlinks.json
是否有效并可以https://example.com/.well-known/assetlinks.json
访问https://digitalassetlinks.googleapis.com/v1/statements:list?source.web.site= https://example.com&relation=delegate_permission/common.handle_all_urls
,以便您访问<intent-filters>
,必须没有错误。<data>
代码的android:autoVerify="true"
个<meta-data>
属性为<application>
。确认您的<meta-data
android:name="asset_statements"
android:resource="@string/asset_statements"/>
代码中包含所需的asset_statements
代码:
<string name="asset_statements" translatable="false">[{\"include\": \"https://example.com/.well-known/assetlinks.json\"}]
build.gradle
字符串的内容必须为:
buildTypes {
release {
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
signingConfig signingConfigs.release
}
debug {
debuggable true
signingConfig signingConfigs.release
}
}
用于调试也是发布签名证书(不要害怕你不能意外上传)在你的function getValue(obj){
alert(obj);// check if obj has something in it before proceeding to "value"
alert(obj.value);
}
中使用它:
{{1}}
答案 4 :(得分:3)
所以我解决了我的问题。不知道是谁做的(可能是组合的),但这是我做的:
当我第一次遇到此问题时,是因为我的网络阻止了对Google服务器的调用,以验证应用程序链接。
在触摸OP和其他答案后,通常对端点的API调用:
digitalassetlinks.googleapis.com
必须成功绕过选择器对话框。 这是Android系统进行的网络调用,用于验证Digital Asset Link JSON文件,并且似乎是在应用程序安装/更新时进行的。 Logcat是一个有用的地方,它搜索带有文本“ I / SingleHostAsyncVerifier:”的项目。如果您在日志末尾看到“-> true”,则您的应用程序
不过,由于似乎是最近引入的一些错误,这些调用对我来说一直失败。设备正在从上面的API调用中收到此响应:
错误:不可用:从{host} /。well-known / assetlinks.json(等同于'{host} /。well-known / assetlinks.json')中获取语句时,HTTP响应标头中的内容类型错误。 :预期为“内容类型:应用程序/ json”,但在从{host}获取Web语句时找到了text / html [11]。/。well-known / assetlinks.json
自从我上次查看这些请求以来已经有一段时间了,所以我不记得他们以前的样子。但是,似乎有可能最近进行了一些涉及App Link或Android网络框架的更新,在这些更新中,他们切换到了此功能的协议缓冲区(并忘记了在另一个版本中支持该功能)。
另一个可能已发生变化的迹象是,今天的请求路径看起来不同于先前答案中提到的路径:
https://digitalassetlinks.googleapis.com/google.digitalassetlinks.v1.AssetLinks/Check
答案 5 :(得分:1)
对我而言,我的assetlinks.json
文件是UTF-8,并且包含字节顺序标记(BOM),这是一个三字节的幻数。将编码信号通知给消耗程序的文件头。 BOM是可选的,显然Google / Android工具不喜欢看到它。当它出现时,谷歌的数字资产链接验证程序(下面的URL)给了我一个错误的JSON&#34;错误。
如果您正在使用Visual Studio,请按照以下步骤确定您的文件中是否包含BOM,并在必要时将其删除:
EF BB BF
开头,那就是问题所在。以下是您可以用来检查文件的网址(将example.com替换为您的实际网址):
答案 6 :(得分:0)
就我而言,adb shell dumpsys package d
显示packageName
中的assetlinks.json
配置错误。我在package
中使用了manifest
标记的AndroidManifest.xml
属性值,但我应该在android.defaultConfig.packageId
文件中使用build.gradle
值。
答案 7 :(得分:0)
两种情况下的系统应用选择窗口
1)用户通过转到设置来更改与设置相关的开放链接&gt;应用&gt;齿轮图标&gt;打开链接&gt;选择一个应用&gt;打开支持的链接&gt;每次都选择提示。
2)默认应用未由用户设置,并且其中一个应用链接支持的应用未启用自动验证
我认为在你的情况下启用了自动验证,所以请检查用户设置。
答案 8 :(得分:0)
对我来说,请勿更改assetlinks.json
的任何内容,包括修剪空白和换行符。
答案 9 :(得分:0)
感谢这里的所有其他答案,我能够找到我的问题。尽管一切正确。这是我的问题。
这怎么会出错很简单。如果项目有多个自动验证网址,则操作系统会尝试对其进行全部验证。即使失败,操作系统也会无法验证每个URL。
在主应用程序模块中打开清单文件,然后从底部选项卡中选择“合并清单”选项。现在,检查右侧的清单源(列表),并手动查找每个库项目的清单文件。
在我的情况下,启用了第三方库的自动验证标志。我为期两天的搜索结束了。祝你好运。
答案 10 :(得分:0)
在我们的案例中,清单中有2个带有应用程序链接的意图过滤器:一个带有autoVerify="true"
的意图过滤器,另一个没有。
因此,验证者尝试验证第二个意图过滤器的域并失败,并将我们所有的应用链接视为“未验证”。您可以在this question中找到更多详细信息。
您必须确保可以验证每个应用链接(这意味着要为每个要验证的域添加assetlinks.json
)。
答案 11 :(得分:0)
我确定这无法回答最初的问题,因为我认为它早于Android应用程序捆绑包,但最终导致我失败的原因是我启用了Google Play控制台重新签名的应用程序(对于AAB是必需的),因此我从keytool
获得的SHA-256指纹与下载的应用程序的数字签名不匹配。
使用控制台中的指纹更新我的assetlinks.json
即可解决