title: Android Search not returning results after suggestion chosen
body: <p>I have a simple application that just uses the hardware search key to search my database via my content provider.  After getting the results from the Suggestions and clicking on one of the choices the listview screen appears and it's blank.  I get an error:</p>
  
  <pre><code>E/InputQueue-JNI(1137): channel '4150a5d0 PopupWindow:412ccf98 (client)' ~ Publisher closed input channel or an error occurred.  events=0x8
  </code></pre>
  
  <p>I'm new to android development, I did some research, but can't figure out what this even means. </p>
  
  <p>Here's the full logcat: </p>
  
  <pre><code>06-24 14:54:03.154: I/TDAProvider(1137): query 
  06-24 14:54:03.924: I/TDAProvider(1137): query return cursor 
  06-24 14:54:04.014: I/TDAProvider(1137): query 
  06-24 14:54:04.304: I/TDAProvider(1137): query return cursor 
  06-24 14:54:04.754: D/dalvikvm(1137): GC_CONCURRENT freed 137K, 3% free 9374K/9607K, paused 23ms+28ms
  06-24 14:54:07.154: E/InputQueue-JNI(1137): channel '4150a5d0 PopupWindow:412ccf98 (client)' ~ Publisher closed input channel or an error occurred.  events=0x8
  06-24 14:54:07.464: I/TDAProvider(1137): query 
  06-24 14:54:07.464: I/TDAProvider(1137): query return cursor 
  06-24 14:54:07.694: I/dalvikvm(1137): threadid=3: reacting to signal 3
  06-24 14:54:07.745: I/dalvikvm(1137): Wrote stack traces to '/data/anr/traces.txt'
  </code></pre>
  
  <p>Any suggestions on how to either solve this or debug it would be welcome. </p>
  
  <p>Since most of the processing is being done by android classes, I'm not sure what to look at.  I'm using 2 uri's 'SEARCH' and 'CONTENT_URI_RULES' from my content provider (TDAProvider.java).  My guess is there's an issue in the content provider, but I'm not sure what.</p>
  
  <p>Here's my manifest file:</p>
  
  <pre><code>&lt;RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
  xmlns:tools="http://schemas.android.com/tools"
  android:layout_width="match_parent"
  android:layout_height="match_parent"
  android:paddingBottom="@dimen/activity_vertical_margin"
  android:paddingLeft="@dimen/activity_horizontal_margin"
  android:paddingRight="@dimen/activity_horizontal_margin"
  android:paddingTop="@dimen/activity_vertical_margin"
  tools:context=".ActivityMain"
       &gt;
  
  &lt;TextView
      android:id="@+id/textView1"
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:layout_alignParentLeft="true"
      android:layout_alignParentTop="true"
      android:layout_marginLeft="64dp"
      android:layout_marginTop="22dp"
      android:text="Test Search - using hardware button. Search for 'check'"
      android:textAppearance="?android:attr/textAppearanceMedium" /&gt;
  
  &lt;/RelativeLayout&gt;
  </code></pre>
  
  <p>Here's my searchable.xml that I put into the xml folder.</p>
  
  <pre><code>&lt;searchable xmlns:android="http://schemas.android.com/apk/res/android"
  android:label="@string/app_name"
  android:searchSettingsDescription="@string/search_description"
  android:searchSuggestAuthority="com.birdsall.tda.contentprovidertda"
  android:searchSuggestIntentAction="android.intent.action.VIEW"
  android:searchSuggestIntentData="content://com.birdsall.tda.TDAProvider/rules" &gt;
  
  &lt;/searchable&gt;
  </code></pre>
  
  <p>Here the ActivitySearch.java that is used to facilitate the search:</p>
  
  <pre><code>package com.birdsall.tda;
  
  import android.app.ListActivity;
  import android.app.LoaderManager;
  import android.app.SearchManager;
  import android.content.CursorLoader;
  import android.content.Intent;
  import android.content.Loader;
  import android.database.Cursor;
  import android.os.Bundle;
  import android.widget.SimpleCursorAdapter;
  
  public class ActivitySearch extends ListActivity implements
      LoaderManager.LoaderCallbacks&lt;Cursor&gt; {
  
  private SimpleCursorAdapter adapter;
  
  @Override
  public void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
  
      // Create a new adapter and bind it to the List View
      adapter = new SimpleCursorAdapter(this,
              android.R.layout.simple_list_item_1, null,
              new String[] { TDAdb.COL_RULETITLE },
              new int[] { android.R.id.text1 }, 0);
      setListAdapter(adapter);
  
      // Initiate the Cursor Loader
      getLoaderManager().initLoader(0, null, this);
  
      // Get the launch Intent
      parseIntent(getIntent());
  }
  
  @Override
  protected void onNewIntent(Intent intent) {
      super.onNewIntent(intent);
      parseIntent(getIntent());
  }
  
  private static String QUERY_EXTRA_KEY = "QUERY_EXTRA_KEY";
  
  private void parseIntent(Intent intent) {
      // If the Activity was started to service a Search request,
      // extract the search query.
      if (Intent.ACTION_SEARCH.equals(intent.getAction())) {
          String searchQuery = intent.getStringExtra(SearchManager.QUERY);
  
          // Perform the search, passing in the search query as an argument
          // to the Cursor Loader
          Bundle args = new Bundle();
          args.putString(QUERY_EXTRA_KEY, searchQuery);
  
          // Restart the Cursor Loader to execute the new query.
          getLoaderManager().restartLoader(0, args, this);
      }
  }
  
  public Loader&lt;Cursor&gt; onCreateLoader(int id, Bundle args) {
      String query = "0";
  
      if (args != null) {
          // Extract the search query from the arguments.
          query = args.getString(QUERY_EXTRA_KEY);
      }
  
      // Construct the new query in the form of a Cursor Loader.
      String[] projection = { TDAdb.KEY_ROWID, TDAdb.COL_RULETITLE };
      String where = TDAdb.COL_RULETITLE + " LIKE \"%" + query + "%\"";
      String[] whereArgs = null;
      String sortOrder = TDAdb.COL_RULETITLE;
  
      // Create the new Cursor loader.
      return new CursorLoader(this, TDAProvider.CONTENT_URI_RULES,
              projection, where, whereArgs, sortOrder);
  }
  
  public void onLoadFinished(Loader&lt;Cursor&gt; loader, Cursor cursor) {
      // Replace the result Cursor displayed by the Cursor Adapter with
      // the new result set.
      adapter.swapCursor(cursor);
  }
  
  public void onLoaderReset(Loader&lt;Cursor&gt; loader) {
      // Remove the existing result Cursor from the List Adapter.
      adapter.swapCursor(null);
  }
  
  }
  </code></pre>
  
  <p>Here's the content provider (TDAProvider.java), I do user some raw queries, but not for this example:</p>
  
  <pre><code>package com.birdsall.tda;
  
  import java.util.HashMap;
  
  import android.app.SearchManager;
  import android.content.ContentProvider;
  import android.content.ContentValues;
  import android.content.UriMatcher;
  import android.database.Cursor;
  import android.database.sqlite.SQLiteDatabase;
  import android.database.sqlite.SQLiteQueryBuilder;
  import android.net.Uri;
  import android.text.TextUtils;
  import android.util.Log;
  
  public class TDAProvider extends ContentProvider {
  
  private TDAdbHelper dbHelper;
  private static final String TAG = "TDAProvider";
  
  private static final int ALL_CHAPTERS = 1;
  private static final int SINGLE_CHAPTER = 2;
  private static final int ALL_RULES = 3;
  private static final int SINGLE_RULE = 4;
  private static final int ALL_RAW_QUERY = 5;
  private static final int SINGLE_RAW_QUERY = 6;
  private static final int SEARCH = 7;
  // authority is the symbolic name of your provider
  // To avoid conflicts with other providers, you should use
  // Internet domain ownership (in reverse) as the basis of your provider
  // authority.
  private static final String AUTHORITY = "com.birdsall.tda.contentprovidertda";
  
  // create content URIs from the authority by appending path to database
  // table
  public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY
          + "/chapters");
  
  public static final Uri CONTENT_URI_RULES = Uri.parse("content://"
          + AUTHORITY + "/rules");
  
  public static final Uri CONTENT_URI_RAWQUERY = Uri.parse("content://"
          + AUTHORITY + "/rawquery");
  
  // a content URI pattern matches content URIs using wildcard characters:
  // *: Matches a string of any valid characters of any length.
  // #: Matches a string of numeric characters of any length.
  private static final UriMatcher uriMatcher;
  static {
      uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
      uriMatcher.addURI(AUTHORITY, "chapters", ALL_CHAPTERS);
      uriMatcher.addURI(AUTHORITY, "chapters/#", SINGLE_CHAPTER);
      uriMatcher.addURI(AUTHORITY, "rules", ALL_RULES);
      uriMatcher.addURI(AUTHORITY, "rules/#", SINGLE_RULE);
      uriMatcher.addURI(AUTHORITY, "rawquery", ALL_RAW_QUERY);
      uriMatcher.addURI(AUTHORITY, "rawquery/#", SINGLE_RAW_QUERY);
      uriMatcher.addURI(AUTHORITY, SearchManager.SUGGEST_URI_PATH_QUERY,
              SEARCH);
      uriMatcher.addURI(AUTHORITY, SearchManager.SUGGEST_URI_PATH_QUERY
              + "/*", SEARCH);
      uriMatcher.addURI(AUTHORITY, SearchManager.SUGGEST_URI_PATH_SHORTCUT,
              SEARCH);
      uriMatcher.addURI(AUTHORITY, SearchManager.SUGGEST_URI_PATH_SHORTCUT
              + "/*", SEARCH);
  }
  
  // system calls onCreate() when it starts up the provider.
  @Override
  public boolean onCreate() {
      // get access to the database helper
      Log.i(TAG, "onCreate ");
      dbHelper = new TDAdbHelper(getContext());
      return false;
  }
  
  // Return the MIME type corresponding to a content URI
  @Override
  public String getType(Uri uri) {
      Log.i(TAG, "getType ");
      switch (uriMatcher.match(uri)) {
      case ALL_CHAPTERS:
          return "vnd.android.cursor.dir/vnd.com.birdsall.peter.contentprovidertda.chapters";
      case SINGLE_CHAPTER:
          return "vnd.android.cursor.item/vnd.com.birdsall.peter.contentprovidertda.chapters";
      case ALL_RULES:
          return "vnd.android.cursor.dir/vnd.com.birdsall.peter.contentprovidertda.rules";
      case SINGLE_RULE:
          return "vnd.android.cursor.item/vnd.com.birdsall.peter.contentprovidertda.rules";
      case ALL_RAW_QUERY:
          return "vnd.android.cursor.dir/vnd.com.birdsall.peter.contentprovidertda.rulesdescribed";
      case SINGLE_RAW_QUERY:
          return "vnd.android.cursor.item/vnd.com.birdsall.peter.contentprovidertda.rulesdescribed";
      case SEARCH:
          return SearchManager.SUGGEST_MIME_TYPE;
      default:
          throw new IllegalArgumentException("Unsupported URI: " + uri);
      }
  }
  
  private static final HashMap&lt;String, String&gt; SEARCH_PROJECTION_MAP;
  static {
      SEARCH_PROJECTION_MAP = new HashMap&lt;String, String&gt;();
      SEARCH_PROJECTION_MAP.put(SearchManager.SUGGEST_COLUMN_TEXT_1,
              TDAdb.COL_RULETITLE + " AS "
                      + SearchManager.SUGGEST_COLUMN_TEXT_1);
      SEARCH_PROJECTION_MAP.put("_id", TDAdb.KEY_ROWID + " AS " + "_id");
  }
  
  // The insert() method adds a new row to the appropriate table, using the
  // values
  // in the ContentValues argument. If a column name is not in the
  // ContentValues argument,
  // you may want to provide a default value for it either in your provider
  // code or in
  // your database schema.
  @Override
  public Uri insert(Uri uri, ContentValues values) {
  
      Log.i(TAG, "insert ");
      SQLiteDatabase db = dbHelper.getWritableDatabase();
      switch (uriMatcher.match(uri)) {
      case ALL_CHAPTERS:
          // do nothing
          break;
      default:
          throw new IllegalArgumentException("Unsupported URI: " + uri);
      }
      long id = db.insert(TDAdb.CHAPTER_TABLE, null, values);
      getContext().getContentResolver().notifyChange(uri, null);
      return Uri.parse(CONTENT_URI + "/" + id);
  }
  
  // The query() method must return a Cursor object, or if it fails,
  // throw an Exception. If you are using an SQLite database as your data
  // storage,
  // you can simply return the Cursor returned by one of the query() methods
  // of the
  // SQLiteDatabase class. If the query does not match any rows, you should
  // return a
  // Cursor instance whose getCount() method returns 0. You should return null
  // only
  // if an internal error occurred during the query process.
  // public Cursor query (Uri uri, String[] projection, String selection,
  // String[] selectionArgs,
  // String having, String groupby, String sortOrder, String limit,
  // CancellationSignal cancellationSignal) {
  public Cursor query(Uri uri, String[] projection, String selection,
          String[] selectionArgs, String sortOrder) {
  
      String id;
      Log.i(TAG, "query ");
  
      SQLiteDatabase db = dbHelper.getWritableDatabase();
      SQLiteQueryBuilder queryBuilder = new SQLiteQueryBuilder();
      // queryBuilder.setTables(TDAdb.CHAPTER_TABLE);
  
      switch (uriMatcher.match(uri)) {
      case ALL_CHAPTERS:
          // do nothing
          queryBuilder.setTables(TDAdb.CHAPTER_TABLE);
          break;
      case SINGLE_CHAPTER:
          queryBuilder.setTables(TDAdb.CHAPTER_TABLE);
          id = uri.getPathSegments().get(1);
          queryBuilder.appendWhere(TDAdb.KEY_ROWID + "=" + id);
          break;
      case ALL_RULES:
          // do nothing
          queryBuilder.setTables(TDAdb.RULE_TABLE);
          break;
      case SINGLE_RULE:
          queryBuilder.setTables(TDAdb.RULE_TABLE);
          id = uri.getPathSegments().get(1);
          queryBuilder.appendWhere(TDAdb.KEY_ROWID + "=" + id);
          break;
      case ALL_RAW_QUERY:
          db = dbHelper.getReadableDatabase();
          return db.rawQuery(selection, selectionArgs);
      case SINGLE_RAW_QUERY:
          db = dbHelper.getReadableDatabase();
          return db.rawQuery(selection, selectionArgs);
      case SEARCH:
          queryBuilder.setTables(TDAdb.RULE_TABLE);
          queryBuilder.appendWhere(TDAdb.COL_RULETITLE + " LIKE \"%"
                  + uri.getPathSegments().get(1) + "%\"");
          queryBuilder.setProjectionMap(SEARCH_PROJECTION_MAP);
          break;
      default:
          throw new IllegalArgumentException("Unsupported URI: " + uri);
      }
  
      Cursor cursor = queryBuilder.query(db, projection, selection,
              selectionArgs, null, null, sortOrder);
      Log.i(TAG, "query return cursor ");
      // Register the contexts ContentResolver to be notified if
      // the cursor result set changes.
      cursor.setNotificationUri(getContext().getContentResolver(), uri);
      return cursor;
  
  }
  
  // The delete() method deletes rows based on the seletion or if an id is
  // provided then it deleted a single row. The methods returns the numbers
  // of records delete from the database. If you choose not to delete the data
  // physically then just update a flag here.
  @Override
  public int delete(Uri uri, String selection, String[] selectionArgs) {
  
      Log.i(TAG, "delete ");
      SQLiteDatabase db = dbHelper.getWritableDatabase();
      switch (uriMatcher.match(uri)) {
      case ALL_CHAPTERS:
          // do nothing
          break;
      case SINGLE_CHAPTER:
          String id = uri.getPathSegments().get(1);
          selection = TDAdb.KEY_ROWID
                  + "="
                  + id
                  + (!TextUtils.isEmpty(selection) ? " AND (" + selection
                          + ')' : "");
          break;
      default:
          throw new IllegalArgumentException("Unsupported URI: " + uri);
      }
      int deleteCount = db.delete(TDAdb.CHAPTER_TABLE, selection,
              selectionArgs);
      getContext().getContentResolver().notifyChange(uri, null);
      return deleteCount;
  }
  
  // The update method() is same as delete() which updates multiple rows
  // based on the selection or a single row if the row id is provided. The
  // update method returns the number of updated rows.
  @Override
  public int update(Uri uri, ContentValues values, String selection,
          String[] selectionArgs) {
      Log.i(TAG, "update ");
      SQLiteDatabase db = dbHelper.getWritableDatabase();
      switch (uriMatcher.match(uri)) {
      case ALL_CHAPTERS:
          // do nothing
          break;
      case SINGLE_CHAPTER:
          String id = uri.getPathSegments().get(1);
          selection = TDAdb.KEY_ROWID
                  + "="
                  + id
                  + (!TextUtils.isEmpty(selection) ? " AND (" + selection
                          + ')' : "");
          break;
      default:
          throw new IllegalArgumentException("Unsupported URI: " + uri);
      }
      int updateCount = db.update(TDAdb.CHAPTER_TABLE, values, selection,
              selectionArgs);
      getContext().getContentResolver().notifyChange(uri, null);
      Log.i(TAG, "update return updateCount ");
      return updateCount;
  }
  
  }
  </code></pre>
  
  <p>Here's the database activity (TDAdb.java):</p>
  
  <pre><code>package com.birdsall.tda;
  
  import android.database.sqlite.SQLiteDatabase;
  import android.util.Log;
  
  public class TDAdb {
  
  public static final String LOG_TAG = "TDAdb";
  
  // tables
  public static final String CHAPTER_TABLE = "chapters";
  public static final String RULE_TABLE = "rules";
  public static final String INDEXHEADER_TABLE = "indexheader";
  public static final String KEYDESCRIPTORS_TABLE = "keydescriptors";
  public static String SQLITE_TABLE = "chapters";
  
  // Chapter Table Columns
  public static final String KEY_ROWID = "_id";
  public static final String COL_CHAPTER = "chapter";
  public static final String COL_CHAPTERTITLE = "chaptertitle";
  
  // Rule Table Columns
  public static final String COL_RULE = "rule";
  // public static final String COL_CHAPTER = "chapter";
  public static final String COL_KEYDESCRIPTOR = "keydescriptor";
  public static final String COL_RULETITLE = "ruletitle";
  public static final String COL_DESCR = "descr";
  public static final String COL_DESCRIPTION = "description"; // LongText
  public static final String COL_LABEL = "label";
  public static final String COL_USERLABEL = "userlabel";
  public static final String COL_LABELID = "labelid"; // Integer
  public static final String COL_USERLABELID = "userlabelid"; // Integer
  public static final String COL_TDTIP = "tdtip";
  public static final String COL_DEFUNCT = "defunct";
  public static final String COL_USCFREVISION = "uscfrevision";
  public static final String COL_HIGHLIGHT = "highlight"; // LongText
  public static final String COL_PAGENO = "pageno";
  public static final String COL_CHANGEDATE = "changedate"; // Integer
  public static final String COL_REFINC = "refinc";
  public static final String COL_RULEINC = "ruleinc";
  
  // keydescriptors table columns
  public static final String COL_KEYDESC = "keydesc";
  public static final String COL_IMAGEREFERENCE = "imagereference";
  
  // indexheader table columns
  public static final String COL_INDEX_HEADER = "index_header";
  public static final String COL_INDEXID = "indexid";
  public static final String COL_INDEXLEXICON = "indexlexicon";
  
  // columns defined in RAW Queries via AS
  public static final String COLRAW_XREFRULE = "xrefrule";
  public static final String COL_PROJ_THECOUNT = "count(*) as thecound";
  public static final String COLTHECOUNT = "thecound";
  
  public static final String[] PROJECTION_CHAPTER = { KEY_ROWID, COL_CHAPTER,
          COL_CHAPTERTITLE, };
  
  public static final String[] PROJECTION_RULES = { KEY_ROWID, COL_CHAPTER,
          COL_RULE, COL_RULETITLE, COL_KEYDESCRIPTOR, };
  
  /* ************** MAKE SURE THERE'S and _id *********************** */
  public static final String RAWQUERY_RULESDESCRIBED = "select rules._id, rule, chapter, ruletitle, rules.keydescriptor, keydesc FROM rules LEFT OUTER JOIN keydescriptors ON rules.keydescriptor = keydescriptors.keydescriptor WHERE chapter = ? group by 1, 2, 3, 4, 5 order by 1, 4";
  public static final String RAWQUERY_RULESCROSSREF = "SELECT rules._id, rules.rule, rules.ruletitle,  rulereferences.rule AS xrefrule FROM rulereferences INNER JOIN rules ON rulereferences.rulereference = rules.rule WHERE (((rules.keydescriptor)='2') AND ((rulereferences.rule)= ? )) ORDER BY rules.rule";
  public static final String RAWQUERY_RULESCROSSREFDETAIL = "SELECT rules._id, rules.rule, rules.ruletitle, keydescriptors.keydesc FROM rules INNER JOIN keydescriptors ON rules.keydescriptor = keydescriptors.keydescriptor WHERE (((rules.rule)= ? )) GROUP BY rules.rule, rules.ruletitle, keydescriptors.keydesc ORDER BY rules.rule, Min(rules.keydescriptor)";
  public static final String RAWQUERY_INDEX = "SELECT DISTINCT _id, indexlexicon FROM indexheader GROUP BY 2 ORDER BY 2";
  public static final String RAWQUERY_INDEXCHILD = "SELECT indexheader._id, indexheader.index_header, indexer.rule, indexheader.indexid, rules.pageno, rules.uscfrevision, rules.defunct FROM (indexheader LEFT JOIN indexer ON indexheader.indexid = indexer.indexid) LEFT JOIN rules ON indexer.rule = rules.rule WHERE (((indexheader.indexlexicon)= ? )) GROUP BY indexheader._id, indexheader.index_header, indexer.rule, indexheader.indexid, rules.pageno, rules.uscfrevision, rules.defunct HAVING (((rules.pageno) Is Not Null)) ORDER BY indexheader.index_header, indexheader.indexid";
  public static final String RAWQUERY_RULEDETAIL = "SELECT rules.rule, rules.ruletitle, rules.descr, rules.description, rules.keydescriptor, rules.tdtip, rules.uscfrevision, rules.defunct, rules.highlight, rules.label, rules.userlabel, rules.changedate FROM rules GROUP BY 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 HAVING (((rules.rule)= ? )) ORDER BY 1, 5";
  public static final String RAWQUERY_LABEL = "select distinct _id, label, count(*) as thecount from rules group by 2 order by label";
  public static final String RAWQUERY_LABELDETAIL = "SELECT rules._id, rules.rule, rules.ruletitle, keydescriptors.keydesc FROM rules INNER JOIN keydescriptors ON rules.keydescriptor = keydescriptors.keydescriptor WHERE (((rules.label)= ? )) GROUP BY rules.rule, rules.ruletitle, keydescriptors.keydesc ORDER BY rules.rule, Min(rules.keydescriptor)";
  
  public static void onCreate(SQLiteDatabase db) {
  
      Log.i(LOG_TAG, "onCreate");
  }
  
  public static void onUpgrade(SQLiteDatabase db, int oldVersion,
          int newVersion) {
      Log.w(LOG_TAG, "Upgrading database from version " + oldVersion + " to "
              + newVersion + ", which will destroy all old data");
  
      onCreate(db);
  }
  }
  </code></pre>
  
  <p>And here is the database helper (TDAdbHelper.java):</p>
  
  <pre><code>package com.birdsall.tda;
  
  import java.io.FileOutputStream;
  import java.io.IOException;
  import java.io.InputStream;
  import java.io.OutputStream;
  
  import android.content.Context;
  import android.database.Cursor;
  import android.database.SQLException;
  import android.database.sqlite.SQLiteDatabase;
  import android.database.sqlite.SQLiteOpenHelper;
  import android.util.Log;
  
  public class TDAdbHelper extends SQLiteOpenHelper {
  
  public static String DATABASE_PATH;
  public static final String DATABASE_NAME = "tda.db";
  private static final int DATABASE_VERSION = 1;
  private Context context;
  private SQLiteDatabase db;
  
  public TDAdbHelper(Context context) {
      super(context, DATABASE_NAME, null, DATABASE_VERSION);
      this.context = context;
      String packageName = context.getPackageName();
      DATABASE_PATH = String.format("//data//data//%s//databases//",
              packageName);
      Log.i(this.getClass().toString(), "... before calling openDatabase ");
      openDataBase();
      Log.i(this.getClass().toString(), "... after return openDatabase ");
  }
  
  @Override
  public void onCreate(SQLiteDatabase db) {
      Log.i(this.getClass().toString(), "... Starting TDAdb.onCreate ");
      TDAdb.onCreate(db);
  }
  
  @Override
  public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
      TDAdb.onUpgrade(db, oldVersion, newVersion);
  }
  
  // Performing a database existence check
  private boolean checkDataBase() {
      Log.i(this.getClass().toString(), "... Starting checkDatabase ");
      SQLiteDatabase checkDb = null;
      try {
          String path = DATABASE_PATH + DATABASE_NAME;
          checkDb = SQLiteDatabase.openDatabase(path, null,
                  SQLiteDatabase.OPEN_READONLY);
      } catch (SQLException e) {
          Log.e(this.getClass().toString(), "Error while checking db");
      }
      // Android doesn’t like resource leaks, everything should
      // be closed
      if (checkDb != null) {
          checkDb.close();
      }
      return checkDb != null;
  }
  
  // Method for copying the database
  private void copyDataBase() throws IOException {
      // Open a stream for reading from our ready-made database
      // The stream source is located in the assets
      Log.i(this.getClass().toString(), "... in copyDataBase ");
      InputStream externalDbStream = context.getAssets().open(DATABASE_NAME);
  
      // Path to the created empty database on your Android device
      String outFileName = DATABASE_PATH + DATABASE_NAME;
  
      // Now create a stream for writing the database byte by byte
      OutputStream localDbStream = new FileOutputStream(outFileName);
  
      // Copying the database
      byte[] buffer = new byte[1024];
      int bytesRead;
      while ((bytesRead = externalDbStream.read(buffer)) &gt; 0) {
          localDbStream.write(buffer, 0, bytesRead);
      }
      // Don’t forget to close the streams
      localDbStream.close();
      externalDbStream.close();
  }
  
  // This piece of code will create a database if it’s not yet created
  public void createDataBase() {
      Log.i(this.getClass().toString(), "... in createDataBase ");
      boolean dbExist = checkDataBase();
      if (!dbExist) {
          this.getReadableDatabase();
          try {
              copyDataBase();
          } catch (IOException e) {
              Log.e(this.getClass().toString(), "Copying error");
              throw new Error("Error copying database!");
          }
      } else {
          Log.i(this.getClass().toString(), "Database already exists");
      }
  }
  
  public SQLiteDatabase openDataBase() throws SQLException {
      String path = DATABASE_PATH + DATABASE_NAME;
      Log.i(this.getClass().toString(), "Starting openDatabase " + path);
      if (db == null) {
          createDataBase();
          db = SQLiteDatabase.openDatabase(path, null,
                  SQLiteDatabase.OPEN_READWRITE);
      }
  
      return db;
  }
  
  }
  </code></pre>
  
  <p>For completeness there is the main activity (ActivityMain.java), it's as simple a Hello World:</p>
  
  <pre><code>package com.birdsall.tda;
  
  import android.os.Bundle;
  import android.app.Activity;
  import android.view.Menu;
  
  public class ActivityMain extends Activity {
  
  @Override
  protected void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      setContentView(R.layout.activity_main);
  }
  
  
  }
  </code></pre>
  
  <p>And the simple layout for the main activity (activity_main.xml):</p>
  
  <pre><code>&lt;RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
  xmlns:tools="http://schemas.android.com/tools"
  android:layout_width="match_parent"
  android:layout_height="match_parent"
  android:paddingBottom="@dimen/activity_vertical_margin"
  android:paddingLeft="@dimen/activity_horizontal_margin"
  android:paddingRight="@dimen/activity_horizontal_margin"
  android:paddingTop="@dimen/activity_vertical_margin"
  tools:context=".ActivityMain"
       &gt;
  
  &lt;TextView
      android:id="@+id/textView1"
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:layout_alignParentLeft="true"
      android:layout_alignParentTop="true"
      android:layout_marginLeft="64dp"
      android:layout_marginTop="22dp"
      android:text="Test Search - using hardware button. Search for 'check'"
      android:textAppearance="?android:attr/textAppearanceMedium" /&gt;
  
  &lt;/RelativeLayout&gt;
  </code></pre>
  
  <p>So if you have any idea on how to fix or debug this issue, I would appreciate it. Remember I new to Android Development, so a few words as to the why would also be helpful.  </p>
  
  <p>Have a great day.</p>