2012-11-26 18 views
10

Sto leggendo this tutorial sull'implementazione del mio ContentProvide per lavorare con SQLite. Int il ContentProvider.query ci sono alcune cose che mi imbarazza. Sembra molto codificato a un solo tavolo (il tavolo da gioco nel tutorial), ma forse non lo capisco? Ora se volessi interrogare un'altra tabella, diciamo nodo, come cambierei il ContentProvider?Own ContentProvider con SQLite e tabelle multiple

Devo aggiungere in qualche modo i nomi delle tabelle in queryBuilder.setTables (String inTables)?

E i CONTENT_TYPE e CONTENT_ITEM_TYPE, dovrebbe essercene uno per ogni tabella?

Che cosa circa le varibili TODO e TODO_ID e lo switch nel metodo di query?

Sembra che sia necessario avere un sacco di condizioni if ​​/ switch per supportare più tabelle con lo stesso ContentProvider, è questa la strada da percorrere o sono su un percorso sbagliato?

Grazie
Søren

+0

1. setTables ... Dipende dalle vostre esigenze, se avete bisogno di unirsi a voi dovrebbe, ma ancora puntare 2 ... 2. Contenuto mime ... Sì 3. Ancora per ogni tabella. 4. Percorso errato ... No, penso che un buon percorso ... Puoi provare a cercare/scrivere qualche tipo di generatore fx http://selvin.pl/autocontent.zip <= il mio ma non è ancora supportato solo tabelle – Selvin

risposta

27

Ora, se ho voluto per interrogare un altro tavolo, diciamo nodo, come vorrei cambiare il ContentProvider?

Interrogazione di un nuovo tavolo significherebbe che è necessario aggiungere un nuovo Uri, dal momento che la Uri seleziona l'origine dati, simile ad usare una tabella diversa.

Si aggiungerebbero essenzialmente tutti i valori codificati che sono già presenti per gli altri per l'altra tabella. Per esempio:

// ------- usually the same for all 
private static final String AUTHORITY = "de.vogella.android.todos.contentprovider"; 

// ------- define some Uris 
private static final String PATH_TODOS = "todos"; 
private static final String PATH_REMINDERS = "reminders"; 

public static final Uri CONTENT_URI_TODOS = Uri.parse("content://" + AUTHORITY 
    + "/" + PATH_TODOS); 
public static final Uri CONTENT_URI_REMINDERS = Uri.parse("content://" + AUTHORITY 
     + "/" + PATH_REMINDERS); 

// ------- maybe also define CONTENT_TYPE for each 

// ------- setup UriMatcher 
private static final int TODOS = 10; 
private static final int TODO_ID = 20; 
private static final int REMINDERS = 30; 
private static final int REMINDERS_ID = 40; 
private static final UriMatcher sURIMatcher = new UriMatcher(UriMatcher.NO_MATCH); 
static { 
    sURIMatcher.addURI(AUTHORITY, PATH_TODOS, TODOS); 
    sURIMatcher.addURI(AUTHORITY, PATH_TODOS + "/#", TODO_ID); 
    sURIMatcher.addURI(AUTHORITY, PATH_REMINDERS, REMINDERS); 
    sURIMatcher.addURI(AUTHORITY, PATH_REMINDERS + "/#", REMINDERS_ID); 
} 

//@Override 
public Cursor query(Uri uri, String[] projection, String selection, 
     String[] selectionArgs, String sortOrder) { 

    // Using SQLiteQueryBuilder instead of query() method 
    SQLiteQueryBuilder queryBuilder = new SQLiteQueryBuilder(); 

    int uriType = sURIMatcher.match(uri); 
    switch (uriType) { 

     case TODO_ID: 
      // Adding the ID to the original query 
      queryBuilder.appendWhere(TodoTable.COLUMN_ID + "=" 
        + uri.getLastPathSegment()); 
      //$FALL-THROUGH$ 
     case TODOS: 
      queryBuilder.setTables(TodoTable.TABLE_TODO); 
      break; 

     case REMINDERS_ID: 
      // Adding the ID to the original query 
      queryBuilder.appendWhere(ReminderTable.COLUMN_ID + "=" 
        + uri.getLastPathSegment()); 
      //$FALL-THROUGH$ 
     case REMINDERS: 
      queryBuilder.setTables(ReminderTable.TABLE_REMINDER); 
      break; 

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

Devo aggiungere i nomi di tabella in qualche modo in queryBuilder.setTables (String inTables)?

Sì, se diverso Uri viene letto da tabelle diverse, quindi impostare la tabella in base alla corrispondenza Uri.

E riguardo il CONTENT_TYPE e il CONTENT_ITEM_TYPE, dovrebbe essercene uno per ogni tabella?

Dipende dal tipo di contenuto effettivo. Se sono diversi e hai bisogno di un tipo si. Ma non è necessario averli affatto. Quell'esempio li definisce ma non li usa nemmeno. Dovrebbe essere necessario restituire il tipo in getType, vedere documentation.

Che cosa circa le varibili TODO e TODO_ID e lo switch nel metodo di query?

Questi sono costanti definite per la UriMatcher che si spiega ben here. È fondamentalmente una semplificazione per la corrispondenza delle stringhe. Un grande ContentProvider può avere 100 diversi Uris e selezionare la tabella giusta in query sarebbe doloroso se fosse necessario scrivere if (uri.getPath().equals("todos") { /* code */ } else if (uri.. fino in fondo.

+0

ciao, come implementeresti il ​​metodo di cancellazione in questo caso? puoi per favore aiutare? – JoaoFilipeClementeMartins

1

Ecco la domanda solution, utilizzando UriMatcher, è possibile implementare più tabelle in un provider di contenuti.

0

Tipo di contenuto ed elemento di contenuto possono essere come segue e possono essere avvolti in una classe separata per ogni tabella

public static final String GENERAL_CONTENT_TYPE = "vnd.android.cursor.dir/vnd.myfirstapp.db.member" ; public static final String SPECIFIC_CONTENT_TYPE = "vnd.android.cursor.item/vnd.myfirstapp.db.member" ;

`vnd.android.cursor.dir/vnd.yourownanything.anything.tablename '

questo definisce il tipo di contenuto generale `vnd.android.cursor.item/vnd.anthingasabove.table' questo definisce anche la specifica ed è costante per qualsiasi applicazione quelle stringhe (parole) vnd.android.cursor .dir e .item devono essere così e dopo/vnd. deve essere come quella

e nella classe che estende ContentProvider appena g_developer la stessa istanza di UriMatcher per mappare le tabelle

Problemi correlati