Android SQLite插入有效,查询无效

这是我第一次在该网站上发帖,希望这将是一次积极的经历.我有一个Android sqlite / ContentProvider问题,在过去3个小时中,我一直在犹豫不决.以下是ContentProvider代码

public class IncidentProvider extends ContentProvider {

private static final UriMatcher sUriMatcher;
private static final HashMap<String,String> projectionMap;
private static final int INCIDENTS = 1;

public static final String AUTHORITY = "com.test.providers.IncidentsProvider";
public static final String TABLE_NAME = "incidents";

private static class DatabaseHelper extends sqliteOpenHelper {

    public DatabaseHelper(Context context) {
        super(context,context.getString(R.string.database_name),null,Integer.parseInt(context.getString(R.string.database_version)));
    }

    @Override
    public void onCreate(sqliteDatabase db) {
        db.execsql("CREATE TABLE " + TABLE_NAME + " (" 
                + Incidents.INCIDENT_ID + " INTEGER PRIMARY KEY AUTOINCREMENT," 
                + Incidents.NAME + " VARCHAR(30),"
                + Incidents.CREATE_TIME + " LONG," 
                + Incidents.LAST_UPDATE + " LONG," 
                + Incidents.IS_ACTIVE + " VARCHAR(30)" + ");");
    }

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

}

private DatabaseHelper dbHelper;

/**
 * Delete a row from the database
 */
@Override
public int delete(Uri uri,String where,String[] whereArgs) {
    sqliteDatabase db = dbHelper.getWritableDatabase();
    int count;
    switch(sUriMatcher.match(uri)) {
        case INCIDENTS:
            count = db.delete(TABLE_NAME,where,whereArgs);
            break;
        default:
            throw new IllegalArgumentException("Unknown URI " + uri);
    }
    getContext().getContentResolver().notifyChange(uri,null);
    db.close();
    return count;
}

/**
 * Return the content type managed by this ContentProvider
 */
@Override
public String getType(Uri uri) {
    switch(sUriMatcher.match(uri)) {
        case INCIDENTS:
            return Incidents.CONTENT_TYPE;
        default:
            throw new IllegalArgumentException("UNKNOWN URI " + uri);
    }
}

/**
 * Insert new content into a row in the database
 */
@Override
public Uri insert(Uri uri,ContentValues initialValues) {
    if(sUriMatcher.match(uri) != INCIDENTS) 
        throw new IllegalArgumentException("UNKNOWN URI " + uri);

    ContentValues values;
    if(initialValues != null) {
        values = new ContentValues(initialValues);
    } else {
        values = new ContentValues();
    }

    sqliteDatabase db = dbHelper.getWritableDatabase();
    long rowId = db.insert(TABLE_NAME,Incidents.NAME,values);

    if(rowId > 0) {
        Uri incidentUri = ContentUris.withAppendedId(Incidents.CONTENT_URI,rowId);
        getContext().getContentResolver().notifyChange(incidentUri,null);
        db.close();
        return incidentUri;
    }
    db.close();
    throw new sqlException("Failed to insert row into " + uri);
}

/**
 * Called when creating this ContentProvider
 */
@Override
public boolean onCreate() {
    dbHelper = new DatabaseHelper(getContext());
    return false;
}

/**
 * Called when making a query to this content provider
 */
@Override
public Cursor query(Uri uri,String[] projection,String selection,String[] selectionArgs,String sortOrder) {

    sqliteQueryBuilder qb = new sqliteQueryBuilder();

    switch(sUriMatcher.match(uri)) {
        case INCIDENTS:
            qb.setTables(TABLE_NAME);
            qb.setProjectionMap(projectionMap);
            break;
        default:
            throw new IllegalArgumentException("UNKNOWN URI " + uri);
    }

    sqliteDatabase db = dbHelper.getWritableDatabase();

    Cursor c = qb.query(db,projection,selection,selectionArgs,sortOrder);
    c.setNotificationUri(getContext().getContentResolver(),uri);
    db.close();
    return c;
}

/**
 * Called when updating a row through this content provider
 */
@Override
public int update(Uri uri,ContentValues values,String[] whereArgs) {
    sqliteDatabase db = dbHelper.getWritableDatabase();
    int count;

    switch(sUriMatcher.match(uri)) {
        case INCIDENTS:
            count = db.update(TABLE_NAME,values,whereArgs);
            break;
        default:
            throw new IllegalArgumentException("UNKNOWN URI " + uri);
    }

    getContext().getContentResolver().notifyChange(uri,null);
    db.close();
    return count;
}

static {
    sUriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
    sUriMatcher.addURI(AUTHORITY,TABLE_NAME,INCIDENTS);

    projectionMap = new HashMap<String,String>();
    projectionMap.put(Incidents.INCIDENT_ID,Incidents.INCIDENT_ID);
    projectionMap.put(Incidents.NAME,Incidents.NAME);
    projectionMap.put(Incidents.CREATE_TIME,Incidents.CREATE_TIME);
    projectionMap.put(Incidents.LAST_UPDATE,Incidents.LAST_UPDATE);
    projectionMap.put(Incidents.IS_ACTIVE,Incidents.IS_ACTIVE);
}  

}

