32

मैं अपना ऐप सेट अप कर रहा हूं ताकि लोग अपने दोस्तों के समूह बना सकें। जब कोई समूह बनाया जाता है, तो यह SQL डेटाबेस में 2 टेबल लिखता है। पहली तालिका में समूह का नाम और समूह आईडी है। दूसरी तालिका में 2 कॉलम, एक समूह आईडी और उपयोगकर्ता आईडी है। यह ठीक काम कर रहा है।एक कर्सरलोडर के साथ एंड्रॉइड में SQLite डीबी कैसे पढ़ा जाए?

हालांकि, अब मैं डेटाबेस से पढ़ने में सक्षम होना चाहता हूं। मैं cursorloader के साथ एक सूचीदृश्य खंड का उपयोग कर रहा हूं लेकिन मुझे जानकारी प्रदर्शित करने में परेशानी हो रही है। मैं अपनी सूची दृश्य में पहली तालिका से सभी समूह नामों को सूचीबद्ध करना चाहता हूं।

मेरे समस्या यह है कि, जब मैं पहली बार cursorloadercontent provider से onCreateLoader विधि में इस्तेमाल अपने संपर्कों को सूचीबद्ध करने के लिए, मैं एक Uri उपयोग कर रहा था है। विशेष रूप से ContactsContracts.Contacts कक्षा से CONTENT_URI था।

cursorloadercontentprovider साथ का उदाहरण:

@Override 
public Loader<Cursor> onCreateLoader(int i, Bundle bundle) { 
    Uri contentUri = ContactsContract.Contacts.CONTENT_URI; 
    return new CursorLoader(getActivity(),contentUri,PROJECTION,SELECTION,ARGS,ORDER); 
} 

हालांकि, एक सामग्री प्रदाता का उपयोग किए बिना, मैं क्या onCreateLoader विधि में डालने के लिए क्योंकि return new CursorLoader(...) दूसरा तर्क में एक Uri की आवश्यकता है पता नहीं है।

कोई सुझाव है कि मैं सूचीदृश्य में अपना डेटाबेस डेटा कैसे प्रदर्शित कर सकता हूं?

टुकड़ा वर्ग कोड:

public class GroupListFragment extends ListFragment implements LoaderManager.LoaderCallbacks<Cursor> { 

CursorAdapter mAdapter; 
private OnItemSelectedListener listener; 
private static final String[] PROJECTION ={GroupContract.GroupDetails.COLUMN_NAME_GROUP_NAME}; 
private static final String SELECTION = null; 
final String[] FROM = {GroupContract.GroupDetails.COLUMN_NAME_GROUP_NAME}; 
final int[] TO = {android.R.id.text1}; 
private static final String[] ARGS = null; 
private static final String ORDER = null; 
private Cursor c; 


@Override 
public void onCreate(Bundle savedInstanceState){ 
    super.onCreate(savedInstanceState); 
    mAdapter = new SimpleCursorAdapter(getActivity(), android.R.layout.simple_list_item_1,null,FROM,TO,0); 
    ReadDBAsync readDB = new ReadDBAsync(); 
    readDB.execute(); 
} 

@Override 
public void onActivityCreated(Bundle savedInstanceState){ 
    super.onActivityCreated(savedInstanceState); 
    setListAdapter(mAdapter); 
    getLoaderManager().initLoader(0,null,this); 
} 

@Override 
public Loader<Cursor> onCreateLoader(int i, Bundle bundle) { 
    Uri contenturi = Uri.parse("content://preamble.oneapp"); 
    Uri tableuri = Uri.withAppendedPath(contenturi,GroupContract.GroupDetails.TABLE_NAME); 
    return new CursorLoader(getActivity(),tableuri,PROJECTION,SELECTION,ARGS,ORDER); 
} 

@Override 
public void onLoadFinished(Loader<Cursor> cursorLoader, Cursor cursor) { 
    mAdapter.swapCursor(cursor); 
} 

@Override 
public void onLoaderReset(Loader<Cursor> cursorLoader) { 
    mAdapter.swapCursor(null); 
} 


private class ReadDBAsync extends AsyncTask<Void,Void,String> { 

    @Override 
    protected String doInBackground(Void... voids) { 

     ContractDBHelpers mDBHelper = new ContractDBHelpers(getActivity()); 
     SQLiteDatabase db = mDBHelper.getReadableDatabase(); 
     String returnvalue = "database read"; 
     c = db.query(GroupContract.GroupDetails.TABLE_NAME,PROJECTION,null,null,null,null,null); 
     return returnvalue; 
    } 

    @Override 
    protected void onPostExecute(String result){ 
     Toast.makeText(getActivity(), result, Toast.LENGTH_LONG).show(); 
    } 
} 

} 
+0

क्या आपने अपना डेटाबेस प्रबंधित करने के लिए कोई सामग्री प्रदाता बनाया है? – user936414

+0

@ user936414 नहीं, क्या यह आवश्यक है? ऐसा करने के लाभ/नुकसान क्या हैं? संपादित करें: बस इसे पढ़ें, मुझे डेटा को एकाधिक अनुप्रयोगों में साझा करने की आवश्यकता नहीं है इसलिए मुझे आपकी जानकारी के लिए सामग्री प्रदाता –

उत्तर

35

ये एक सूची टुकड़ा

1) में एक cursorloader बनाने के लिए चरण एक वर्ग SQLiteOpenHelper विस्तार बनाएँ और onCreate और onUpgrade अपने टेबल बनाने के लिए ओवरराइड कर रहे हैं।

