2014-11-03 125 views
1

我似乎無法理解內容提供者的概念。我個人認爲它會使代碼變得越來越多,它使它過度複雜化,而且顯然很糟糕。Android - 內容提供者查詢光標

順便說一句,這將是您可以在網上找到的多表ContentProvider的第一個示例代碼。絕對沒有其他的,除了可能的ContactsProvider(「veeeerrrrry有用」 - 通過超級塞滿和indescifrable)。我相信像我這樣的許多新手會讚賞這一點。

請幫我做一個簡單的光標從內容提供商。我有正常的代碼波紋管(使用簡單SQLiteOpenHelper),我需要把它翻譯成內容提供商代碼:

Button btnp = (Button) findViewById(R.id.btnproc); 
    btnp.setOnClickListener(new View.OnClickListener() { 
     @Override 
     public void onClick(View view) { 
     Context mycontext = getApplicationContext(); 
     SQLiteDatabase db = new myDbHelper(mycontext).getWritableDatabase(); 
     String sql = "select _id,data,titlu,cont from notificari where date(data)<=date(datetime())"; 
     Cursor cursor = db.rawQuery(sql, null); 
     Log.w("...MainActivity...", "Record count:"+Integer.toString(curu.getCount())); 
      while(curu.moveToNext()){ 
       String lista = curu.getString(0)+",'"+curu.getString(1)+"',"+curu.getString(2)+",'"+ 
         curu.getString(3)+"'"; 
       Log.e("...MainActivity...", lista); 
      } 

     } 
    }); 

所以我需要將光標從內容提供商獲取。我已經開始開發這個「令人興奮」的內容提供者,但我不知道我所做的事情是否可以,因爲它過於複雜。這裏有雲(我的內容提供商需要REFFERENCE多個表):

public class MyFirstProvider extends ContentProvider { 
static final String PROVIDER_NAME = "com.mystuff.myapp.MyFirstProvider"; 
    static final String URL = "content://" + PROVIDER_NAME + "/cte"; 
    static final String URL2 = "content://" + PROVIDER_NAME + "/clienti"; 
    static final String URL3 = "content://" + PROVIDER_NAME + "/uzeri"; 
    static final String URL4 = "content://" + PROVIDER_NAME + "/notificari"; 
    static final Uri CONTENT_URI = Uri.parse(URL); 
    static final Uri CONTENT_URI2 = Uri.parse(URL2); 
    static final Uri CONTENT_URI3 = Uri.parse(URL3); 
    static final Uri CONTENT_URI4 = Uri.parse(URL4); 


    static final int uriCode = 1; 
    static final int uriCode1 = 2; 
    static final int uriCode2 = 3; 
    static final int uriCode3 = 4; 
    static final int uriCode4 = 5; 
    static final int uriCode5 = 6; 
    static final int uriCode6 = 7; 
    static final int uriCode7 = 8; 


    static final UriMatcher uriMatcher; 
    private static HashMap<String, String> values; 
    static { 
     uriMatcher = new UriMatcher(UriMatcher.NO_MATCH); 
     uriMatcher.addURI(PROVIDER_NAME, "cte", uriCode); 
     uriMatcher.addURI(PROVIDER_NAME, "cte/*", uriCode1); 
     uriMatcher.addURI(PROVIDER_NAME, "clienti", uriCode2); 
     uriMatcher.addURI(PROVIDER_NAME, "clienti/*", uriCode3); 
     uriMatcher.addURI(PROVIDER_NAME, "uzeri", uriCode4); 
     uriMatcher.addURI(PROVIDER_NAME, "uzeri/*", uriCode5); 
     uriMatcher.addURI(PROVIDER_NAME, "notificari", uriCode6); 
     uriMatcher.addURI(PROVIDER_NAME, "notificari/*", uriCode7); 
    } 

    @Override 
    public boolean onCreate() { 
     Context context = getContext(); 
     DatabaseHelper dbHelper = new DatabaseHelper(context); 
     db = dbHelper.getWritableDatabase(); 
     if (db != null) { 
      return true; 
     } 
     return false; 
    } 

