android - SearchInfo siempre sale nulo
android-search android-searchmanager (7)
Tengo problemas para configurar la vista de búsqueda en la barra de acción.
Seguí el sitio del desarrollador, pero no funciona. Tengo la sensación de que me estoy perdiendo algo.
Cuando ejecuto mi código, siempre muestra "no se pudo obtener información de búsqueda" (MainActivity.setupSearchView ()).
MainActivity.java
// package...
// imports...
public class MainActivity extends Activity {
private static String tag = "Main Activity";
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater mi = getMenuInflater();
mi.inflate(R.menu.search_view, menu);
setupSearchView(menu);
return true;
}
private void setupSearchView(Menu menu) {
SearchManager sm = (SearchManager) getSystemService(Context.SEARCH_SERVICE);
SearchableInfo si = sm.getSearchableInfo(getComponentName());
if (si == null) {
Log.wtf(tag, "failed to get searchable info");
return;
}
SearchView sv = (SearchView) menu.findItem(R.id.menu_search).getActionView();
sv.setSearchableInfo(si);
// Do not iconify the widget; expand it by default
sv.setIconifiedByDefault(false);
}
}
SearchResultsActivity.java
// package...
// imports...
public class SearchResultsActivity extends ListActivity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
final Intent queryIntent = getIntent();
doSearchQuery(queryIntent);
}
@Override
public void onNewIntent(final Intent newIntent) {
super.onNewIntent(newIntent);
final Intent queryIntent = getIntent();
doSearchQuery(queryIntent);
}
}
searchable.xml
<?xml version="1.0" encoding="utf-8"?>
<searchable xmlns:android="http://schemas.android.com/apk/res/android"
android:hint="@string/search_hint"
android:label="@string/search_label" >
</searchable>
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="kpaek.examples"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk android:minSdkVersion="15" />
<application
android:icon="@drawable/ic_launcher"
android:label="@string/app_name" >
<activity
android:name=".search.MainActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".SearchResultsActivity">
<intent-filter>
<action android:name="android.intent.action.SEARCH" />
</intent-filter>
<meta-data
android:name="android.app.searchable"
android:resource="@xml/searchable" />
</activity>
</application>
</manifest>
Descubrí que los elementos de metadatos y filtro de intención deben incluirse en el elemento de actividad de manifiesto desde el que se inicia la búsqueda (MainActivity con SearchView) para el método getSearchableInfo (getComponentName ()) para devolver la configuración correcta y no nulo.
<activity
android:name=".MainActivity"
android:label="@string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.SEARCH" />
</intent-filter>
<meta-data
android:name="android.app.searchable"
android:resource="@xml/searchable" />
</activity>
Me pregunto si en cambio (y la solución con la que voy por ahora) uno debería dejar la intención y los metadatos en la declaración de la actividad de resultados y cambiar el argumento a getSearchableInfo () de la siguiente manera:
<activity android:name=".SearchResultsActivity">
<intent-filter>
<action android:name="android.intent.action.SEARCH" />
</intent-filter>
<meta-data
android:name="android.app.searchable"
android:resource="@xml/searchable" />
</activity>
Y los cambios en MainActivity (note la declaración de asignación para searchableInfo):
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu_search, menu);
SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE);
SearchView mySearchView = (SearchView) menu.findItem(R.id.action_search).getActionView();
SearchableInfo searchableInfo = searchManager.getSearchableInfo(new ComponentName(getApplicationContext(), SearchResultsActivity.class));
mySearchView.setSearchableInfo(searchableInfo);
return true;
}
Desde el sitio de desarrollo:
Una configuración de búsqueda define cómo se comporta SearchView y se define en un archivo res / xml / searchable.xml. Como mínimo, una configuración de búsqueda debe contener un atributo android: label que tenga el mismo valor que el atributo android: label del elemento o en su manifiesto de Android.
Como ejemplo, muestran:
<searchable xmlns:android="http://schemas.android.com/apk/res/android"
android:label="@string/app_name"
android:hint="@string/search_hint" />
app_name es, como en tu manifiesto, la etiqueta de la actividad. Sin embargo, en su búsqueda, la etiqueta se refiere a search_label. Funciona quizás si app_name y search_label son iguales, pero eso me parece frágil.
En mi caso, usar etiquetas personalizadas en res/menu/mymenu.xml
funcionó para mí:
app:showAsAction="ifRoom|collapseActionView"
app:actionViewClass="android.support.v7.widget.SearchView"
No utilice:
android:showAsAction="ifRoom|collapseActionView"
android:actionViewClass="android.support.v7.widget.SearchView"
Encontré este problema pero el consejo anterior no lo resolvió. En su lugar, resultó ser la configuración predeterminada de la categoría en SearchResultActivity. Por ejemplo las siguientes pausas:
<activity android:name=".SearchResultActivity"
android:label="@string/app_name"
android:theme="@style/AppTheme">
<intent-filter>
<action android:name="android.intent.action.SEARCH" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
<meta-data
android:name="android.app.searchable"
android:resource="@xml/searchable" />
</activity>
Eliminando android.intent.category.DEFAULT resuelve este problema .:
<activity android:name=".SearchResultActivity"
android:label="@string/app_name"
android:theme="@style/AppTheme">
<intent-filter>
<action android:name="android.intent.action.SEARCH" />
</intent-filter>
<meta-data
android:name="android.app.searchable"
android:resource="@xml/searchable" />
</activity>
También las respuestas anteriores a esta pregunta tienen un error. MainActivity debe definirse con android.app.default_searchable . android.app.searchable es solo para su SearchResultsActivity.
<activity
android:name=".MainActivity"
android:label="@string/app_name">
<!-- other stuff-->
<meta-data android:name="android.app.default_searchable"
android:value=".SearchResultsActivity" />
</activity>
En conclusión, el SearchManager es un componente frágil propenso a fallas silenciosas cuando el AndroidManifest.xml no es perfecto.
Esto me mató por un día. Pensé que estaba relacionado con ActionBarSherlock, pero no funciona bien con eso.
El problema era que estaba tratando de cortocircuitar la muestra. Al menos una de tus actividades, de la que estás haciendo la búsqueda es suficiente, debe tener este filtro de intención en el manifiesto:
<intent-filter>
<action android:name="android.intent.action.SEARCH" />
</intent-filter>
Si no, entonces searchManager.getSearchableInfo(getComponentName())
siempre devuelve un valor nulo, y su configuración se ignora.
La clave que encontré es que searchable.xml no debe contener cadenas literales, solo recursos. Perdí alrededor de medio día en eso, ya que hace que getSearchableInfo falle silenciosamente.
Perdí 8 horas completas en este caso porque verifiqué todas las soluciones anteriores pero me faltaba una cosa.
En mi manifiesto de Android:
<meta-data
android:name="android.app.searchable"
android:value="@xml/searchable" />
Debería haber sido:
<meta-data
android:name="android.app.searchable"
android:resource="@xml/searchable" />
Para mí estaba fallando en silencio. Lo mejor que se puede hacer al principio es simplemente copiar y pegar los ejemplos. Solo asegúrate de que todos tus atributos sean exactamente iguales.