2) ContentProvider का विस्तार करने वाली कक्षा बनाएं और अपने डेटाबेस तक पहुंचने के लिए यूआरआई बनाएं। http://developer.android.com/guide/topics/providers/content-providers.html देखें। यूआरआई से मेल खाने के लिए onCreate, onUpdate, क्वेरी, आदि (ओवरराइड विधियों) में URIMatcher पर अपने यूआरआई जोड़ें। http://developer.android.com/reference/android/content/UriMatcher.html

3) सम्मिलित विधि में getContext().getContentResolver().notifyChange(uri, null) पर कॉल करें। क्वेरी विधि में सम्मिलन परिवर्तन के लिए सामग्री प्रदाता को लौटने से पहले अपने लोडर को स्वचालित रूप से प्रतिबिंबित करने के लिए setNotificationUri(ContentResolver cr, Uri uri) पर कॉल करें। (https://stackoverflow.com/a/7915117/936414)।

4) onCreateLoader में उस यूआरआई को दें।

नोट: सामग्री प्रदाता के बिना, सूची में परिवर्तनों का स्वचालित रीफ्रेशिंग वर्तमान एंड्रॉइड संस्करण के रूप में व्यवहार्य नहीं है। यदि आप अपने कंटेंटप्रोवाइडर को दिखाना नहीं चाहते हैं, तो निर्यात में विशेषता को गलत में प्रकट करें। या डेटाबेस से डेटा पुनर्प्राप्त करने के लिए आप अपने कस्टम कर्सर लोडर को https://stackoverflow.com/a/7422343/936414 में कार्यान्वित कर सकते हैं। लेकिन इस मामले में डेटा का स्वचालित रीफ्रेशिंग संभव नहीं है

+9

धन्यवाद की आवश्यकता नहीं है, मैं इसे देख लूंगा। मुझे यह अजीब लगता है कि मेरे विकल्प 'ContentProvider' (जिसे मुझे अन्यथा आवश्यक नहीं है) का उपयोग करना है या अपना स्वयं का कस्टम' कर्सर लोडर '(जो अतिरिक्त कार्य प्रतीत होता है) का उपयोग करना है ... बिना डेटाबेस के पूछताछ नहीं करेगा 'कंटेंट प्रदाता' इतना आम है कि वे पहले से ही अतिरिक्त काम किए बिना ऐसा करने का कोई तरीका बनाते? –

+0

Contentprovider होने के कारणों में से एक यह है कि डेटाबेस में सामग्री बदलते समय वे सभी पंजीकृत पर्यवेक्षकों (कर्सर लोडर में पंजीकृत) को सूचित कर सकते हैं। – user936414

+5

क्या यह एक प्रकार का डेटा है जो नहीं बदलेगा? मुझे 'ContentProvider' का उपयोग करने के लिए मजबूर होना बहुत अजीब लगता है। स्थिर स्क्लाइट डेटा के लिए कोई तेज/हल्का समाधान नहीं है? –

62

एंड्रॉइड गाइड ContentProvider बनाने का सुझाव देता है जब आप अन्य डेटा के साथ अपना डेटा साझा करना चाहते हैं। यदि आपको इसकी आवश्यकता नहीं है, तो आप CursorLoader कक्षा के विधि loadInBackgroud() को ओवरराइड कर सकते हैं। उदाहरण के लिए इस तरह अपने onCreateLoader:

return new CursorLoader(YourContext, null, YourProjection, YourSelection, YourSelectionArgs, YourOrder) 
      { 
       @Override 
       public Cursor loadInBackground() 
       { 
        // You better know how to get your database. 
        SQLiteDatabase DB = getReadableDatabase(); 
        // You can use any query that returns a cursor. 
        return DB.query(YourTableName, getProjection(), getSelection(), getSelectionArgs(), null, null, getSortOrder(), null); 
       } 
      }; 
+12

यही वह है जो मैं उपयोग करता हूं क्योंकि मुझे अपना डेटा साझा करने की आवश्यकता नहीं है, और मैं एक सामग्री प्रदाता होने के लिए अपने डेटाबेस एपीआई को दोबारा नहीं बदलना चाहता हूं। नकारात्मकता यह है कि ContentProvider सामान के बिना मेरी सूचीदृश्य स्वचालित रूप से नहीं जानते हैं जब डेटा बदल गया है, जो ContentProviders के बारे में अच्छी चीजों में से एक है। जब मैं जानता हूं कि परिवर्तन बदल गया है, तो मैं अपने लोडर को फिर से बनाने के लिए, यानी 'कर्सर.क्रक्वायरी()' को कॉल करने के बजाय अब मैं 'getLoaderManager()। RestartLoader (MY_LOADER_ID, null, this) का उपयोग करता हूं;'। यह अजीब है, लेकिन 'startManagingCursor()' दृष्टिकोण को प्रतिस्थापित करने के लिए यह सबसे आसान तरीका है। – Fish

+0

@ फिश, इस जानकारी के लिए धन्यवाद, लेकिन अब मुझे जानने में दिलचस्पी है ** ** कितना महंगा 'restartLoader()' हो सकता है ..? ** यह सही मायने रखता है? – eRaisedToX

+0

किसी भी कारण से मुझे AsyncTaskLoader वापस नहीं करना चाहिए यदि मुझे आपका प्रोजेक्शन, आपका चयन, आपका चयनआर्ग और आपका ऑर्डर निर्दिष्ट करने की परवाह नहीं है? – steamer25

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