Android SQLite data fetching - java

Every time I run a "select *" query from my SQLite, the app keeps stopping. I've deduced it to it calling the database helper every time, but I don't know how to fix it.
MainActivity.java
public class MainActivity extends AppCompatActivity {
DatabaseHelper databaseHelper;
#Override
protected void onCreate(Bundle savedInstanceState) {
getWindow().setStatusBarColor(Color.WHITE);
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
displayUsers();
}
public void displayUsers() {
Cursor cursor = databaseHelper.getAllUsers(); //here's where the error keeps on happening
if(cursor.getCount() == 0) {
Toast.makeText(this, "none", Toast.LENGTH_SHORT).show();
}
}
}
DatabaseHelper.java
public class DatabaseHelper extends SQLiteOpenHelper {
public static final String DATABASE_NAME = "reminders.db";
public static final String T_1 = "tbl_users";
public static final String T1_COL_1 = "ID";
public static final String T1_COL_2 = "FIRST_NAME";
public static final String T1_COL_3 = "MIDDLE_INITIAL";
public static final String T1_COL_4 = "LAST_NAME";
public static final String T1_COL_5 = "PHONE";
public static final String T1_COL_6 = "EMAIL";
public static final String T1_COL_7 = "USERNAME";
public static final String T1_COL_8 = "PASSWORD";
public DatabaseHelper(#Nullable Context context) {
super(context, DATABASE_NAME, null, 1);
SQLiteDatabase database = this.getWritableDatabase();
}
...//other functions
public Cursor getAllUsers() {
SQLiteDatabase database = this.getWritableDatabase();
Cursor cursor = database.rawQuery("select * from " + T_1, null);
return cursor;
}
}

Your DatabaseHelper class doesn’t create any object cause you didn’t call new DatabaseHelper (this). Thats why databasehelper return null.
You can try those line in onCreate method,
databaseHelper= new DatabaseHelper(this);

Before returning cursor close your database
public Cursor getAllUsers() {
SQLiteDatabase database = this.getWritableDatabase();
Cursor cursor = database.rawQuery("select * from " + T_1, null);
database.close(); // Added
return cursor;
}

In following function at first your have to initialize database to get WritableDatabase in DatabaseHelper class.
public void displayUsers() {
databaseHelper = DatabaseHelper(MainActivity.this)
Cursor cursor = databaseHelper.getAllUsers();
if(cursor.getCount() == 0) {
Toast.makeText(this, "none", Toast.LENGTH_SHORT).show();
}
}

Related

How to adapt startManagingCursor() to a non-deprecated method?

