This is my first publication on this site, so I hope it will be a positive experience. I have problems with Android SQLite / ContentProvider that I have been beating my head against the wall for the past 3 hours. Below is the code for 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;
@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;
}
@Override
public String getType(Uri uri) {
switch(sUriMatcher.match(uri)) {
case INCIDENTS:
return Incidents.CONTENT_TYPE;
default:
throw new IllegalArgumentException("UNKNOWN URI " + uri);
}
}
@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);
}
@Override
public boolean onCreate() {
dbHelper = new DatabaseHelper(getContext());
return false;
}
@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, null, null, sortOrder);
c.setNotificationUri(getContext().getContentResolver(), uri);
db.close();
return c;
}
@Override
public int update(Uri uri, ContentValues values, String where,
String[] whereArgs) {
SQLiteDatabase db = dbHelper.getWritableDatabase();
int count;
switch(sUriMatcher.match(uri)) {
case INCIDENTS:
count = db.update(TABLE_NAME, values, where, 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);
}
}
I also wrote a db helper class to make interaction with ContentProvider easier. 2 examples of DBHelper methods are the following (1 for insertion, 1 for query).
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);
}
public ArrayList<Incident> getIncidents(ContentResolver contentResolver) {
Cursor c = contentResolver.query(Incidents.CONTENT_URI, null, null, null, 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, . SQLiteQueryBuilder SQLiteDatabase.rawQuery , -1. , . -1.
? - ?
, !
UPDATE:
( ) ( )
IncidentsDB db = IncidentsDB.getInstance();
workingIncident.setLastUpdate(System.currentTimeMillis()); // isActive, and createTime set in constructor
db.addNewIncident(this.getContentResolver(), workingIncident);
Cursor c = IncidentsDB.getInstance().getIncidents(this.getContentResolver());