我正在尋找一種替代方法來從android.net.Uri獲取查詢參數名稱。 getQueryParameterNames()需要api級別11.我想對任何較低級別的api執行相同的操作。 我在看getQuery(),它會返回'?'後的所有內容。標誌。最好的解決方法是解析該字符串並在'='之前搜索所有內容並捕獲它?我根本不知道每次會顯示哪些查詢參數。android.net.uri getQueryParameterNames()替代
回答
唯一的問題與API的< 11是這種方法沒有實現設置結果到一個新的ArrayList,而不是鏈表。我想最好的想法是查看Android源代碼並使用API> = 11的實現。即使在較舊的API上,這也應該可以獲得絕對的功能。
這一個是從4.1.1,修改,以開放的作爲參數,所以你可以使用它了:如果你想深入到它自己
/**
* Returns a set of the unique names of all query parameters. Iterating
* over the set will return the names in order of their first occurrence.
*
* @throws UnsupportedOperationException if this isn't a hierarchical URI
*
* @return a set of decoded names
*/
private Set<String> getQueryParameterNames(Uri uri) {
if (uri.isOpaque()) {
throw new UnsupportedOperationException("This isn't a hierarchical URI.");
}
String query = uri.getEncodedQuery();
if (query == null) {
return Collections.emptySet();
}
Set<String> names = new LinkedHashSet<String>();
int start = 0;
do {
int next = query.indexOf('&', start);
int end = (next == -1) ? query.length() : next;
int separator = query.indexOf('=', start);
if (separator > end || separator == -1) {
separator = end;
}
String name = query.substring(start, separator);
names.add(Uri.decode(name));
// Move start to end of name.
start = end + 1;
} while (start < query.length());
return Collections.unmodifiableSet(names);
}
,這裏是原來的代碼:
我對此代碼感到困惑,我懷疑這是因爲我正在使用更新版本的Android SDK(API 18)。查詢變量由uri.getEncodedQuery()填充,它基於我的測試 - 編碼所有&字符。作爲使用編碼字符串的結果,對indexOf()的調用總是返回-1,並且返回整個查詢字符串,就像它是參數名稱一樣。 – markproxy 2014-06-09 18:11:49
這裏是[Android 4.4.2的實現](http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/4.4.2_r1/android/net/Uri。 java#Uri.getQueryParameterNames%28%29),它是一樣的。你可能使用'Uri.Builder.query(String)',即使用'&'和'='來編碼整個參數。你應該使用'Uri.Builder.appendQueryParameter(String,String)'來編碼參數名稱和值,但保持分隔符完好無損。當你打電話給Uri時。getEncodedQuery()',它返回帶有編碼參數名稱和值的查詢,但是'&'和'='完好無損。 – foxter 2014-06-09 23:20:10
好吧,這是我想到的。有沒有編譯或測試它因此在這裏沒有保證
ArrayList<String> getQueryParamNames(String input)
{
ArrayList<String> result = new ArrayList<String>();
//If its everything after the ? then up to the first = is the first parameter
int start = 0;
int end = input.indexOf("=");
if (end == -1) return null; //No parameters in string
while (end != -1)
{
result.Add(input.substring(start, end)); //May need to do end - 1 to remove the =
//Look for next parameter, again may need to add 1 to this result to get rid of the &
start = input.indexOf("&", end);
if (start == -1) //No more parameters
break;
//If you want to grab the values you can do so here by doing
//input.substring(end, start);
end = input.indexOf("=", start);
}
return result;
}
我寫了這個深夜,沒有測試它,所以你可能通過增加或減少1。此外,我可能已經忘記了一些調整的呼叫將其添加到List
的確切語法。我想對其他人看到的任何錯誤發表評論,但這是它的一般要旨。我有一種感覺,我忘了;
某處。
編輯:作爲建議如下
我foxter同意,最好的選擇是讓從最新的Android版本的代碼,並添加到您的代碼庫。每當我遇到這樣的問題時,我都會創建一個方法來抽象版本特性。它是這樣的:
public class FWCompat {
public static boolean isFroyo_8_OrNewer() {
return Build.VERSION.SDK_INT >= Build.VERSION_CODES.FROYO;
}
public static boolean isGingerbread_9_OrNewer() {
return Build.VERSION.SDK_INT >= Build.VERSION_CODES.GINGERBREAD;
}
public static boolean isHoneycomb_11_OrNewer() {
return Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB;
}
public static boolean isHoneycomb_13_OrNewer() {
return Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB_MR2;
}
public static boolean isJellyBean_16_OrNewer() {
return Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN;
}
}
@SuppressLint("NewApi")
public class FWUriCompat {
public static Set<String> getQueryParameterNames(Uri uri) {
if (FWCompat.isHoneycomb_11_OrNewer()) {
return uri.getQueryParameterNames();
}
return FW_getQueryParameterNames(uri);
}
private static Set<String> FW_getQueryParameterNames(Uri uri) {
if (uri == null) {
throw new InvalidParameterException("Can't get parameter from a null Uri");
}
if (uri.isOpaque()) {
throw new UnsupportedOperationException("This isn't a hierarchical URI.");
}
String query = uri.getEncodedQuery();
if (query == null) {
return Collections.emptySet();
}
Set<String> names = new LinkedHashSet<String>();
int start = 0;
do {
int next = query.indexOf('&', start);
int end = (next == -1) ? query.length() : next;
int separator = query.indexOf('=', start);
if (separator > end || separator == -1) {
separator = end;
}
String name = query.substring(start, separator);
names.add(Uri.decode(name));
// Move start to end of name.
start = end + 1;
} while (start < query.length());
return Collections.unmodifiableSet(names);
}
}
如果你有java.net.URI
(或創建一個),你可以使用URLEncodedUtils.parse
得到的參數和值NameValuePair
:
Map<String, String> parameters = Maps.newHashMap();
List<NameValuePair> params = URLEncodedUtils.parse(uri, "UTF-8");
for (NameValuePair param : params) {
parameters.put(param.getName(), param.getValue());
}
- 1. Serialize android.net.Uri對象
- 2. 引起︰java.io.NotSerializableException︰android.net.Uri $ StringUri
- 3. Nullpointer Exception「void android.media.MediaPlayer.setDataSource(android.content.Context,android.net.Uri)」
- 4. Intent.ACTION_VIEW和子類化android.net.Uri
- 5. android.net.Uri $ HierarchicalUri無法轉換爲java.util.ArrayList
- 6. android.net.Uri權責不明或路徑
- 7. Android Studio單元測試 - android.net.Uri缺失
- 8. 使用android.net.Uri自定義URI解析
- 9. 如何把android.net.Uri轉換成java.net.URL?
- 10. 如何將字符串轉換爲android.net.Uri
- 11. 替代替換
- 12. 代替代替使用PowerShell
- 13. 什麼是替代(替代())?
- 14. 替代蟒蛇代替
- 15. 替代
- 16. 替代
- 17. 替代
- 18. (。*)代替(。*?)
- 19. 替代
- 20. 替代
- 21. ViewModel代替主鍵代替主鍵
- 22. c#Array.ForEach替代元素替代
- 23. 替代corba的好替代品
- 24. 使用`/ *`代替`//`代替文件頭
- 25. main =粘貼(替代(...),替代(...))在R_hist_title
- 26. BASH:與SED替代PERL就地替代
- 27. 替換使用替代
- 28. Java替換替代碼
- 29. 類型不兼容 - 要求:android.net.Uri,發現:整數
- 30. 如何將Android.Net.Uri路徑轉換爲xamarin中的物理路徑?
應該是一些簡單的字符串解析,給我有幾分鐘的時間,我會爲你提供一個函數 – Russ 2012-07-25 04:07:41