    @Override 
    public Cursor query(Uri uri, String[] projection, String selection,String[] selectionArgs, String sortOrder) { 
     SQLiteQueryBuilder qb = new SQLiteQueryBuilder(); 
     switch (uriMatcher.match(uri)) { 
      case uriCode: 
       qb.setTables(TABLE_NAME); 
       qb.setProjectionMap(values); 
       break; 
      case uriCode2: 
       qb.setTables(TABLE_CLIENTI); 
       qb.setProjectionMap(values); 
       if (sortOrder == null || sortOrder == "") { 
        sortOrder = TCL_NUME_CLIENT; 
       } 
       break; 
      case uriCode6: 
       qb.setTables(TABLE_NOTIF); 
       qb.setProjectionMap(values); 
       break; 

      default: 
       throw new IllegalArgumentException("Unsupported URI: " + uri); 
     } 
     Cursor c = qb.query(db, projection, selection, selectionArgs, null,null, sortOrder); 
     c.setNotificationUri(getContext().getContentResolver(), uri); 
     return c; 
    } 


    // ... there is other code here regarding the insert,update and delete (not relevant now) 

    private SQLiteDatabase db; 
    static final String DATABASE_NAME = "mydb"; 
    static final String TABLE_NAME = "names"; 
    public static final String TABLE_UZERI = "uzeri"; 
    public static final String TABLE_NOTIF = "notificari"; 


    static final int DATABASE_VERSION = 3; 
    static final String CREATE_DB_TABLE = " CREATE TABLE " + TABLE_NAME 
      + " (_id INTEGER PRIMARY KEY AUTOINCREMENT, " 
      + " name TEXT NOT NULL);"; 

    static final String CREATE_DB_TABLE_NOTIFICARI = "CREATE TABLE IF NOT EXISTS " + TABLE_NOTIF + " (_id INTEGER PRIMARY KEY AUTOINCREMENT, " + 
      TNOT_ID_NOT + " INTEGER NOT NULL DEFAULT 0, " + 
      TNOT_DATA + " DATE NOT NULL, " + 
      TNOT_SURSA + " INTEGER NOT NULL DEFAULT 0, "+ 
      TNOT_DEST + " INTEGER NOT NULL DEFAULT 0, "+ 
      TNOT_TIP + " TEXT, "+ 
      TNOT_TITLU + " TEXT, "+ 
      TNOT_TITLUCONT + " TEXT, "+ 
      TNOT_CONT + " TEXT, "+ 
      TNOT_STERS + " INTEGER DEFAULT 0, "+ 
      TNOT_NOU + " INTEGER NOT NULL DEFAULT 0)"; 

    private static class DatabaseHelper extends SQLiteOpenHelper { 
     DatabaseHelper(Context context) { 
      super(context, DATABASE_NAME, null, DATABASE_VERSION); 
     } 

     @Override 
     public void onCreate(SQLiteDatabase db) { 
      db.execSQL(CREATE_DB_TABLE); 
      db.execSQL(CREATE_DB_TABLE_UZERI); 
      db.execSQL(CREATE_DB_TABLE_NOTIFICARI); 
     } 

