I am following this tutorial to create a search view in my toolbar. What I want is when I click on one of the search result items I want to display its corresponding data in a details activity but I can't seem to make it happen.
This is my code:
MainActivity class:
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu_search, menu);
MenuItem searchItem = menu.findItem(R.id.search);
SearchView searchView = (SearchView) MenuItemCompat.getActionView(searchItem);
searchView.setOnQueryTextListener(this);
SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE);
searchView.setSearchableInfo(searchManager.getSearchableInfo(
new ComponentName(this, SearchableActivity.class)));
searchView.setIconifiedByDefault(false);
return true;
}
@Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
if (Intent.ACTION_SEARCH.equals(intent.getAction())) {
String query = intent.getStringExtra(SearchManager.QUERY);
Toast.makeText(this, "Searching by: "+ query, Toast.LENGTH_SHORT).show();
} else if (Intent.ACTION_VIEW.equals(intent.getAction())) {
String uri = intent.getDataString();
Toast.makeText(this, "Suggestion: "+ uri, Toast.LENGTH_SHORT).show();
}
}
@Override
public boolean onQueryTextSubmit(String query) {
// User pressed the search button
return false;
}
@Override
public boolean onQueryTextChange(String newText) {
// User changed the text
return false;
}
SearchableActivity class:
public class SearchableActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_searchable);
TextView txt = (TextView)findViewById(R.id.textView);
Intent intent = getIntent();
if (Intent.ACTION_SEARCH.equals(intent.getAction())) {
String query = intent.getStringExtra(SearchManager.QUERY);
txt.setText("Searching by: "+ query);
} else if (Intent.ACTION_VIEW.equals(intent.getAction())) {
String uri = intent.getDataString();
txt.setText("Suggestion: "+ uri);
}
}
CitySuggestionProvider class:
public class CitySuggestionProvider extends ContentProvider {
List<String> cities;
@Override
public boolean onCreate() {
return false;
}
@Override
public Cursor query(Uri uri, String[] projection, String selection,
String[] selectionArgs, String sortOrder) {
if (cities == null || cities.isEmpty()){
Log.d("NGVL", "WEB");
List<CityPojo> pojos = new ArrayList<>();
cities = new ArrayList<>();
DatabaseHelper db = new DatabaseHelper(getContext());
try {
try {
db.create();
} catch (IOException ioe) {
throw new Error("Unable to create database");
}
if (db.open()) {
pojos = db.getCities();
}
db.close();
int lenght = pojos.size();
for (int i = 0; i < lenght; i++) {
String city = pojos.get(i).getCity();
cities.add(city);
}
} catch (Exception e) {
e.printStackTrace();
}
} else {
Log.d("NGVL", "Cache!");
}
MatrixCursor cursor = new MatrixCursor(
new String[] {
BaseColumns._ID,
SearchManager.SUGGEST_COLUMN_TEXT_1,
SearchManager.SUGGEST_COLUMN_INTENT_DATA_ID
}
);
if (cities != null) {
String query = uri.getLastPathSegment().toUpperCase();
int limit = Integer.parseInt(uri.getQueryParameter(SearchManager.SUGGEST_PARAMETER_LIMIT));
int lenght = cities.size();
for (int i = 0; i < lenght && cursor.getCount() < limit; i++) {
String city = cities.get(i);
if (city.toUpperCase().contains(query)){
cursor.addRow(new Object[]{ i, city, i });
}
}
}
return cursor;
}
}
Manifest:
<activity
android:name=".MainActivity"
android:launchMode="singleTop">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
<provider
android:name=".CitySuggestionProvider"
android:authorities="ngvl.android.demosearch.citysuggestion"
android:enabled="true"
android:exported="true"/>
<activity android:name=".SearchableActivity">
<intent-filter>
<action android:name="android.intent.action.SEARCH"/>
</intent-filter>
<meta-data
android:name="android.app.searchable"
android:resource="@xml/searchable"/>
</activity>
searchable.xml:
<searchable xmlns:android="http://schemas.android.com/apk/res/android"
android:hint="@string/hint_search"
android:label="@string/app_name"
android:voiceSearchMode="showVoiceSearchButton|launchRecognizer"
android:searchSuggestAuthority="ngvl.android.demosearch.citysuggestion"
android:searchSuggestIntentAction="android.intent.action.VIEW"
android:searchSuggestIntentData="content://ngvl.android.demosearch.city"/>
Everthing works fine I get the results just like this image:
but the problem is when I click on a suggestion I want to show its details in another activity. I have 2 text fields: city and country so when the user clicks the city in the suggestion I want to display its corresponding country in the details activity. I am not sure how to pass the country data to the details activity. I am using SQLite to get the data in the content provider class
I'm the author of the mentioned tutorial :) First of all, sorry for the sample is not clear enough, and let me try to explain it better.
The content provider described in the sample should provides only search suggestions. So, when the user choose an option in the list a Uri is returned (in most of cases) to another provider. Notice that in the searchable configuration file (res/xml/searchable.xml) there is this property:
content://ngvl.android.demosearch.city
So, you should have a content provider to attend this Uri and return all details about the user selection. For this reason I just display the Uri in the second activity (SearchableActivity.java).
However, I update the code to answer your question :) Now the suggestion provider is answering for both Uris :) This is the link for the commit. https://github.com/nglauber/playground/commit/51741babd301b42be220fc771c563da660808b20
Let me know if you have any questions ;)
Hope it helps!