0

Ich möchte Vorschläge von meiner DB-Tabelle erhalten, während Sie SearchView verwenden.IllegalArgumentException: Ungültige Spalte - SEARCHVIEW

ich Illegal: Ungültige Spalte (Name der Spalte)

private static final HashMap<String, String> mColumnMap = buildColumnMap(); 

    //Build a map for all columns that may be requested, which will be given to SQLiteQueryBuilder. 
    //This allow ContentProvider to request columns without the need to know real column names and 
    //create the alias itself 
    private static HashMap<String, String> buildColumnMap() { 
     HashMap<String, String> map = new HashMap<String, String>(); 

     map.put(SearchManager.SUGGEST_COLUMN_TEXT_1, "rowid AS " + 
       CookingContract.FoodEntry.COLUMN_NAME); 
     map.put(SearchManager.SUGGEST_COLUMN_TEXT_2, "rowid AS " + 
       CookingContract.FoodEntry.COLUMN_DESCRIPTION); 
     map.put(SearchManager.SUGGEST_COLUMN_INTENT_DATA_ID, "rowid AS " + CookingContract.FoodEntry._ID); 


     return map; 
    } 


    //Return a Cursor over all words that match the given query 
    public Cursor getWordMatches(String query, String[] columns) { 
     String selection = CookingContract.FoodEntry.COLUMN_NAME + " LIKE ?"; 
     String[] selectionArgs = new String[]{"%" + query + "%"}; 

     return query(selection, selectionArgs, columns); 
    } 

    //The SQLiteBuilder provides a map for all possible columns requested to actual columns in the 
    //DB, creating a simple column alias mechanism by which the ContentProvider doesn't need to know 
    //the real column names 
    private Cursor query(String selection, String[] selectionArgs, String[] columns) { 
     SQLiteQueryBuilder builder = new SQLiteQueryBuilder(); 
     builder.setTables(CookingContract.FoodEntry.TABLE_NAME); 
     builder.setProjectionMap(mColumnMap); 


     Cursor cursor = builder.query(getReadableDatabase(), 
       columns, selection, selectionArgs, null, null, null); 

     if (cursor == null) { 
      return null; 
     } else if (!cursor.moveToFirst()) { 
      cursor.close(); 
      return null; 
     } 
     return cursor; 
    } 
} 

Hier ist ein Teil des Codes meines Contentprovider ist

public Cursor query(Uri uri, String[] projection, String selection, 
        String[] selectionArgs, String sortOrder) { 
    Cursor retCursor; 
    switch (sUriMatcher.match(uri)) { 

     case SEARCH_SUGGEST: 

      if (selectionArgs == null) { 
       throw new IllegalArgumentException(
         "selectionArgs must be provided for the Uri: +"uri"); 
      } 
      return getSuggestions(selectionArgs[0]); 

     default: 
      throw new UnsupportedOperationException("Unknown uri: " + uri); 
    } 

    retCursor.setNotificationUri(getContext().getContentResolver(), uri); 
    return retCursor; 
} 

private Cursor getSuggestions(String query) { 
    query = query.toLowerCase(); 
    String[] columns = new String[]{ 
      CookingContract.FoodEntry._ID, 
      CookingContract.FoodEntry.COLUMN_NAME, 
      CookingContract.FoodEntry.COLUMN_DESCRIPTION, 

    }; 
    return cookingDBHelper.getWordMatches(query, columns); 
} 

Mit setProjectionMap ich soll in der Lage sein zu sagen, Android welchen Namen meine Spalten haben und unter Berücksichtigung der SearchManager-Einschränkungen ... Was mache ich falsch?

Antwort

0

Ich denke, Ihre Projektionskarte (mColumnMap) nicht korrekt ist, was Sie haben, ist dies:

map.put(SearchManager.SUGGEST_COLUMN_TEXT_1, "rowid AS " + 
      CookingContract.FoodEntry.COLUMN_NAME); 
map.put(SearchManager.SUGGEST_COLUMN_TEXT_2, "rowid AS " + 
      CookingContract.FoodEntry.COLUMN_DESCRIPTION); 
map.put(SearchManager.SUGGEST_COLUMN_INTENT_DATA_ID, "rowid AS " + 
      CookingContract.FoodEntry._ID); 

Dies bedeutet, dass Sie die Spalten in der folgenden Art und Weise zuordnen:

SUGGEST_COLUMN_NAME -> rowid AS COLUMN_NAME 
SUGGEST_COLUMN_TEXT_2 -> rowid AS COLUMN_DESCRIPTION 
SUGGEST_COLUMN_INTENT_DATA_ID -> rowid AS _ID 

Wenn die Der Query Builder verwendet Ihre Map. Er benennt die Spaltennamen in die als Werte auf der Karte angegebenen um, aber gemäß den Spalten, die Sie als Schlüssel auf der Karte bereitstellen, wird keine der aktuellen Spalten, die Sie abfragen, korrekt zugeordnet.

Die obigen Spalten können nicht korrekt zugeordnet werden, da keine von ihnen als Schlüssel auf der Projektionskarte existiert.

Einige Beispiele zur Kartenprojektion und warum es nützlich ist, finden Sie unter this question.

Unter Berücksichtigung der Führung auf custom suggestions, der Cursor wird wieder erwartet, dass mindestens zwei Spalten enthalten: _ID und SUGGEST_COLUMN_TEXT_1, so würde ich Ihnen vorschlagen, um Ihre Karte zu dem folgenden ändern:

map.put(CookingContract.FoodEntry._ID, 
      CookingContract.FoodEntry._ID + " as " + SearchManager._ID); 
map.put(CookingContract.FoodEntry.COLUMN_NAME, 
      CookingContract.FoodEntry.COLUMN_NAME + " as " + SearchManager.SUGGEST_COLUMN_TEXT_1); 
map.put(CookingContract.FoodEntry.COLUMN_DESCRIPTION, 
      CookingContract.FoodEntry.COLUMN_DESCRIPTION + " as " + SearchManager.SUGGEST_COLUMN_TEXT_2); 
Damit

die Spalten Karte Ihr in der folgenden Art und Weise abgebildet werden bieten:

FoodEntry._ID -> _ID 
FoodEntry.COLUMN_NAME -> FoodEntry.COLUMN_NAME as SUGGEST_COLUMN_TEXT_1 
FoodEntry.COLUMN_DESCRIPTION -> FoodEntry.COLUMN_DESCRIPTION as SUGGEST_COLUMN_TEXT_2 

Beachten Sie, dass ich die SUGGEST_COLUMN_INTENT_DATA_ID Spalte weggelassen, weil ich nicht weiß whi ch Spalte, die Sie verwenden, um die Datenbank nach einem einzelnen Datensatz abzufragen, könnte es entweder rowId oder _ID sein, können Sie die Projektion Karte nach Ihren Bedürfnissen anpassen.

Stellen Sie auch sicher, dass Sie die android:searchSuggestIntentAction in your manifest konfigurieren, um eine Aktion ordnungsgemäß zu behandeln.

Hoffen, dass dies das Denken über die Ausnahme klarer macht.

+0

Ich bearbeitet meinen Code und jetzt bekomme ich die folgende Fehlermeldung: Suchvorschläge abfragen warf eine Ausnahme. 'android.database.sqlite.SQLiteException: keine solche Spalte: suggest_text_1 (Code 1):, beim Kompilieren: SELECT _id, suggest_text_1, suggest_text_2 FROM Essen WHERE (name LIKE?)' – Alex

+0

Es funktioniert! Danke, das Problem war, wie du die Aliasnamen sagst – Alex