2012-11-26 16 views
10

मैं SQLite के साथ काम करने के लिए अपने स्वयं के ContentProvide को लागू करने पर this tutorial पढ़ रहा हूं। IntP ContentProvider.query कुछ चीजें हैं जो मुझे पहेली बनाती हैं। यह सिर्फ एक टेबल (ट्यूटोरियल में टोडो टेबल) के लिए बहुत कठिन लगता है, लेकिन शायद मैं इसे प्राप्त नहीं कर रहा हूं? अब अगर मैं एक और टेबल पूछना चाहता हूं, तो कहें, मैं ContentProvider कैसे बदलूं?SQLite और एकाधिक तालिकाओं के साथ स्वयं सामग्री प्रदाता

क्या मुझे क्वेरीबिल्डर.सेटटेबल्स (स्ट्रिंग इनटेबल्स) में टेबल नामों को किसी भी तरह जोड़ना चाहिए?

CONTENT_TYPE और CONTENT_ITEM_TYPE के बारे में क्या, प्रत्येक तालिका के लिए एक होना चाहिए?

TODO और TODO_ID varibles और क्वेरी विधि में स्विच के बारे में क्या है?

ऐसा लगता है कि मुझे एक ही सामग्री प्रदाता के साथ एकाधिक तालिकाओं का समर्थन करने के लिए बहुत सी if/switch शर्तों की आवश्यकता है, क्या यह गलत रास्ते पर जाने या जाने का तरीका है?

धन्यवाद
सोरेन

+0

1. setTables ... यह अपनी आवश्यकताओं पर निर्भर करता है मैप करने के लिए यदि आप में शामिल होने के लिए आपको लेकिन अभी भी बात की जरूरत है 2 ... 2. सामग्री माइम ... हाँ 3. फिर से प्रत्येक टेबल के लिए। 4. गलत रास्ता ... नहीं, मुझे लगता है कि एक अच्छा रास्ता ... आप किसी प्रकार के जनरेटर fx को खोजने/लिखने का प्रयास कर सकते हैं http://selvin.pl/autocontent.zip <= इसकी मेरा लेकिन यह अभी तक समर्थन विचार नहीं है केवल टेबल्स – Selvin

उत्तर

27

अब अगर मैं एक और तालिका क्वेरी करने के लिए चाहता था, की सुविधा देता है Nodo कहता हूँ, मैं ContentProvider कैसे बदल जाएगा?

एक नया टेबल का पता कर रहा मतलब यह होगा कि आप एक नया Uri जोड़ने की जरूरत है के बाद से Uri डेटा स्रोत, एक अलग तालिका का उपयोग करने के लिए इसी तरह की चयन करता है।

आप अनिवार्य रूप से सभी हार्डकोडेड मान जोड़ रहे होंगे जो आपकी अन्य तालिका के लिए पहले से ही टोडोस के लिए हैं। उदाहरण के लिए:

// ------- 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); 
    } 

मैं queryBuilder.setTables (स्ट्रिंग inTables) में किसी भी तरह की मेज के नाम संलग्न करना चाहिए?

हां, यदि विभिन्न Uri अलग-अलग तालिकाओं से पढ़े गए हैं तो यूरी मैच के आधार पर तालिका सेट करें।

CONTENT_TYPE और CONTENT_ITEM_TYPE के बारे में क्या, प्रत्येक तालिका के लिए एक होना चाहिए?

वास्तविक सामग्री प्रकार पर निर्भर करता है। यदि वे अलग हैं और आपको एक प्रकार की हां की आवश्यकता है। लेकिन आपको उन्हें बिल्कुल रखने की ज़रूरत नहीं है। वह उदाहरण उन्हें परिभाषित करता है लेकिन उनका उपयोग भी नहीं करता है। इसे getType में टाइप करने की आवश्यकता होगी, documentation देखें।

TODO और TODO_ID varibles और क्वेरी विधि में स्विच के बारे में क्या है?

उन UriMatcher जो अच्छी तरह से समझाया गया है here के लिए परिभाषित स्थिरांक हैं। यह मूल रूप से स्ट्रिंग मिलान के लिए एक सरलीकरण है। एक बड़ा ContentProvider में 100 अलग-अलग यूरी हो सकते हैं और query में सही तालिका का चयन करना दर्दनाक होगा यदि आपको if (uri.getPath().equals("todos") { /* code */ } else if (uri.. लिखना होगा।

+0

नमस्ते, आप इस मामले में डिलीट विधि को कैसे कार्यान्वित करेंगे? क्या आप मदद कर सकते हैं? – JoaoFilipeClementeMartins

1

UriMatcher का उपयोग करके, आपके प्रश्न पर solution है, आप सामग्री प्रदाता में एकाधिक तालिकाओं को लागू कर सकते हैं।

0

सामग्री प्रकार और सामग्री मद के रूप में इस प्रकार है और वे एक मेज

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 के लिए एक अलग वर्ग में लिपटे जा सकता है हो सकता है यह भी विशिष्ट परिभाषित करता है और यह किसी भी अनुप्रयोग उन तार (शब्द) vnd.android.cursor को स्थिर है '

यह सामान्य सामग्री प्रकार `vnd.android.cursor.item/vnd.anthingasabove.table को परिभाषित करता है' .dir और .item उस तरह और/vnd के बाद होना चाहिए। कि

की तरह होना चाहिए और वर्ग है कि आप contentprovider फैली में सिर्फ UriMatcher का एक ही उदाहरण uset टेबल

संबंधित मुद्दे