2014-01-06 14 views
0

我有一個Fragment列表類(如下),用於顯示使用Content Provider的本地SQLite數據庫中的值。如何使用其他Activity的內容提供者來刷新ListFragment?

public static ContentResolver resolver; 
Uri uri; 
AsyncQueryHandler handler; 
public static SimpleCursorAdapter adapter; 
private Cursor localCursor; 

public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 

    resolver = this.getActivity().getContentResolver(); 
    uri = Uri 
      .parse("content://com.n00111715.messengerlist.model.MessageContentProvider/messages"); 
    handler = new AsyncQueryHandler(resolver) { 
     public void onQueryComplete(int token, Object cookie, Cursor cursor) { 
      MessageListFragment.this.onQueryComplete(cursor); 
     } 
    }; 
    handler.startQuery(0, null, uri, null, null, null, null); 
} 

public void onQueryComplete(Cursor cursor) { 
    // store the cursor values 
    localCursor = cursor; 

    String[] from = new String[] { "_id", "reciever", "sender", "subject", 
      "date", "message" }; 

    int[] to = new int[] { R.id.hidden_id_field, R.id.hidden_to_field, 
      R.id.list_item_message_from_textview, 
      R.id.list_item_message_subject_textview, 
      R.id.list_item_message_date_textview, 
      R.id.list_item_message_content_textview }; 

    // create a simple cursor adapter that used the cursor from the 
    // database, and maps the values 
    // to the textviews in the list items that make up the list fragment   
    adapter = new SimpleCursorAdapter(this.getActivity(), 
      R.layout.list_item_message, cursor, from, to, 0); 
    // set this as this list fragments adapter 
    setListAdapter(adapter); 
} 

public void onListItemClick(ListView l, View v, int position, long id) { 

    String currentId = String.valueOf(id); 
    int i = 0; 
    String[] values = new String[6]; 

    // loop through the cursor object 
    localCursor.moveToFirst(); 
    while (localCursor.isAfterLast() == false) { 
     // extract this row values for the id column, if the match the 
     // selected id 
     if (localCursor.getString(0).equals(currentId)) { 
      // loop through the values of the full row 
      for (int j = 0; j < values.length; j++) { 
       // add these values to the values string array 
       values[j] = localCursor.getString(j); 
      } 
     } 
     i++; 
     localCursor.moveToNext(); 
    } 
    // create new intent 
    Intent intent = new Intent(getActivity(), ViewingMessageActivity.class); 
    // add the selected messages values into extras 
    intent.putExtra("values", values); 
    // start the ne activity 
    startActivity(intent); 
} 

當我在列表中選擇一個項目時,會顯示一個Activity(如下所示)。

// variable for the UI elements 
Button deleteButton, saveButton, forwardButton; 
EditText editTextFrom, editTextSubject, editTextContent; 
//MessageListFragment mlf; 
String[] values; 
Intent intent; 

public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 

    // set the layout file for this activity 
    setContentView(R.layout.viewing_fragment_layout); 

    // get the the intent 
    intent = getIntent(); 

    // retrieve the string array from extras 
    values = intent.getStringArrayExtra("values"); 
    Log.d("this is my array", "values: " + Arrays.toString(values)); 
    getReferences(); 
    populateUIFields(); 
} 

private void populateUIFields() { 
    // insert message values into the text fields 
    editTextFrom.setText(values[2]); // from 
    editTextSubject.setText(values[3]); // subject 
    editTextContent.setText(values[4]); // content 
} 