I've been trying to stick with startManagingCursor() for my read-only SQLite database, but it's throwing a lot of errors even if I use stopManagingCursor() (yes, I know they're deprecated).
I'd like to have some help to know the steps to go from managing cursors to a better method without changing much since I've never used them and this code is somehow stable although random errors pop up from time to time because of startManagingCursor() (in a single activity app, it works fine, but when using it as a frament in a multifragment app, it gets really problematic).
However, when I simply change startManagingCursor() to getLoaderManager() it still works, but the documentation also tells it's deprecated and indicates getSupportLoaderManager() and, when I use this one, it gets crossed out as if it's also deprecated (Lint says "getSupportLoaderManager() is deprecated", but doesn't say the same for getLoaderManager()); and those may produce java.lang.NullPointerException what wasn't happening with startManagingCursor(cursor) although both are runnable.
So what should I do then?
The SQLite fragment is this:
public class SQLiteDatabaseActivity extends Fragment {
public static SQLiteDatabaseActivity newInstance() {
return new SQLiteDatabaseActivity();
}
ExpandableListView expandableListView;
Database mDatabase;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.sqlite_database_activity, container, false);
mDatabase = new Database(getActivity());
mDatabase.open();
Cursor cursor = mDatabase.getDatabase();
getActivity().startManagingCursor(cursor);
String[] groupFrom = {
Database.DATABASE_GROUP_1,
Database.DATABASE_GROUP_2,
Database.DATABASE_GROUP_3,
Database.DATABASE_GROUP_4
};
int[] groupTo = {
R.id.group_number,
R.id.group_name,
R.id.group_path,
R.id.group_company
};
String[] childFrom = new String[]{
Database.DATABASE_CHILD_1,
Database.DATABASE_CHILD_2,
Database.DATABASE_CHILD_3,
Database.DATABASE_CHILD_4,
Database.DATABASE_CHILD_5,
Database.DATABASE_CHILD_6,
Database.DATABASE_CHILD_7,
Database.DATABASE_CHILD_8,
Database.DATABASE_CHILD_9,
Database.DATABASE_CHILD_10,
Database.DATABASE_CHILD_11,
Database.DATABASE_CHILD_12
};
int[] childTo = {
R.id.child1,
R.id.child2,
R.id.child_saturday_origin,
R.id.child_saturday_destiny,
R.id.child_sunday_origin,
R.id.child_sunday_destiny,
R.id.child_origin,
R.id.child_destiny,
R.id.child_saturday_origin_origin,
R.id.child_saturday_destiny_destiny,
R.id.child_sunday_origin_origin,
R.id.child_sunday_destiny_destiny
};
SimpleCursorTreeAdapter simplecursortreeAdapter = new ExpandableListViewAdapter(
getActivity(),
cursor,
R.layout.sqlite_database_list_group,
groupFrom,
groupTo,
R.layout.sqlite_database_list_child,
childFrom,
childTo
);
expandableListView = view.findViewById(R.id.expandableListview);
expandableListView.setAdapter(simplecursortreeAdapter);
getActivity().stopManagingCursor(cursor);
return view;
}
private class ExpandableListViewAdapter extends SimpleCursorTreeAdapter {
private ExpandableListViewAdapter(
Context context,
Cursor cursor,
int groupLayout,
String[] groupFrom,
int[] groupTo,
int childLayout,
String[] childFrom,
int[] childTo) {
super(context, cursor, groupLayout, groupFrom, groupTo, childLayout, childFrom, childTo);
}
protected Cursor getChildrenCursor(Cursor groupCursor) {
return mDatabase.getID(groupCursor.getInt(groupCursor.getColumnIndex(Database.DATABASE_ID)));
}
}
public void onDestroy() {
super.onDestroy();
mDatabase.close();
}
}
The database is here:
public class Database {
private static final int DATABASE_VERSION = 3;
private static final String DATABASE_NAME = "BusScheduleDatabase.db";
private static final String DATABASE_TABLE = "BusSchedule";
public static final String DATABASE_ID = "_id";
public static final String DATABASE_GROUP_1 = "Linha";
public static final String DATABASE_GROUP_2 = "Nome";
public static final String DATABASE_GROUP_3 = "Caminho";
public static final String DATABASE_GROUP_4 = "Empresa";
public static final String DATABASE_CHILD_1 = "SemanaIda";
public static final String DATABASE_CHILD_2 = "SemanaVolta";
public static final String DATABASE_CHILD_3 = "SabadoIda";
public static final String DATABASE_CHILD_4 = "SabadoVolta";
public static final String DATABASE_CHILD_5 = "DomingoIda";
public static final String DATABASE_CHILD_6 = "DomingoVolta";
public static final String DATABASE_CHILD_7 = "Origem";
public static final String DATABASE_CHILD_8 = "Destino";
public static final String DATABASE_CHILD_9 = "Origem";
public static final String DATABASE_CHILD_10 = "Destino";
public static final String DATABASE_CHILD_11 = "Origem";
public static final String DATABASE_CHILD_12 = "Destino";
private final Context mContext;
private DatabaseHelper mDatabaseHelper;
private SQLiteDatabase mDB;
public Database(Context context) {
mContext = context;
}
public void open() {
mDatabaseHelper = new DatabaseHelper(mContext, DATABASE_NAME, null, DATABASE_VERSION);
mDB = mDatabaseHelper.getReadableDatabase();
}
public void close() {
if (mDatabaseHelper != null) mDatabaseHelper.close();
}
public Cursor getDatabase() {
return mDB.query(DATABASE_TABLE, null, null, null, null, null, DATABASE_GROUP_1);
}
public Cursor getID(long rowID) {
return mDB.query(DATABASE_TABLE, null, "_id" + " = "
+ rowID, null, null, null, null);
}
public class DatabaseHelper extends SQLiteAssetHelper {
public DatabaseHelper(Context mContext, String DATABASE_NAME, SQLiteDatabase.CursorFactory factory, int DATABASE_VERSION) {
super(mContext, DATABASE_NAME, factory, DATABASE_VERSION);
super.setForcedUpgrade();
}
}
}
And the repetitive error is basically the following:
java.lang.IllegalStateException: this should only be called when the cursor is valid
Thank you very much in advance for the help!

