问题 从深层链接中排除少数网址
我可以在我的Manifest中的intent-filter中使用以下过滤器成功实现app的深层链接:
<data android:host="myhost.com"
android:pathPrefix="/v"
android:scheme="http" />
例如。我的网址是:
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
?如果是这样,如何处理查询参数的值?
12193
2017-11-28 08:24
起源
答案:
很遗憾,我们无法排除任何特定网址,因为Android不提供该选项。
最佳做法是给予 作为精确的pathPrefix尽可能。
只指定没有任何pathPrefix的主机是正常的,只要应用程序执行的所有操作都有意义。但是,如果有任何链接应该在应用程序无法处理时执行某些特定操作,那么它应该让Web服务正确处理它。在这种情况下,如果您的Web服务可以比您的应用程序做得更多,那么将所有内容列入白名单并不是一个好主意。
有些人喜欢只在清单中匹配主机,然后在代码中处理不同的情况。你永远不知道可以捕获到什么意外的网址,如果它真的通过“其他”条件来理解它。更好,仔细,只列出我们确定的pathPrefix。
回到你的情况,大多数时候,我相信应用程序能够处理url,如果它只在查询参数中有所不同。因为它属于同一个动作(通过API的路由处理程序),只是不同的结果。只有当整个路由不同时,才应该通过给出正确的pathPrefix来区别对待它。
所以有效的例子可能是:
// 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,不适用于深层链接排除。
6
2017-07-01 14:45
您可以让应用决定是否让浏览器处理该URL
@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。
3
2017-08-19 02:15
答案:
很遗憾,我们无法排除任何特定网址,因为Android不提供该选项。
最佳做法是给予 作为精确的pathPrefix尽可能。
只指定没有任何pathPrefix的主机是正常的,只要应用程序执行的所有操作都有意义。但是,如果有任何链接应该在应用程序无法处理时执行某些特定操作,那么它应该让Web服务正确处理它。在这种情况下,如果您的Web服务可以比您的应用程序做得更多,那么将所有内容列入白名单并不是一个好主意。
有些人喜欢只在清单中匹配主机,然后在代码中处理不同的情况。你永远不知道可以捕获到什么意外的网址,如果它真的通过“其他”条件来理解它。更好,仔细,只列出我们确定的pathPrefix。
回到你的情况,大多数时候,我相信应用程序能够处理url,如果它只在查询参数中有所不同。因为它属于同一个动作(通过API的路由处理程序),只是不同的结果。只有当整个路由不同时,才应该通过给出正确的pathPrefix来区别对待它。
所以有效的例子可能是:
// 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,不适用于深层链接排除。
6
2017-07-01 14:45
您可以让应用决定是否让浏览器处理该URL
@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。
3
2017-08-19 02:15
我通过在第二个意图中禁用深层链接来解决它
表现
<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);
}
1
2018-01-22 08:36
这对我有用
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);
}
0
2017-10-03 08:58