I am following this tutorial made by our folks over at Google.
If you look at the third code snippet, the tutorial shows the FeedReaderDbHelper class which extends from the SQLiteOpenHelper class.
public class FeedReaderDbHelper extends SQLiteOpenHelper
Then, it shows how to create an instance of the FeedReaderDbHelper object in order to use it to read and write to the database.
FeedReaderDbHelper mDbHelper = new FeedReaderDbHelper(getContext());
The problem as I see it is that SQLiteOpenHelper is an abstract class. So whenever I do the following in my own program:
MatchEntry.MatchDBHelper dbHelper = new MatchEntry.MatchDBHelper(context);
I get an error: ....MatchContract.MatchEntry is not an enclosing class
Is this because of SQLiteOpenHelper being abstract? The way I have set-up my classes are exactly the same and pretty much mimic exactly what the docs have.
Update
This is how the structure looks like so far:
public class MatchContract {
public MatchContract() {
}
public static abstract class MatchEntry implements BaseColumns {
...
...
...
}
public class MatchDBHelper extends SQLiteOpenHelper {
...
...
...
}
}
Am I correct to put the MatchDBHelper inside the MatchContract class? I assume so as it needs to know the SQL_CREATE_TABLE string, otherwise it won't know.
The idea is, that a Contract class is an abstraction of the database, So, in MatchContract you will have all the global variables of the database and in the inner class, MatchEntry you will implement the abstraction of the database itself (columns etc). Then, with MatchDBHelper you will be managing the database (Creating it, upgrading it etc) And writing SQL entries.
As I said in the comments, You need to create the helper class as a normal class, not an inner class:
public class MatchContract {
public MatchContract() {
}
/// Global variables for the DB
public static abstract class MatchEntry implements BaseColumns {
// Structure of the database
}
}
public class MatchDBHelper extends SQLiteOpenHelper {
// Manage the database
}
As a complete example:
public final class PersonContract {
public PersonContract() {
}
public static abstract class PersonEntry implements BaseColumns{
public static final String TABLE_NAME = "person";
public static final String COLUMN_NAME_ENTRY_ID = "personID";
public static final String COLUMN_NAME_FIRST_NAME = "firstname";
public static final String COLUMN_NAME_SECOND_NAME = "secondname";
}
}
public class PersonDbBHelper extends SQLiteOpenHelper {
public static final int DATABASE_VERSION = 1;
public static final String DATABASE_NAME = "Persons.db";
private static final String TEXT_TYPE = " TEXT";
private static final String COMMA_SEP = ",";
private static final String SQL_CREATE_ENTRIES =
"CREATE TABLE " + PersonEntry.TABLE_NAME + " (" +
PersonEntry._ID + " INTEGER PRIMARY KEY," + // Heredado de BaseColumns
PersonEntry.COLUMN_NAME_ENTRY_ID + TEXT_TYPE + COMMA_SEP +
PersonEntry.COLUMN_NAME_FIRST_NAME + TEXT_TYPE + COMMA_SEP +
PersonEntry.COLUMN_NAME_SECOND_NAME + TEXT_TYPE +
" )";
private static final String SQL_DELETE_ENTRIES =
"DROP TABLE IF EXISTS " + PersonEntry.TABLE_NAME;
public PersonDbBHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
#Override
public void onCreate(SQLiteDatabase db) {
db.execSQL(SQL_CREATE_ENTRIES);
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL(SQL_DELETE_ENTRIES);
onCreate(db);
}
#Override
public void onDowngrade(SQLiteDatabase db, int oldVersion, int newVersion) {
onUpgrade(db, oldVersion, newVersion);
}
}
Related
When I Run My App I Don't See Any Database File In Dir >> Android >> Data >> packagename....
And Also There Is No Crash Or Error:
My dpopenhelper Class:
public class dbopenhelper extends SQLiteOpenHelper {
public static final String dbname = "dbtest";
public static final String tblname = "tblname";
public static final String cid = "id";
public static final String cquestion = "queston";
public static final String canswe = "answer";
public static final String createtbl = "CREATE TABLE "+ tblname +"("+cid+" INTEGER PRIMARY KEY AUTOINCREMENT,"+cquestion+" TEXT,"+canswe+" TEXT);";
public dbopenhelper(Context context) {
super(context, dbname, null, 1);
}
#Override
public void onCreate(SQLiteDatabase db) {
db.execSQL(createtbl);
}
#Override
public void onUpgrade(SQLiteDatabase sqLiteDatabase, int i, int i1) {
}
}
And In My MainActivity
public class MainActivity extends AppCompatActivity {
private dbopenhelper dbm;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
dbm = new dbopenhelper(this);
dbm.getWritableDatabase();
}
}
Are you trying to access from an emulator or real device....
real device would need to be rooted so as to access the data directory that has the db file
but I guess you could try to use getDatabasePath("your_db_name") in the app to return the file object then use getAbsolutePath() to get accurate path and try navigating to that path and if u see the file, rename it adding the .db3 extension and access it in SQLiteExplorer
In my app, I have a database with a table that contains several user made entries. Here's a simplified version of my SQLite database helper class:
public class DatabaseHelper extends SQLiteOpenHelper {
public static final String DATABASE_NAME = "data.db";
public static final String TABLE_NAME = "log";
public static final String COL_1 = "ID"; //autoincrement in oncreate
...
public static final String COL_12 = "NUMBER"; //set through getCount()
public DatabaseHelper(Context context) {
...
}
#Override
public void onCreate(SQLiteDatabase db) {
...
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
...
}
public long getCount() {
...
}
public boolean insertData(...) {
...
}
public void update(long id, String param) {
...
}
public Cursor getAllData() {
...
}
//for when an entry is deleted and thus COL_12 numbering is not fixed
public void consolidate() {
SQLiteDatabase db = this.getWritableDatabase();
db.execSQL("ALTER TABLE log ORDER BY NUMBER ASC");
}
}
However, whenever I call myDb.consolidate(), my app crashes. From what I've read from other posts, this should work, but it only throws error code 1: missing database. Anyone know why? Any help is appreciated.
im trying to do a system.out.println("something") inside onCreate() for SQLiteOpenHelper. but i didn't get anything. i even made sure to call getReadableDatabase();
anyone knows why?
this is my sqlite class
public class ChatOpenHelper extends SQLiteOpenHelper {
private static final int DATABASE_VERSION = 2;
public static final String DATABASE_NAME = "FeedReader.db";
private static final String CHAT_TABLE_NAME = "Bolster_ME_YOU";
private static final String CHAT_TABLE_CREATE =
"CREATE TABLE IF NOT EXISTS " + CHAT_TABLE_NAME + " (" +
" test VARCHAR(255) );";
private static final String CHAT_TABLE_DELETE =
"DROP TABLE IF NOT EXISTS " + CHAT_TABLE_NAME + ");";
public ChatOpenHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
#Override
public void onCreate(SQLiteDatabase db) {
System.out.println("hello from sqlite");
System.out.println(this.getDatabaseName());
db.execSQL(CHAT_TABLE_DELETE);
db.execSQL(CHAT_TABLE_CREATE);
Log.v("smartdbhelper", "after creation");
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
this.onCreate(db);
}
}
//this is the activity class
public class LoginActivity extends ActionBarActivity {
private Button signin;
private Button signup;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);
signin = (Button)findViewById(R.id.login_signin);
signup = (Button)findViewById(R.id.login_signup);
ChatOpenHelper open = new ChatOpenHelper(this);
SQLiteDatabase sql = open.getReadableDatabase();
sql.close();
open.close();
}
}
SQLiteOpenHelper.onCreate() is only called when the database is created for the first time.
You'd better use Log.d("label", "value") rather than System.out.print().
Im a bit new to OOP so i want to know if im doing things correctly. For communication with database i have created a class SQLiteHelper witch does all the usual stuff (onCreate, onUpdate) and also opens and closes connection.
Here is the class, at the moment it has just on table but more will be added:
public class SQLiteHelper extends SQLiteOpenHelper{
public static final String DATABASE_NAME = "notebook";
public static final int DATABASE_VERSION = 2;
public static final String TABLE_LIST = "list";
public static final String TABLE_LIST_ID = "_id";
public static final String TABLE_LIST_NAME = "name";
public SQLiteDatabase db;
public SQLiteHelper(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("create table " + TABLE_LIST + "(" + TABLE_LIST_ID
+ " integer primary key autoincrement, " + TABLE_LIST_NAME
+ " text not null);");
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
// TODO Auto-generated method stub
db.execSQL("DROP TABLE IF EXISTS " + TABLE_LIST);
onCreate(db);
}
public void open(){
db = getWritableDatabase();
}
public void close(){
db.close();
}
}
And next for each table i will create a new class witch extends previous class andd where i do all the operations relevant to that specific table.
For example ListSQL:
public class ListSQL extends SQLiteHelper {
public ListSQL(Context context) {
super(context);
}
public void delete(int id) {
open();
db.delete(TABLE_LIST, TABLE_LIST_ID + " = " + id, null);
close();
}
}
My question is that in OOP is this the correct way of doing things? Espesially the usage of open/close methods and db and TABLE variables in ListSQL seem kind of strange to me?
I always open the db connection in onResume() and close it in onPause(). In this way database is always open for each activity.
The reason I am not doing it in onCreate() and onDestroy() is once user go to other activity onCreate() of new activity will be called first then onDestroy() of old activity so if I perform any operation(ex:- search in my list or changing the status of user etc) on places other then onCreate() it will crash the app with reason database already closed.
Note: You have to open and close the connection, even if you are using SQLiteHelper class.
According to the Android manual, you do not need to close a database when using an SQLiteOpenHelper. The system will do it for you.
As #Dan mentioned above, you do no need to open and close the database every time you do a read/write operation if you are using SQLiteOpenHelper. The best way to use the database is :
1.
Declare and initialize an instance of SQLiteHelper in your Application base class like this :
public class App extends Application {
public static SQLiteHelper db;
#Override
public void onCreate() {
super.onCreate();
db = new SQLiteHelper(getApplicationContext());
db.open();
}
}
2.
In you activity, or any other place you want to use the DB, initialize the SQLiteHelper object like this :
SQLiteHelper db = App.db;
And then you can use the database anyway you want without having to worry about opening and closing it (:
i've problem access other class in android...
i've class databasex (non static) and class CountingFragment (static)....
in CountingFragment i want to access databasex class..but i get result null....
here is my piece of code...
class Databasex
public class DataBasex {
public static final String KEY_ROWID="_id";
public static final String KEY_NAME="namaLokasi";
public static final String KEY_JENIS="jenis";
public static final String KEY_KETERANGAN="ket";
public static final String tanda="DataBasex";
private static final String DATABASE_NAME="DbPeta";
private static final String DATABASE_TABLE="lokasi";
private static final int DATABASE_VERSION=1;
private DbHelper ourHelper;
private final Context ourContext;
private SQLiteDatabase ourDatabase;
private static class DbHelper extends SQLiteOpenHelper{
public DbHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
Log.i(tanda,"dbHelper-> "+context);
// TODO Auto-generated constructor stub
}
#Override
public void onCreate(SQLiteDatabase db) {
// TODO Auto-generated method stub
Log.i(tanda,"onCreate-> "+db);
/*db.execSQL("CREATE TABLE " + DATABASE_TABLE + "("+
KEY_ROWID +" INTEGER PRIMARY KEY AUTOINCREMENT, " +
KEY_NAME +" TEXT NOT NULL, " + KEY_JENIS +" TEXT NOT NULL, " +
KEY_KETERANGAN +" TEXT NOT NULL);");
*/
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
// TODO Auto-generated method stub
Log.i(tanda,"onUpgrade-> "+db);
//db.execSQL("DROP TABLE IF EXISTS"+DATABASE_TABLE);
//onCreate(db);
}
}
public DataBasex(Context c){
ourContext =c;
Log.i(tanda,"DataBasex-> "+ourContext);
}
public DataBasex open() throws SQLException{
Log.i(tanda,"DataBasex open awal ");
ourHelper = new DbHelper(ourContext);
ourDatabase=ourHelper.getWritableDatabase();
Log.i(tanda,"DataBasex open-> "+ourDatabase);
return this;
}
public void close(){
Log.i(tanda,"[close]");
ourHelper.close();
}
}
and here is CountingFragment class...
public static class CountingFragment extends SherlockFragment {
//here myproblem...
DataBasex con=new DataBasex(getSherlockActivity());
/**
*other method
*/
}
i think the code bellow is my problem
DataBase con=new DataBase(getSherlockActivity());
if in non-static class i use code bellow and everything is ok....but in static class i can't...why??
DataBase con=new DataBase(this);
It is due to the fact that Fragments need to first be attached to an Activity (see the document on Fragments before they can return an Activity. Specifically the lifecycle. First the Fragment is attached to an Activity (and onAttach() is called. Then the Fragment can get an Activity instance.
DataBasex con=new DataBasex(getSherlockActivity());
is in the root of the Class, it will return null - the Fragment does not have an Activity right off the bat.
Change
DataBasex con=new DataBasex(getSherlockActivity());
So it is:
DataBasex con;
And add this method:
#Override
public void onCreate (Bundle b)
{
super.onCreate (b);
con = new DataBasex(getSherlockActivity());
}
The reason for that is because in Static class there will be No Object, and the access of the methods will be class level access, but in the none-static class there will be an Object of that class, then you should have no null value in the none-static class