private void getReferences() { 
    // get references to the ui elements 
    deleteButton = (Button) findViewById(R.id.deleteButton); 
    saveButton = (Button) findViewById(R.id.saveButton); 
    forwardButton = (Button) findViewById(R.id.forwardButton); 
    editTextFrom = (EditText) findViewById(R.id.editTextFrom); 
    editTextSubject = (EditText) findViewById(R.id.editTextSubject); 
    editTextContent = (EditText) findViewById(R.id.editTextContent); 
    // add click listeners to each button 
    deleteButton.setOnClickListener(new View.OnClickListener() { 
     public void onClick(View view) { 
      String whereClause = "_id = " + values[0]; 
      ContentResolver resolver = getApplicationContext() 
        .getContentResolver(); 
      Uri uri = Uri 
        .parse("content://com.n00111715.messengerlist.model.MessageContentProvider/messages"); 
      AsyncQueryHandler handler = new AsyncQueryHandler(resolver) { 
       public void onDeleteComplete(int token, Object cookie, 
         int result) { 
        ViewingMessageActivity.this.onDeleteComplete(result); 
       } 
      }; 
      handler.startDelete(0, null, uri, whereClause, null); 
     } 
    }); 

    saveButton.setOnClickListener(new View.OnClickListener() { 
     public void onClick(View view) { 

      values[2] = editTextFrom.getText().toString(); 
      values[3] = editTextSubject.getText().toString(); 
      values[4] = editTextContent.getText().toString(); 

      ContentValues row = new ContentValues(); 
      row.put("reciever", values[1]); 
      row.put("sender", values[2]); 
      row.put("subject", values[3]); 
      row.put("message", values[4]); 
      row.put("date", values[5]); 

      String whereClause = "_id = " + values[0]; 

      ContentResolver resolver = getApplicationContext() 
        .getContentResolver(); 
      Uri uri = Uri 
        .parse("content://com.n00111715.messengerlist.model.MessageContentProvider/messages"); 
      AsyncQueryHandler handler = new AsyncQueryHandler(resolver) { 
       public void onUpdateComplete(int token, Object cookie, 
         int result) { 
        ViewingMessageActivity.this.onSaveComplete(result); 
       } 
      }; 
      handler.startUpdate(0, null, uri, row, whereClause, null); 
     } 
    }); 

} 

protected void onDeleteComplete(int result) { 
    Toast.makeText(getApplicationContext(), "message deleted", 
      Toast.LENGTH_LONG).show(); 
    //return to the list fragment and refresh the list 

} 

protected void onSaveComplete(int result) { 
    Toast.makeText(getApplicationContext(), "message saved", 
      Toast.LENGTH_LONG).show(); 
    //return to the list fragment and refresh the list 
} 

當數據庫從該類我想返回到列表中的片段(當前活動的處理?),並有刷新列表以顯示數據的任何變化中更新。

我想我需要創建一個新的查詢到數據庫和這個列表片段的新適配器。我不知道我應該如何從觀看活動中去解決這個問題。我發現this answer that is similar to my problem,但我不能讓它工作。

這就是Content Provider的樣子。

public static final String AUTHORITY = "com.n00111715.messengerlist.model.MessageContentProvider"; 
private static final UriMatcher sUriMatcher; 
private static final int MESSAGE_COLLECTION_URI_INDICATOR = 1; 
private static final int SINGLE_MESSAGE_URI_INDICATOR = 2; 

public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY 
     + "/" + MessageTableGateway.TABLE_MESSAGES); 
public static final String CONTENT_TYPE = "vnd.android.cursor.dir/vnd.com.n00111715.messengerlist.model.message"; 
public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/vnd.com.n00111715.messengerlist.model.message"; 

static { 
    sUriMatcher = new UriMatcher(UriMatcher.NO_MATCH); 
    sUriMatcher.addURI(AUTHORITY, MessageTableGateway.TABLE_MESSAGES, 
      MESSAGE_COLLECTION_URI_INDICATOR); 
    sUriMatcher.addURI(AUTHORITY, 
      MessageTableGateway.TABLE_MESSAGES + "/#", 
      SINGLE_MESSAGE_URI_INDICATOR); 
} 

private MessageTableGateway mMessageTableGateway; 
private ContentResolver mContentResolver; 

@Override 
public boolean onCreate() { 
    Context context = getContext(); 
    mContentResolver = context.getContentResolver(); 

    MessengerListOpenHelper helper = MessengerListOpenHelper 
      .getInstance(context); 
    SQLiteDatabase db = helper.getWritableDatabase(); 
    mMessageTableGateway = MessageTableGateway.getInstance(db); 
    return true; 
} 

@Override 
public int update(Uri uri, ContentValues values, String whereClause, 
     String[] whereArgs) { 
    int count; 

    switch (sUriMatcher.match(uri)) { 
    case MESSAGE_COLLECTION_URI_INDICATOR: 
     count = mMessageTableGateway.update(values, whereClause, whereArgs); 
     break; 
    case SINGLE_MESSAGE_URI_INDICATOR: 
     String id = uri.getPathSegments().get(1); 
     String where = MessageTableGateway.COLUMN_ID + " = " + id; 

     if (TextUtils.isEmpty(whereClause)) { 
      whereClause = where; 
     } else { 
      whereClause = where + " AND " + where; 
     } 
     count = mMessageTableGateway.update(values, whereClause, whereArgs); 
     break; 
    default: 
     throw new IllegalArgumentException("Unknown URI " + uri); 
    } 
    mContentResolver.notifyChange(uri, null, false); 


    return count; 
} 

