I am trying to code my own content provider for users. When I try to verify if the user exists,when the DBHelper tries to create the database, it throws a null exception.
Here is the content provider:
public class MyUserProvider extends ContentProvider {
private UserDBHelper db;
private static final int USERS = 10;
private static final int USER_ID = 20;
private static final String AUTHORITY =
"net.ifo420.ritc.agenda.userprovider";
private static final String BASE_PATH = "users";
public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY
+ "/" + BASE_PATH);
public static final String CONTENT_TYPE =
ContentResolver.CURSOR_DIR_BASE_TYPE + "/users";
public static final String CONTENT_ITEM_TYPE =
ContentResolver.CURSOR_ITEM_BASE_TYPE + "/user";
private static final UriMatcher uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
static {
uriMatcher.addURI(AUTHORITY, BASE_PATH, USERS);
uriMatcher.addURI(AUTHORITY, BASE_PATH + "/#", USER_ID);
}
public MyUserProvider() {
}
#Override
public boolean onCreate() {
db = new UserDBHelper(getContext());
return false;
}
#Override
public Cursor query(Uri uri, String[] projection, String selection,
String[] selectionArgs, String sortOrder) {
SQLiteQueryBuilder queryBuilder = new SQLiteQueryBuilder();
checkColumns(projection);
queryBuilder.setTables(UserTable.TABLE);
int uriType = uriMatcher.match(uri);
switch (uriType) {
case USERS:
break;
case USER_ID:
queryBuilder.appendWhere(UserTable.COLUMN_ID + " = " + uri.getLastPathSegment());
break;
default:
throw new IllegalArgumentException("Uknown uri " + uri);
}
SQLiteDatabase db1 = db.getReadableDatabase();
Cursor cursor = queryBuilder.query(db1, projection, selection, selectionArgs,
null, null, sortOrder);
cursor.setNotificationUri(getContext().getContentResolver(), uri);
return cursor;
}
#Override
public String getType(Uri uri) {
return null;
}
#Override
public Uri insert(Uri uri, ContentValues values) {
int uriType = uriMatcher.match(uri);
SQLiteDatabase database = db.getReadableDatabase();
long id = 0;
switch (uriType) {
case USERS:
id = database.insert(UserTable.TABLE, null, values);
break;
default:
throw new IllegalArgumentException("Unknown URI: " + uri);
}
getContext().getContentResolver().notifyChange(uri, null);
return Uri.parse(BASE_PATH + "/" + id);
}
#Override
public int delete(Uri uri, String selection, String[] selectionArgs) {
int uriType = uriMatcher.match(uri);
SQLiteDatabase sqLiteDatabase = db.getReadableDatabase();
int rowsDeleted = 0;
switch (uriType) {
case USERS:
rowsDeleted = sqLiteDatabase.delete(UserTable.TABLE, selection,
selectionArgs);
break;
case USER_ID:
String id = uri.getLastPathSegment();
if(TextUtils.isEmpty(selection)) {
rowsDeleted = sqLiteDatabase.delete(UserTable.TABLE,
UserTable.COLUMN_ID + " = " + id, null);
} else {
rowsDeleted = sqLiteDatabase.delete(UserTable.TABLE,
UserTable.COLUMN_ID + " = " + id + " and " +
selection, selectionArgs);
}
break;
default:
throw new IllegalArgumentException("Unknown URI: " + uri);
}
getContext().getContentResolver().notifyChange(uri, null);
return rowsDeleted;
}
#Override
public int update(Uri uri, ContentValues values, String selection,
String[] selectionArgs) {
int uriType = uriMatcher.match(uri);
SQLiteDatabase sqLiteDatabase = db.getReadableDatabase();
int rowsUpdated = 0;
switch (uriType) {
case USERS:
rowsUpdated = sqLiteDatabase.update(UserTable.TABLE,
values,
selection,
selectionArgs);
break;
case USER_ID:
String id = uri.getLastPathSegment();
if (TextUtils.isEmpty(selection)) {
rowsUpdated = sqLiteDatabase.update(UserTable.TABLE,
values,
UserTable.COLUMN_ID + "=" + id,
null);
} else {
rowsUpdated = sqLiteDatabase.update(UserTable.TABLE,
values,
UserTable.COLUMN_ID + "=" + id
+ " and "
+ selection,
selectionArgs);
}
break;
default:
throw new IllegalArgumentException("Unknown URI: " + uri);
}
getContext().getContentResolver().notifyChange(uri, null);
return rowsUpdated;
}
private void checkColumns(String[] projection) {
String[] available = {UserTable.COLUMN_USERNAME, UserTable.COLUMN_PASSWORD,
UserTable.COLUMN_ID};
if (projection != null) {
HashSet<String> requestedColumns =
new HashSet<String>(Arrays.asList(projection));
HashSet<String> availableColumns =
new HashSet<String>(Arrays.asList(available));
if (!availableColumns.containsAll(requestedColumns)) {
throw new IllegalArgumentException("Unknown columns in projection");
}
}
}
Here is my DBHelper
public class UserDBHelper extends SQLiteOpenHelper {
private static final String DB_NAME = "agenda.db";
private static final int DB_VERSION = 1;
public UserDBHelper (Context context) {
super(context, DB_NAME, null, DB_VERSION);
}
#Override
public void onCreate(SQLiteDatabase db) {
UserTable.onCreate(db);
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
UserTable.onUpgrade(db, oldVersion, newVersion);
}
Here is the sample code I am using to verify if the user exists (sorry a bit is in french):
public void onClick(View view) {
switch (view.getId()) {
case R.id.boutonLogin:
if (userExists()) {
Toast.makeText(this, "L'utilisateur existe.", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(this, "L'utilisateur n'existe pas.", Toast.LENGTH_SHORT).show();
}
}
private boolean userExists() {
String username = nomUtilisateur.getText().toString();
String password = motPasse.getText().toString();
Cursor users = userProvider.query(MyUserProvider.CONTENT_URI,
null,
" WHERE username = " + nomUtilisateur.getText().toString() +
" AND password = " + motPasse.getText().toString(), null, null);
if (users.getCount() != 0) {
return true;
} else {
return false;
}
Here is what the logcat gives me:
java.lang.NullPointerException: Attempt to invoke virtual method 'android.database.sqlite.SQLiteDatabase net.info420.ritc.agendacegep.UserDBHelper.getReadableDatabase()' on a null object reference
at net.info420.ritc.agendacegep.MyUserProvider.query(MyUserProvider.java:70)
at net.info420.ritc.agendacegep.LoginActivity.utilisateurExiste(LoginActivity.java:69)
at net.info420.ritc.agendacegep.LoginActivity.onClick(LoginActivity.java:57)
at android.view.View.performClick(View.java:5610)
at android.view.View$PerformClick.run(View.java:22260)
at android.os.Handler.handleCallback(Handler.java:751)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6077)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:865)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:755)
You can't directly instantiate and call a ContentProvider- you have to go through a content resolver. Otherwise it doesn't go through the provider's lifecycle and onCreate isn't called.
Well, I got my own answer. Yes I couldn't instantiate my ContentProvider, but it was not only that. I changed my code and realised that I only did not really undertand the selection and selectionArgs parameters in the query.
So it went from:
private boolean userExists() {
String username = nomUtilisateur.getText().toString();
String password = motPasse.getText().toString();
Cursor users = userProvider.query(MyUserProvider.CONTENT_URI,
null,
" WHERE username = " + nomUtilisateur.getText().toString() +
" AND password = " + motPasse.getText().toString(), null, null);
if (users.getCount() != 0) {
return true;
} else {
return false;
}
}
To :
private boolean userExists() {
String username = nomUtilisateur.getText().toString();
String password = motPasse.getText().toString();
String[] selection = {username, password};
Cursor users = getApplicationContext().getContentResolver().query
(Agenda.UserEntry.CONTENT_URI,
null,
"username = ? AND password = ?", selection, null);
if (users.getCount() != 0) {
return true;
} else {
return false;
}
}
So, the cursor was null because I did not make a correct query and that is why my database was not created: because i did not need it at the end in my code.
Related
The error occurs when the app starts.
Tried to define:
queryBuilder.setTables(Constants.NOTES_TABLE);
but that gives an error saying
android.database.sqlite.SQLiteException: no such column:
The complete error:
Caused by: java.lang.IllegalStateException: Invalid tables
at android.database.sqlite.SQLiteDatabase.findEditTable(SQLiteDatabase.java:973)
at android.database.sqlite.SQLiteQueryBuilder.query(SQLiteQueryBuilder.java:400)
at android.database.sqlite.SQLiteQueryBuilder.query(SQLiteQueryBuilder.java:294)
at com.hackathon.hackmsit.data.NoteContentProvider.query(NoteContentProvider.java:70)
at android.content.ContentProvider.query(ContentProvider.java:1000)
at android.content.ContentProvider$Transport.query(ContentProvider.java:214)
at android.content.ContentResolver.query(ContentResolver.java:478)
at android.content.ContentResolver.query(ContentResolver.java:422)
at com.hackathon.hackmsit.data.NoteManager.getAllNotes(NoteManager.java:60)
at com.hackathon.hackmsit.fragments.NoteListFragment.setupList(NoteListFragment.java:98)
at com.hackathon.hackmsit.fragments.NoteListFragment.onCreateView(NoteListFragment.java:54)
at android.support.v4.app.Fragment.performCreateView(Fragment.java:1962)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1026)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1207)
at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:738)
at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1572)
at android.support.v4.app.FragmentController.execPendingActions(FragmentController.java:330)
at android.support.v4.app.FragmentActivity.onStart(FragmentActivity.java:511)
at android.app.Instrumentation.callActivityOnStart(Instrumentation.java:1236)
at android.app.Activity.performStart(Activity.java:6057)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2317)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2416)
at android.app.ActivityThread.access$900(ActivityThread.java:153)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1319)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5287)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:904)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:699)
at de.robv.android.xposed.XposedBridge.main(XposedBridge.java:114)
MainActivity.java:
public class MainActivity extends AppCompatActivity {
private Toolbar mToolbar;
private com.mikepenz.materialdrawer.Drawer result = null;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mToolbar = (Toolbar)findViewById(R.id.toolbar);
setSupportActionBar(mToolbar);
getSupportActionBar().setDisplayHomeAsUpEnabled(false);
DatabaseHelper databaseHelper = new DatabaseHelper(this);
databaseHelper.getWritableDatabase();
result = new DrawerBuilder()
.withActivity(this)
.withToolbar(mToolbar)
.withActionBarDrawerToggle(true)
.addDrawerItems(
new PrimaryDrawerItem().withName(R.string.title_home).withIcon(FontAwesome.Icon.faw_home).withIdentifier(1),
//new PrimaryDrawerItem().withName(R.string.title_editor).withIcon(FontAwesome.Icon.faw_edit).withIdentifier(2),
new PrimaryDrawerItem().withName(R.string.title_settings).withIcon(FontAwesome.Icon.faw_list).withIdentifier(2)
)
.withOnDrawerItemClickListener(new Drawer.OnDrawerItemClickListener() {
#Override
public boolean onItemClick(View view, int i, IDrawerItem drawerItem) {
if (drawerItem != null && drawerItem instanceof Nameable){
String name = ((Nameable)drawerItem).getName().getText(MainActivity.this);
mToolbar.setTitle(name);
}
if (drawerItem != null){
int selectedScreen = drawerItem.getIdentifier();
switch (selectedScreen){
case 1:
//go to List of Notes
openFragment(new NoteListFragment(), "Notes");
break;
/*case 2:
//go the editor screen
startActivity(new Intent(MainActivity.this, NoteEditorActivity.class));*/
case 2:
//go to settings screen, yet to be added
//this will be your home work
Toast.makeText(MainActivity.this, "Settings Clicked", Toast.LENGTH_SHORT).show();
break;
}
}
return false;
}
})
.withOnDrawerListener(new Drawer.OnDrawerListener() {
#Override
public void onDrawerOpened(View view) {
KeyboardUtil.hideKeyboard(MainActivity.this);
}
#Override
public void onDrawerClosed(View view) {
}
#Override
public void onDrawerSlide(View view, float v) {
}
})
.withFireOnInitialOnClick(true)
.withSavedInstance(savedInstanceState)
.build();
if (savedInstanceState == null){
result.setSelection(1);
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
private void openFragment(final Fragment fragment, String title){
getSupportFragmentManager()
.beginTransaction()
.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN)
.replace(R.id.container, fragment)
.addToBackStack(null)
.commit();
getSupportActionBar().setTitle(title);
}
}
NoteContentProvider.java:
public class NoteContentProvider extends ContentProvider {
private DatabaseHelper dbHelper;
private static final String BASE_PATH_NOTE = "notes";
private static final String AUTHORITY = "com.hackathon.hackmsit.data.provider";
public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY + "/" + BASE_PATH_NOTE);
private static final int NOTE = 100;
private static final int NOTES = 101;
private static final UriMatcher URI_MATCHER = new UriMatcher(UriMatcher.NO_MATCH);
static {
URI_MATCHER.addURI(AUTHORITY, BASE_PATH_NOTE, NOTES);
URI_MATCHER.addURI(AUTHORITY, BASE_PATH_NOTE + "/#", NOTE);
}
private SQLiteDatabase db;
private void checkColumns(String[] projection) {
if (projection != null) {
HashSet<String> request = new HashSet<>(Arrays.asList(projection));
HashSet<String> available = new HashSet<>(Arrays.asList(Constants.COLUMNS));
if (!available.containsAll(request)) {
throw new IllegalArgumentException("Unknown columns in projection");
}
}
}
#Override
public boolean onCreate() {
dbHelper = new DatabaseHelper(getContext());
db = dbHelper.getWritableDatabase();
return (db == null)? false:true;
}
#Override
public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {
SQLiteQueryBuilder queryBuilder = new SQLiteQueryBuilder();
//queryBuilder.setTables(Constants.NOTES_TABLE);
checkColumns(projection);
int type = URI_MATCHER.match(uri);
switch (type){
case NOTE:
//there is not to do if the query is for the table
break;
case NOTES:
queryBuilder.appendWhere(Constants.COLUMN_ID + " = " + uri.getLastPathSegment());
break;
default:
throw new IllegalArgumentException("Unknown URI: " + uri);
}
SQLiteDatabase db = dbHelper.getWritableDatabase();
Cursor cursor = queryBuilder.query(db, projection, selection, selectionArgs, null, null, sortOrder);
cursor.setNotificationUri(getContext().getContentResolver(), uri);
return cursor;
}
#Override
public String getType(Uri uri) {
return null;
}
#Override
public Uri insert(Uri uri, ContentValues values) {
int type = URI_MATCHER.match(uri);
SQLiteDatabase db = dbHelper.getWritableDatabase();
Long id;
switch (type){
case NOTES:
id = db.insert(Constants.NOTES_TABLE, null, values);
break;
default:
throw new IllegalArgumentException("Unknown URI: " + uri);
}
getContext().getContentResolver().notifyChange(uri, null);
return Uri.parse(BASE_PATH_NOTE + "/" + id);
}
#Override
public int delete(Uri uri, String selection, String[] selectionArgs) {
int type = URI_MATCHER.match(uri);
SQLiteDatabase db = dbHelper.getWritableDatabase();
int affectedRows;
switch (type) {
case NOTES:
affectedRows = db.delete(Constants.NOTES_TABLE, selection, selectionArgs);
break;
case NOTE:
String id = uri.getLastPathSegment();
if (TextUtils.isEmpty(selection)) {
affectedRows = db.delete(Constants.NOTES_TABLE, Constants.COLUMN_ID + "=" + id, null);
} else {
affectedRows = db.delete(Constants.NOTES_TABLE, Constants.COLUMN_ID + "=" + id + " and " + selection, selectionArgs);
}
break;
default:
throw new IllegalArgumentException("Unknown URI: " + uri);
}
getContext().getContentResolver().notifyChange(uri, null);
return affectedRows;
}
#Override
public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
int type = URI_MATCHER.match(uri);
SQLiteDatabase db = dbHelper.getWritableDatabase();
int affectedRows;
switch (type) {
case NOTES:
affectedRows = db.update(Constants.NOTES_TABLE, values, selection, selectionArgs);
break;
case NOTE:
String id = uri.getLastPathSegment();
if (TextUtils.isEmpty(selection)) {
affectedRows = db.update(Constants.NOTES_TABLE, values, Constants.COLUMN_ID + "=" + id, null);
} else {
affectedRows = db.update(Constants.NOTES_TABLE, values, Constants.COLUMN_ID + "=" + id + " and " + selection, selectionArgs);
}
break;
default:
throw new IllegalArgumentException("Unknown URI: " + uri);
}
getContext().getContentResolver().notifyChange(uri, null);
return affectedRows;
}
}
DatabaseHelper.java:
public class DatabaseHelper extends SQLiteOpenHelper {
private static final String DATABASE_NAME = "notes.db";
private static final int DATABASE_VERSION = 3;
private static final String CREATE_TABLE_NOTE = "create table "
+ Constants.NOTES_TABLE
+ "("
+ Constants.COLUMN_ID + " integer primary key autoincrement, "
+ Constants.COLUMN_TITLE + " text not null, "
+ Constants.COLUMN_CONTENT + " text not null, "
+ Constants.COLUMN_MODIFIED_TIME + " integer not null, "
+ Constants.COLUMN_CREATED_TIME + " integer not null " + ");";
public DatabaseHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
#Override
public void onCreate(SQLiteDatabase db) {
db.execSQL(CREATE_TABLE_NOTE);
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL("DROP TABLE IF EXISTS " + Constants.NOTES_TABLE);
onCreate(db);
}
}
Manifest entry:
<provider
android:name=".data.NoteContentProvider"
android:authorities="com.hackathon.hackmsit.data.provider"
android:exported="false" />
Edit:
Constants.java:
public class Constants {
public static final String NOTES_TABLE = "notes";
public static final String COLUMN_ID = "_id";
//public final static String COLUMN_NAME = "name";
public static final String COLUMN_TITLE = "title";
public static final String COLUMN_CONTENT = "content";
public static final String COLUMN_MODIFIED_TIME = "modified_time";
public static final String COLUMN_CREATED_TIME = "created_time";
public static final String[] COLUMNS = {
Constants.COLUMN_ID,
Constants.COLUMN_TITLE,
Constants.COLUMN_CONTENT,
Constants.COLUMN_MODIFIED_TIME,
Constants.COLUMN_CREATED_TIME
};
}
Any help is appreciated.
android.database.sqlite.SQLiteException: no such column:
At First Modify your CREATE TABLE Statement
String CREATE_TABLE_NOTE = "CREATE TABLE " + Constants.NOTES_TABLE + "("
+ Constants.COLUMN_ID + " INTEGER PRIMARY KEY AUTOINCREMENT, "
+ Constants.COLUMN_TITLE + " TEXT Default 'Unknown', "
+ Constants.COLUMN_CONTENT + " TEXT Default 'Unknown', "
+ Constants.COLUMN_MODIFIED_TIME + " INTEGER, "
+ Constants.COLUMN_CREATED_TIME + " INTEGER )";
Then Un-install old App & Run Again .
I am working on databases for my project and I have columns for primary key (rowid), number (contact number) and name. I am adding two different entries with same number in my database and i need to extract both of them from the database. Code for extracting is
public Cursor SelectList(String number) throws SQLException {
String query = "SELECT FROM " + DATABASE_TABLE + " WHERE " + KEY_NUMBER + "='" + number.trim()+"'";
Cursor mcursor = db.rawQuery(query, null);
if(mcursor != null) {
mcursor.moveToFirst();
}
return mcursor;
}
But it is showing SQLite exception at this line
Cursor mcursor = db.rawQuery(query, null);
Code for DatabaseHandler
package com.example.gul.databasealvie;
/**
* Created by gul on 6/6/15.
*/
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.util.Log;
public class DBAdapter {
static final String KEY_ROWID = "_id";
static final String KEY_NAME = "name";
static final String KEY_NUMBER = "number";
static final String KEY_ID="listid";
static final String TAG = "DBAdapter";
static final String DATABASE_NAME = "MyDB20";
static final String DATABASE_TABLE = "contacts5";
static final int DATABASE_VERSION = 1;
static final String DATABASE_CREATE= "create table contacts5(_id integer primary key , "
+ "name text not null, number text not null, listid text not null);";
final Context context;
DatabaseHelper DBHelper;
SQLiteDatabase db;
public DBAdapter(Context ctx)
{
this.context = ctx;
DBHelper = new DatabaseHelper(context);
}
private static class DatabaseHelper extends SQLiteOpenHelper
{
DatabaseHelper(Context context)
{
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
#Override
public void onCreate(SQLiteDatabase db)
{
try {
db.execSQL(DATABASE_CREATE);
} catch (SQLException e) {
e.printStackTrace();
}
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion)
{
Log.w(TAG, "Upgrading database from version " + oldVersion + " to "
+ newVersion + ", which will destroy all old data");
db.execSQL("DROP TABLE IF EXISTS contacts");
onCreate(db);
}
}
//---opens the database---
public DBAdapter open() throws SQLException
{
db = DBHelper.getWritableDatabase();
return this;
}
public boolean DeleteList(String number){
db.execSQL("DELETE FROM "+DATABASE_TABLE+" WHERE "+KEY_NUMBER+"="+number);
return true;
}
public void DropTable(){
db.execSQL("Delete From " + DATABASE_TABLE);
}
public Cursor SelectList(String number) throws SQLException {
String query = "SELECT FROM " + DATABASE_TABLE + " WHERE " + KEY_NUMBER + "='" + number.trim()+"'";
Cursor mcursor = db.rawQuery(query,null);
if (mcursor != null) {
mcursor.moveToFirst();
}
return mcursor;
}
//---closes the database---
public void close()
{
DBHelper.close();
}
//---insert a contact into the database---
public long insertContact(TableData contact, String id )
{
long myid=Long.parseLong(id);
ContentValues initialValues = new ContentValues();
initialValues.put(KEY_NAME, contact.getName());
initialValues.put(KEY_NUMBER,contact.getPhoneNumber());
initialValues.put(KEY_ID, id);
return db.insert(DATABASE_TABLE, null, initialValues);
}
//---deletes a particular contact---
public boolean DeletContact(String number)throws SQLException{
return db.delete(DATABASE_TABLE, KEY_NUMBER + "=" + number, null) > 0;
}
public long insertContact(Anonymous contact, String id )
{
ContentValues initialValues = new ContentValues();
initialValues.put(KEY_NAME, contact.getName());
initialValues.put(KEY_NUMBER, contact.getPhoneNumber());
initialValues.put(KEY_ID, id);
// Log.d("Contact", contact.getName() + contact.getPhoneNumber());
return db.insert(DATABASE_TABLE, null, initialValues);
}
public boolean deleteContact(String number)
{
return db.delete(DATABASE_TABLE, KEY_NUMBER + " = ?",
new String[] { number }) > 0;
}
public Cursor getAllContacts()
{
return db.query(DATABASE_TABLE, new String[] {KEY_ROWID, KEY_NAME,
KEY_NUMBER}, null, null, null, null, null);
}
//---retrieves a particular contact---
public Cursor getContact(long rowId) throws SQLException
{
Cursor mCursor =
db.query(true, DATABASE_TABLE, new String[] {KEY_ROWID,
KEY_NAME, KEY_NUMBER}, KEY_ROWID + "=" + rowId, null,
null, null, null, null);
if (mCursor != null) {
mCursor.moveToFirst();
}
return mCursor;
}
public boolean iskey(long rowid)throws SQLException
{
Cursor mCursor=db.query(true,DATABASE_TABLE, new String[]{KEY_ROWID,KEY_NAME,KEY_NUMBER },KEY_ROWID+"="+rowid,null,null
,null,null,null);
if(mCursor!=null && mCursor.moveToFirst()){
return true;
}
else
return false;
}
//---updates a contact---
public boolean updateContact(long rowId, String name, String email)
{
ContentValues args = new ContentValues();
args.put(KEY_NAME, name);
args.put(KEY_NUMBER, email);
return db.update(
DATABASE_TABLE, args, KEY_ROWID + "=" + rowId, null) > 0;
}
}
Code for testing purposes
package com.example.gul.databasealvie;
import android.app.Activity;
import android.database.Cursor;
import android.os.Bundle;
import android.util.Log;
import android.widget.Toast;
public class MainActivity extends Activity {
DBAdapter db;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
db = new DBAdapter(this);
AddContact();
PrintingList();
GetContacts();
GetContact();
//UpdateContact();
DeleteContact();
}
public void AddContact() {
Anonymous a= new Anonymous(34,"Wei-Meng Lee", "12345");
Anonymous b= new Anonymous(2,"Wejhkjh Lee", "12234");
//---add a contact---
db.open();
if (db.insertContact(a,"22") >= 0){
Toast.makeText(this, "Add successful.", Toast.LENGTH_LONG).show();
}
if (db.insertContact(b,"21") >= 0) {
Toast.makeText(this, "Add successful.", Toast.LENGTH_LONG).show();
}
if (db.insertContact(b,"21") >= 0) {
Toast.makeText(this, "Add successful.", Toast.LENGTH_LONG).show();
}
db.close();
}
public void PrintingList(){
db.open();
Cursor mCursor=db.SelectList("12234");
if(mCursor.moveToFirst()){
do {
displaylist(mCursor);
}while(mCursor.moveToNext());
}
db.close();
}
public void GetContacts() {
//--get all contacts---
db.open();
// db.DeleteList("12345");
// if(db.DeletContact("12234")) {
// Log.i("Deleted contact", "");
//}
Cursor c = db.getAllContacts();
if (c.moveToFirst())
{
do {
DisplayContact(c);
} while (c.moveToNext());
}
db.close();
}
public void GetContact() {
//---get a contact---
db.open();
Cursor c = db.getContact(2);
if (c.moveToFirst())
DisplayContact(c);
else
Toast.makeText(this, "No contact found", Toast.LENGTH_LONG).show();
db.close();
}
public void UpdateContact() {
//---update a contact---
db.open();
if (db.updateContact(1, "Wei-Meng Lee", "weimenglee#gmail.com"))
Toast.makeText(this, "Update successful.", Toast.LENGTH_LONG).show();
else
Toast.makeText(this, "Update failed.", Toast.LENGTH_LONG).show();
db.close();
}
public void DeleteContact() {
db.open();
//if (db.deleteContact(1))
// Toast.makeText(this, "Delete successful.", Toast.LENGTH_LONG).show();
//else
// Toast.makeText(this, "Delete failed.", Toast.LENGTH_LONG).show();
db.close();
}
public void DisplayContact(Cursor c)
{
Log.i(
"contacts", "id: " + c.getString(0) + "\n" +
"Name: " + c.getString(1) + "\n" +
"Number: " + c.getString(2)
);
db.open();
if((db.iskey(2))){
Log.i("Yay ", "it's working");
}
db.close();
}
public void displaylist(Cursor c){
Log.i(
"List","listid:"+c.getString(0)+ "\n"+
"NAMElist: " + c.getString(1)+ "\n" +
"list: "+c.getString(2)
);
}
}
Code For Anonymous.java
package com.example.gul.databasealvie;
/**
* Created by gul on 6/6/15.
*/
/**
* Created by Noor Zia on 5/26/2015.
*/
public class Anonymous {
public long id;
public String name;
public String number;
public Anonymous(){
name="Unknown";
}
public Anonymous(String no){
name="Unknown";
number = no;
}
public Anonymous(long id, String name, String number){
name=name;
this.number=number;
this.name=name;
this.id=id;
}
public long getID(){
return this.id;
}
// setting id
// getting name
public String getName(){
return this.name;
}
// setting name
// getting phone number
public String getPhoneNumber(){
return this.number;
}
// setting phone number
}
dbHelper = new DBHelper(getApplicationContext());
SQLiteDatabase db = dbHelper.getReadableDatabase();
Cursor cursor = db.rawQuery("select * from centuaryTbl where email='"+email+"'",null);
if (cursor.moveToFirst())
{
do
{
String s1 = cursor.getString(cursor.getColumnIndex("s1"));
String s2 = cursor.getString(cursor.getColumnIndex("s2"));
String s3 = cursor.getString(cursor.getColumnIndex("s3"));
}while (cursor.moveToNext());
}
You need to specify the columns to retrieve. For instance:
String query = "SELECT name, number FROM " + DATABASE_TABLE + " WHERE " + KEY_NUMBER + "='" + number.trim() + "'";
More information about Select clause
Or you can fetch all columns using '*'
Your query will be
String query = "SELECT * FROM " + DATABASE_TABLE + " WHERE " + KEY_NUMBER + "='" + number.trim()+"'";
public String select_data(String email)
{
db=this.getReadableDatabase();
String query="select email,password from "+Table_name;
Cursor cursor=db.rawQuery(query,null);
String a,b;
b="not found";
if (cursor.moveToFirst()) {
do {
a=cursor.getString(0);
if(a.equals(email))
{
b=cursor.getString(1);
break;
}
} while(cursor.moveToNext());
}
return b;
}
I wanted to play with a ContentProvider example but I ran into an issue I can't seem to solve.
This example consists of an Activity:
import android.content.ContentUris;
import android.content.ContentValues;
import android.database.Cursor;
import android.net.Uri;
import android.support.v4.widget.SimpleCursorAdapter;
import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.ListView;
public class MainActivity extends ActionBarActivity
{
final String LOG_TAG = "myLogs";
final Uri CONTACT_URI = Uri.parse("content://zulfigarov.com.trainingprj.MyContactsProvider/contacts");
final String CONTACT_NAME = "name";
final String CONTACT_EMAIL = "email";
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Cursor cursor = getContentResolver().query(CONTACT_URI, null, null, null, null);
startManagingCursor(cursor);
String[] from = {"name", "email"};
int[] to = {android.R.id.text1, android.R.id.text2};
SimpleCursorAdapter adapter
= new SimpleCursorAdapter(this, android.R.layout.simple_list_item_2, cursor, from, to, 0);
ListView lvContact = (ListView)findViewById(R.id.lvContacts);
lvContact.setAdapter(adapter);
}
public void onClickInsert(View view)
{
ContentValues cv = new ContentValues();
cv.put(CONTACT_NAME, "name 4");
cv.put(CONTACT_EMAIL, "email 4");
Uri newUri = getContentResolver().insert(CONTACT_URI, cv);
Log.d(LOG_TAG, "insert, result Uri: " + newUri.toString());
}
public void onClickUpdate(View view)
{
ContentValues cv = new ContentValues();
cv.put(CONTACT_NAME, "name 5");
cv.put(CONTACT_EMAIL, "email 5");
Uri uri = ContentUris.withAppendedId(CONTACT_URI, 2);
int cnt = getContentResolver().update(uri, cv, null, null);
Log.d(LOG_TAG, "update, count = " + cnt);
}
public void onClickDelete(View view)
{
Uri uri = ContentUris.withAppendedId(CONTACT_URI, 3);
int cnt = getContentResolver().delete(uri, null, null);
Log.d(LOG_TAG, "delete, count = " + cnt);
}
public void onClickError(View view)
{
Uri uri = Uri.parse("content://zulfigarov.com.trainingprj.MyContentProvider/phones");
try
{
Cursor cursor = getContentResolver().query(uri, null, null, null, null);
}
catch (Exception ex)
{
Log.d(LOG_TAG, "Error: " + ex.getClass() + ", " + ex.getMessage());
}
}
}
and a ContentProvider:
import android.content.ContentProvider;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.Context;
import android.content.UriMatcher;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.net.Uri;
import android.text.TextUtils;
import android.util.Log;
public class MyContactsProvider extends ContentProvider
{
final String LOG_TAG = "myLogs";
static final String DB_NAME = "mydb";
static final int DB_VERSION = 1;
static final String CONTACT_TABLE = "contacts";
static final String CONTACT_ID = "_id";
static final String CONTACT_NAME = "name";
static final String CONTACT_EMAIL = "email";
static final String DB_CREATE = "CREATE TABLE " + CONTACT_TABLE + "("
+ CONTACT_ID + " INTEGER PRIMARY KEY AUTOINCREMENT, "
+ CONTACT_NAME + " TEXT, "
+ CONTACT_EMAIL + " TEXT" + ");";
static final String AUTHORITY = "zulfigarov.com.trainingprj.MyContactsProvider";
static final String CONTACT_PATH = "contacts";
public static final Uri CONTACT_CONTENT_URI = Uri.parse("content://" + AUTHORITY + "/" + CONTACT_PATH);
static final String CONTACT_CONTENT_TYPE = "vnd.android.cursor.dir/vnd." + AUTHORITY + "." + CONTACT_PATH;
static final String CONTACT_CONTENT_ITEM_TYPE = "vnd.android.cursor.item/vnd." + AUTHORITY + "." + CONTACT_PATH;
static final int URI_CONTACTS = 1;
static final int URI_CONTACTS_ID = 2;
private static final UriMatcher uriMatcher;
static
{
uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
uriMatcher.addURI(AUTHORITY, CONTACT_PATH, URI_CONTACTS);
uriMatcher.addURI(AUTHORITY, CONTACT_PATH + "/#", URI_CONTACTS_ID);
}
DBHelper dbHelper;
SQLiteDatabase db;
#Override
public boolean onCreate()
{
Log.d(LOG_TAG, "onCreate provider");
dbHelper = new DBHelper(getContext());
return true;
}
#Override
public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder)
{
Log.d(LOG_TAG,"query, " + uri.toString());
switch (uriMatcher.match(uri))
{
case URI_CONTACTS:
Log.d(LOG_TAG, "URI_CONTACTS");
if(TextUtils.isEmpty(sortOrder))
{
sortOrder = CONTACT_NAME + " ASC";
}
break;
case URI_CONTACTS_ID:
String id = uri.getLastPathSegment();
Log.d(LOG_TAG, "URI_CONTACTS_ID");
if (TextUtils.isEmpty(selection))
selection = CONTACT_ID + " = " + id;
else
selection = selection + " AND " + CONTACT_ID + " = " + id;
break;
default:
throw new IllegalArgumentException("Wrong URI: " + uri);
}
db = dbHelper.getWritableDatabase();
Cursor cursor = db.query(CONTACT_TABLE, projection, selection,
selectionArgs, null, null, sortOrder);
cursor.setNotificationUri(getContext().getContentResolver(),CONTACT_CONTENT_URI);
return cursor;
}
#Override
public String getType(Uri uri)
{
Log.d(LOG_TAG, "getTYpe, " + uri.toString());
switch (uriMatcher.match(uri))
{
case URI_CONTACTS:
return CONTACT_CONTENT_TYPE;
case URI_CONTACTS_ID:
return CONTACT_CONTENT_ITEM_TYPE;
}
return null;
}
#Override
public Uri insert(Uri uri, ContentValues values)
{
Log.d(LOG_TAG,"insert, " + uri.toString());
if(uriMatcher.match(uri) != URI_CONTACTS)
throw new IllegalArgumentException("Wrong URI: " + uri);
db = dbHelper.getWritableDatabase();
long rowID = db.insert(CONTACT_TABLE, null, values);
Uri resultUri = ContentUris.withAppendedId(CONTACT_CONTENT_URI, rowID);
getContext().getContentResolver().notifyChange(resultUri, null);
return resultUri;
}
#Override
public int delete(Uri uri, String selection, String[] selectionArgs)
{
Log.d(LOG_TAG,"delete, " + uri.toString());
switch (uriMatcher.match(uri))
{
case URI_CONTACTS:
Log.d(LOG_TAG,"URI_CONTACTS");
break;
case URI_CONTACTS_ID:
String id = uri.getLastPathSegment();
Log.d(LOG_TAG,"URI_CONTACTS_ID, " + id);
if(TextUtils.isEmpty(selection))
{
selection = CONTACT_ID + " = " + id;
}
else
{
selection = selection + " AND " + CONTACT_ID + " = " + id;
}
break;
default:
throw new IllegalArgumentException("Wrong URI: " + uri);
}
db = dbHelper.getWritableDatabase();
int cnt = db.delete(CONTACT_TABLE, selection, selectionArgs);
getContext().getContentResolver().notifyChange(uri, null);
return cnt;
}
#Override
public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs)
{
Log.d(LOG_TAG,"update, " + uri.toString());
switch (uriMatcher.match(uri))
{
case URI_CONTACTS:
Log.d(LOG_TAG,"URI_CONTACTS");
break;
case URI_CONTACTS_ID:
String id = uri.getLastPathSegment();
Log.d(LOG_TAG, "URI_CONTACTS_ID");
if(TextUtils.isEmpty(selection))
{
selection = CONTACT_ID;
}
else
{
selection = selection + " AND " + CONTACT_ID + " = " + id;
}
break;
default:
throw new IllegalArgumentException("Wrong URI: " + uri);
}
db = dbHelper.getWritableDatabase();
int cnt = db.update(CONTACT_TABLE, values, selection, selectionArgs);
getContext().getContentResolver().notifyChange(uri,null);
return cnt;
}
private class DBHelper extends SQLiteOpenHelper
{
public DBHelper(Context context)
{
super(context, DB_NAME, null, DB_VERSION);
}
#Override
public void onCreate(SQLiteDatabase db)
{
db.execSQL(DB_CREATE);
ContentValues cv = new ContentValues();
for (int i = 1; i <= 3; i++)
{
cv.put(CONTACT_NAME, "name " + i);
cv.put(CONTACT_EMAIL, "email " + i);
db.insert(CONTACT_TABLE, null, cv);
}
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion)
{
}
}
}
The touble is that when I click on the buttons (firing onClickInsert, onClickUpdate etc. methods in MainActivity) it updates the data in database but doesn't update the ListView on an activity. Looks like
getContext().getContentResolver().notifyChange(resultUri, null);
is not working properly. So I can't find where i'm wrong.
Use CursorLoaders to load the data and populate the ListView.
http://developer.android.com/reference/android/content/CursorLoader.html
Then use getContext().getContentResolver().notifyChange(resultUri, null); when you insert, update or delete!
Without CursorLoaders you will have to use ContentObservers
So, although DB is updated in background and you are using notifyChange() but no one is listening to that!
You should be calling adapter.notifyDataSetChanged() (after the onClickInsert) in order to make your ListView notice about the change.
I am using an android content provider and I have a few tables I am inserting data into. The first table has three columns and in my usecontentprovider class I display all the rows being added using a toast message at the bottom. Everything was working OK. Then I then tried to include another table which has two columns (id2, id3) and I tried to query that table and display the rows being added and whenever I do that I get an error saying Failed to read row 0, column -1 from a CursorWindow which has 1 rows, 3 columns. I am not sure what I am doing wrong, so any help would be greatly appreciated.
public class UseContentProvideActivity extends Activity {
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// add the 1st course
ContentValues values = new ContentValues();
values.put(MyContentProvider._ID, 1510);
values.put(MyContentProvider.NAME, "Jordan");
values.put(MyContentProvider.GRADE, 9);
Uri uri = getContentResolver().insert(MyContentProvider.CONTENT_URI,
values);
ContentValues values2 = new ContentValues();
values2.put(MyContentProvider._ID2, 1510);
values2.put(MyContentProvider._ID3, 9000);
Uri uri2 = getContentResolver().insert(MyContentProvider.CONTENT_URI2,
values);
uri2 = getContentResolver().insert(
Uri.parse("content://cs.ecl.provider.Courses/friend"), values);
// query added highschooler
Toast.makeText(this, "Added Schooler:", Toast.LENGTH_SHORT).show();
Uri allDescs = Uri.parse("content://cs.ecl.provider.Courses/highschooler");
Cursor cl = managedQuery(allDescs, null, null, null, "name");
if (cl.moveToFirst()) {
do {
Toast.makeText(
this,
cl.getString(cl.getColumnIndex(MyContentProvider._ID))
+ ", "
+ cl.getString(cl
.getColumnIndex(MyContentProvider.NAME))
+ ", "
+ cl.getString(cl
.getColumnIndex(MyContentProvider.GRADE)),
Toast.LENGTH_LONG).show();
} while (cl.moveToNext());
}
//2nd table
// query added friends
Toast.makeText(this, "Added Friend:", Toast.LENGTH_SHORT).show();
Uri allDescs2 = Uri.parse("content://cs.ecl.provider.Courses/friend");
Cursor cl2 = managedQuery(allDescs2, null, null, null, "name");
if (cl2.moveToFirst()) {
do {
Toast.makeText(
this,
cl2.getString(cl2.getColumnIndex(MyContentProvider._ID2))
+ ", "
+ cl2.getString(cl2
.getColumnIndex(MyContentProvider._ID3))
,
Toast.LENGTH_LONG).show();
} while (cl2.moveToNext());
}
getContentResolver().delete(
Uri.parse("content://cs.ecl.provider.Courses/highschooler"), null,
null);
}
}
public class MyContentProvider extends ContentProvider {
public static final String PROVIDER_NAME = "cs.ecl.provider.Courses";
// first url
public static final Uri CONTENT_URI = Uri.parse("content://"
+ PROVIDER_NAME + "/highschooler");
// second url
public static final Uri CONTENT_URI2 = Uri.parse("content://"
+ PROVIDER_NAME + "/friend");
// third url
public static final Uri CONTENT_URI3 = Uri.parse("content://"
+ PROVIDER_NAME + "/like");
public static final String _ID = "_id";
public static final String NAME = "name";
public static final String GRADE = "grade";
public static final String _ID2 = "_id1";
public static final String _ID3 = "_id2";
private static final int COURSES = 1;
private static final int COURSE_ID = 2;
// 2nd
private static final int COURSES2 = 3;
private static final int COURSE2_ID = 4;
private static final UriMatcher uriMatcher;
static {
uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
uriMatcher.addURI(PROVIDER_NAME, "highschooler", COURSES);
uriMatcher.addURI(PROVIDER_NAME, "highschooler/#", COURSE_ID);
// second table
uriMatcher.addURI(PROVIDER_NAME, "friend", COURSES2);
uriMatcher.addURI(PROVIDER_NAME, "friend/#", COURSE2_ID);
}
// for using SQLite database
private SQLiteDatabase coursesDB;
private static final String DATABASE_NAME = "Lab2";
private static final String DATABASE_TABLE = "Highschooler";
// 2nd table
private static final String DATABASE_TABLE2 = "Friend";
private static final int DATABASE_VERSION = 1;
private static final String DATABASE_CREATE = "create table "
// + DATABASE_TABLE + " (_id integer primary key autoincrement, "
+ DATABASE_TABLE + " (_id integer, "
+ "name text not null, grade integer);";
private static final String DATABASE_CREATE2 = "create table "
// + DATABASE_TABLE + " (_id integer primary key autoincrement, "
+ DATABASE_TABLE2 + " (_id1 integer, " + "_id2 integer);";
// for using SQLite database
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);
db.execSQL(DATABASE_CREATE2);
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL("DROP TABLE IF EXISTS descs");
onCreate(db);
}
}
#Override
public int delete(Uri arg0/* uri */, String arg1/* selection */,
String[] arg2/* delectionArgs */) {
int count = 0;
switch (uriMatcher.match(arg0)) {
case COURSES:
count = coursesDB.delete(DATABASE_TABLE, arg1, arg2);
break;
case COURSE_ID:
String id = arg0.getPathSegments().get(1);
count = coursesDB.delete(DATABASE_TABLE, _ID + " = " + id
+ (!TextUtils.isEmpty(arg1) ? " AND (" + arg1 + ')' : ""),
arg2);
break;
default:
throw new IllegalArgumentException("Unknown URI " + arg0);
}
getContext().getContentResolver().notifyChange(arg0, null);
return count;
}
#Override
public String getType(Uri uri) {
switch (uriMatcher.match(uri)) {
// get all courses
case COURSES:
return "vnd.android.cursor.dir/vnd.ecl.courses ";
// get one course
case COURSE_ID:
return "vnd.android.cursor.item/vnd.ecl.courses ";
// new stuff
// get all courses
case COURSES2:
return "vnd.android.cursor.dir/vnd.ecl.courses2 ";
// get one course
case COURSE2_ID:
return "vnd.android.cursor.item/vnd.ecl.courses2 ";
default:
throw new IllegalArgumentException("Unsupported URI: " + uri);
}
}
#Override
public Uri insert(Uri uri, ContentValues values) {
Uri _uri = null;
switch (uriMatcher.match(uri)){
case COURSES:
System.out.println("GOT TO INSERT1");
long _ID1 = coursesDB.insert(DATABASE_TABLE, "", values);
//---if added successfully---
if (_ID1 > 0) {
_uri = ContentUris.withAppendedId(CONTENT_URI, _ID1);
getContext().getContentResolver().notifyChange(_uri, null);
}
break;
case COURSES2:
System.out.println("GOT TO INSERT2");
long _ID2 = coursesDB.insert(DATABASE_TABLE2, "", values);
//---if added successfully---
if (_ID2 > 0) {
_uri = ContentUris.withAppendedId(CONTENT_URI2, _ID2);
getContext().getContentResolver().notifyChange(_uri, null);
}
break;
default: throw new SQLException("Failed to insert row into " + uri);
}
return _uri;
}
#Override
public boolean onCreate() {
Context context = getContext();
DatabaseHelper dbHelper = new DatabaseHelper(context);
coursesDB = dbHelper.getWritableDatabase();
return (coursesDB == null) ? false : true;
}
#Override
public Cursor query(Uri uri, String[] projection, String selection,
String[] selectionArgs, String sortOrder) {
SQLiteQueryBuilder sqlBuilder = new SQLiteQueryBuilder();
sqlBuilder.setTables(DATABASE_TABLE);
if (uriMatcher.match(uri) == COURSE_ID)
// -- if getting one course --
sqlBuilder.appendWhere(_ID + " = " + uri.getPathSegments().get(1));
if (sortOrder == null || sortOrder == "")
sortOrder = NAME;
Cursor cl = sqlBuilder.query(coursesDB, projection, selection,
selectionArgs, null, null, sortOrder);
// register to watch a content URI for changes
cl.setNotificationUri(getContext().getContentResolver(), uri);
return cl;
}
#Override
public int update(Uri uri, ContentValues values, String selection,
String[] selectionArgs) {
int count = 0;
switch (uriMatcher.match(uri)) {
case COURSES:
count = coursesDB.update(DATABASE_TABLE, values, selection,
selectionArgs);
break;
case COURSE_ID:
count = coursesDB.update(
DATABASE_TABLE,
values,
_ID
+ " = "
+ uri.getPathSegments().get(1)
+ (!TextUtils.isEmpty(selection) ? " AND ("
+ selection + ')' : ""), selectionArgs);
break;
default:
throw new IllegalArgumentException("Unknown URI " + uri);
}
getContext().getContentResolver().notifyChange(uri, null);
return count;
}
}
Granted, I'm pretty new to ContentProviders (just started learning them this week), but I think your problem is right here:
public Cursor query(Uri uri, String[] projection, String selection,
String[] selectionArgs, String sortOrder) {
SQLiteQueryBuilder sqlBuilder = new SQLiteQueryBuilder();
sqlBuilder.setTables(DATABASE_TABLE);
You set the table to DATABASE_TABLE, rather than using a switch to catch an occurance of COURSES2, which is your UriMatcher code for when you end your Uri with /friend. So it's trying to look at your Highschoolers table, and you're giving it invalid column names for that table (which I think is why it's failing to read "column -1").
So here's how you make it refer to the Friends table:
public Cursor query(Uri uri, String[] projection, String selection,
String[] selectionArgs, String sortOrder) {
SQLiteQueryBuilder sqlBuilder = new SQLiteQueryBuilder();
switch(uriMatcher.match(uri)){
case COURSE_ID:
// -- if getting one course --
sqlBuilder.setTables(DATABASE_TABLE);
sqlBuilder.appendWhere(_ID + " = " + uri.getPathSegments().get(1));
break;
case COURSES2
sqlBuilder.setTables(DATABASE_TABLE2);
break;
default:
throw new IllegalArgumentException("Bad Uri");
}
One more note about your code: Try to make your variables more descriptive than DATABASE_TABLE and DATABASE_TABLE2, or COURSES and COURSES2. Using descriptive variables makes things a lot easier to remember, especially as your code grows (I'm currently using a ContentProvider with 843 lines, and it's still growing).
Like I said, I'm new to ContentProviders, so I'm probably missing a few other things you could do to improve your code, but the solution I gave should hopefully be enough to get your code working.
This is the code:
TodoTable.java:
public class TodoTable {
// Database table
public static final String TABLE_TODO = "todo";
public static final String COLUMN_ID_U = "_id";
public static final String COLUMN_CATEGORY = "category";
public static final String COLUMN_SUMMARY = "summary";
public static final String COLUMN_DESCRIPTION = "description";
public static final String COLUMN_SATZE = "satze";
// Database creation SQL statement
private static final String DATABASE_CREATE = "create table "
+ TABLE_TODO
+ "("
+ COLUMN_ID_U + " integer primary key autoincrement, "
+ COLUMN_CATEGORY + " text not null, "
+ COLUMN_SUMMARY + " text not null, "
+ COLUMN_DESCRIPTION + " text not null, "
+ COLUMN_SATZE + " text not null"
+ ");";
public static void onCreate(SQLiteDatabase database) {
database.execSQL(DATABASE_CREATE);
}
public static void onUpgrade(SQLiteDatabase database, int oldVersion,
int newVersion) {
Log.w(TodoTable.class.getName(), "Upgrading database from version "
+ oldVersion + " to " + newVersion
+ ", which will destroy all old data");
database.execSQL("DROP TABLE IF EXISTS " + TABLE_TODO);
onCreate(database);
}}
TodoDetailAktivity.java:
public class TodoDetailActivity extends Activity {
private Spinner mCategory;
private EditText mTitleText;
private EditText mBodyText;
private EditText mSatzText;
private EditText mPauseText;
private EditText mWDHText;
private EditText mGewichtText;
private Uri todoUri;
#Override
protected void onCreate(Bundle bundle) {
super.onCreate(bundle);
setContentView(R.layout.todo_edit);
mCategory = (Spinner) findViewById(R.id.category);
mTitleText = (EditText) findViewById(R.id.todo_edit_summary);
mBodyText = (EditText) findViewById(R.id.todo_edit_description);
mSatzText = (EditText) findViewById(R.id.editTextsatz);
Button confirmButton = (Button) findViewById(R.id.todo_edit_button);
Bundle extras = getIntent().getExtras();
// Check from the saved Instance
todoUri = (bundle == null) ? null : (Uri) bundle
.getParcelable(MyTodoContentProvider.CONTENT_ITEM_TYPE);
// Or passed from the other activity
if (extras != null) {
todoUri = extras
.getParcelable(MyTodoContentProvider.CONTENT_ITEM_TYPE);
fillData(todoUri);
}
confirmButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
if (TextUtils.isEmpty(mTitleText.getText().toString())) {
makeToast();
} else {
setResult(RESULT_OK);
finish();
}
}
});
}
private void fillData(Uri uri) {
String[] projection = { TodoTable.COLUMN_SUMMARY,
TodoTable.COLUMN_DESCRIPTION, TodoTable.COLUMN_CATEGORY };
Cursor cursor = getContentResolver().query(uri, projection, null, null,
null);
if (cursor != null) {
cursor.moveToFirst();
String category = cursor.getString(cursor
.getColumnIndexOrThrow(TodoTable.COLUMN_CATEGORY));
for (int i = 0; i < mCategory.getCount(); i++) {
String s = (String) mCategory.getItemAtPosition(i);
if (s.equalsIgnoreCase(category)) {
mCategory.setSelection(i);
}
}
mTitleText.setText(cursor.getString(cursor
.getColumnIndexOrThrow(TodoTable.COLUMN_SUMMARY)));
mBodyText.setText(cursor.getString(cursor
.getColumnIndexOrThrow(TodoTable.COLUMN_DESCRIPTION)));
mSatzText.setText(cursor.getString(cursor
.getColumnIndexOrThrow(TodoTable.COLUMN_SATZE)));
// Always close the cursor
cursor.close();
}
}
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
saveState();
outState.putParcelable(MyTodoContentProvider.CONTENT_ITEM_TYPE, todoUri);
}
#Override
protected void onPause() {
super.onPause();
saveState();
}
private void saveState() {
String category = (String) mCategory.getSelectedItem();
String summary = mTitleText.getText().toString();
String description = mBodyText.getText().toString();
String satze = mSatzText.getText().toString();
// Only save if either summary or description
// is available
if (description.length() == 0 && summary.length() == 0 && satze.length() == 0) {
return;
}
ContentValues values = new ContentValues();
values.put(TodoTable.COLUMN_CATEGORY, category);
values.put(TodoTable.COLUMN_SUMMARY, summary);
values.put(TodoTable.COLUMN_DESCRIPTION, description);
values.put(TodoTable.COLUMN_SATZE, satze);
if (todoUri == null) {
// New todo
todoUri = getContentResolver().insert(MyTodoContentProvider.CONTENT_URI, values);
} else {
// Update todo
getContentResolver().update(todoUri, values, null, null);
}
}
private void makeToast() {
Toast.makeText(TodoDetailActivity.this, "Please maintain a summary",
Toast.LENGTH_LONG).show();
}}
TodosOverviewAktivity.java:
/*
* TodosOverviewActivity displays the existing todo items
* in a list
*
* You can create new ones via the ActionBar entry "Insert"
* You can delete existing ones via a long press on the item
*/
#TargetApi(11)
public class TodosOverviewActivity extends ListActivity implements
LoaderManager.LoaderCallbacks<Cursor> {
private static final int ACTIVITY_CREATE = 0;
private static final int ACTIVITY_EDIT = 1;
private static final int DELETE_ID = Menu.FIRST + 1;
// private Cursor cursor;
private SimpleCursorAdapter adapter;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.todo_list);
this.getListView().setDividerHeight(1);
fillData();
registerForContextMenu(getListView());
}
// Create the menu based on the XML defintion
#Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.listmenu, menu);
return true;
}
// Reaction to the menu selection
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.insert:
createTodo();
return true;
}
return super.onOptionsItemSelected(item);
}
#Override
public boolean onContextItemSelected(MenuItem item) {
switch (item.getItemId()) {
case DELETE_ID:
AdapterContextMenuInfo info = (AdapterContextMenuInfo) item
.getMenuInfo();
Uri uri = Uri.parse(MyTodoContentProvider.CONTENT_URI + "/"
+ info.id);
getContentResolver().delete(uri, null, null);
fillData();
return true;
}
return super.onContextItemSelected(item);
}
private void createTodo() {
Intent i = new Intent(this, TodoDetailActivity.class);
startActivityForResult(i, ACTIVITY_CREATE);
}
// Opens the second activity if an entry is clicked
#Override
protected void onListItemClick(ListView l, View v, int position, long id) {
super.onListItemClick(l, v, position, id);
Intent i = new Intent(this, TodoDetailActivity.class);
Uri todoUri = Uri.parse(MyTodoContentProvider.CONTENT_URI + "/" + id);
i.putExtra(MyTodoContentProvider.CONTENT_ITEM_TYPE, todoUri);
// Activity returns an result if called with startActivityForResult
startActivityForResult(i, ACTIVITY_EDIT);
}
// Called with the result of the other activity
// requestCode was the origin request code send to the activity
// resultCode is the return code, 0 is everything is ok
// intend can be used to get data
#Override
protected void onActivityResult(int requestCode, int resultCode,
Intent intent) {
super.onActivityResult(requestCode, resultCode, intent);
}
private void fillData() {
// Fields from the database (projection)
// Must include the _id column for the adapter to work
String[] from = new String[] { TodoTable.COLUMN_SUMMARY };
// Fields on the UI to which we map
int[] to = new int[] { R.id.label };
getLoaderManager().initLoader(0, null, this);
adapter = new SimpleCursorAdapter(this, R.layout.todo_row, null, from,
to, 0);
setListAdapter(adapter);
}
#Override
public void onCreateContextMenu(ContextMenu menu, View v,
ContextMenuInfo menuInfo) {
super.onCreateContextMenu(menu, v, menuInfo);
menu.add(0, DELETE_ID, 0, R.string.menu_delete);
}
// Creates a new loader after the initLoader () call
#Override
public Loader<Cursor> onCreateLoader(int id, Bundle args) {
String[] projection = { TodoTable.COLUMN_ID_U, TodoTable.COLUMN_SUMMARY };
CursorLoader cursorLoader = new CursorLoader(this,
MyTodoContentProvider.CONTENT_URI, projection, null, null, null);
return cursorLoader;
}
#Override
public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
adapter.swapCursor(data);
}
#Override
public void onLoaderReset(Loader<Cursor> loader) {
// data is not available anymore, delete reference
adapter.swapCursor(null);
}}
MyTodoContentProvider.java:
public class MyTodoContentProvider extends ContentProvider {
// database
private TodoDatabaseHelper database;
// Used for the UriMacher
private static final int TODOS = 10;
private static final int TODO_ID = 20;
private static final String AUTHORITY = "de.vogella.android.todos.contentprovider";
private static final String BASE_PATH = "todos";
public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY
+ "/" + BASE_PATH);
public static final String CONTENT_TYPE = ContentResolver.CURSOR_DIR_BASE_TYPE
+ "/todos";
public static final String CONTENT_ITEM_TYPE = ContentResolver.CURSOR_ITEM_BASE_TYPE
+ "/todo";
private static final UriMatcher sURIMatcher = new UriMatcher(UriMatcher.NO_MATCH);
static {
sURIMatcher.addURI(AUTHORITY, BASE_PATH, TODOS);
sURIMatcher.addURI(AUTHORITY, BASE_PATH + "/#", TODO_ID);
}
#Override
public boolean onCreate() {
database = new TodoDatabaseHelper(getContext());
return false;
}
#Override
public Cursor query(Uri uri, String[] projection, String selection,
String[] selectionArgs, String sortOrder) {
// Uisng SQLiteQueryBuilder instead of query() method
SQLiteQueryBuilder queryBuilder = new SQLiteQueryBuilder();
// Check if the caller has requested a column which does not exists
checkColumns(projection);
// Set the table
queryBuilder.setTables(TodoTable.TABLE_TODO);
int uriType = sURIMatcher.match(uri);
switch (uriType) {
case TODOS:
break;
case TODO_ID:
// Adding the ID to the original query
queryBuilder.appendWhere(TodoTable.COLUMN_ID_U + "="
+ uri.getLastPathSegment());
break;
default:
throw new IllegalArgumentException("Unknown URI: " + uri);
}
SQLiteDatabase db = database.getWritableDatabase();
Cursor cursor = queryBuilder.query(db, projection, selection,
selectionArgs, null, null, sortOrder);
// Make sure that potential listeners are getting notified
cursor.setNotificationUri(getContext().getContentResolver(), uri);
return cursor;
}
#Override
public String getType(Uri uri) {
return null;
}
#Override
public Uri insert(Uri uri, ContentValues values) {
int uriType = sURIMatcher.match(uri);
SQLiteDatabase sqlDB = database.getWritableDatabase();
int rowsDeleted = 0;
long id = 0;
switch (uriType) {
case TODOS:
id = sqlDB.insert(TodoTable.TABLE_TODO, null, values);
break;
default:
throw new IllegalArgumentException("Unknown URI: " + uri);
}
getContext().getContentResolver().notifyChange(uri, null);
return Uri.parse(BASE_PATH + "/" + id);
}
#Override
public int delete(Uri uri, String selection, String[] selectionArgs) {
int uriType = sURIMatcher.match(uri);
SQLiteDatabase sqlDB = database.getWritableDatabase();
int rowsDeleted = 0;
switch (uriType) {
case TODOS:
rowsDeleted = sqlDB.delete(TodoTable.TABLE_TODO, selection,
selectionArgs);
break;
case TODO_ID:
String id = uri.getLastPathSegment();
if (TextUtils.isEmpty(selection)) {
rowsDeleted = sqlDB.delete(TodoTable.TABLE_TODO,
TodoTable.COLUMN_ID_U + "=" + id,
null);
} else {
rowsDeleted = sqlDB.delete(TodoTable.TABLE_TODO,
TodoTable.COLUMN_ID_U + "=" + id
+ " and " + selection,
selectionArgs);
}
break;
default:
throw new IllegalArgumentException("Unknown URI: " + uri);
}
getContext().getContentResolver().notifyChange(uri, null);
return rowsDeleted;
}
#Override
public int update(Uri uri, ContentValues values, String selection,
String[] selectionArgs) {
int uriType = sURIMatcher.match(uri);
SQLiteDatabase sqlDB = database.getWritableDatabase();
int rowsUpdated = 0;
switch (uriType) {
case TODOS:
rowsUpdated = sqlDB.update(TodoTable.TABLE_TODO,
values,
selection,
selectionArgs);
break;
case TODO_ID:
String id = uri.getLastPathSegment();
if (TextUtils.isEmpty(selection)) {
rowsUpdated = sqlDB.update(TodoTable.TABLE_TODO,
values,
TodoTable.COLUMN_ID_U + "=" + id,
null);
} else {
rowsUpdated = sqlDB.update(TodoTable.TABLE_TODO,
values,
TodoTable.COLUMN_ID_U + "=" + id
+ " and "
+ selection,
selectionArgs);
}
break;
default:
throw new IllegalArgumentException("Unknown URI: " + uri);
}
getContext().getContentResolver().notifyChange(uri, null);
return rowsUpdated;
}
private void checkColumns(String[] projection) {
String[] available = { TodoTable.COLUMN_CATEGORY,
TodoTable.COLUMN_SUMMARY, TodoTable.COLUMN_DESCRIPTION, TodoTable.COLUMN_SATZE, TodoTable.COLUMN_ID_U };
if (projection != null) {
HashSet<String> requestedColumns = new HashSet<String>(Arrays.asList(projection));
HashSet<String> availableColumns = new HashSet<String>(Arrays.asList(available));
// Check if all columns which are requested are available
if (!availableColumns.containsAll(requestedColumns)) {
throw new IllegalArgumentException("Unknown columns in projection");
}
}
}
}
TodoDatabaseHelper.java:
public class TodoDatabaseHelper extends SQLiteOpenHelper {
private static final String DATABASE_NAME = "todotable.db";
private static final int DATABASE_VERSION = 1;
public TodoDatabaseHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
// Method is called during creation of the database
#Override
public void onCreate(SQLiteDatabase database) {
TodoTable.onCreate(database);
}
// Method is called during an upgrade of the database,
// e.g. if you increase the database version
#Override
public void onUpgrade(SQLiteDatabase database, int oldVersion,
int newVersion) {
TodoTable.onUpgrade(database, oldVersion, newVersion);
}
}
The most of code I have copied from: http://www.vogella.com/articles/AndroidSQLite/article.html#todo
But I get the errormessage (LogCat):
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.de.vogella.android.todos/com.example.de.vogella.android.todos.TodoDetailActivity}: java.lang.IllegalArgumentException: column 'satze' does not exist
Can anybody find a mistake in the code?
Thanks
Here is your bug:
private void fillData(Uri uri) {
String[] projection = { TodoTable.COLUMN_SUMMARY,
TodoTable.COLUMN_DESCRIPTION, TodoTable.COLUMN_CATEGORY }; //add satze here!
Cursor cursor = getContentResolver().query(uri, projection, null, null,
null);
if (cursor != null) {
cursor.moveToFirst();
String category = cursor.getString(cursor
.getColumnIndexOrThrow(TodoTable.COLUMN_CATEGORY));
for (int i = 0; i < mCategory.getCount(); i++) {
String s = (String) mCategory.getItemAtPosition(i);
if (s.equalsIgnoreCase(category)) {
mCategory.setSelection(i);
}
}
mTitleText.setText(cursor.getString(cursor
.getColumnIndexOrThrow(TodoTable.COLUMN_SUMMARY)));
mBodyText.setText(cursor.getString(cursor
.getColumnIndexOrThrow(TodoTable.COLUMN_DESCRIPTION)));
mSatzText.setText(cursor.getString(cursor
.getColumnIndexOrThrow(TodoTable.COLUMN_SATZE)));//you don't have satze in projection!
// Always close the cursor
cursor.close();
}
}
You are trying to read TodoTable.COLUMN_SATZE but you forgot about it in projection:
Please change this line:
String[] projection = { TodoTable.COLUMN_SUMMARY,
TodoTable.COLUMN_DESCRIPTION, TodoTable.COLUMN_CATEGORY };
into this:
String[] projection = { TodoTable.COLUMN_SUMMARY,
TodoTable.COLUMN_DESCRIPTION, TodoTable.COLUMN_CATEGORY, TodoTable.COLUMN_SATZE };
In your CREATE TABLE statement you need spaces between your column names and column types.