Is it the correct way to initialize SQLite in MainActivity?

Im working on android studio and i encountered a problem, I cant initialize my sqlite instance in my DataHandler class but I can initialize it in my MainActivity class.
Example:
MainActivity class:
public class MainActivity extends AppCompatActivity {
private RecyclerView recyclerView;
private RecyclerView.LayoutManager layoutManager;
private RecyclerView.Adapter adapter;
//valid
private SQLiteDatabase sqLiteDatabase = openOrCreateDatabase("Database", Context.MODE_PRIVATE , null); //...
in datahandler class:
public class DataHandler {
public static String[] names,dates;
//invalid: cannot resolve method
SQLiteDatabase sqLiteDatabase = openOrCreateDatabase("HMDB", Context.MODE_PRIVATE , null);
so, i did this
in main activity:
public SQLiteDatabase getSqLiteDatabase() {
return sqLiteDatabase;
}
in datahandler:
MainActivity mainActivity;
SQLiteDatabase sqLiteDatabase = mainActivity.getSqLiteDatabase();
is this the correct way? is there any better method? sry if hard to understand
Is this the correct way?
Did it throws any errors when project is running ?
This is how I normally do in DatabaseHandler (just sharing)
public class DatabaseHandler extends SQLiteOpenHelper {
public static final String DATABASE_NAME = "DATA.db";
public static final String TABLE_NAME = "TITLE";
public static final String COL0 = "ID";
public static final String COL1 = "TODO";
public static final String COL2 = "DETAIL";
public DatabaseHandler(Context context) {
super(context, DATABASE_NAME, null, 1);
}
#Override
public void onCreate(SQLiteDatabase db) {
String createTable = "CREATE TABLE " + TABLE_NAME + " (ID INTEGER PRIMARY KEY AUTOINCREMENT, TODO TEXT, DETAIL TEXT)";
db.execSQL(createTable); }
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL("drop if database is exists" + TABLE_NAME);
onCreate(db);
}
}
In MainActivity, declare this line
DatabaseHandler db;
In onCreate method, initialize DatabaseHandler
db = new DatabaseHandler(this);
When you want to use SQLite database, make sure you have this line
SQLiteDatabase db = this.getWritableDatabase();
The best approach is to use Singleton Pattern as described here
https://github.com/codepath/android_guides/wiki/Local-Databases-with-SQLiteOpenHelper
public class PostsDatabaseHelper extends SQLiteOpenHelper {
private static PostsDatabaseHelper sInstance;
// ...
public static synchronized PostsDatabaseHelper getInstance(Context context) {
// Use the application context, which will ensure that you
// don't accidentally leak an Activity's context.
if (sInstance == null) {
sInstance = new PostsDatabaseHelper(context.getApplicationContext());
}
return sInstance;
}
/**
* Constructor should be private to prevent direct instantiation.
* Make a call to the static method "getInstance()" instead.
*/
private PostsDatabaseHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
}
And in your MainActivity use it like
// In any activity just pass the context and use the singleton method
PostsDatabaseHelper helper = PostsDatabaseHelper.getInstance(this);
// or
PostsDatabaseHelper helper = PostsDatabaseHelper.getInstance(context);
// or
PostsDatabaseHelper helper = PostsDatabaseHelper.getInstance(getActivity());
// Do something with data via Cursor and
helper.close();
This approach perfect suits to get access to the database from different places of you app like Service, Fragment and etc...

getDatabase called recursively sqlite insert and getReadableDatabase()

I just started with my first App and I am trying to create a table settings, which should contain an entry PIN. after that I want to run the method getPIN() to get the value of this setting.
The problem is, that I get always the error "getDatabase called recursively". As I just started with this, I have no idea how to fix it. I've seen a lot of used to have the same problem, but the solutions doesn't work for me.
Could you please help me to understand what I'm doing wrong.
The contacts table was part of a tutorial I followed before, that´s the reason it's still in there.
Thank you.
This is my Database Helper
public class DatabaseHelper extends SQLiteOpenHelper {
private static final int DATABASE_VERSION =3;
private static final String DATABASE_NAME = "contacts.db";
private static final String TABLE_NAME = " contacts";
private static final String COLUMN_ID = "id";
private static final String COLUMN_NAME = "name";
private static final String COLUMN_EMAIL = "email";
private static final String COLUMN_PASS = "pass";
SQLiteDatabase db;
private static final String TABLE_CREATE = "create table contacts (id integer primary key not null ," +
"name text not null, email text not null, pass text not null);";
private static final String TABLE_SETTINGS = "create table settings (id integer primary key not null ," +
"setting text not null, value integer not null);";
public DatabaseHelper(Context context){
super(context, DATABASE_NAME, null,DATABASE_VERSION );
}
#Override
public void onCreate(SQLiteDatabase db){
String ssetting = "PIN";
db.execSQL(TABLE_CREATE);
db.execSQL(TABLE_SETTINGS);
db=this.getWritableDatabase();
ContentValues values = new ContentValues();
String query = "Select * from settings";
Cursor cursor = db.rawQuery(query, null);
int count = cursor.getCount();
values.put("id",count);
values.put("setting", ssetting);
values.put("value", 0);
db.insert("settings", null, values);
db.close();
this.db=db;
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion){
String query = "DROP TABLE IF EXISTS"+TABLE_NAME;
db.execSQL(query);
this.onCreate(db);
}
public int insertContact(Contact c){
db=this.getWritableDatabase();
ContentValues values = new ContentValues();
String query = "Select * from contacts";
Cursor cursor = db.rawQuery(query, null);
int count = cursor.getCount();
values.put(COLUMN_ID,count);
values.put(COLUMN_NAME, c.getName());
values.put(COLUMN_EMAIL, c.getEmail());
values.put(COLUMN_PASS, c.getPass());
db.insert(TABLE_NAME, null, values);
db.close();
return 0;
}
public String searchPass(String uname)
{
db = this.getReadableDatabase();
String query = "select name, pass from "+TABLE_NAME;
Cursor cursor = db.rawQuery(query, null);
String a,b;
b="not found";
if (cursor.moveToFirst()){
do {
a = cursor.getString(0);
b = cursor.getString(1);
if (a.equals(uname)) {
b = cursor.getString(1);
break;
}
}
while(cursor.moveToNext());
}
db.close();
return b;
}
public int getPIN()
{
db = this.getReadableDatabase();
int pin=1;
String query = "select id, setting, value from settings where setting='PIN'";
Cursor cursor = db.rawQuery(query, null);
if (cursor.moveToFirst()){
do {
pin = cursor.getInt(2);
break;
}
while(cursor.moveToNext());
}
db.close();
return pin;
}
}
and the MainActivity
public class MainActivity extends AppCompatActivity {
DatabaseHelper helper = new DatabaseHelper(this);
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
int pin = helper.getPIN();
if (pin==0){
Intent i = new Intent(MainActivity.this, Loginpin.class);
startActivity(i);
}
if (pin==1) {
Intent i = new Intent(MainActivity.this, Setuppin.class);
startActivity(i);
}
//pin = helper.getPIN();
}
public void b_newOnClick(View v) {
if (v.getId() == R.id.blogin)
{
EditText user = (EditText) findViewById(R.id.tfuser);
String su = user.getText().toString();
EditText pass = (EditText) findViewById(R.id.tf_pw);
String spass = pass.getText().toString();
String password = helper.searchPass(spass);
if(spass.equals(password))
{
Intent i = new Intent(MainActivity.this, Welcome.class);
i.putExtra("username", su);
startActivity(i);
}
else{
Toast.makeText(MainActivity.this, "Password incorrect", Toast.LENGTH_LONG).show();
}
}
}
public void onSignClick(View v) {
if (v.getId() == R.id.bsign) {
Intent i = new Intent(MainActivity.this, SignUp.class);
startActivity(i);
}
}
}
Thank you so much.
regards, S
Kilimanscharo
Don't call getWritableDatabase() or getReadableDatabase() from your SQLiteOpenHelper lifecycle methods such as onCreate() or onUpgrade() that are in turn triggered by a call to get...Database(). Instead, use the SQLiteDatabase object that is given as a parameter to these methods.
Specifically, remove this line from your onCreate():
db=this.getWritableDatabase();

