我正在为Android开发笔记应用程序,当我点击保存按钮时,它应该使用内容提供程序方法插入将数据插入到数据库中,之后加载程序将自动加载数据,并且simplecursoradapter应该填充该数据。但是,点击保存后没有任何内容。在我看来应用程序无法访问数据库,因为我在单击保存按钮时获取此日志
02-27 12:31:31.112: E/SQLiteLog(13232): (257) Open fd: 74, file: /data/data/com.project.android.notes/databases/notes.db-journal
02-27 12:31:31.112: E/SQLiteLog(13232): (257) Close fd: 74
02-27 12:31:31.112: E/SQLiteLog(13232): (257) Open fd: 74, file: /data/data/com.project.android.notes/databases/notes.db-journal
02-27 12:31:31.186: E/SQLiteLog(13232): (257) Close fd: 74
02-27 12:31:31.271: E/SQLiteLog(13232): (257) Open fd: 80, file: /data/data/com.project.android.notes/databases/notes.db-journal
02-27 12:31:31.271: E/SQLiteLog(13232): (257) Close fd: 80
02-27 12:31:31.907: E/MCA(13851): Here call up the service!
02-27 12:31:31.908: E/MCA(13851): LT passed!
02-27 12:31:34.392: E/(180): AudioCloseDumpPCMFile file== NULL
02-27 12:31:34.392: E/(180): AudioCloseDumpPCMFile file== NULL
内容提供商代码:
public class NotesProvider extends ContentProvider{
// database
private static TodoDatabaseHelper mdatabaseHelper;
// used for the UriMacher
private static final int NOTES = 10; //in case an entire table were requested to be returned.
private static final int NOTES_ID = 20; //in case a specific item with a specific uri needs to be returned.
//Let's build the UriMatcher:
static UriMatcher sUriMatcher = new UriMatcher(UriMatcher.NO_MATCH); //sUriMatcher: s stands for static, it is just a name.
//when we initialize the UriMatcher we first say that it still has no matches. Let's assign the matches:
//we do that in a static block, that's once the class is created the matches are built.
static {
sUriMatcher.addURI(NotesContract.CONTENT_AUTHORITY, NotesContract.NOTES_PATH, NOTES); //match an entire table.
sUriMatcher.addURI(NotesContract.CONTENT_AUTHORITY, NotesContract.NOTES_PATH +"/#", NOTES_ID);
}//end matching static block.
@Override
public boolean onCreate() {
//get a dbHelper obj,
mdatabaseHelper = new TodoDatabaseHelper(getContext()); //why? Because this will help us retrieve a readable/writable db on which we can make operations like CRUD.
return true; //we were successfully able to create an obj representation of the DB.
}
@Override
public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {
//here we should use the uri matcher to know how we can conduct the query.
SQLiteQueryBuilder queryBuilder = new SQLiteQueryBuilder();
queryBuilder.setTables(NotesContract.NotesTable.TABLE_TODO); //could be used for joins also.
verifyColumns (projection); //verify if the columns are valid.
int match= sUriMatcher.match(uri); //save the int associated with this uri in a var to be able to use it in the switch.
Cursor cursor=null; //initialize cursor, it will be used to return the result of the query.
SQLiteDatabase db= mdatabaseHelper.getReadableDatabase(); //we need this because we use an SQLiteQueryBuilder.
switch (match) //start the switch
{
case NOTES:
// call method query and send the params.
cursor= queryBuilder.query(db, projection, selection,
selectionArgs, null, null, sortOrder);
break; //don't go to next case.
case NOTES_ID:
//first initialize the where clause in the queyBuilder:
queryBuilder.appendWhere(NotesContract.NotesTable._ID + "=" + ContentUris.parseId(uri));
//invoke the query method:
cursor= queryBuilder.query(db, projection, selection,
selectionArgs, null, null, sortOrder);
break;
default:
throw new IllegalArgumentException("Unknown URI: " + uri);
}//end switch
/*the queries above could be built using mSQLiteHelper.getReadableDatabase.query(..)*/
cursor.setNotificationUri(getContext().getContentResolver(), uri); //very important and required, to update the ui when the data change.
return cursor; //return the query result.
}//end query.
@Override
public String getType(Uri uri) {
return null;
}
@Override
public Uri insert(Uri uri, ContentValues contentValues) {
int match = sUriMatcher.match(uri);
SQLiteDatabase db = mdatabaseHelper.getWritableDatabase();
long id = 0;
switch (match) {
case NOTES:
id = db.insert(NotesContract.NotesTable.TABLE_TODO, null, contentValues);
break;
default:
throw new IllegalArgumentException("Unknown URI: " + uri);
}
getContext().getContentResolver().notifyChange(uri, null); //notify observers about any update.
return Uri.parse(NotesContract.NOTES_PATH + "/" + id);
}
@Override
public int delete(Uri uri, String selection, String[] selectionArgs) {
int match = sUriMatcher.match(uri);
SQLiteDatabase db = mdatabaseHelper.getWritableDatabase();
int rowsDeleted = 0;
switch (match) {
case NOTES:
rowsDeleted = db.delete(NotesContract.NotesTable.TABLE_TODO, selection, selectionArgs);
break;
case NOTES_ID:
if (selection.isEmpty()){
String whereClause= NotesContract.NotesTable._ID + "=" + ContentUris.parseId(uri);
rowsDeleted = db.delete(NotesContract.NotesTable.TABLE_TODO, whereClause, null);}
else{
rowsDeleted = db.delete(NotesContract.NotesTable.TABLE_TODO,
NotesContract.NotesTable._ID + "=" + ContentUris.parseId(uri)
+ " and " + selection,
selectionArgs);
}//end else
break;
default:
throw new IllegalArgumentException("Unknown URI: " + uri);
}//end switch
getContext().getContentResolver().notifyChange(uri, null); //if any delete happens notify the observers.
return rowsDeleted;
}//end delete
@Override
public int update(Uri uri, ContentValues contentValues, String selection, String[] selectionArgs) {
SQLiteDatabase db = mdatabaseHelper.getWritableDatabase(); //return a writable obj from the db.
int rowsUpdated = 0;
int match= sUriMatcher.match(uri);
switch (match) {
case NOTES:
rowsUpdated = db.update(NotesContract.NotesTable.TABLE_TODO,
contentValues,
selection,
selectionArgs);
break;
case NOTES_ID:
long id = ContentUris.parseId(uri);
if (TextUtils.isEmpty(selection)) {
rowsUpdated = db.update(NotesContract.NotesTable.TABLE_TODO,
contentValues,
NotesContract.NotesTable._ID + "=" + id,
null);
} else {
rowsUpdated = db.update(NotesContract.NotesTable.TABLE_TODO,
contentValues,
NotesContract.NotesTable._ID + "=" + id
+ " and "
+ selection,
selectionArgs);
}
break;
default:
throw new IllegalArgumentException("Unknown URI: " + uri);
}
getContext().getContentResolver().notifyChange(uri, null);
return rowsUpdated;
}
private void verifyColumns (String [] cols) {
//lets get the columns in the Db and compare.
String[] existed = {NotesContract.NotesTable._ID, NotesContract.NotesTable.COLUMN_CATEGORY,
NotesContract.NotesTable.COLUMN_DESCRIPTION,
NotesContract.NotesTable.COLUMN_SUMMARY};
if (cols != null) {
ArrayList<String> existedCols = new ArrayList<String>(Arrays.asList(existed)); //this is how we convert an array to an arraylist.
ArrayList<String> requestedCols = new ArrayList<String>(Arrays.asList(cols));
// check if all columns which are requested are available
if (!existedCols.containsAll(requestedCols)) {
throw new IllegalArgumentException("Some columns don't exist in the database");
}//end if.
}//end outer if.
}//end verification.
public static Cursor searchDescription (String key)
{
String desc []= {"%"+key +"%"};
SQLiteDatabase db = mdatabaseHelper.getReadableDatabase();
Cursor rtCursor= db.rawQuery("select * from " + NotesContract.NotesTable.TABLE_TODO+ " where " +
NotesContract.NotesTable.COLUMN_DESCRIPTION + " like ?", desc);
return rtCursor;
}//end searchDescription
}//end Provider.
详细说明编辑和保存记事的活动代码:
public class NotesDetails extends ActionBarActivity {
private EditText noteSummary;
private EditText noteDescription;
private Spinner noteCategory;
@Override
protected void onCreate(Bundle savedInstanceState) {
final ContentResolver resolver = getApplicationContext().getContentResolver();
super.onCreate(savedInstanceState);
setContentView(R.layout.notes_edit);
Button saveButton = (Button) findViewById(R.id.todo_edit_button);
noteSummary = (EditText) findViewById(R.id.todo_edit_summary);
noteDescription = (EditText) findViewById(R.id.todo_edit_description);
noteCategory= (Spinner) findViewById(R.id.category);
if (getIntent().getStringArrayExtra(Intent.EXTRA_TEXT)!=null){
String [] receivedData=getIntent().getStringArrayExtra(Intent.EXTRA_TEXT);
if (receivedData [0].equalsIgnoreCase("important")){
noteCategory.setSelection(0);}//end if
else {
noteCategory.setSelection(1);} //end else
noteSummary.setText(receivedData[1]);
noteDescription.setText(receivedData[2]);
}//end if (feasible only if the received intent contains an array of string, which happens if the user clicks onm one of the items in the simplecursoradapter view)
saveButton.setOnClickListener(new View.OnClickListener() {
String summary= null;
String description= null;
String category= null;
@Override
public void onClick(View view) { //this will happen every time you click the button.
summary= noteSummary.getText().toString();
description= noteDescription.getText().toString();
category = noteCategory.getSelectedItem().toString();
Toast toast ;
if (summary.isEmpty()) {
toast = Toast.makeText(NotesDetails.this, "Summary cannot be empty", Toast.LENGTH_SHORT);
toast.show();
}
else {
ContentValues values = new ContentValues();
values.put(NotesTable.COLUMN_CATEGORY, category);
values.put(NotesTable.COLUMN_SUMMARY, summary);
values.put(NotesTable.COLUMN_DESCRIPTION, description);
//start inserting into the db via provider.
Uri uri =getContentResolver().insert(NotesTable.NOTES_URI, values);
Intent intent = new Intent(NotesDetails.this, NotesList.class);
startActivity(intent);
}
}//end onClick
}); //end onClickListener
}
}
任何人都可以告诉我为什么会这样,以及如何解决问题?
由于
答案 0 :(得分:0)
将此用于插入
public void onClickAddName(View view) {
ContentValues values = new ContentValues();
values.put(MyProvider.name, ((EditText) findViewById(R.id.txtName))
.getText().toString());
Uri uri = getContentResolver().insert(MyProvider.CONTENT_URI, values);
Toast.makeText(getBaseContext(), "New record inserted", Toast.LENGTH_LONG).show();
}