@Override 
public int delete(Uri uri, String whereClause, String[] whereArgs) { 
    int count; 

    switch (sUriMatcher.match(uri)) { 
    case MESSAGE_COLLECTION_URI_INDICATOR: 
     count = mMessageTableGateway.delete(whereClause, whereArgs); 
     break; 
    case SINGLE_MESSAGE_URI_INDICATOR: 
     String id = uri.getPathSegments().get(1); 
     String where = MessageTableGateway.COLUMN_ID + " = " + id; 

     if (TextUtils.isEmpty(whereClause)) { 
      whereClause = where; 
     } else { 
      whereClause = where + " AND " + where; 
     } 
     count = mMessageTableGateway.delete(whereClause, whereArgs); 
     break; 
    default: 
     throw new IllegalArgumentException("Unknown URI " + uri); 
    } 
    mContentResolver.notifyChange(uri, null); 

    return count; 
} 

@Override 
public String getType(Uri uri) { 
    switch (sUriMatcher.match(uri)) { 
    case MESSAGE_COLLECTION_URI_INDICATOR: 
     return CONTENT_TYPE; 
    case SINGLE_MESSAGE_URI_INDICATOR: 
     return CONTENT_ITEM_TYPE; 
    default: 
     throw new IllegalArgumentException("Unknown URI " + uri); 
    } 
} 

@Override 
public Uri insert(Uri uri, ContentValues values) { 
    Uri insertedMessageUri; 
    if (sUriMatcher.match(uri) != MESSAGE_COLLECTION_URI_INDICATOR) { 
     throw new IllegalArgumentException("Unknown URI " + uri); 
    } 

    long id = mMessageTableGateway.insert(values); 
    if (id > 0) { 
     insertedMessageUri = ContentUris.withAppendedId(CONTENT_URI, id); 
    } else { 
     throw new SQLException("Failed to insert message into " + uri); 
    } 
    mContentResolver.notifyChange(insertedMessageUri, null); 

    return insertedMessageUri; 
} 

@Override 
public Cursor query(Uri uri, String[] columns, String whereClause, 
     String[] whereArgs, String sortOrder) { 
    Cursor c; 

    switch(sUriMatcher.match(uri)) { 
    case MESSAGE_COLLECTION_URI_INDICATOR: 
     c = mMessageTableGateway.query(columns, whereClause, whereArgs, null, null, sortOrder, null); 
     break; 
    case SINGLE_MESSAGE_URI_INDICATOR: 
     String id = uri.getPathSegments().get(1); 
     String where = MessageTableGateway.COLUMN_ID + " = " + id; 

     if (TextUtils.isEmpty(whereClause)) { 
      whereClause = where; 
     } else { 
      whereClause = whereClause + " AND " + where; 
     } 
     c = mMessageTableGateway.query(columns, whereClause, whereArgs, null, null, sortOrder, null); 
     break; 
     default: 
      throw new IllegalArgumentException("Unknown URI " + uri); 
    } 
    c.setNotificationUri(mContentResolver, uri); 

    return c; 
} 

回答

0

添加與您的列表片段查詢相同的URI的notifyChange調用。它可能是沒有添加特定行ID的更新uri。

+0

感謝您的答覆,即時通訊還是有點失落,如果我一個完整的內容提供商你能告訴我,我需要做什麼。 我的列表片段是查詢以下的Uri: 「content://com.n00111715.messengerlist.model.MessageContentProvider/messages」 –

+0

你的更新方法的URI是content://..auth../messages/#和列表片段正在監視歸屬於消息uri的更改(不包含行ID)。你只需要在你的update()方法中添加基本uri的通知: uri = Uri .parse(「content://com.n00111715.messengerlist.model.MessageContentProvider/messages」) mContentResolver.notifyChange(uri ,null,false); – dangVarmit

0

如果您想自動執行此操作,請在活動中使用CursorLoader。有很多使用這種方法的教程。

我建議您在本教程:http://www.vogella.com/tutorials/AndroidSQLite/article.html(在你的情況下,最有趣的Poing的是9,不過我建議你仔細閱讀它來獲得整個畫面)

我會指出最重要的兩點:

  • 你的片段具有擴展一個類ListFragment
  • ListFragmentListView必須具有此ID @android:/id_list
  • 林在本教程中介紹onCreateLoaderonLoadFinishedonLoaderReset
  • 使用您SimpleCursorAdapter您認爲合適的plement這個接口LoaderManager.LoaderCallbacks<Cursor>及其3種方法
  • 調用此方法是絕對重要的一個getLoaderManager().initLoader(your_id, null, this);作爲your_id是在應用程序中定義的唯一Integer

希望它可以幫助