Table is not found in SQLiteDatabase

I am facing this strange problem that I searched alot, but no use so far.
The following code I am using to retrieve SQLite database using a DBHelper that extends from openhelper class.
public class DBHelper extends SQLiteOpenHelper {
public static final int DB_VERSION = 1;
public static final String DB_NAME = "cp.db";
public static final String DB_PATH = "/data/data/abdulla.com.test/databases/";
public static final String ID = "no";
public static final String NAME = "name";
public static final String FORMULA = "formula";
public static final String MW = "mw";
public static final String OMEGA = "omega";
public static final String TC = "tc";
public static final String PC = "pc";
SQLiteDatabase db;
Cursor cursor;
ArrayList<String> elementName;
public DBHelper(Context context) {
super(context, DB_NAME, null, DB_VERSION);
}
#Override
public void onCreate(SQLiteDatabase db) {
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL("drop table if exists elements");
this.onCreate(db);
}
public List<Element> getAllElements() {
List<Element> elementList = new ArrayList<Element>();
// Select All Query
Cursor cursor = null;
String selectQuery = "SELECT * FROM elements";
SQLiteDatabase db = this.getReadableDatabase();
cursor = db.rawQuery(selectQuery, null);
// looping through all rows and adding to list
if (cursor.moveToFirst()) {
do {
Element element = new Element();
element.setNo(Integer.parseInt(cursor.getString(0)));
element.setFormula(cursor.getString(1));
element.setName(cursor.getString(2));
// Adding contact to list
elementList.add(element);
} while (cursor.moveToNext());
}
// return contact list
return elementList;
}
}
This is capture from MainActivity class
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
DBHelper helper = new DBHelper(this);
List<Element> elementList = helper.getAllElements();
for(Element element : elementList){
String log = "no: "+element.getNo();
Log.d("No: ", log);
}
}
}
I am getting this error:
java.lang.RuntimeException: Unable to start activity
ComponentInfo{abdulla.com.test/abdulla.com.test.MainActivity}:
android.database.sqlite.SQLiteException: no such table: elements (code 1):
, while compiling: SELECT * FROM elements
I know that elements table is there
Any help?
Probably the issue is in your onUpgrade() method. If your database doesn't have version, application tries to upgrade it, and drops your table (db.execSQL("drop table if exists elements");).
Solution: set version to DB or change onUpgrade() method (delete DROP statement).

