如果我在项目的 Gradle 构建脚本中使用 packageNameSuffix
,我遇到 getSearchableInfo
方法在 SearchView
初始化期间总是返回 null。
SearchView 初始化:
final SearchManager searchManager = (SearchManager) context.getSystemService(Context.SEARCH_SERVICE);
SearchableInfo info = searchManager.getSearchableInfo(componentName);
mSearchView.setSearchableInfo(info);
项目的build.gradle:
android {
[...]
buildTypes {
debug {
packageNameSuffix ".debug"
versionNameSuffix "-debug"
signingConfig signingConfigs.debug
}
[...]
}
}
如果不使用包后缀,给定的componentName
是ComponentInfo{com.example.android/com.example.android.MapActivity}
和 SearchView
及其关联的 SuggestionsProvider
工作正常。
但如果 packageNameSuffix
设置为 ".debug"
,则给定的 componentName
是 ComponentInfo{com.example.android. debug/com.example.android.MapActivity}
和 SearchManager
返回 null
,而不是返回相应的 SearchableInfo
对象。
有谁知道如何从 SearchManager
获得正确的 SearchableInfo
?谢谢!
[编辑]
Eugen Martinov 在评论中提到,此行为可能与不正确或缺失的权限重命名有关。但我还配置了一个依赖构建类型的权限命名,为了简单起见,我在最初的帖子中省略了这一点。
项目的build.gradle:
android {
[...]
sourceSets {
debug {
java.srcDirs = [
'src/main/java'
]
java.srcDirs = [
'src/debug/res',
'src/main/res'
]
}
release {
java.srcDirs = [
'src/main/java'
]
java.srcDirs = [
'src/release/res',
'src/main/res'
]
}
[...]
}
}
src/debug/res/values/build-config.xml:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="cfg_app_name">App - Debug</string>
<string name="cfg_authorities">com.example.debug.SuggestionsProvider</string>
<string name="cfg_maps_key"><!-- some key --></string>
</resources>
src/release/res/values/build-config.xml:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="cfg_app_name">App</string>
<string name="cfg_authorities">com.example.SuggestionsProvider</string>
<string name="cfg_maps_key"><!-- some other key --></string>
</resources>
src/main/res/xml/searchable.xml:
<?xml version="1.0" encoding="utf-8"?>
<searchable xmlns:android="http://schemas.android.com/apk/res/android"
android:hint="@string/action_search_hint"
android:label="@string/cfg_app_name"
android:includeInGlobalSearch="false"
android:queryAfterZeroResults="true"
android:searchSuggestAuthority="@string/cfg_authorities"
android:searchSuggestIntentAction="android.intent.action.VIEW"
android:searchSuggestThreshold="3" />
在同一台设备上同时安装调试(使用 packageNameSuffix
选项)和发布 apk。我没有收到类似 Failure [INSTALL_FAILED_CONFLICTING_PROVIDER]
的错误...但是正如已经说过的那样,SearchableInfo
是 null
。
在没有 packageNameSuffix
选项的情况下安装这两个 apk 会导致以下错误:失败 [INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES] - 安装失败,因为设备已经有一个具有相同包但签名不同的应用程序。
还是我在这里遗漏了什么?
[/EDIT]
最佳答案
我正在使用完全改变包装名称的产品口味。我发现通过使用 ComponentName(Context pkg, Class<?> cls)
我的搜索 Activity 的构造函数我得到一个有效的 SearchableInfo。
SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE);
SearchableInfo searchableInfo = searchManager.getSearchableInfo(new ComponentName(this, SearchActivity.class));
我还必须调整我的提供者以使用不同的包,以便我的可搜索 xml 位于每个 flavor 目录中,并且提供者也列在每个 flavor 的 list 中。 这是我的目录结构:
src
main
AndoridManifest.xml
flavor1
res
xml
search.xml
AndroidManifest.xml
flavor2
res
xml
search.xml
AndroidManifest.xml
主/AndroidManifest.xml
<application
android:icon="@drawable/ic_launcher"
android:logo="@drawable/actionbar_icon"
android:label="@string/app_name"
android:name=".App"
android:allowBackup="true"
android:theme="@style/AppTheme">
<activity
android:name=".ui.MainActivity"
android:launchMode="singleTask">
<meta-data
android:name="android.app.default_searchable"
android:value=".ui.activity.SearchActivity"/>
</activity>
<activity android:name=".ui.SearchActivity" android:launchMode="singleTop">
<intent-filter>
<action android:name="android.intent.action.SEARCH" />
</intent-filter>
<meta-data
android:name="android.app.searchable"
android:resource="@xml/search"/>
</activity>
<provider
android:authorities=".provider.SuggestionProvider"
android:name="com.example.main.provider.SuggestionProvider"
android:exported="false"
android:enabled="true"
/>
</applicaiton
flavor1/AndroidManifest.xml
<application>
<provider
tools:replace="android:authorities"
android:authorities="com.example.flavor1.provider.SuggestionProvider"
android:name="com.example.main.provider.SuggestionProvider"
android:exported="false"
android:enabled="true"
/>
</application>
flavor1/res/xml/search.xml
<searchable xmlns:android="http://schemas.android.com/apk/res/android"
android:label="@string/app_name"
android:includeInGlobalSearch="false"
android:voiceSearchMode="showVoiceSearchButton|launchRecognizer"
android:searchMode="queryRewriteFromText"
android:searchSuggestAuthority="com.example.flavor1.provider.SuggestionProvider"
android:searchSuggestSelection="title LIKE ?"
android:searchSuggestThreshold="0"
>
</searchable>
flavor2/AndroidManifest.xml
<application>
<provider
tools:replace="android:authorities"
android:authorities="com.example.flavor2.provider.SuggestionProvider"
android:name="com.example.main.provider.SuggestionProvider"
android:exported="false"
android:enabled="true"
/>
</application>
flavor2/res/xml/search.xml
<searchable xmlns:android="http://schemas.android.com/apk/res/android"
android:label="@string/app_name"
android:includeInGlobalSearch="false"
android:voiceSearchMode="showVoiceSearchButton|launchRecognizer"
android:searchMode="queryRewriteFromText"
android:searchSuggestAuthority="com.example.flavor2.provider.SuggestionProvider"
android:searchSuggestSelection="title LIKE ?"
android:searchSuggestThreshold="0"
>
</searchable>
关于Android:在 Gradle 构建脚本中使用 packageNameSuffix 时,SearchableInfo 为 null,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20825949/