我还编写了一个db helper类,以使其易于与ContentProvider进行交互. 2个示例DBHelper方法如下(1用于插入,1用于查询).

    /**
     *  Adds a new incident to the database
     **/
 public void addNewIncident(ContentResolver contentResolver,Incident incident) {
  ContentValues contentValues = new ContentValues();
  contentValues.put(Incidents.NAME,incident.getName());
  contentValues.put(Incidents.CREATE_TIME,incident.getCreateTime());
  contentValues.put(Incidents.LAST_UPDATE,incident.getLastUpdate());
  contentValues.put(Incidents.IS_ACTIVE,incident.isActive()?"true":"false");

  contentResolver.insert(Incidents.CONTENT_URI,contentValues);

 } 

    /**
     * Retrieves all incidents from the database
     **/
    public ArrayList<Incident> getIncidents(ContentResolver contentResolver) {
  Cursor c = contentResolver.query(Incidents.CONTENT_URI,null);
  ArrayList<Incident> returnList = new ArrayList<Incident>();

  if(c!=null && c.moveToNext()) {
   for(int i=0; i<c.getCount(); i++) {
    c.moveToPosition(i);
    Incident incident = new Incident(c.getString(c.getColumnIndex(Incidents.NAME)));
    incident.setCreateTime(c.getLong(c.getColumnIndex(Incidents.CREATE_TIME)));
    incident.setLastUpdate(c.getLong(c.getColumnIndex(Incidents.LAST_UPDATE)));
    incident.setActive(c.getString(c.getColumnIndex(Incidents.IS_ACTIVE)).equalsIgnoreCase("true"));
    returnList.add(incident);
   }
   c.close();
  }

  return returnList;
 }

好的!所以这是我的问题.我可以毫无问题地插入数据库!如果我通过adb shell查询数据库,则可以看到所有正在插入的记录.当我使用sqliteQueryBuilder或sqliteDatabase.rawQuery或任何其他查询方法进行查询时,返回的游标以-1返回.无论查询单个记录还是查询整个数据库都没有关系.查询仍然返回-1.

有任何想法吗?我错过了一件非常简单的事情吗?

在此先感谢任何愿意帮助沮丧的人的人!

更新:

以下是用于插入(有效)和查询(无效)的示例代码

/** 
 * Following db insert works
 */
IncidentsDB db = IncidentsDB.getInstance(); 
workingIncident.setLastUpdate(System.currentTimeMillis());     // isActive,and createTime set in constructor
db.addNewIncident(this.getContentResolver(),workingIncident);

/**
 * Following db queries do not work,cursor ends up with mCount=-1 
 */
 Cursor c = IncidentsDB.getInstance().getIncidents(this.getContentResolver());
最佳答案
好吧,看来我已经解决了.事实证明,最好使用finalize方法关闭数据库,而不是像上面发布的代码中那样在每个delete,insert,query和update方法中打开和关闭.这是像我一样遇到此问题的人员的代码片段:

// add sqliteDatabase member variable to content provider
private sqliteDatabase db;

/**
 * Delete a row from the database
 */
@Override
public int delete(Uri uri,String[] whereArgs) {
    // use Content Provider's db member variable in the following code block
    int count;
    switch(sUriMatcher.match(uri)) {
        case INCIDENTS:
            count = db.delete(TABLE_NAME,null);
    return count;
}

然后将以下完成代码添加到您的内容提供商

    @Override
    protected void finalize() throws Throwable {
        super.finalize();
        db.close();
    }

相关文章

以下为个人理解,如错请评 CE: 凭据加密 (CE) 存储空间, 实际路径/data/user_ce/ DE: 设备加密 (DE) 存...
转载来源:https://blog.csdn.net/yfbdxz/article/details/114702144 用EventLog.writeEvent打的日志(或...
事件分发机制详解 一、基础知识介绍 1、经常用的事件有:MotionEvent.ACTION_DOWN,MotionEvent.ACTION...
又是好久没有写博客了,一直都比较忙,最近终于有时间沉淀和整理一下最近学到和解决的一些问题。 最近进...
Android性能优化——之控件的优化 前面讲了图像的优化,接下来分享一下控件的性能优化,这里主要是面向...
android的开源库是用来在android上显示gif图片的。我在网上查了一下,大家说这个框架写的不错,加载大的...