我可以在我的Manifest中的intent-filter中使用以下过滤器成功实现app的深层链接:
<data android:host="myhost.com"
android:pathPrefix="/v"
android:scheme="http" />
EG。我的网址是:
http://myhost.com/v/login1.php?id=123&name=abc&type=a
http://myhost.com/v/login1.php?id=123&name=abc&type=b
我想要排除
http://myhost.com/v/login1.php?id=123&name=abc&type=c
现在我要排除一些具有相同前缀的Url。是否可以或我是否需要使用android:path
明确指定所有网址?如果是这样,如何处理查询参数的值?
答案 0 :(得分:7)
很遗憾,我们无法排除任何特定网址,因为Android并未提供该选项。
最佳做法是尽可能作为精确路径前缀。
只指定没有任何pathPrefix的主机,只要应用程序执行的所有操作都有意义。但是,如果有任何链接应该在应用程序无法处理时执行某些特定操作,那么它应该让Web服务正确处理它。在这种情况下,如果您的Web服务可以比您的应用程序做得更多,那么将所有内容列入白名单并不是一个好主意。
有些人喜欢只在清单中匹配主机,然后在代码中处理不同的情况。你永远不会知道可以捕获到什么意外的网址,如果它真的能让感官处理它,那么其他的就是&#34;条件。更好,仔细,只列出我们确定的pathPrefix。
回到你的情况,大多数时候,我相信应用程序能够处理url,如果它只在查询参数中有所不同。因为它属于同一个动作(通过API的路由处理程序),所以只有不同的结果。只有当整个路由不同时,您才应该通过给出正确的路径前缀来区别对待它。
所以有效的例子可能是:
// To handle:
http://myhost.com/v/login1?id=123&name=abc&type=a
// To exclude:
http://myhost.com/v/login2?id=123&name=abc&type=a
然后在AndroidManifest.xml中:
<data android:scheme="http"
android:host="myhost.com"
android:pathPrefix="/v/login1" />
注意: 如果你遇到noindex.xml,那就是App Indexing,而不是深层链接排除。
答案 1 :(得分:4)
您可以让应用决定是否让浏览器处理网址
@Override
protected void onNewIntent(Intent intent) {
if (intent.getData().getQueryParameter("type").equals("c")) {
forwardToBrowser(intent);
}
else {
handleIntent(intent);
}
};
// from https://stackoverflow.com/a/23268821/3221253
private void forwardToBrowser(Intent i) {
Intent intent = new Intent();
intent.setAction(android.content.Intent.ACTION_VIEW);
intent.setDataAndType(i.getData(), i.getType());
List<ResolveInfo> activities = getPackageManager().queryIntentActivities(intent, 0);
ArrayList<Intent> targetIntents = new ArrayList<Intent>();
String thisPackageName = getApplicationContext().getPackageName();
for (ResolveInfo currentInfo : activities) {
String packageName = currentInfo.activityInfo.packageName;
if (!thisPackageName.equals(packageName)) {
Intent targetIntent = new Intent(android.content.Intent.ACTION_VIEW);
targetIntent.setDataAndType(intent.getData(),intent.getType());
targetIntent.setPackage(intent.getPackage());
targetIntent.setComponent(new ComponentName(packageName, currentInfo.activityInfo.name));
targetIntents.add(targetIntent);
}
}
if(targetIntents.size() > 0) {
Intent chooserIntent = Intent.createChooser(targetIntents.remove(0), "Open with");
chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, targetIntents.toArray(new Parcelable[] {}));
startActivity(chooserIntent);
finish();
}
}
forwardToBrowser
的实现(来自https://stackoverflow.com/a/23268821/3221253)允许用户选择具有多个浏览器的浏览器。如果您愿意,可以直接打开Chrome。
答案 2 :(得分:1)
我通过在第二个意图中禁用深层链接来解决它
清单
<activity android:name=".Deeplinking">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<data android:host="*.example.com" />
</intent-filter>
</activity>
在代码中我可以理解我是否希望浏览器/应用程序处理它,并在需要时触发新意图。
private void openInBrowser(String url) {
setDeepLinkingState(PackageManager.COMPONENT_ENABLED_STATE_DISABLED);
startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(url)));
setDeepLinkingState(PackageManager.COMPONENT_ENABLED_STATE_ENABLED);
}
private void setDeepLinkingState(int state) {
ComponentName compName = new ComponentName(getPackageName(), getPackageName() + ".Deeplinking");
getApplicationContext().getPackageManager().setComponentEnabledSetting(
compName,
state,
PackageManager.DONT_KILL_APP);
}
答案 3 :(得分:0)
这项工作对我来说
if(Build.VERSION.SDK_INT < 23) {
Intent intent = new Intent();
intent.setAction(android.content.Intent.ACTION_VIEW);
intent.setDataAndType(i.getData(), i.getType());
List<ResolveInfo> activities = getPackageManager().queryIntentActivities(intent, 0);
ArrayList<Intent> targetIntents = new ArrayList<Intent>();
String thisPackageName = getApplicationContext().getPackageName();
for (ResolveInfo currentInfo : activities) {
String packageName = currentInfo.activityInfo.packageName;
if (!thisPackageName.equals(packageName)) {
Intent targetIntent = new Intent(android.content.Intent.ACTION_VIEW);
targetIntent.setDataAndType(intent.getData(), intent.getType());
targetIntent.setPackage(intent.getPackage());
targetIntent.setComponent(new ComponentName(packageName, currentInfo.activityInfo.name));
targetIntents.add(targetIntent);
}
}
if (targetIntents.size() > 0) {
Intent chooserIntent = Intent.createChooser(targetIntents.remove(0), "Open with");
chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, targetIntents.toArray(new Parcelable[]{}));
startActivity(chooserIntent);
finish();
}
}
// from SDK 23, queryIntentActivities only return your activity, so you need to disable you activity before forward to browser and enable it later.
else {
final PackageManager pm = getPackageManager();
final ComponentName component = new ComponentName(this, HandleDeepLinkActivity.class);
pm.setComponentEnabledSetting(component, PackageManager.COMPONENT_ENABLED_STATE_DISABLED, PackageManager.DONT_KILL_APP);
Intent webIntent = new Intent(Intent.ACTION_VIEW);
webIntent.setData(i.getData());
startActivity(webIntent);
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
@Override
public void run() {
pm.setComponentEnabledSetting(component, PackageManager.COMPONENT_ENABLED_STATE_ENABLED, 0);
}
}, 500);
}