Building a Mobile Employee Directory – Step 6: Create a Search Interface using Android’s search dialog
For the source code relating to this post, checkout this Github repository.
Continuing with the mobile employee directory example, I’ve added a Search Interface using Android’s search dialog.
MainActivity.java
package com.himebaugh.employeedirectory; import java.util.List; import android.annotation.TargetApi; import android.app.ListActivity; import android.app.SearchManager; import android.content.Context; import android.content.Intent; import android.database.Cursor; import android.net.Uri; import android.os.AsyncTask; import android.os.Build; import android.os.Bundle; import android.support.v4.widget.SimpleCursorAdapter; import android.view.Menu; import android.view.MenuItem; import android.view.View; import android.widget.ListView; import android.widget.SearchView; import android.widget.TextView; // GOAL: Build a native android Mobile Employee Directory // ** The result is similar to the sample with Flex and Flash Builder // see http://www.adobe.com/devnet/flex/articles/employee-directory-android-flex.html // PURPOSE: Learning how to build an Android App. // Step 6: Create a Search Interface using Android's search dialog. // 1) Modify MainActivity (add SearchView to onCreateOptionsMenu, add onSearchRequested() to onOptionsItemSelected ) // 2) Modify EmployeeProvider (Add Search logic within the ContentProvider) // 3) Create SearchableActivity // 4) Create searchable.xml (in res/xml) // 5) Modify main.xml (in res/menu) // 6) Modify strings.xml (in res/values) // 7) Modify AndroidManifest.xml // Step 6B: Pass data to DetailActivity using Intent.ACTION_VIEW in place of intent.putExtra // 1) Modify MainActivity (add Intent.ACTION_VIEW in onListItemClick ) // 2) Modify DetailActivity // 3) Modify AndroidManifest.xml (add android:mimeType="vnd.android.cursor.item...) public class MainActivity extends ListActivity { public List<Employee> employees = null; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // Parse xml data in a non-ui thread new LoadEmployeesTask().execute(); } private class LoadEmployeesTask extends AsyncTask<String, Void, Cursor> { @Override protected Cursor doInBackground(String... args) { Uri uri = EmployeeProvider.CONTENT_URI; String[] projection = { EmployeeDatabase.COLUMN_ID, EmployeeDatabase.COLUMN_FIRSTNAME, EmployeeDatabase.COLUMN_LASTNAME, EmployeeDatabase.COLUMN_TITLE, EmployeeDatabase.COLUMN_DEPARTMENT, EmployeeDatabase.COLUMN_CITY, EmployeeDatabase.COLUMN_OFFICE_PHONE, EmployeeDatabase.COLUMN_MOBILE_PHONE, EmployeeDatabase.COLUMN_EMAIL, EmployeeDatabase.COLUMN_PICTURE }; String selection = null; String[] selectionArgs = null; String sortOrder = EmployeeDatabase.COLUMN_LASTNAME + " COLLATE LOCALIZED ASC"; Cursor cursor = getContentResolver().query(uri, projection, selection, selectionArgs, sortOrder); return cursor; } @Override protected void onPostExecute(Cursor cursor) { String[] dataColumns = { EmployeeDatabase.COLUMN_FIRSTNAME, EmployeeDatabase.COLUMN_TITLE, EmployeeDatabase.COLUMN_DEPARTMENT, EmployeeDatabase.COLUMN_CITY, EmployeeDatabase.COLUMN_OFFICE_PHONE, EmployeeDatabase.COLUMN_MOBILE_PHONE, EmployeeDatabase.COLUMN_EMAIL, EmployeeDatabase.COLUMN_PICTURE }; int[] viewIDs = { R.id.list_item_name, R.id.list_item_title, R.id.list_item_department, R.id.list_item_city, R.id.list_item_office_phone, R.id.list_item_mobile_phone, R.id.list_item_email, R.id.list_item_picture }; SimpleCursorAdapter records = new SimpleCursorAdapter(getBaseContext(), R.layout.list_item, cursor, dataColumns, viewIDs, 0); setListAdapter(records); } } @Override protected void onListItemClick(ListView l, View view, int position, long id) { // // get values from selected ListItem // String empID = ((TextView) view.findViewById(R.id.list_item_emp_id)).getText().toString(); // String name = ((TextView) view.findViewById(R.id.list_item_name)).getText().toString(); // String title = ((TextView) view.findViewById(R.id.list_item_title)).getText().toString(); // String department = ((TextView) view.findViewById(R.id.list_item_department)).getText().toString(); // String city = ((TextView) view.findViewById(R.id.list_item_city)).getText().toString(); // String officePhone = ((TextView) view.findViewById(R.id.list_item_office_phone)).getText().toString(); // String mobilePhone = ((TextView) view.findViewById(R.id.list_item_mobile_phone)).getText().toString(); // String email = ((TextView) view.findViewById(R.id.list_item_email)).getText().toString(); // String picture = ((TextView) view.findViewById(R.id.list_item_picture)).getText().toString(); // // // Start new intent // Intent intent = new Intent(getApplicationContext(), DetailActivity.class); // intent.putExtra("empID", empID); // intent.putExtra("name", name); // intent.putExtra("title", title); // intent.putExtra("department", department); // intent.putExtra("city", city); // intent.putExtra("officePhone", officePhone); // intent.putExtra("mobilePhone", mobilePhone); // intent.putExtra("email", email); // intent.putExtra("picture", picture); // startActivity(intent); Uri details = Uri.withAppendedPath(EmployeeProvider.CONTENT_URI, "" + id); Intent detailsIntent = new Intent(Intent.ACTION_VIEW, details); startActivity(detailsIntent); } @TargetApi(Build.VERSION_CODES.HONEYCOMB) @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.main, menu); // Get the SearchView and set the searchable configuration SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE); SearchView searchView = (SearchView) menu.findItem(R.id.menu_search).getActionView(); searchView.setSearchableInfo(searchManager.getSearchableInfo(getComponentName())); searchView.setIconifiedByDefault(false); return true; } @Override public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { case R.id.menu_search: onSearchRequested(); return true; default: return false; } } }
EmployeeProvider.java
package com.himebaugh.employeedirectory; import java.util.HashMap; import android.app.SearchManager; import android.content.ContentProvider; import android.content.ContentResolver; import android.content.ContentValues; import android.content.UriMatcher; import android.database.Cursor; import android.database.sqlite.SQLiteQueryBuilder; import android.net.Uri; public class EmployeeProvider extends ContentProvider { private EmployeeDatabase mEmployeeDatabase; // Uri matcher to decode incoming URIs. private final UriMatcher mUriMatcher; private static final String AUTHORITY = "com.himebaugh.employeedirectory.EmployeeProvider"; // content mime types public static final String BASE_DATA_NAME = "employees"; public static final String CONTENT_ITEM_TYPE = ContentResolver.CURSOR_ITEM_BASE_TYPE + "/vnd.himebaugh.search." + BASE_DATA_NAME; public static final String CONTENT_TYPE = ContentResolver.CURSOR_DIR_BASE_TYPE + "/vnd.himebaugh.search." + BASE_DATA_NAME; // common URIs public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY + "/" + BASE_DATA_NAME); public static final Uri SEARCH_SUGGEST_URI = Uri.parse("content://" + AUTHORITY + "/" + BASE_DATA_NAME + "/" + SearchManager.SUGGEST_URI_PATH_QUERY); // matcher private static final int EMPLOYEES = 1; // The incoming URI matches the main table URI pattern private static final int EMPLOYEE_ID = 2; // The incoming URI matches the main table row ID URI pattern private static final int SEARCH_SUGGEST = 3; private static final HashMap<String, String> SEARCH_SUGGEST_PROJECTION_MAP; static { SEARCH_SUGGEST_PROJECTION_MAP = new HashMap<String, String>(); SEARCH_SUGGEST_PROJECTION_MAP.put(EmployeeDatabase.COLUMN_ID, EmployeeDatabase.COLUMN_ID); SEARCH_SUGGEST_PROJECTION_MAP.put(SearchManager.SUGGEST_COLUMN_TEXT_1, EmployeeDatabase.COLUMN_FIRSTNAME + " AS " + SearchManager.SUGGEST_COLUMN_TEXT_1); SEARCH_SUGGEST_PROJECTION_MAP.put(SearchManager.SUGGEST_COLUMN_TEXT_2, EmployeeDatabase.COLUMN_LASTNAME + " AS " + SearchManager.SUGGEST_COLUMN_TEXT_2); SEARCH_SUGGEST_PROJECTION_MAP.put(SearchManager.SUGGEST_COLUMN_INTENT_DATA_ID, EmployeeDatabase.COLUMN_ID + " AS " + SearchManager.SUGGEST_COLUMN_INTENT_DATA_ID); } public EmployeeProvider() { // Create and initialize URI matcher. mUriMatcher = new UriMatcher(UriMatcher.NO_MATCH); mUriMatcher.addURI(AUTHORITY, EmployeeDatabase.TABLE_EMPLOYEES, EMPLOYEES); mUriMatcher.addURI(AUTHORITY, EmployeeDatabase.TABLE_EMPLOYEES + "/#", EMPLOYEE_ID); // to get suggestions... mUriMatcher.addURI(AUTHORITY, SearchManager.SUGGEST_URI_PATH_QUERY, SEARCH_SUGGEST); mUriMatcher.addURI(AUTHORITY, SearchManager.SUGGEST_URI_PATH_QUERY + "/*", SEARCH_SUGGEST); } @Override public boolean onCreate() { mEmployeeDatabase = new EmployeeDatabase(getContext()); return true; } @Override public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) { SQLiteQueryBuilder queryBuilder = new SQLiteQueryBuilder(); queryBuilder.setTables(EmployeeDatabase.TABLE_EMPLOYEES); switch (mUriMatcher.match(uri)) { case SEARCH_SUGGEST: selectionArgs = new String[] { "%" + selectionArgs[0] + "%", "%" + selectionArgs[0] + "%" }; queryBuilder.setProjectionMap(SEARCH_SUGGEST_PROJECTION_MAP); break; case EMPLOYEES: // no filter break; case EMPLOYEE_ID: queryBuilder.appendWhere(EmployeeDatabase.COLUMN_ID + "=" + uri.getLastPathSegment()); break; default: throw new IllegalArgumentException("Unknown URI"); } Cursor cursor = queryBuilder.query(mEmployeeDatabase.getReadableDatabase(), projection, selection, selectionArgs, null, null, sortOrder); cursor.setNotificationUri(getContext().getContentResolver(), uri); return cursor; } @Override public String getType(Uri uri) { switch (mUriMatcher.match(uri)) { case EMPLOYEES: return CONTENT_TYPE; case EMPLOYEE_ID: return CONTENT_ITEM_TYPE; case SEARCH_SUGGEST: return null; default: throw new IllegalArgumentException("Unknown URI " + uri); } } @Override public Uri insert(Uri uri, ContentValues values) { return null; } @Override public int delete(Uri uri, String selection, String[] selectionArgs) { return 0; } @Override public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) { return 0; } }
SearchableActivity.java
package com.himebaugh.employeedirectory; import android.annotation.TargetApi; import android.app.ListActivity; import android.app.SearchManager; import android.content.Intent; import android.database.Cursor; import android.net.Uri; import android.os.Build; import android.os.Bundle; import android.view.MenuItem; import android.view.View; import android.widget.ListAdapter; import android.widget.ListView; import android.widget.SimpleCursorAdapter; @TargetApi(Build.VERSION_CODES.HONEYCOMB) public class SearchableActivity extends ListActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // implement Up Navigation with caret in front of App icon in the Action Bar getActionBar().setDisplayHomeAsUpEnabled(true); Intent intent = getIntent(); checkIntent(intent); } @Override protected void onNewIntent(Intent newIntent) { // update the activity launch intent setIntent(newIntent); // handle it checkIntent(newIntent); } private void checkIntent(Intent intent) { String query = ""; String intentAction = intent.getAction(); if (Intent.ACTION_SEARCH.equals(intentAction)) { query = intent.getStringExtra(SearchManager.QUERY); } else if (Intent.ACTION_VIEW.equals(intentAction)) { Uri details = intent.getData(); Intent detailsIntent = new Intent(Intent.ACTION_VIEW, details); startActivity(detailsIntent); } fillList(query); } private void fillList(String query) { String wildcardQuery = "%" + query + "%"; Cursor cursor = getContentResolver().query( EmployeeProvider.CONTENT_URI, null, EmployeeDatabase.COLUMN_FIRSTNAME + " LIKE ? OR " + EmployeeDatabase.COLUMN_LASTNAME + " LIKE ?", new String[] { wildcardQuery, wildcardQuery }, null); ListAdapter adapter = new SimpleCursorAdapter( this, android.R.layout.simple_list_item_2, cursor, new String[] { EmployeeDatabase.COLUMN_FIRSTNAME, EmployeeDatabase.COLUMN_LASTNAME }, new int[] { android.R.id.text1, android.R.id.text2 }, 0); setListAdapter(adapter); } @Override protected void onListItemClick(ListView l, View view, int position, long id) { Uri details = Uri.withAppendedPath(EmployeeProvider.CONTENT_URI, "" + id); Intent detailsIntent = new Intent(Intent.ACTION_VIEW, details); startActivity(detailsIntent); } @Override public boolean onOptionsItemSelected(MenuItem item) { if (item.getItemId() == android.R.id.home) { // This is called when the Home (Up) button is pressed // in the Action Bar. Intent parentActivityIntent = new Intent(this, MainActivity.class); parentActivityIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK); startActivity(parentActivityIntent); finish(); return true; } return super.onOptionsItemSelected(item); } }
DetailActivity.java
package com.himebaugh.employeedirectory; import java.io.IOException; import java.io.InputStream; import android.annotation.SuppressLint; import android.app.Activity; import android.content.ContentUris; import android.content.Context; import android.content.Intent; import android.database.Cursor; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.net.Uri; import android.os.AsyncTask; import android.os.Build; import android.os.Bundle; import android.telephony.PhoneStateListener; import android.telephony.TelephonyManager; import android.util.Log; import android.view.Menu; import android.view.MenuInflater; import android.view.MenuItem; import android.view.View; import android.view.View.OnClickListener; import android.widget.ImageView; import android.widget.TextView; public class DetailActivity extends Activity implements OnClickListener { public TextView mName; public TextView mTitle; public TextView mDepartment; public TextView mCity; private TextView mOfficePhone; private TextView mMobilePhone; private TextView mSms; private TextView mEmail; private ImageView mPicture; private int mID; public Uri uri; @SuppressLint("NewApi") @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_detail); // implement Up Navigation with caret in front of App icon in the Action // Bar if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) { getActionBar().setDisplayHomeAsUpEnabled(true); } // getting intent data Intent intent = getIntent(); Uri launchData = intent.getData(); mID = Integer.parseInt(launchData.getLastPathSegment()); uri = ContentUris.withAppendedId(EmployeeProvider.CONTENT_URI, mID); // Update values on the screen with XML values from previous intent mName = (TextView) findViewById(R.id.activity_detail_name); mTitle = (TextView) findViewById(R.id.activity_detail_title); mDepartment = (TextView) findViewById(R.id.activity_detail_department); mCity = (TextView) findViewById(R.id.activity_detail_city); mOfficePhone = (TextView) findViewById(R.id.activity_detail_office_phone); mMobilePhone = (TextView) findViewById(R.id.activity_detail_mobile_phone); mSms = (TextView) findViewById(R.id.activity_detail_sms); mEmail = (TextView) findViewById(R.id.activity_detail_email); mPicture = (ImageView) findViewById(R.id.activity_detail_picture); // listen for button clicks findViewById(R.id.activity_detail_call_office_button).setOnClickListener(this); findViewById(R.id.activity_detail_office_phone).setOnClickListener(this); findViewById(R.id.activity_detail_call_mobile_button).setOnClickListener(this); findViewById(R.id.activity_detail_mobile_phone).setOnClickListener(this); findViewById(R.id.activity_detail_send_sms_button).setOnClickListener(this); findViewById(R.id.activity_detail_sms).setOnClickListener(this); findViewById(R.id.activity_detail_send_email_button).setOnClickListener(this); findViewById(R.id.activity_detail_email).setOnClickListener(this); // add PhoneStateListener FROM // http://www.mkyong.com/android/how-to-make-a-phone-call-in-android/ PhoneCallListener phoneListener = new PhoneCallListener(); TelephonyManager telephonyManager = (TelephonyManager) this.getSystemService(Context.TELEPHONY_SERVICE); telephonyManager.listen(phoneListener, PhoneStateListener.LISTEN_CALL_STATE); // Parse xml data in a non-ui thread new LoadEmployeesTask().execute(); } private class LoadEmployeesTask extends AsyncTask<String, Void, Cursor> { @Override protected Cursor doInBackground(String... args) { String[] projection = { EmployeeDatabase.COLUMN_ID, EmployeeDatabase.COLUMN_FIRSTNAME, EmployeeDatabase.COLUMN_LASTNAME, EmployeeDatabase.COLUMN_TITLE, EmployeeDatabase.COLUMN_DEPARTMENT, EmployeeDatabase.COLUMN_CITY, EmployeeDatabase.COLUMN_OFFICE_PHONE, EmployeeDatabase.COLUMN_MOBILE_PHONE, EmployeeDatabase.COLUMN_EMAIL, EmployeeDatabase.COLUMN_PICTURE }; String selection = null; String[] selectionArgs = null; String sortOrder = null; Cursor cursor = getContentResolver().query(uri, projection, selection, selectionArgs, sortOrder); return cursor; } @Override protected void onPostExecute(Cursor cursor) { if (cursor != null && cursor.getCount() > 0) { cursor.moveToFirst(); mName.setText(cursor.getString(cursor.getColumnIndex(EmployeeDatabase.COLUMN_FIRSTNAME))); mName.setText(cursor.getString(cursor.getColumnIndex(EmployeeDatabase.COLUMN_LASTNAME))); mTitle.setText(cursor.getString(cursor.getColumnIndex(EmployeeDatabase.COLUMN_TITLE))); mDepartment.setText(cursor.getString(cursor.getColumnIndex(EmployeeDatabase.COLUMN_DEPARTMENT))); mCity.setText(cursor.getString(cursor.getColumnIndex(EmployeeDatabase.COLUMN_CITY))); mOfficePhone.setText(cursor.getString(cursor.getColumnIndex(EmployeeDatabase.COLUMN_OFFICE_PHONE))); mMobilePhone.setText(cursor.getString(cursor.getColumnIndex(EmployeeDatabase.COLUMN_MOBILE_PHONE))); mSms.setText(cursor.getString(cursor.getColumnIndex(EmployeeDatabase.COLUMN_MOBILE_PHONE))); mEmail.setText(cursor.getString(cursor.getColumnIndex(EmployeeDatabase.COLUMN_EMAIL))); InputStream is; try { is = getAssets().open( "pics/" + cursor.getString(cursor.getColumnIndex(EmployeeDatabase.COLUMN_PICTURE))); Bitmap bit = BitmapFactory.decodeStream(is); mPicture.setImageBitmap(bit); } catch (IOException e) { e.printStackTrace(); } } } } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the options menu from XML MenuInflater inflater = getMenuInflater(); inflater.inflate(R.menu.main, menu); return true; } @Override public boolean onOptionsItemSelected(MenuItem item) { if (item.getItemId() == android.R.id.home) { // This is called when the Home (Up) button is pressed in the Action // Bar. Intent parentActivityIntent = new Intent(this, MainActivity.class); parentActivityIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK); startActivity(parentActivityIntent); finish(); return true; } return super.onOptionsItemSelected(item); } // @Override public void onClick(View view) { switch (view.getId()) { case R.id.activity_detail_call_office_button: case R.id.activity_detail_office_phone: // clicking on textView will // have same action as the // button Intent callIntent = new Intent(Intent.ACTION_CALL); callIntent.setData(Uri.parse("tel:" + mOfficePhone.getText().toString())); startActivity(callIntent); break; case R.id.activity_detail_call_mobile_button: case R.id.activity_detail_mobile_phone: // clicking on textView will // have same action as the // button Intent callIntent2 = new Intent(Intent.ACTION_CALL); callIntent2.setData(Uri.parse("tel:" + mMobilePhone.getText().toString())); startActivity(callIntent2); break; case R.id.activity_detail_send_sms_button: case R.id.activity_detail_sms: // clicking on textView will have same // action as the button Intent smsIntent = new Intent(Intent.ACTION_SENDTO); smsIntent.setData(Uri.parse("smsto:" + mMobilePhone.getText().toString())); // smsIntent.putExtra("sms_body", "Hello " + // mName.getText().toString() ); startActivity(smsIntent); break; case R.id.activity_detail_send_email_button: case R.id.activity_detail_email: // clicking on textView will have same // action as the button String to = mEmail.getText().toString(); String subject = "textSubject"; String message = "textMessage"; Intent email = new Intent(Intent.ACTION_SEND); email.putExtra(Intent.EXTRA_EMAIL, new String[] { to }); email.putExtra(Intent.EXTRA_SUBJECT, subject); email.putExtra(Intent.EXTRA_TEXT, message); // prompts email apps email.setType("message/rfc822"); startActivity(Intent.createChooser(email, "Choose an Email client :")); break; } } // monitor phone call activities private class PhoneCallListener extends PhoneStateListener { private boolean isPhoneCalling = false; @Override public void onCallStateChanged(int state, String incomingNumber) { if (TelephonyManager.CALL_STATE_RINGING == state) { // phone ringing } if (TelephonyManager.CALL_STATE_OFFHOOK == state) { // active isPhoneCalling = true; } if (TelephonyManager.CALL_STATE_IDLE == state) { // run when class initial and phone call ended, // need detect flag from CALL_STATE_OFFHOOK if (isPhoneCalling) { // restart app Intent i = getBaseContext().getPackageManager().getLaunchIntentForPackage( getBaseContext().getPackageName()); i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); startActivity(i); isPhoneCalling = false; } } } } }
main.xml (in res/menu)
<menu xmlns:android="http://schemas.android.com/apk/res/android" > <item android:id="@+id/menu_search" android:actionViewClass="android.widget.SearchView" android:icon="@android:drawable/ic_menu_search" android:showAsAction="always|collapseActionView|withText" android:title="@string/menu_search"/> <item android:id="@+id/action_settings" android:orderInCategory="100" android:showAsAction="never" android:title="@string/action_settings"/> </menu>
strings.xml (in res/values)
<?xml version="1.0" encoding="utf-8"?> <resources> <string name="app_name">Employee Directory</string> <string name="employee_details">Employee Details</string> <string name="employee_photo">Employee Photo</string> <string name="detail_header1">Call Office</string> <string name="detail_header2">Call Mobile</string> <string name="detail_header3">SMS</string> <string name="detail_header4">Email</string> <string name="place_holder">Text will be replaced</string> <string name="action_settings">Settings</string> <string name="menu_search">Search</string> <string name="search_hint">"Search employees" </string> </resources>
searchable.xml (in res/xml)
<?xml version="1.0" encoding="utf-8"?> <searchable xmlns:android="http://schemas.android.com/apk/res/android" android:label="@string/app_name" android:hint="@string/search_hint" android:searchSuggestAuthority="com.himebaugh.employeedirectory.EmployeeProvider" android:searchSuggestIntentAction="android.intent.action.VIEW" android:searchSuggestIntentData="content://com.himebaugh.employeedirectory.EmployeeProvider/employees" android:searchSuggestSelection="first_name LIKE ? OR last_name LIKE ?" android:searchSuggestThreshold="2" android:voiceSearchMode="showVoiceSearchButton|launchRecognizer" > </searchable>
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.himebaugh.employeedirectory" android:versionCode="1" android:versionName="1.0" > <uses-sdk android:minSdkVersion="8" android:targetSdkVersion="17" /> <uses-permission android:name="android.permission.SEND_SMS" /> <uses-permission android:name="android.permission.CALL_PHONE" /> <uses-permission android:name="android.permission.READ_PHONE_STATE" /> <application android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" > <!-- Main --> <activity android:name="com.himebaugh.employeedirectory.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> <!-- Detail --> <activity android:name="com.himebaugh.employeedirectory.DetailActivity" android:label="@string/employee_details" > <intent-filter> <action android:name="android.intent.action.VIEW" /> <category android:name="android.intent.category.DEFAULT" /> <data android:mimeType="vnd.android.cursor.item/vnd.himebaugh.search.employees" /> </intent-filter> </activity> <!-- Searchable --> <activity android:name=".SearchableActivity" android:launchMode="singleTop" > <intent-filter> <action android:name="android.intent.action.SEARCH" /> </intent-filter> <intent-filter> <action android:name="android.intent.action.VIEW" /> </intent-filter> <meta-data android:name="android.app.searchable" android:resource="@xml/searchable" /> </activity> <!-- Points to searchable activity so the whole app can invoke search. --> <meta-data android:name="android.app.default_searchable" android:value="com.himebaugh.employeedirectory.SearchableActivity" /> <provider android:name="com.himebaugh.employeedirectory.EmployeeProvider" android:authorities="com.himebaugh.employeedirectory.EmployeeProvider" android:multiprocess="true" > </provider> </application> </manifest>
Other files unchanged see Step 5
Screenshots of the application
Category: Android Application Development
Is it possible to add/edit/delete any employee thru coding to this directory app??? if so then plz tell me???
The code has been place on GitHub. Download at https://github.com/langhimebaugh/EmployeeDirectory/tree/Step-6