1.正在播放界面,长按专辑/艺术家/歌曲-》选择音乐
2.音乐列表界面,选择一首音乐长按-》搜索-》音乐
3.音乐播放器任意界面,点击搜索键,输入字符进行搜索
三种情况下都为“未搜索到结果"。
对搜索过程进行分析,发现最后调用到了MediaProvider.java中的doAudioSearch():
for (int i = 0; i < len; i++) {
// Because we match on individual words here, we need to remove words
// like 'a' and 'the' that aren't part of the keys.
String key = MediaStore.Audio.keyFor(searchWords[i]); //类hash处理
key = key.replace("\\", "\\\\");
key = key.replace("%", "\\%");
key = key.replace("_", "\\_");
wildcardWords[i] =
(searchWords[i].equals("a") || searchWords[i].equals("an") ||
searchWords[i].equals("the")) ? "%" : "%" + key + "%";
}
String where = "";
for (int i = 0; i < searchWords.length; i++) {
if (i == 0) {
where = "match LIKE ? ESCAPE '\\'"; //查询条件是match列like
} else {
where += " AND match LIKE ? ESCAPE '\\'"; //and match列like
}
}
qb.setTables("search"); //最后的查询是在视图search里面进行的
String [] cols;
if (mode == AUDIO_SEARCH_FANCY) {
cols = mSearchColsFancy;
} else if (mode == AUDIO_SEARCH_BASIC) {
cols = mSearchColsBasic;
} else {
cols = mSearchColsLegacy;
}
return qb.query(db, cols, where, wildcardWords, null, null, null, limit);
这里要说明一下的是,当在进行media文件scan的时候,就会对media文件的title进行一次上面的类hash计算,再将值存入数据库。
通过打log发现,这里计算出来的类hash值(即String key = MediaStore.Audio.keyFor(searchWords[i]); )与数据库里面保存的值不对,导致了匹配不上,而没有查询到结果。而数据库里面保存的值是在扫描的时候调用同样的函数(MediaStore.Audio.keyFor(String string))来计算的。为什么同样的title值,同样的计算代码,会得出不同的结果,到现在为止还没有最根本的原因。
但既然发现了查询不到的原因,就好对症下药了:
1,在doAudioSearch()的最后,return qb.query()前先判断下Cursor是否查询出了内容。
2,如果没有查询到内容,则在后面继续构造查询。
2.1,查询语句要重新构造。原来是在match中查询title_key,当查询不到时,就需要在title和artist中查询了。
2.2,查询语句的连接可以用or,where += " ro artist LIKE ? ESCAPE '\\'";
2.3,查询语句的条件要变成searchWords而不是wildcardWords。