自定义方案的 Intent-filter pathPattern
Intent-filter pathPattern for custom scheme
我希望我的应用能够处理以下自定义 url myscheme://product?id=123
。这按预期工作。但是,以下 url 也得到了处理 myscheme://product/something/else?id=123
如何防止第二个 url 被应用程序处理?
我设置了处理深层 link 的 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="myscheme"/>
<data android:host="product"/>
<data android:pathPattern=".*"/>
</intent-filter>
我刚开始玩 deep linking,所以非常感谢任何帮助!
尝试将 .* 替换为 .product?* 这应该使过滤器仅与产品查询字符串对齐,而不是产品 url 路径 (/product/something/else?id)
<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="myscheme"/>
<data android:host="product"/>
<data android:pathPattern=".product?*"/>
另一种选择是创建两个意图过滤器,并将它们按接收意图的顺序排列:
Intent 1: product/something/else
Intent 2: product?id=1
更新:这里的关键是使用 getData() 而不是 get extras()。学会了艰难的方式:)
@Override
public void onNewIntent(Intent i) {
super.onNewIntent(i);
Bundle b = i.getExtras();
if (i != null && i.getData() != null) {
try {
Uri data = i.getData();
Map<String, String> a = splitQuery(data);
if (a.containsKey("Product") && a.containsKey("SOMETHINGELSE")){
//todo:something that takes care of something else:
}else if (a.containsKey("Product")){
mItemNumber = a.get("ID");
setUpFragmentForItem(mItemNumber);
}
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
}
将 URI 分成多个段:
public static Map<String, String> splitQuery(Uri url) throws UnsupportedEncodingException {
try {
Map<String, String> query_pairs = new LinkedHashMap<String, String>();
String query = url.getQuery();
String[] pairs = query.split("/");
for (String pair : pairs) {
int idx = pair.indexOf("=");
query_pairs.put(URLDecoder.decode(pair.substring(0, idx), "UTF-8"), URLDecoder.decode(pair.substring(idx + 1), "UTF-8"));
}
return query_pairs;
} catch (Exception e) {
throw new UnsupportedEncodingException(e.getMessage());
}
}
更新:发现一个做同样事情的库,值得一提,还没有用过,但我可以试一试:
https://android-arsenal.com/details/1/2072
我希望我的应用能够处理以下自定义 url myscheme://product?id=123
。这按预期工作。但是,以下 url 也得到了处理 myscheme://product/something/else?id=123
如何防止第二个 url 被应用程序处理?
我设置了处理深层 link 的 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="myscheme"/>
<data android:host="product"/>
<data android:pathPattern=".*"/>
</intent-filter>
我刚开始玩 deep linking,所以非常感谢任何帮助!
尝试将 .* 替换为 .product?* 这应该使过滤器仅与产品查询字符串对齐,而不是产品 url 路径 (/product/something/else?id)
<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="myscheme"/>
<data android:host="product"/>
<data android:pathPattern=".product?*"/>
另一种选择是创建两个意图过滤器,并将它们按接收意图的顺序排列:
Intent 1: product/something/else
Intent 2: product?id=1
更新:这里的关键是使用 getData() 而不是 get extras()。学会了艰难的方式:)
@Override
public void onNewIntent(Intent i) {
super.onNewIntent(i);
Bundle b = i.getExtras();
if (i != null && i.getData() != null) {
try {
Uri data = i.getData();
Map<String, String> a = splitQuery(data);
if (a.containsKey("Product") && a.containsKey("SOMETHINGELSE")){
//todo:something that takes care of something else:
}else if (a.containsKey("Product")){
mItemNumber = a.get("ID");
setUpFragmentForItem(mItemNumber);
}
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
}
将 URI 分成多个段:
public static Map<String, String> splitQuery(Uri url) throws UnsupportedEncodingException {
try {
Map<String, String> query_pairs = new LinkedHashMap<String, String>();
String query = url.getQuery();
String[] pairs = query.split("/");
for (String pair : pairs) {
int idx = pair.indexOf("=");
query_pairs.put(URLDecoder.decode(pair.substring(0, idx), "UTF-8"), URLDecoder.decode(pair.substring(idx + 1), "UTF-8"));
}
return query_pairs;
} catch (Exception e) {
throw new UnsupportedEncodingException(e.getMessage());
}
}
更新:发现一个做同样事情的库,值得一提,还没有用过,但我可以试一试: https://android-arsenal.com/details/1/2072