Listview with Cusror adapter displays nothing

In my android app, I read some data from SQLite database and tried to display it into listview. Here is my code:
ListView listContent;
SQLiteAdapterno nadapter;
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.ofrnumber);
listContent=(ListView)findViewById(R.id.listView1);
nadapter=new SQLiteAdapterno(this);
nadapter.openToRead();
Cursor c=nadapter.queueAll();
String[] from = new String[]{SQLiteAdapterno.KEY_ID, SQLiteAdapterno.KEY_RCODE, SQLiteAdapterno.KEY_RNAME,SQLiteAdapterno.KEY_OFNO};
int[] to = new int[]{R.id.id,R.id.text1,android.R.id.text2,android.R.id.text2};
SimpleCursorAdapter cursorAdapter =new SimpleCursorAdapter(this, R.layout.row,c, from, to);
listContent.setAdapter(cursorAdapter);
}
SQLiteAdapterno:
public class SQLiteAdapterno {
public static final String MYDATABASE_NAME2 = "MY_DATABASEOFRN";
public static final String MYDATABASE_TABLE2 = "MY_OFFERNO";
public static final int MYDATABASE_VERSION = 1;
public static final String KEY_RCODE = "rcode";
public static final String KEY_OFNO = "ofno";
public static final String KEY_RNAME = "rname";
public static final String KEY_ID = "_id";
private static final String SCRIPT_CREATE_DATABASE1 =
"create table " + MYDATABASE_TABLE2 + " ("
+ KEY_ID +" integer primary key autoincrement, "
+ KEY_RCODE + " text, "
+ KEY_RNAME + " text, "
+ KEY_OFNO + " text);";
private SQLiteHelper sqLiteHelper;
private SQLiteDatabase sqLiteDatabase;
private Context context;
public SQLiteAdapterno(Context c)
{
context=c;
}
public SQLiteAdapterno openToRead() throws android.database.SQLException {
sqLiteHelper = new SQLiteHelper(context, MYDATABASE_NAME2, null, MYDATABASE_VERSION);
sqLiteDatabase = sqLiteHelper.getReadableDatabase();
return this;
}
public SQLiteAdapterno openToWrite() throws android.database.SQLException {
sqLiteHelper = new SQLiteHelper(context, MYDATABASE_NAME2, null, MYDATABASE_VERSION);
sqLiteDatabase = sqLiteHelper.getWritableDatabase();
return this;
}
public void close(){
sqLiteHelper.close();
}
public long insert(String rcode, String rname, String ofno){
ContentValues contentValues = new ContentValues();
contentValues.put(KEY_RCODE, rcode);
contentValues.put(KEY_RNAME, rname);
contentValues.put(KEY_OFNO, ofno);
return sqLiteDatabase.insert(MYDATABASE_TABLE2, null, contentValues);
}
public Cursor queueAll(){
String[] columns = new String[]{KEY_ID, KEY_RCODE, KEY_RNAME, KEY_OFNO};
Cursor cursor = sqLiteDatabase.query(MYDATABASE_TABLE2, columns,
null, null, null, null, null);
return cursor;
}
public int deleteAll(){
return sqLiteDatabase.delete(MYDATABASE_TABLE2, null, null);
}
I didn't found the result, It doesn't show any items in Listview. Can someone say what is the mistake in this code and how to solve it?
Code seems good. Most likely your Cursor is empty. Try to add simple condition:
Cursor c = nadapter.queueAll();
if (c != null && c.getCount() > 0) {
// set Adapter
}
else {
Toast.makeText(this, "Cursor is empty", Toast.LENGTH_SHORT).show();
}
If Toast will be shown, your getAll() method returns no data.
public Cursor queueAll(){
String[] columns = new String[] {KEY_ID, KEY_RCODE, KEY_RNAME, KEY_OFNO};
Cursor cursor = sqLiteDatabase.query(MYDATABASE_TABLE2, columns,
null, null, null, null, null);
return cursor;
}
Here is problem.

Categories

Resources