I'm trying to make an app that involves a database. I'm using a ContentProvider and it's crashing in the query method when it tries to getWritableDatabase.
It returns a NullPointerException. I know for a fact that the Context isn't null, since that seems to be the main cause of this kind of problem.
Here's the ContentProvider code:
package com.corvus.corvusenterprises.digimonapp;
import android.content.ContentProvider;
import android.content.ContentResolver;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.Context;
import android.content.UriMatcher;
import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteQueryBuilder;
import android.net.Uri;
import android.text.TextUtils;
import android.util.Log;
import java.util.Arrays;
import java.util.HashSet;
import static com.corvus.corvusenterprises.digimonapp.DBHelper.presentDigimon;
/**
* Created by Jack on 01/05/2017.
*/
public class DigimonContentProvider extends ContentProvider {
private static DigimonContentProvider instance;
private DBHelper dbHelper;
private SQLiteDatabase db;
private static final int DIGIMON = 10;
private static final int DIGIMON_ID = 20;
private static final int ATTACKS = 30;
private static final int ATTACKS_ID = 40;
private static final int EVOLUTIONS = 50;
private static final int EVOLUTIONS_ID = 60;
private static final String AUTHORITY = "com.corvus.corvusenterprises.digimonapp";
private static final String BASE_PATH_DIGIMON = "digimon";
private static final String BASE_PATH_ATTACKS = "attacks";
private static final String BASE_PATH_EVOLUTIONS = "evolutions";
public static final Uri CONTENT_URI_DIGIMON = Uri.parse("content://" + AUTHORITY + "/" + BASE_PATH_DIGIMON);
public static final Uri CONTENT_URI_ATTACKS = Uri.parse("content://" + AUTHORITY + "/" + BASE_PATH_ATTACKS);
public static final Uri CONTENT_URI_EVOLUTIONS = Uri.parse("content://" + AUTHORITY + "/" + BASE_PATH_EVOLUTIONS);
public static final String CONTENT_TYPE = ContentResolver.CURSOR_DIR_BASE_TYPE + "/digimon";
public static final String CONTENT_ITEM_TYPE = ContentResolver.CURSOR_ITEM_BASE_TYPE + "/digimon";
private static final UriMatcher sURIMatcher = new UriMatcher(UriMatcher.NO_MATCH);
static {
sURIMatcher.addURI(AUTHORITY, BASE_PATH_DIGIMON, DIGIMON);
sURIMatcher.addURI(AUTHORITY, BASE_PATH_DIGIMON + "/#", DIGIMON_ID);
sURIMatcher.addURI(AUTHORITY, BASE_PATH_ATTACKS, ATTACKS);
sURIMatcher.addURI(AUTHORITY, BASE_PATH_ATTACKS + "/#", ATTACKS_ID);
sURIMatcher.addURI(AUTHORITY, BASE_PATH_EVOLUTIONS, EVOLUTIONS);
sURIMatcher.addURI(AUTHORITY, BASE_PATH_EVOLUTIONS + "/#", EVOLUTIONS_ID);
}
private DigimonContentProvider()
{
}
public static DigimonContentProvider getInstance() {
if (instance == null)
instance = new DigimonContentProvider();
return instance;
}
#Override
public boolean onCreate() {
Context ctx = MyApp.getContext();
dbHelper = DBHelper.getInstance(ctx);
dbHelper.insertDigimon("Guilmon", "Guilmon", "Child/Rookie", "Virus", "Dinosaur", "TRUE","R.mipmap.guilmon.jpg");
dbHelper.insertDigimon("Growmon", "Growlmon", "Adult/Champion", "Virus", "Bigger Dinosaur", "FALSE","R.mipmap.growmon.jpg");
dbHelper.insertDigimon("Terriermon", "terriermon", "Child/Rookie", "Vaccine", "Dogbunny", "FALSE","R.mipmap.terriermon.jpg");
dbHelper.insertDigimon("Galgomon", "Gargomon", "Adult/Champion", "Vaccine", "Gunbunny", "FALSE","R.mipmap.galgomon.jpg");
dbHelper.insertDigimon("Kyubimon", "Kyubimon", "Adult/Champion", "Data", "9-Tailed Fox", "FALSE","R.mipmap.kyubimon.jpg");
dbHelper.insertDigimon("Taomon", "Taomon", "Perfect/Ultimate", "Data", "Kitsune Miko", "FALSE","R.mipmap.taomon.jpg");
dbHelper.insertDigimon("Impmon", "Impmon", "Child/Rookie", "Virus", "Kid in a purple onesie", "FALSE","R.mipmap.impmon.jpg");
dbHelper.insertDigimon("Beelzebumon", "Beelzemon", "Ultimate/Mega", "Virus", "Demon Lord of Gluttony", "FALSE","R.mipmap.beelzebumon.jpg");
presentDigimon[460] = true; presentDigimon[454] = true;
presentDigimon[1019] = true; presentDigimon[374] = true;
presentDigimon[572] = true; presentDigimon[1013] = true;
presentDigimon[507] = true; presentDigimon[100] = true;
dbHelper.insertEvolution("Guilmon", "Growmon", "");
dbHelper.insertEvolution("Terriermon", "Galgomon","");
dbHelper.insertEvolution("Kyubimon", "Taomon","");
dbHelper.insertEvolution("Impmon", "Beelzebumon", "(Warp Evolution)");
dbHelper.insertAttack("Fireball", "Pyro Sphere", "Guilmon", "Explosive Fireball");
dbHelper.insertAttack("Rock Breaker", "Rock Breaker", "Guilmon", "Claw Swipe");
dbHelper.insertAttack("Exhaust Flame", "Pyro Blaster", "Growmon", "Fire Laser");
dbHelper.insertAttack("Plasma Blade", "Dragon Slash", "Growmon", "Forearm Blades");
dbHelper.insertAttack("Blazing Fire", "Bunny Blast", "Terriermon", "Energy Blast");
dbHelper.insertAttack("Petit Twister", "Terrier Tornado", "Terriermon", "Throws Tornado");
dbHelper.insertAttack("Gatling Arm", "Gargo Laser", "Galgomon", "Fires Guns");
dbHelper.insertAttack("Dum Dum Upper", "Bunny Pummel", "Galgomon", "Fires Guns While Punching");
dbHelper.insertAttack("Koenryu", "Dragon Wheel", "Kyubimon", "Fire Dragon");
dbHelper.insertAttack("Onibidama", "Fox-Tail Inferno", "Kyubimon", "Fireballs from the tails");
dbHelper.insertAttack("Bonhitsusen", "Talisman of Light", "Taomon", "Energy Seal Laser");
dbHelper.insertAttack("Oṃ", "Talisman Spell", "Taomon", "Makes a dome shield");
dbHelper.insertAttack("Night of Fire", "Badaboom", "Impmon", "Mini-Fireballs");
dbHelper.insertAttack("Pillar of Fire", "", "Impmon", "Wall of Flames");
dbHelper.insertAttack("Double Impact", "Double Impact", "Beelzebumon", "Fires two bullets");
dbHelper.insertAttack("Darkness Claw", "", "Beelzebumon", "Kills Leomon");
db = dbHelper.getWritableDatabase();
return false;
}
#Override
public Uri insert(Uri uri, ContentValues values) {
Uri _uri = null;
switch (sURIMatcher.match(uri)) {
case DIGIMON:
long _ID1 = db.insert(DigimonTable.DIGIMON_TABLE_NAME, "", values);
if (_ID1 > 0) {
_uri = ContentUris.withAppendedId(CONTENT_URI_DIGIMON, _ID1);
MyApp.getContext().getContentResolver().notifyChange(_uri, null);
}
break;
case ATTACKS:
long _ID2 = db.insert(AttacksTable.ATTACKS_TABLE_NAME, "", values);
if (_ID2 > 0) {
_uri = ContentUris.withAppendedId(CONTENT_URI_ATTACKS, _ID2);
MyApp.getContext().getContentResolver().notifyChange(_uri, null);
}
break;
case EVOLUTIONS:
long _ID3 = db.insert(EvolutionsTable.EVOLUTIONS_TABLE_NAME, "", values);
if (_ID3 > 0) {
_uri = ContentUris.withAppendedId(CONTENT_URI_EVOLUTIONS, _ID3);
MyApp.getContext().getContentResolver().notifyChange(_uri, null);
}
break;
default:
throw new SQLException("Failed to insert row into " + uri);
}
MyApp.getContext().getContentResolver().notifyChange(uri, null);
return _uri;
}
#Override
public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {
SQLiteQueryBuilder queryBuilder = new SQLiteQueryBuilder();
int uriType = sURIMatcher.match(uri);
checkColumns(projection, uriType);
queryBuilder.setTables(DigimonTable.DIGIMON_TABLE_NAME + ", " + EvolutionsTable.EVOLUTIONS_TABLE_NAME + ", " + AttacksTable.ATTACKS_TABLE_NAME);
switch (uriType) {
case DIGIMON:
break;
case DIGIMON_ID:
queryBuilder.appendWhere(DigimonTable.DIGIMON_COLUMN_ID+"="+uri.getLastPathSegment());
case ATTACKS:
break;
case ATTACKS_ID:
queryBuilder.appendWhere(AttacksTable.ATTACKS_COLUMN_ID+"="+uri.getLastPathSegment());
case EVOLUTIONS:
break;
case EVOLUTIONS_ID:
queryBuilder.appendWhere(EvolutionsTable.EVOLUTIONS_COLUMN_ID+"="+uri.getLastPathSegment());
default:
throw new IllegalArgumentException("Unknown URI: "+ uri);
}
Cursor cursor = queryBuilder.query(db, projection, selection, selectionArgs, null, null, sortOrder);
cursor.setNotificationUri(MyApp.getContext().getContentResolver(), uri);
return cursor;
}
#Override
public String getType(Uri uri) {
return null;
}
#Override
public int delete(Uri uri, String selection, String[] selectionArgs) {
int uriType = sURIMatcher.match(uri);
int rowsDeleted = 0;
switch (uriType) {
case DIGIMON:
rowsDeleted = db.delete(DigimonTable.DIGIMON_TABLE_NAME, selection, selectionArgs);
break;
case DIGIMON_ID:
String id1 = uri.getLastPathSegment();
if (TextUtils.isEmpty(selection)) {
rowsDeleted = db.delete(
DigimonTable.DIGIMON_TABLE_NAME,
DigimonTable.DIGIMON_COLUMN_ID + "=" + id1,
null);
} else {
rowsDeleted = db.delete(
DigimonTable.DIGIMON_TABLE_NAME,
DigimonTable.DIGIMON_COLUMN_ID + "=" + id1
+ " and " + selection,
selectionArgs);
}
break;
case ATTACKS:
rowsDeleted = db.delete(AttacksTable.ATTACKS_TABLE_NAME, selection, selectionArgs);
break;
case ATTACKS_ID:
String id2 = uri.getLastPathSegment();
if (TextUtils.isEmpty(selection)) {
rowsDeleted = db.delete(
AttacksTable.ATTACKS_TABLE_NAME,
AttacksTable.ATTACKS_COLUMN_ID + "=" + id2,
null);
} else {
rowsDeleted = db.delete(
AttacksTable.ATTACKS_TABLE_NAME,
AttacksTable.ATTACKS_COLUMN_ID + "=" + id2
+ " and " + selection,
selectionArgs);
}
break;
case EVOLUTIONS:
rowsDeleted = db.delete(EvolutionsTable.EVOLUTIONS_TABLE_NAME, selection, selectionArgs);
break;
case EVOLUTIONS_ID:
String id3 = uri.getLastPathSegment();
if (TextUtils.isEmpty(selection)) {
rowsDeleted = db.delete(
EvolutionsTable.EVOLUTIONS_TABLE_NAME,
EvolutionsTable.EVOLUTIONS_COLUMN_ID + "=" + id3,
null);
} else {
rowsDeleted = db.delete(
EvolutionsTable.EVOLUTIONS_TABLE_NAME,
EvolutionsTable.EVOLUTIONS_COLUMN_ID + "=" + id3
+ " and " + selection,
selectionArgs);
}
break;
default:
throw new IllegalArgumentException("Unknown URI: " + uri);
}
MyApp.getContext().getContentResolver().notifyChange(uri, null);
return rowsDeleted;
}
#Override
public int update(Uri uri, ContentValues values, String selection,
String[] selectionArgs) {
int uriType = sURIMatcher.match(uri);
int rowsUpdated = 0;
switch (uriType) {
case DIGIMON:
rowsUpdated = db.update(DigimonTable.DIGIMON_TABLE_NAME,
values,
selection,
selectionArgs);
break;
case DIGIMON_ID:
String id1 = uri.getLastPathSegment();
if (TextUtils.isEmpty(selection)) {
rowsUpdated = db.update(DigimonTable.DIGIMON_TABLE_NAME,
values,
DigimonTable.DIGIMON_COLUMN_ID + "=" + id1,
null);
} else {
rowsUpdated = db.update(DigimonTable.DIGIMON_TABLE_NAME,
values,
DigimonTable.DIGIMON_COLUMN_ID + "=" + id1
+ " and "
+ selection,
selectionArgs);
}
break;
case ATTACKS:
rowsUpdated = db.update(AttacksTable.ATTACKS_TABLE_NAME,
values,
selection,
selectionArgs);
break;
case ATTACKS_ID:
String id2 = uri.getLastPathSegment();
if (TextUtils.isEmpty(selection)) {
rowsUpdated = db.update(AttacksTable.ATTACKS_TABLE_NAME,
values,
AttacksTable.ATTACKS_COLUMN_ID + "=" + id2,
null);
} else {
rowsUpdated = db.update(AttacksTable.ATTACKS_TABLE_NAME,
values,
AttacksTable.ATTACKS_COLUMN_ID + "=" + id2
+ " and "
+ selection,
selectionArgs);
}
break;
case EVOLUTIONS:
rowsUpdated = db.update(EvolutionsTable.EVOLUTIONS_TABLE_NAME,
values,
selection,
selectionArgs);
break;
case EVOLUTIONS_ID:
String id3 = uri.getLastPathSegment();
if (TextUtils.isEmpty(selection)) {
rowsUpdated = db.update(EvolutionsTable.EVOLUTIONS_TABLE_NAME,
values,
EvolutionsTable.EVOLUTIONS_COLUMN_ID + "=" + id3,
null);
} else {
rowsUpdated = db.update(EvolutionsTable.EVOLUTIONS_TABLE_NAME,
values,
EvolutionsTable.EVOLUTIONS_COLUMN_ID + "=" + id3
+ " and "
+ selection,
selectionArgs);
}
break;
default:
throw new IllegalArgumentException("Unknown URI: " + uri);
}
MyApp.getContext().getContentResolver().notifyChange(uri, null);
return rowsUpdated;
}
private void checkColumns(String[] projection, int uri) {
HashSet<String> availableColumns;
String[] availableDigimon = { DigimonTable.DIGIMON_COLUMN_ID,
DigimonTable.DIGIMON_COLUMN_NAME, DigimonTable.DIGIMON_COLUMN_DUB_NAME,
DigimonTable.DIGIMON_COLUMN_LEVEL, DigimonTable.DIGIMON_COLUMN_ATTRIBUTE,
DigimonTable.DIGIMON_COLUMN_DESCRIPTION, DigimonTable.DIGIMON_COLUMN_FAVOURITE,
DigimonTable.DIGIMON_COLUMN_PATH};
String[] availableAttacks = {AttacksTable.ATTACKS_COLUMN_ID, AttacksTable.ATTACKS_COLUMN_NAME,
AttacksTable.ATTACKS_COLUMN_DUB_NAME, AttacksTable.ATTACKS_COLUMN_DIGIMON,
AttacksTable.ATTACKS_COLUMN_DESCRIPTION};
String[] availableEvolutions = {EvolutionsTable.EVOLUTIONS_COLUMN_ID,EvolutionsTable.EVOLUTIONS_COLUMN_FROM,
EvolutionsTable.EVOLUTIONS_COLUMN_TO, EvolutionsTable.EVOLUTIONS_COLUMN_CONDITIONS};
if (projection != null) {
HashSet<String> requestedColumns = new HashSet<String>(
Arrays.asList(projection));
switch(uri){
case DIGIMON:
case DIGIMON_ID: availableColumns = new HashSet<String>(Arrays.asList(availableDigimon));
break;
case ATTACKS:
case ATTACKS_ID: availableColumns = new HashSet<String>(Arrays.asList(availableAttacks));
break;
case EVOLUTIONS:
case EVOLUTIONS_ID: availableColumns = new HashSet<String>(Arrays.asList(availableEvolutions));
break;
default: availableColumns = new HashSet<String>(Arrays.asList(availableDigimon));
}
// check if all columns which are requested are available
if (!availableColumns.containsAll(requestedColumns)) {
throw new IllegalArgumentException(
"Unknown columns in projection");
}
}
}
public Cursor defaultMainMenu()
{
Cursor cursor = MyApp.getContext().getContentResolver().query(CONTENT_URI_DIGIMON, new String[]{DigimonTable.DIGIMON_COLUMN_NAME, DigimonTable.DIGIMON_COLUMN_FAVOURITE}, null, null, DigimonTable.DIGIMON_COLUMN_NAME + " ASC");
int dummy = cursor.getCount();
return cursor;
}
public Cursor searchMenuQuery(String search)
{
Cursor cursor = MyApp.getContext().getContentResolver().query(CONTENT_URI_DIGIMON,new String[] {DigimonTable.DIGIMON_COLUMN_NAME,DigimonTable.DIGIMON_COLUMN_FAVOURITE},DigimonTable.DIGIMON_COLUMN_NAME+" = '?'",new String[]{search},DigimonTable.DIGIMON_COLUMN_NAME+" ASC");
int dummy = cursor.getCount();
return cursor;
}
public Cursor favouritesMenuQuery()
{
Cursor cursor = MyApp.getContext().getContentResolver().query(CONTENT_URI_DIGIMON,new String[] {DigimonTable.DIGIMON_COLUMN_NAME},DigimonTable.DIGIMON_COLUMN_FAVOURITE+" = true",null,DigimonTable.DIGIMON_COLUMN_NAME+" ASC");
int dummy = cursor.getCount();
return cursor;
}
public Cursor digimonProfileQuery(String name)
{
Cursor cursor = MyApp.getContext().getContentResolver().query(CONTENT_URI_DIGIMON,null,DigimonTable.DIGIMON_COLUMN_NAME+" = '?'",new String[]{name},null);
int dummy = cursor.getCount();
return cursor;
}
public Cursor digimonAttacksQuery(String name)
{
Cursor cursor = MyApp.getContext().getContentResolver().query(CONTENT_URI_ATTACKS,null,AttacksTable.ATTACKS_COLUMN_DIGIMON+" = '?'",new String[]{name},null);
int dummy = cursor.getCount();
return cursor;
}
public Cursor digimonEvolutionFromQuery(String name)
{
Cursor cursor = MyApp.getContext().getContentResolver().query(CONTENT_URI_EVOLUTIONS,null,EvolutionsTable.EVOLUTIONS_COLUMN_FROM+" = '?'",new String[]{name},null);
int dummy = cursor.getCount();
return cursor;
}
public Cursor digimonEvolutionToQuery(String name)
{
Cursor cursor = MyApp.getContext().getContentResolver().query(CONTENT_URI_EVOLUTIONS,null,EvolutionsTable.EVOLUTIONS_COLUMN_TO+" = '?'",new String[]{name},null);
int dummy = cursor.getCount();
return cursor;
}
}
And here's the Logcat results:
Process: com.corvus.corvusenterprises.digimonapp, PID: 12198
java.lang.RuntimeException: Unable to get provider com.corvus.corvusenterprises.digimonapp.DigimonContentProvider: java.lang.NullPointerException
at android.app.ActivityThread.installProvider(ActivityThread.java:5084)
at android.app.ActivityThread.installContentProviders(ActivityThread.java:4673)
at android.app.ActivityThread.handleBindApplication(ActivityThread.java:4613)
at android.app.ActivityThread.access$1800(ActivityThread.java:141)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1298)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:136)
at android.app.ActivityThread.main(ActivityThread.java:5333)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:895)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:711)
at dalvik.system.NativeStart.main(Native Method)
Caused by: java.lang.NullPointerException
at android.database.sqlite.SQLiteOpenHelper.getDatabaseLocked(SQLiteOpenHelper.java:224)
at android.database.sqlite.SQLiteOpenHelper.getWritableDatabase(SQLiteOpenHelper.java:164)
at com.corvus.corvusenterprises.digimonapp.DigimonContentProvider.onCreate(DigimonContentProvider.java:62)
at android.content.ContentProvider.attachInfo(ContentProvider.java:1616)
at android.content.ContentProvider.attachInfo(ContentProvider.java:1587)
at android.app.ActivityThread.installProvider(ActivityThread.java:5081)
at android.app.ActivityThread.installContentProviders(ActivityThread.java:4673)
at android.app.ActivityThread.handleBindApplication(ActivityThread.java:4613)
at android.app.ActivityThread.access$1800(ActivityThread.java:141)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1298)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:136)
at android.app.ActivityThread.main(ActivityThread.java:5333)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:895)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:711)
at dalvik.system.NativeStart.main(Native Method)
Here's the DBHelper code, in case it helps:
package com.corvus.corvusenterprises.digimonapp;
import android.content.ContentValues;
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import static com.corvus.corvusenterprises.digimonapp.DigimonContentProvider.CONTENT_URI_ATTACKS;
import static com.corvus.corvusenterprises.digimonapp.DigimonContentProvider.CONTENT_URI_DIGIMON;
import static com.corvus.corvusenterprises.digimonapp.DigimonContentProvider.CONTENT_URI_EVOLUTIONS;
/**
* Created by Jack on 01/05/2017.
*/
public class DBHelper extends SQLiteOpenHelper {
public static final String[]digimonArray = {
"Gigantic array of names"};
private static final String DATABASE_NAME = "DigimonDatabase.db";
private static final int version = 1;
private static DBHelper instance;
public static boolean[]presentDigimon = new boolean[digimonArray.length];
private DBHelper(Context context) {
super(context, DATABASE_NAME, null, version);
}
public static DBHelper getInstance(Context ctx) {
if (instance == null)
instance = new DBHelper(ctx);
return instance;
}
#Override
public void onCreate(SQLiteDatabase db) {
DigimonTable.onCreate(db);
AttacksTable.onCreate(db);
EvolutionsTable.onCreate(db);
}
public void onUpgrade(SQLiteDatabase db, int oldver, int newVer)
{
DigimonTable.onUpgrade(db,oldver,newVer);
AttacksTable.onUpgrade(db,oldver,newVer);
EvolutionsTable.onUpgrade(db,oldver,newVer);
}
public void insertDigimon(String name, String dub_name, String level, String attribute, String description, String favourite, String path)
{
DigimonContentProvider dcp = DigimonContentProvider.getInstance();
ContentValues values = new ContentValues();
values.put(DigimonTable.DIGIMON_COLUMN_NAME,name);
values.put(DigimonTable.DIGIMON_COLUMN_DUB_NAME,dub_name);
values.put(DigimonTable.DIGIMON_COLUMN_LEVEL,level);
values.put(DigimonTable.DIGIMON_COLUMN_ATTRIBUTE,attribute);
values.put(DigimonTable.DIGIMON_COLUMN_DESCRIPTION,description);
values.put(DigimonTable.DIGIMON_COLUMN_FAVOURITE, favourite);
values.put(DigimonTable.DIGIMON_COLUMN_PATH,path);
dcp.insert(CONTENT_URI_DIGIMON, values);
}
public void insertAttack(String name, String dub_name, String digimon, String description)
{
DigimonContentProvider dcp = DigimonContentProvider.getInstance();
ContentValues values = new ContentValues();
values.put(AttacksTable.ATTACKS_COLUMN_NAME, name);
values.put(AttacksTable.ATTACKS_COLUMN_DUB_NAME,dub_name);
values.put(AttacksTable.ATTACKS_COLUMN_DIGIMON, digimon);
values.put(AttacksTable.ATTACKS_COLUMN_DESCRIPTION, description);
dcp.insert(CONTENT_URI_ATTACKS, values);
}
public void insertEvolution(String from, String to, String conditions)
{
DigimonContentProvider dcp = DigimonContentProvider.getInstance();
ContentValues values = new ContentValues();
values.put(EvolutionsTable.EVOLUTIONS_COLUMN_TO,to);
values.put(EvolutionsTable.EVOLUTIONS_COLUMN_FROM,from);
values.put(EvolutionsTable.EVOLUTIONS_COLUMN_CONDITIONS,conditions);
dcp.insert(CONTENT_URI_EVOLUTIONS, values);
}
}
Any and all help appreciated. If you need more information, just let me know.
(EDITED): New version being worked on. Code updated.
(EDITED 2): Fixed a possible issue with recursive calls.
I know for a fact that the Context isn't null
How do you know that? MyApp.getContext() looks strange to me.
Try giving the Context to the ContentProvider
private Context mContext;
private DigimonContentProvider(Context context)
{
this.mContext = context;
}
private DigimonContentProvider() { }
public static DigimonContentProvider getInstance(Context context) {
if (instance == null)
instance = new DigimonContentProvider(context);
return instance;
}
#Override
public boolean onCreate() {
dbHelper = DBHelper.getInstance(this.mContext);
However, you don't need a ContentProvider to have a database, so try getting the database working without it.
It is throwing a NullPointerException because you are trying to access your ContentProvider methods directly instead of using a ContentResolver for the same.
You can abstract the code you have written in the ContentProvider to access it in an another class. And this time use a ContentResolver instance for the same.
Edit:
Maybe your problem is that your dbHelper is not singleton and you are creating an another instances of it through dbHelper.getInstance(getContext) in insert() method.
Try getting a new instance of dbHelper only in onCreate() method and not in other methods.
You can use this example: MoviesContentProvider.java
I am totally new in this and I am sure I screwed the code somehow, please help me fix it.
I have the following contentprovider for building a database to store favourite tags:
public class FTagsContentProvider extends ContentProvider {
static final String AUTHORITY = "ch.ethz.twimight.FTags";
private static final String BASE_PATH = "ftags";
public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY
+ "/" + BASE_PATH);
// fields for the database
public static final String COL_ID = "id";
public static final String COL_TEXT = "text";
public static final String COL_COUNT = "count";
static final int FTAGS = 1;
static final int FTAGS_ID = 2;
DBHelper dbHelper;
private static HashMap<String, String> FTagsMap;
static final UriMatcher uriMatcher;
static{
uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
uriMatcher.addURI(AUTHORITY, BASE_PATH, FTAGS);
uriMatcher.addURI(AUTHORITY, BASE_PATH + "/#", FTAGS_ID);
}
// database declarations
private SQLiteDatabase database;
static final String DATABASE_NAME = "ftagtable.db";
static final String TABLE_FTAGS = "FTags";
static final int DATABASE_VERSION = 1;
private static final String TABLE_FTAGS_CREATE = "create table "
+ TABLE_FTAGS
+ "("
+ COL_ID + " integer primary key autoincrement, "
+ COL_TEXT + " text not null, "
+ COL_COUNT + " integer"
+ ");";
private static class DBHelper extends SQLiteOpenHelper {
public DBHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
// TODO Auto-generated constructor stub
}
#Override
public void onCreate(SQLiteDatabase db) {
// TODO Auto-generated method stub
db.execSQL(TABLE_FTAGS_CREATE);
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
// TODO Auto-generated method stub
Log.w(DBHelper.class.getName(),
"Upgrading database from version " + oldVersion + " to "
+ newVersion + ". Old data will be destroyed");
db.execSQL("DROP TABLE IF EXISTS " + TABLE_FTAGS);
onCreate(db);
}
}
#Override
public boolean onCreate() {
// TODO Auto-generated method stub
Context context = getContext();
dbHelper = new DBHelper(context);
database = dbHelper.getWritableDatabase();
if(database == null)
return false;
else
return true;
}
#Override
public Cursor query(Uri uri, String[] projection, String selection,
String[] selectionArgs, String sortOrder) {
// TODO Auto-generated method stub
SQLiteQueryBuilder queryBuilder = new SQLiteQueryBuilder();
queryBuilder.setTables(TABLE_FTAGS);
switch (uriMatcher.match(uri)) {
case FTAGS:
queryBuilder.setProjectionMap(FTagsMap);
break;
case FTAGS_ID:
queryBuilder.appendWhere( COL_ID + "=" + uri.getLastPathSegment());
break;
default:
throw new IllegalArgumentException("Unknown URI " + uri);
}
if (sortOrder == null || sortOrder == ""){
sortOrder = COL_TEXT;
}
Cursor cursor = queryBuilder.query(database, projection, selection,
selectionArgs, null, null, sortOrder);
/**
* register to watch a content URI for changes
*/
cursor.setNotificationUri(getContext().getContentResolver(), uri);
return cursor;
}
#Override
public Uri insert(Uri uri, ContentValues values) {
// TODO Auto-generated method stub
long row = database.insert(TABLE_FTAGS, "", values);
if(row > 0) {
Uri newUri = ContentUris.withAppendedId(CONTENT_URI, row);
getContext().getContentResolver().notifyChange(newUri, null);
return newUri;
}
throw new SQLException("Fail to add a new record into " + uri);
}
#Override
public int update(Uri uri, ContentValues values, String selection,
String[] selectionArgs) {
// TODO Auto-generated method stub
int rowsUpdated = 0;
switch (uriMatcher.match(uri)){
case FTAGS:
rowsUpdated = database.update(TABLE_FTAGS, values, selection, selectionArgs);
break;
case FTAGS_ID:
rowsUpdated = database.update(TABLE_FTAGS, values, COL_ID +
" = " + uri.getLastPathSegment() +
(!TextUtils.isEmpty(selection) ? " AND (" +
selection + ')' : ""), selectionArgs);
break;
default:
throw new IllegalArgumentException("Unsupported URI " + uri );
}
getContext().getContentResolver().notifyChange(uri, null);
return rowsUpdated;
}
#Override
public int delete(Uri uri, String selection, String[] selectionArgs) {
// TODO Auto-generated method stub
int count = 0;
switch (uriMatcher.match(uri)){
case FTAGS:
count = database.delete(TABLE_FTAGS, selection, selectionArgs);
break;
case FTAGS_ID:
String id = uri.getLastPathSegment(); //gets the id
count = database.delete( TABLE_FTAGS, COL_ID + " = " + id +
(!TextUtils.isEmpty(selection) ? " AND (" +
selection + ')' : ""), selectionArgs);
break;
default:
throw new IllegalArgumentException("Unsupported URI " + uri);
}
getContext().getContentResolver().notifyChange(uri, null);
return count;
}
#Override
public String getType(Uri uri) {
// TODO Auto-generated method stub
return null;
}
}
I want to set the COL_COUNT as a value of keeping count the times that a tag has been inserted into the database, originally it should be 1 for each tag, and I want it to update only the count like from 1 to 2 and so on every time an existing tag is input.
Here is the Activity:
public class TestActivity extends Activity {
private EditText mText;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.test);
}
public boolean check(String s){
boolean t = false;
ContentResolver contentResolver = this.getContentResolver();
Cursor cursor = contentResolver.query(FTagsContentProvider.CONTENT_URI,
new String []{FTagsContentProvider.COL_TEXT}, FTagsContentProvider.COL_TEXT + "=?", new String[]{s}, null);
if(cursor.getCount > 0){
t = true;
}
else{
t = false;
}
cursor.close();
return t;
}
public void addFTag(View view) {
// Add a new tag
ContentValues values = new ContentValues();
mText = (EditText)findViewById(R.id.name);
String mFtag = mText.getText().toString();
boolean exist = check(mFtag);
if(exist == false){
values.put(FTagsContentProvider.COL_TEXT,
mFtag);
Uri uri = getContentResolver().insert(
FTagsContentProvider.CONTENT_URI, values);
Toast.makeText(getBaseContext(),
"Record inserted!", Toast.LENGTH_LONG).show();
}
else{
// code for only updating the COL_COUNT somehow
Toast.makeText(this, "Some tag meet you again :)",
Toast.LENGTH_LONG).show();
}}
public void showAllTags(View view) {
Cursor c = getContentResolver().query(FTagsContentProvider.CONTENT_URI, null, null, null, null);
String result = "Results:";
if (!c.moveToFirst()) {
Toast.makeText(this, result+" no content yet!", Toast.LENGTH_LONG).show();
}else{
do{
result = result + "\n" + c.getString(c.getColumnIndex(FTagsContentProvider.COL_TEXT)) +
" with id " + c.getString(c.getColumnIndex(FTagsContentProvider.COL_ID)) +
" has count: " + c.getString(c.getColumnIndex(FTagsContentProvider.COL_COUNT));
} while (c.moveToNext());
Toast.makeText(this, result, Toast.LENGTH_LONG).show();
}
}
}
Any help would be much appreciated :)
I have the following method for updating only the COL_COUNT(originally set to 1) of an existing record "tag" in database:
public void addCount(){
mFtag = "tag";
String t = "2";
ContentValues values = new ContentValues();
values.put(FTagsContentProvider.COL_COUNT, t );
getContentResolver().update(FTagsContentProvider.CONTENT_URI, values, "COL_TEXT=?", new String[]{mFtag});
}
When I run it I got the following exception:
I tried changing the line
getContentResolver().update(FTagsContentProvider.CONTENT_URI, values, "COL_TEXT=?", new String[]{mFtag});
to
getContentResolver().update(FTagsContentProvider.CONTENT_URI, values, FTagsContentProvider.COL_TEXT + "=?", new String[]{mFtag});
Still same exception just change from "no such column: COL_TEXT" to "no such column: tag"
Here is the ContentProvider:
public class FTagsContentProvider extends ContentProvider {
static final String AUTHORITY = "ch.ethz.twimight.FTags";
private static final String BASE_PATH = "ftags";
public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY
+ "/" + BASE_PATH);
// fields for the database
public static final String COL_ID = "id";
public static final String COL_TEXT = "text";
public static final String COL_COUNT = "count";
static final int FTAGS = 1;
static final int FTAGS_ID = 2;
DBHelper dbHelper;
private static HashMap<String, String> FTagsMap;
static final UriMatcher uriMatcher;
static{
uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
uriMatcher.addURI(AUTHORITY, BASE_PATH, FTAGS);
uriMatcher.addURI(AUTHORITY, BASE_PATH + "/#", FTAGS_ID);
}
// database declarations
private SQLiteDatabase database;
static final String DATABASE_NAME = "ftagtable.db";
static final String TABLE_FTAGS = "FTags";
static final int DATABASE_VERSION = 1;
private static final String TABLE_FTAGS_CREATE = "create table "
+ TABLE_FTAGS
+ "("
+ COL_ID + " integer primary key autoincrement, "
+ COL_TEXT + " text not null, "
+ COL_COUNT + " integer"
+ ");";
private static class DBHelper extends SQLiteOpenHelper {
public DBHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
// TODO Auto-generated constructor stub
}
#Override
public void onCreate(SQLiteDatabase db) {
// TODO Auto-generated method stub
db.execSQL(TABLE_FTAGS_CREATE);
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
// TODO Auto-generated method stub
Log.w(DBHelper.class.getName(),
"Upgrading database from version " + oldVersion + " to "
+ newVersion + ". Old data will be destroyed");
db.execSQL("DROP TABLE IF EXISTS " + TABLE_FTAGS);
onCreate(db);
}
}
#Override
public boolean onCreate() {
// TODO Auto-generated method stub
Context context = getContext();
dbHelper = new DBHelper(context);
database = dbHelper.getWritableDatabase();
if(database == null)
return false;
else
return true;
}
#Override
public Cursor query(Uri uri, String[] projection, String selection,
String[] selectionArgs, String sortOrder) {
// TODO Auto-generated method stub
SQLiteQueryBuilder queryBuilder = new SQLiteQueryBuilder();
queryBuilder.setTables(TABLE_FTAGS);
switch (uriMatcher.match(uri)) {
case FTAGS:
queryBuilder.setProjectionMap(FTagsMap);
break;
case FTAGS_ID:
queryBuilder.appendWhere( COL_ID + "=" + uri.getLastPathSegment());
break;
default:
throw new IllegalArgumentException("Unknown URI " + uri);
}
if (sortOrder == null || sortOrder == ""){
sortOrder = COL_TEXT;
}
Cursor cursor = queryBuilder.query(database, projection, selection,
selectionArgs, null, null, sortOrder);
/**
* register to watch a content URI for changes
*/
cursor.setNotificationUri(getContext().getContentResolver(), uri);
return cursor;
}
#Override
public Uri insert(Uri uri, ContentValues values) {
// TODO Auto-generated method stub
long row = database.insert(TABLE_FTAGS, "", values);
if(row > 0) {
Uri newUri = ContentUris.withAppendedId(CONTENT_URI, row);
getContext().getContentResolver().notifyChange(newUri, null);
return newUri;
}
throw new SQLException("Fail to add a new record into " + uri);
}
#Override
public int update(Uri uri, ContentValues values, String selection,
String[] selectionArgs) {
// TODO Auto-generated method stub
int rowsUpdated = 0;
switch (uriMatcher.match(uri)){
case FTAGS:
rowsUpdated = database.update(TABLE_FTAGS, values, selection, selectionArgs);
break;
case FTAGS_ID:
rowsUpdated = database.update(TABLE_FTAGS, values, COL_ID +
" = " + uri.getLastPathSegment() +
(!TextUtils.isEmpty(selection) ? " AND (" +
selection + ')' : ""), selectionArgs);
break;
default:
throw new IllegalArgumentException("Unsupported URI " + uri );
}
getContext().getContentResolver().notifyChange(uri, null);
return rowsUpdated;
}
#Override
public int delete(Uri uri, String selection, String[] selectionArgs) {
// TODO Auto-generated method stub
int count = 0;
switch (uriMatcher.match(uri)){
case FTAGS:
count = database.delete(TABLE_FTAGS, selection, selectionArgs);
break;
case FTAGS_ID:
String id = uri.getLastPathSegment(); //gets the id
count = database.delete( TABLE_FTAGS, COL_ID + " = " + id +
(!TextUtils.isEmpty(selection) ? " AND (" +
selection + ')' : ""), selectionArgs);
break;
default:
throw new IllegalArgumentException("Unsupported URI " + uri);
}
getContext().getContentResolver().notifyChange(uri, null);
return count;
}
#Override
public String getType(Uri uri) {
// TODO Auto-generated method stub
return null;
}
}
Is it a problem with the method or there is something wrong with the ContentProvider? Please help
getContentResolver().update(FTagsContentProvider.CONTENT_URI, values, FTagsContentProvider.COL_TEXT + "=?", new String[]{mFtag});
is the correct usage.
public static final String COL_TEXT = "text";
text is a reserved keyword. You can't have a column named text. Change the name of the column and you'll be fine.
I have already checked the other XML files for errors, however this is the file that the error message is saying the error is in. There is also a message that pops up whenever I try to run the app that says, "Files under the build folder are generated and should not be edited".
package com.example.drive.drivercorder;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.util.Log;
public class DBAdapter {
private static final String TAG = "DBAdapter";
public static final String KEY_ROWID = "_id";
public static final int COL_ROWID = 0;
public static final String KEY_DRIVETIME = "Drive Time";
public static final String KEY_NIGHTORDAY = "Time of Day";
public static final int COL_DRIVETIME = 1;
public static final int COL_NIGHTORDAY = 2;
public static final String[] ALL_KEYS = new String[] {KEY_ROWID, KEY_DRIVETIME, KEY_NIGHTORDAY, };
public static final String DATABASE_NAME = "MyDb";
public static final String DATABASE_TABLE = "mainTable";
public static final int DATABASE_VERSION = 2;
private static final String DATABASE_CREATE_SQL =
"create table " + DATABASE_TABLE
+ " (" + KEY_ROWID + " integer primary key autoincrement, "
+ KEY_DRIVETIME + " integer not null, "
+ KEY_NIGHTORDAY + " text not null "
+ ");";
private final Context context;
private DatabaseHelper myDBHelper;
private SQLiteDatabase db;
public DBAdapter(Context ctx) {
this.context = ctx;
myDBHelper = new DatabaseHelper(context);
}
public DBAdapter open() {
db = myDBHelper.getWritableDatabase();
return this;
}
public void close() {
myDBHelper.close();
}
public long insertRow(int drivetime, String nightorday) {
ContentValues initialValues = new ContentValues();
initialValues.put(KEY_DRIVETIME, Drive Time);
initialValues.put(KEY_NIGHTORDAY, Time of Day);
return db.insert(DATABASE_TABLE, null, initialValues);
}
public boolean deleteRow(long rowId) {
String where = KEY_ROWID + "=" + rowId;
return db.delete(DATABASE_TABLE, where, null) != 0;
}
public void deleteAll() {
Cursor c = getAllRows();
long rowId = c.getColumnIndexOrThrow(KEY_ROWID);
if (c.moveToFirst()) {
do {
deleteRow(c.getLong((int) rowId));
} while (c.moveToNext());
}
c.close();
}
public Cursor getAllRows() {
String where = null;
Cursor c = db.query(true, DATABASE_TABLE, ALL_KEYS,
where, null, null, null, null, null);
if (c != null) {
c.moveToFirst();
}
return c;
}
public Cursor getRow(long rowId) {
String where = KEY_ROWID + "=" + rowId;
Cursor c = db.query(true, DATABASE_TABLE, ALL_KEYS,
where, null, null, null, null, null);
if (c != null) {
c.moveToFirst();
}
return c;
}
public boolean updateRow(long rowId, String drivetime, String nightorday) {
String where = KEY_ROWID + "=" + rowId;
ContentValues newValues = new ContentValues();
newValues.put(KEY_DRIVETIME, Drive Time);
newValues.put(KEY_NIGHTORDAY, Time of Day);
return db.update(DATABASE_TABLE, newValues, where, null) != 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(DATABASE_CREATE_SQL);
}
#Override
public void onUpgrade(SQLiteDatabase _db, int oldVersion, int newVersion) {
Log.w(TAG, "Upgrading application's database from version " + oldVersion
+ " to " + newVersion + ", which will destroy all old data!");
_db.execSQL("DROP TABLE IF EXISTS " + DATABASE_TABLE);
onCreate(_db);
}
}
}
There is also a message that pops up whenever I try to run the app that says, "Files under the build folder are generated and should not be edited".
I think you are changing the .class file in debug/DDMS mode or something like that. Please check and make sure to edit your .java file instead.
Posting your relevant logcat messages and also the XML file in question might help understand the problem.
I am populating a ListView using a SimpleCursorAdapter
#Override
public Loader<Cursor> onCreateLoader(int arg0, Bundle arg1) {
String[] projection = new String[] { BlogTable.TITLE_PLAIN, BlogTable.DATE_MODIFIED, BlogTable.EXCERPT, BlogTable.ID };
CursorLoader loader = new CursorLoader(parent, BlogContentProvider.CONTENT_URI, projection, null, null, BlogTable.DATE_MODIFIED + " DESC LIMIT " + BlogContentProvider.QUERY_LIMIT);
return loader;
}
private void fillData(){
//_id is expected from this method that is why we used it earlier
String[] from = new String[] { BlogTable.TITLE_PLAIN, BlogTable.DATE_MODIFIED, BlogTable.EXCERPT};
int[] to = new int[] { R.id.text_news_title, R.id.text_news_date, R.id.text_news_excerpt};
//initialize loader to call this class with a callback
getLoaderManager().initLoader(0, null, this);
//We create adapter to fill list with data, but we don't provide any data as it will be done by loader
adapter = new SimpleCursorAdapter(parent, R.layout.news_list_view, null, from, to, 0);
setListAdapter(adapter);
}
I want to load only 10 items at a time and then at the end of the list call a method addData() and get 10 more rows and so on. I know there is the CWAC EndlessAdapter for this, however I do not know what call to make to add another 10 rows to the current ListView and at the same time keep position.
I know this may sound like a stupid question but I am relatively new to Android development and still learning. Can anyone help?
EDIT:
This is the ContentProvider I am using, maybe it can be of help
package com.brndwgn.database;
import android.content.ContentProvider;
import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.UriMatcher;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteQueryBuilder;
import android.net.Uri;
import android.text.TextUtils;
public class BlogContentProvider extends ContentProvider {
private DbHelper dbh;
//identifiers for URI types
public static final int BLOG_LIST = 1;
public static final int BLOG_ITEM = 2;
//elements of our URI to identify our COntentProvider
public static final String AUTHORITY = "com.brndwgn.database";
public static final String BASE_PATH = "blog";
//URI to query from this Content provider
public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY + "/" + BASE_PATH);
//MIME data types we offer
public static final String BLOG_LIST_TYPE = ContentResolver.CURSOR_DIR_BASE_TYPE + "/bloglist";
public static final String BLOG_ITEM_TYPE = ContentResolver.CURSOR_ITEM_BASE_TYPE + "/blogitem";
public static UriMatcher matcher = new UriMatcher(UriMatcher.NO_MATCH);
//patterns for our provider
static {
matcher.addURI(AUTHORITY, BASE_PATH, BLOG_LIST);
matcher.addURI(AUTHORITY, BASE_PATH + "/#", BLOG_ITEM);
}
public static final int QUERY_LIMIT = 2;
#Override
public boolean onCreate() {
dbh = new DbHelper(getContext());
return true;
}
#Override
public String getType(Uri uri) {
int uriId = matcher.match(uri);
//we check id of URI and return correct MIME type, we defined all of them before
switch(uriId) {
case BLOG_ITEM: return BLOG_ITEM_TYPE;
case BLOG_LIST: return BLOG_LIST_TYPE;
default:
throw new IllegalArgumentException("Unknown uri: " + uri);
}
}
#Override
public Cursor query(Uri uri, String[] projection, String selection,
String[] selectionArgs, String sortOrder) {
int uriId = matcher.match(uri);
//we create object of SQL query builder so we don't need to use plain SQL
SQLiteQueryBuilder builder = new SQLiteQueryBuilder();
//Set a name for the table to query
builder.setTables(BlogTable.TABLE_NAME);
switch(uriId) {
case BLOG_ITEM:
//set where condition to get just one row
builder.appendWhere(BlogTable.ID + "=" + uri.getLastPathSegment());
break;
case BLOG_LIST:
//we don't need to do anything here
break;
default:
new IllegalArgumentException("Unknown uri: " + uri);
}
//get instance of database
SQLiteDatabase db = dbh.getReadableDatabase();
//execute query
Cursor cursor = builder.query(db, projection, selection, selectionArgs, null, null, sortOrder);
//set notifications for this URI
cursor.setNotificationUri(getContext().getContentResolver(), uri);
return cursor;
}
#Override
public int delete(Uri uri, String selection, String[] selectionArgs) {
int uriId = matcher.match(uri);
int deleted=0;
SQLiteDatabase db = dbh.getWritableDatabase();
switch(uriId) {
case BLOG_LIST:
deleted = db.delete(BlogTable.TABLE_NAME, selection, selectionArgs);
break;
case BLOG_ITEM:
if(TextUtils.isEmpty(selection)) {
deleted = db.delete(BlogTable.TABLE_NAME, BlogTable.ID + "=" + uri.getLastPathSegment(), selectionArgs);
}
else {
deleted = db.delete(BlogTable.TABLE_NAME, selection + " and " + BlogTable.ID + "=" + uri.getLastPathSegment(), selectionArgs);
}
break;
default:
throw new IllegalArgumentException("Unknow uri: " + uri);
}
getContext().getContentResolver().notifyChange(uri, null);
return deleted;
}
#Override
public Uri insert(Uri uri, ContentValues values) {
int uriId = matcher.match(uri);
//Variable for ID of new record
long newId;
switch(uriId) {
case BLOG_LIST:
//get instance of Database
SQLiteDatabase db = dbh.getWritableDatabase();
//execute query
newId = db.replace(BlogTable.TABLE_NAME, null, values);
//newId = db.insertWithOnConflict(BlogTable.TABLE_NAME, null, values, SQLiteDatabase.CONFLICT_IGNORE);
//create URI for new added record
Uri newuri = Uri.parse(CONTENT_URI + "/" + newId);
//notify change for list URI
getContext().getContentResolver().notifyChange(uri, null);
return newuri;
default:
throw new IllegalArgumentException("Unknown uri: " + uri);
}
}
#Override
public int update(Uri uri, ContentValues values, String selection,
String[] selectionArgs) {
int uriId = matcher.match(uri);
int updated=0;
SQLiteDatabase db = dbh.getWritableDatabase();
switch(uriId) {
case BLOG_LIST:
updated = db.update(BlogTable.TABLE_NAME, values, selection, selectionArgs);
break;
case BLOG_ITEM:
if(TextUtils.isEmpty(selection)) {
updated = db.update(BlogTable.TABLE_NAME, values, BlogTable.ID + "=" + uri.getLastPathSegment(), null);
}
else {
updated = db.update(BlogTable.TABLE_NAME, values, selection + " and " + BlogTable.ID + "=" + uri.getLastPathSegment(), selectionArgs);
}
break;
default:
throw new IllegalArgumentException("Unknown URI: " + uri);
}
getContext().getContentResolver().notifyChange(uri, null);
return updated;
}
}
Use
adapter.notifyDataSetChanged();
where adapter is your SimpleCursorAdapter for the listview
Edit:
before that you should add data to your adapter. To achieve this, add a method for your adapter to query from the database.