     @Override 
     public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { 
      db.execSQL("DROP TABLE IF EXISTS " + TABLE_NAME); 
      db.execSQL("DROP TABLE IF EXISTS " + TABLE_UZERI); 
      db.execSQL("DROP TABLE IF EXISTS " + TABLE_NOTIFICARI); 
      onCreate(db); 
     } 
    } 

我試圖「翻譯」,它記錄光標的內容的活動代碼,但它只是什麼都不做。這非常令人沮喪。 這裏是我的「翻譯」:

Button btnp = (Button) findViewById(R.id.btnproc); 
btnp.setOnClickListener(new View.OnClickListener() { 
    @Override 
    public void onClick(View view) { 
     String[] coloane = {MyFirstProvider.TNOT_ID_ID, MyFirstProvider.TNOT_DATA,MyFirstProvider.TNOT_TITLU, MyFirstProvider.TNOT_CONT}; 
     Cursor curu = MainActivity.this.getContentResolver().query(MyFirstProvider.CONTENT_URI_NOTIF,coloane,null,null,MyFirstProvider.TNOT_DATA); 

     Log.w("...MainActivity...", "Recorduri:"+Integer.toString(curu.getCount())); 
     while(curu.moveToNext()){ 
      String lista = curu.getString(0)+",'"+curu.getString(1)+"',"+curu.getString(2)+",'"+ 
        curu.getString(3)+"'"; 
      Log.e("...MainActivity...", lista); 
     } 

    } 
}); 

我必須向你保證,這個表有內部4條(我手動插入它們創建表後) 另外,如果我把這個代碼的ContentProvider內,則記錄顯示根據需要將表的內容:

Cursor c = qb.query(db, projection, selection, selectionArgs, null,null, sortOrder); 
     while(c.moveToNext()){ 
      Log.w("...Provider...",c.getString(0)+"-"+c.getString(1)+"-"+c.getString(2)); 
     } 

但我不希望這樣做的內容提供商,我想這樣做在活動代碼。 我在做什麼錯?

請幫忙。

謝謝取而代之的是

btnp.setOnClickListener(new View.OnClickListener 

+0

首先,你需要一個內容提供者? – 2014-11-03 13:49:45

+0

你到底想到了這個嗎?內容提供者是另一個抽象級別,用於對數據進行外部訪問。 在進行查詢時,最好將代碼抽象到一個輔助類,以便該活動不知道底層數據訪問。它將顯着簡化您的代碼並減少您需要複製的次數。 – 2016-10-26 22:45:01

回答

2

如果您不需要,則不必使用ContentProvider。確定你的要求。如果數據對您的應用程序是私有的,並且它必須以表格格式存儲,那麼您可以直接在Android中訪問SQLite引擎,而無需通過ContentProvider。但是如果您希望其他應用程序或系統訪問您的應用程序的數據,那麼是的 - 這是ContentProvider的合法用例。

儘管如此,我建議你閱讀這個article - 告訴你如何訪問SQLite引擎有和沒有ContentProvider

希望這會有所幫助。

不管怎麼說,手頭您的問題,試試這個 -

Cursor c = qb.query(db, projection, selection, selectionArgs, null,null, sortOrder); 
if (c == null) { 
    // error - log some message 
} 
else if (c.getCount() < 1) { 
    // nothing to show - log some message 
} 
else { 
    while(c.moveToNext()){ 
    Log.w("...Provider...",c.getString(0)+"-"+c.getString(1)+"-"+c.getString(2)); 
    } 
} 
+0

我必須,不幸的是。因爲我需要將SQLite數據庫與遠程MySQL數據庫同步......我希望有比ContenrtProvider更好的方法。我只是討厭它 – user1137313 2014-11-03 14:00:05

+0

編輯我的答案... – 2014-11-03 14:36:44

+0

奇怪...我的光標不爲空,但是如果我不測試它(空或不),顯然它會停止處理代碼。多麼好......無論如何,謝謝你的提醒。你解決了我的問題。 (當然,我相信你的意思是第一個if語句應該是「if(c == null)」) – user1137313 2014-11-03 15:23:15

-1

嘗試

btnp.setOnClickListener(this) 

和實施onClickListner的活動。

簡而言之,不是將onClickListener投射到按鈕,而是將其實施到整個活動並嘗試。

+0

你不明白。我的遊標/查詢得到執行,因爲我可以看到提供程序生成的logcat。但是在執行完遊標之後,我還可以看到MainActivity中的LogCat顯示了遊標的getCount(),然後什麼也沒有......我也有多個按鈕,所以我不想將整個遊標執行到整個活動。我也不認爲這會解決我的問題。正如我已經說過的,點擊事件正在工作,但只是部分。 While循環似乎不執行 – user1137313 2014-11-03 14:04:24

+0

非常不現實的解決方案,不能被視爲一個答案 – akash89 2015-06-07 07:22:24

相關問題