I'm developing a custom contacts app. I read default Contacts app source from Github and I don't fully understand.
1, As far as I know ContactsSearchActivity will be called if an intent has action equal
com.android.contacts.action.FILTER_CONTACTS (full manifest)
<!-- The contacts search/filter UI -->
<activity android:name="ContactsListActivity$ContactsSearchActivity"
android:theme="#style/ContactsSearchTheme"
android:windowSoftInputMode="stateAlwaysVisible|adjustPan"
>
<intent-filter>
<action android:name="com.android.contacts.action.FILTER_CONTACTS" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="vnd.android.cursor.dir/contact" android:host="com.android.contacts" />
</intent-filter>
</activity>
But the ContactsSearchActivity has no code.
public class ContactsListActivity extends ListActivity implements View.OnCreateContextMenuListener,
View.OnClickListener, View.OnKeyListener, TextWatcher, TextView.OnEditorActionListener,
OnFocusChangeListener, OnTouchListener {
public static class ContactsSearchActivity extends ContactsListActivity {
}
So i don't understand if ContactsSearchActivity is called.(Full source)
2, The second is about search interface. I know activity which has
<meta-data android:name="android.app.searchable"
android:resource="#xml/searchable"
is the activity handle query and display result. And the one has android:name="android.app.default_searchable" is enabled search + point to search handle activity.
<meta-data
android:name="android.app.default_searchable"
android:value=".ContactsListActivity" />
But again in Contacts's manifest, SearchResultsActivity is empty class extended from ContactsListActivity.
<!-- The contacts search/filter UI -->
<activity android:name="SearchResultsActivity"
android:theme="#style/TallTitleBarTheme"
android:label="#string/contactsList"
>
<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>
and
<meta-data
android:name="android.app.default_searchable"
android:value=".ContactsListActivity" />
in application tag not activity tag (link).
I want to understand these because i don't know how to display this instead of
Thanks in advance and sorry for long question.
Edit: It's ok with part1. In part 2, I want to display a custom diaglog when press search button but now i can only archive result in second image.
That means everything is handled by the codes in ContactListActivity.
Take a look at the onCreate method of that, it reads the incoming Intent to determine how to display the result. It's nothing too special, as many Android app is working in this way.
I change my code and achieve my custom search dialog.
Related
I am having a hard time figuring out the documentation on creating a search Interface.
My main activity contains the search widget on the app bar but when I perform a search query it does not launch the Searchable Activity; responsible for displaying the results.
Below is my manifest file for the SearchbaleActivity and MainActivity
<activity
android:name=".activities.SearchableActivity"
android:exported="false"
android:label="#string/title_activity_searchable"
android:theme="#style/Theme.MoveApplication.NoActionBar">
<intent-filter>
<action android:name="android.intent.action.SEARCH" />
</intent-filter>
<meta-data android:name="android.app.searchable"
android:resource="#xml/searchable"/>
</activity>
<activity
android:name=".activities.MainActivity"
android:exported="false" >
</activity>
Should my intent-filter and meta-data attributes be in my MainActivity or SearchableActivity?
And even so, my SearchableActivity should launch despite not handling the query, right?
My Android skills are not that great so i'll appreciate a vivid explanation with examples
I've searched documentation, but I'm missing something obvious. Or am trying to do something backwards.
What I have is the main activity, that's fired from the launcher and widgets. I have a second activity that I'd like to be fired off when a URL of a specific pattern is attempted to be opened. Here's the two activity definitions:
<activity android:name=".activities.MainMapScreen" 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=".activities.ViewDatasheet" android:configChanges="orientation|keyboardHidden" android:label="#string/app_name" android:process=":BMMapsDatasheet">
<meta-data android:name="Main Screen" android:value=".activities.MainMapScreen" />
<intent-filter>
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="http" android:host="www.ngs.noaa.gov" android:pathPattern="\\/cgi-bin\\/ds_mark.prl\\?PidBox\\=([a-zA-Z]{2}[0-9]{4})" />
</intent-filter>
</activity>
Like the above, url's aren't intercepted. Even if I have nothing in the data but the scheme and host, I don't get the prompt to select my app.
As a test, I copied the browsable and to the main activity, and when I do that, the icon disappears form the launcher altogether. (And I still get no prompt when trying to hit the URL.
All the examples I find has the in the main activity, not a secondary activity, so.. I'm not sure if I'm missing some flags or such.
Any thoughts would be appreciated. If you want me to post the whole Manifest, let me know.
--Mike.
Edit: After adding #iturki suggestions, there was no change. however - if I also added <category android:name="android.intent.category.OPENABLE" /> to the action to handle the URLs, that worked. None of the examples I saw with the had that category, so I'm not yet sure if it would affect other operations of the activities in my application or not.
Try adding a VIEW action to your second Activity's <intent-filter>:
<action android:name="android.intent.action.VIEW"></action>
And I think you might want to add your Intent to the DEFAULT category too:
<category android:name="android.intent.category.DEFAULT"></category>
I'm not sure if it is important but all the <intent-filter>s have this category.
I am trying to use the Search Manager from Android.
In fact, I have an activity where I am calling
onSearchRequested()
Then, I am using in the same activity this function to get the search string:
// Get the intent, verify the action and get the query
Intent intent = getIntent();
if (Intent.ACTION_SEARCH.equals(intent.getAction())) {
String query = intent.getStringExtra(SearchManager.QUERY);
}
The problem is the next: When i am clicking to the search button, I am opening a new activity and i would like to stay on the same and do some searches. So, my goal is to avoid the new activity opening when I click to the search button.
Thank you.
The solution consists to reuse the developpers example http://developer.android.com/guide/topics/search/search-dialog.html
The important thing is to create 2 activities, one for searches and one other for displaying the results.
In the manifest, use this code:
<application ... >
<!-- this is the searchable activity; it performs searches -->
<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>
<!-- this activity enables the search dialog to initiate searches
in the SearchableActivity -->
<activity android:name=".OtherActivity" ... >
<!-- enable the search dialog to send searches to SearchableActivity -->
<meta-data android:name="android.app.default_searchable"
android:value=".SearchableActivity" />
</activity>
...
use in Manifest
<activity android:name="BrowseItems" android:label="#string/browseitems"
android:launchMode="singleTop">
<intent-filter>
<action android:name="android.intent.action.SEARCH" />
</intent-filter>
<meta-data android:name="android.app.searchable"
android:resource="#xml/itemsearchable" />
</activity>
I am trying to implement search in my application.
My application contain 4 activities and I want to add the search dialog only on 3 of them while only one of them (ProductsActivity) will be the default context.
unfortunately while I activate the search I keep getting the following error:
"Key android.app.default_searchable expected String but value was a java.lang.Integer. The default value was returned."
<activity android:label="#string/app_name" class=".AppEntry" android:name=".AppEntry">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".category.CategoriesListActivity">
<intent-filter>
<action android:name="android.intent.action.SEARCH" />
</intent-filter>
<meta-data android:name="android.app.searchable" android:resource="#xml/searchable"/>
</activity>
<activity android:name=".product.ProductsActivity">
<intent-filter>
<action android:name="android.intent.action.SEARCH" />
</intent-filter>
<meta-data android:name="android.app.default_searchable" android:resource="#xml/searchable"/>
</activity>
Any idea why ?
Thanks
For default searchable activity you have to put the meta-data tag under the application tag.
<application ... >
<meta-data android:name="android.app.default_searchable"
android:value=".DefaultSearchActivity"/>
<activity android:name=".ProductActivity" >
...
<meta-data android:name="android.app.default_searchable"
android:value=".SearchActivityForProducts"/>
</activity>
...
In that example the default application search will be done on the DefaultSearchActivity, while in the ProductActivity the search will be on SearchActivityForProducts. Hope it helps someone.
Shouldn't it be
<meta-data android:name="android.app.default_searchable"
android:value=".product.ProductsActivity"/>
instead of passing the #xml reference there again.
One thing really important here is to correctly name your activities as the Android guidelines explains http://developer.android.com/guide/topics/manifest/activity-element.html#nm
android:name The name of the class that implements the activity, a
subclass of Activity. The attribute value should be a fully qualified
class name (such as, "com.example.project.ExtracurricularActivity").
However, as a shorthand, if the first character of the name is a
period (for example, ".ExtracurricularActivity"), it is appended to
the package name specified in the element. Once you publish
your application, you should not change this name (unless you've set
android:exported="false").
There is no default. The name must be specified.
If you don't put the DOT in your activity name, your search action will only work on the activity you declared as "default_searchable". This little DOT cost us hours so be careful!
I have an Android app which has a few different activities for browsing articles and images downloaded from RSS.
I'd like to be able to offer to hook up the search button to the Search dialog, using the a searchable.xml file. I've managed to do this with one search, using:
<activity android:name=".search.SearchResultsActivity"
android:label="#string/search_results_activity_title" >
<intent-filter>
<action android:name="android.intent.action.SEARCH" />
</intent-filter>
<meta-data android:name="android.app.searchable"
android:resource="#xml/searchable_articles"/>
</activity>
and in the <application />
<meta-data android:name="android.app.default_searchable"
android:value=".search.SearchResultsActivity" />
I can now launch the Search dialog from any activity, and it launches the SearchResultsActivity.
I would now like to be able to search for images when the user is an ImageListActivity, using a searchable_images.xml, and use the default everywhere else.
I have a SearchResultsImageActivity which includes the following meta-data element, and used the same element in the ImageListActivity.
<meta-data android:name="android.app.searchable"
android:resource="#xml/searchable_images"/>
On pressing the search button in the ImageListActivity, I get the default search from searchable_articles.xml.
If I change the default_searchable to SearchResultsImageActivity, the image search is always launched, and the article search is never launched.
If I remove the default_searchable meta-data element altogether, and add searchable meta-data only selected activities, no search is launched.
I'm fairly sure this should be possible, but I don't know what I'm doing wrong.
In your Manifest file update the ImageListActivity activity tag
<activity
android:name=".ImageListActivity"
...
<meta-data
android:name="android.app.default_searchable"
android:value=".SearchResultsImageActivity" />
</activity>
So when you will trigger native search in ImageListActivity it will invoke the SearchResultsImageActivity and default one for others.
Assuming SearchResultsImageActivity is searchable.
One way I did this was to create fake activities then switch out the activities when you need them.
<activity android:name="activitySearchMain" />
<activity android:name="activitySearchSub1">
<intent-filter>
<action android:name="android.intent.action.SEARCH" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.ALTERNATIVE" />
<category android:name="android.intent.category.SELECTED_ALTERNATIVE" />
<data android:scheme="user" />
</intent-filter>
</activity>
<activity android:name="activitySearchSub2">
<intent-filter>
<action android:name="com.sample.twitter.action.SEARCH" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.ALTERNATIVE" />
<category android:name="android.intent.category.SELECTED_ALTERNATIVE" />
<data android:scheme="user" />
</intent-filter>
</activity>
Create two class that are named for the sub activities.
then create intents like this when component is clicked...
Intent sourceIntent = getIntent();
Intent newIntent = new Intent(this, activitySearchSub2.class);
newIntent.setAction(activitySearchSub2.ACTION2);
newIntent.setData(sourceIntent.getData());
startActivity(newIntent);
finish();
and call the intents from onClick when a button is clicked or some other component is click:
If you override the search function in just that activity, it should prevent the search call from going up to the application level. The return value controls if the call is propagated up.
#Override
public boolean onSearchRequested() {
onPromptSearch();
return false; // don't go ahead and show the search box
}