I am trying to implement an activity, that has 3 spinners (drop down lists) each of which are populated by a different table from an sqlite database. I managed to create one spinner that is populated correctly, but i am having trouble creating the other two and populating them correctly.
this is my main activity so far:
public class MainActivity extends Activity implements OnClickListener, OnItemSelectedListener {
private DBManager data;
private SQLiteDatabase db;
private final String DB_NAME = "hanakolfein.s3db";
private Spinner spinner;
List<String> list;
ArrayAdapter<String> adapter;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
/*Spinner sp1, sp2, sp3;
sp1 = (Spinner) findViewById(R.id.spinner1);
sp2 = (Spinner) findViewById(R.id.spinner2);
sp3 = (Spinner) findViewById(R.id.spinner3);
sp1.setOnItemSelectedListener(null);
sp2.setOnItemSelectedListener(null);
sp3.setOnItemSelectedListener(null); */
data = new DBManager(this, DB_NAME);
db = data.openDataBase();
spinner = (Spinner) findViewById(R.id.spinner1);
spinner.setOnItemSelectedListener(this);
loadSpinner();
}
private void loadSpinner() {
Set<String> set = data.getAllData();
List<String> list = new ArrayList<String>(set);
adapter = new ArrayAdapter<String>(MainActivity.this,
android.R.layout.simple_spinner_item, list);
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spinner.setAdapter(adapter);
spinner.setWillNotDraw(false);
}
#Override
public void onItemSelected(AdapterView<?> parent, View view,
int position, long id) {
// TODO Auto-generated method stub
}
#Override
public void onNothingSelected(AdapterView<?> parent) {
// TODO Auto-generated method stub
}
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
}
}
and this is my database manager:
public class DBManager extends SQLiteOpenHelper {
//Path to the device folder with databases
public static String DB_PATH;
//Database file name
public static String DB_NAME;
public SQLiteDatabase database;
public final Context context;
public final static int DB_VERSION = 6;
public SQLiteDatabase getDb() {
return database;
}
public DBManager(Context context, String databaseName) {
super(context, databaseName, null, DB_VERSION);
this.context = context;
//full path to the databases
String packageName = context.getPackageName();
DB_PATH = String.format("//data//data//%s//databases//", packageName);
DB_NAME = databaseName;
openDataBase();
}
//This piece of code will create a database if it’s not yet created
public void createDataBase() {
boolean dbExist = checkDataBase();
if (!dbExist) {
this.getReadableDatabase();
try {
copyDataBase();
} catch (IOException e) {
Log.e(this.getClass().toString(), "Copying error");
throw new Error("Error copying database!");
}
} else {
Log.i(this.getClass().toString(), "Database already exists");
}
}
//Performing a database existence check
private boolean checkDataBase() {
SQLiteDatabase checkDb = null;
try {
String path = DB_PATH + DB_NAME;
checkDb = SQLiteDatabase.openDatabase(path, null,SQLiteDatabase.OPEN_READONLY);
} catch (SQLException e) {
Log.e(this.getClass().toString(), "Error while checking db");
}
//Android doesn’t like resource leaks, everything should
// be closed
if (checkDb != null) {
checkDb.close();
}
return checkDb != null;
}
//Method for copying the database
private void copyDataBase() throws IOException {
//Open a stream for reading from our ready-made database
//The stream source is located in the assets
InputStream externalDbStream = context.getAssets().open(DB_NAME);
//Path to the created empty database on your Android device
String outFileName = DB_PATH + DB_NAME;
//Now create a stream for writing the database byte by byte
OutputStream localDbStream = new FileOutputStream(outFileName);
//Copying the database
byte[] buffer = new byte[1024];
int bytesRead;
while ((bytesRead = externalDbStream.read(buffer)) > 0) {
localDbStream.write(buffer, 0, bytesRead);
}
//Don’t forget to close the streams
localDbStream.close();
externalDbStream.close();
}
public SQLiteDatabase openDataBase() throws SQLException {
String path = DB_PATH + DB_NAME;
if (database == null) {
createDataBase();
database = SQLiteDatabase.openDatabase(path, null,
SQLiteDatabase.OPEN_READWRITE);
}
return database;
}
#Override
public synchronized void close() {
if (database != null) {
database.close();
}
super.close();
}
public Set<String> getAllData() {
Set<String> set = new HashSet<String>();
String selectQuery = "select * from cuisine";
SQLiteDatabase db = this.getReadableDatabase();
Cursor cursor = db.rawQuery(selectQuery, null);
if (cursor.moveToFirst()) {
do {
set.add(cursor.getString(1));
} while (cursor.moveToNext());
}
cursor.close();
db.close();
return set;
}
#Override
public void onCreate(SQLiteDatabase db) {}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {}
}
Alright, first of all you should not query your database from the main Thread.
I recommend using a Loader as described here. You can have as many Loaders as you like, in your case 1 for each Spinner (just make sure to give them different IDs).
You need to clear that arraylist which you pass to arrayadapter. Because when you use first spinner, you are calling gatAllData & storing that data in arraylist, passing it to arrayadapter. Next time for second spinner you are doing same procedure but it is concatenating to previous entries of arraylist. So before calling to getAllData you need to clear your arraylist. It'll solve your problem.
Related
I created a database containing several tables.
I have this database saved in the assets folder.
I am trying to simply access the EXERCISESTABLE from this database and then display its values in a modified listView.
However, I keep getting the error:
W/System.err: java.io.FileNotFoundException.
Here is my MainActivity extends Activity Class:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
lvExercise = (ListView)findViewById(R.id.listView_exercises);
mDBHelper = new DatabaseHelper(this);
//Check exists database
File database = getApplicationContext().getDatabasePath(DatabaseHelper.DBNAME);
if(false == database.exists()){
mDBHelper.getReadableDatabase();
// Copy Database
if(copyDatabase(this)){
Toast.makeText(this, "Copy database success", Toast.LENGTH_SHORT).show();
}else {
Toast.makeText(this, "Copy data error", Toast.LENGTH_SHORT).show();
return;
}
}
//Get exercise List in db when db exists
mExercisesList = mDBHelper.getListExercise();
//Init adapter
adapter = new ListExerciseAdapter(this, mExercisesList);
//Set adapter for list view
lvExercise.setAdapter(adapter);
}
private boolean copyDatabase(Context context){
try{
InputStream inputStream = context.getAssets().open(DatabaseHelper.DBNAME);
String outFileName = DatabaseHelper.DBLOCATION + DatabaseHelper.DBNAME;
OutputStream outputStream = new FileOutputStream(outFileName);
byte[]buff = new byte[1024];
int length =0;
while ((length = inputStream.read(buff)) >0){
outputStream.write(buff, 0, length);
}
outputStream.flush();
outputStream.close();
Log.w("MainActivity", "DB copied");
return true;
}catch(Exception e){
e.printStackTrace();
return false;
}
}
I have my workout_program.db database file located in the assets folder, however I cant seem to access it even though it all looks correct to me.
Here is my DBHelper extends SQLiteOpenHelper Code:
private Context mContext;
private SQLiteDatabase mDatabase;
public DatabaseHelper(Context context){
super(context, DBNAME, null, 1);
this.mContext = context;
}
#Override
public void onCreate(SQLiteDatabase db) {
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
}
public void openDatabase() {
String dbPath = mContext.getDatabasePath(DBNAME).getPath();
if(mDatabase != null && mDatabase.isOpen()){
return;
}
mDatabase = SQLiteDatabase.openDatabase(dbPath,null,SQLiteDatabase.OPEN_READWRITE);
}
public void closeDatabase(){
if(mDatabase!=null){
mDatabase.close();
}
}
public List<Exercise> getListExercise(){
Exercise exercise = null;
List<Exercise> exerciseList = new ArrayList<>();
openDatabase();
Cursor cursor = mDatabase.rawQuery("SELECT * FROM EXERCISESTABLE ", null);
cursor.moveToFirst();
while(!cursor.isAfterLast()){
exercise = new Exercise(cursor.getInt(0),cursor.getString(1), cursor.getInt(2), cursor.getInt(3));
exerciseList.add(exercise);
cursor.moveToNext();
closeDatabase();
}
return exerciseList;
}
Here is my exercise class:
public class Exercise {
private int exercise_id;
private String exercise_name;
private int exercise_type_id;
private int exercise_equipment_id;
public Exercise(int exercise_id, String exercise_name, int exercise_type_id, int exercise_equipment_id) {
this.exercise_id = exercise_id;
this.exercise_name = exercise_name;
this.exercise_type_id = exercise_type_id;
this.exercise_equipment_id = exercise_equipment_id;
}
public int getExercise_id() {
return exercise_id;
}
public void setExercise_id(int exercise_id) {
this.exercise_id = exercise_id;
}
public String getExercise_name() {
return exercise_name;
}
public void setExercise_name(String exercise_name) {
this.exercise_name = exercise_name;
}
public int getExercise_type_id() {
return exercise_type_id;
}
public void setExercise_type_id(int exercise_type_id) {
this.exercise_type_id = exercise_type_id;
}
public int getExercise_equipment_id() {
return exercise_equipment_id;
}
public void setExercise_equipment_id(int exercise_equipment_id) {
this.exercise_equipment_id = exercise_equipment_id;
}
}
Here is my ListExerciseAdapter extends BaseAdapter class:
public ListExerciseAdapter(Context mContext, List<Exercise> exercisesList) {
this.mContext = mContext;
this.mExercisesList = exercisesList;
}
#Override
public int getCount() {
return mExercisesList.size();
}
#Override
public Object getItem(int position) {
return mExercisesList.get(position);
}
#Override
public long getItemId(int position) {
return mExercisesList.get(position).getExercise_id();
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View v = View.inflate(mContext, R.layout.exercises_listview_layout, null);
TextView exercise_name = (TextView)v.findViewById(R.id.exercise_name);
TextView exercise_type_id = (TextView)v.findViewById(R.id.exercise_type_id);
TextView exercise_equipment_id = (TextView)v.findViewById(R.id.exercise_equipment_id);
exercise_name.setText(mExercisesList.get(position).getExercise_name());
exercise_type_id.setText(String.valueOf(mExercisesList.get(position).getExercise_type_id()));
exercise_equipment_id.setText(String.valueOf(mExercisesList.get(position).getExercise_equipment_id()));
return v;
}
Any help will be greatly appreciated.
According to the prepopulated Room Database from the official documentation. You have 2 options:
1) createFromAssets: in this option, you may create a directory called "databases" under assets folder
so your could will be as follow:
.createFromAssets("/databases/YOUR DATABASE FILENAME")
2) createFromFile: This option may work with the file you are assigning its path.
.createFromFile(File("YOUR FILE PATH"))
if you are stuck with these two solutions, you can try the manual solution, we may call it manual solution yeah !. by accessing your database file in assets folder.
private fun copyDBFromStorage(databaseName: String) {
if (checkIfDBExists(this, databaseName)) return
val databaseFile = File(this.getDatabasePath(databaseName).toString())
val sourceLocation = assets.open("Your database file path")
try {
val inputStream = sourceLocation
val os = FileOutputStream(databaseFile)
val buffer = ByteArray(1024 * 32)
var length = inputStream.read(buffer)
while (length > 0) {
os.write(buffer, 0, length)
length = inputStream.read(buffer)
}
os.flush()
os.close()
inputStream.close()
} catch (ex: IOException) {
ex.printStackTrace();
throw RuntimeException("Error copying storage database");
}
}
private fun checkIfDBExists(
context: Context,
databaseName: String
): Boolean {
val dbfile = File(context.getDatabasePath(databaseName).toString())
if (dbfile.exists()) return true
if (!dbfile.parentFile.exists()) {
dbfile.parentFile.mkdirs()
}
return false
}
Note: you can convert this Kotlin code to java using android studio code conversion feature.
If you found any problem with that, kindly reply.
Happy coding 🤓
I am trying to create a quiz app where a category can be selected by clicking on a listView item. Each category has code like 0,1,2. For football, it is 0. After clicking on the football item, the app keeps on going to the home screen instead of logging the data I want. Please help me with the error.
Quiz Category Selection Class
String quizCategory = intent.getStringExtra("QuizCategory");
//Deciding which database to Open and choose
switch (quizCategory) {
case "0":
Log.i("Category", "Football");
Football football = new Football(this);
football.createDatabase();
football.openDatabase();
football.getWritableDatabase();
long x=football.getRowCount();
break;
default:
Log.i("Message", "Error");
}
}
Football Class
public class Football extends SQLiteOpenHelper {
private static final String Database_path = "/data/data/com.google.quiz/databases/";
private static final String Database_name = "football.db";
private static Context context;
private static final int version = 1;
public SQLiteDatabase sqlite;
public Football(Context context) {
super(context, Database_name, null, version);
this.context = context;
}
#Override
public void onCreate(SQLiteDatabase db) {
}
#Override
public void onUpgrade(SQLiteDatabase db, int i, int i1) {
}
public void createDatabase() {
createDB();
}
private void createDB() {
boolean dbexist = DBexists();
if (!dbexist) {
this.getReadableDatabase();
copyDBfromResource();
}
}
private void copyDBfromResource() {
InputStream is;
OutputStream os;
String filePath = Database_path + Database_name;
try {
is = context.getAssets().open(Database_name);//reading purpose
os = new FileOutputStream(filePath);//writing purpose
byte[] buffer = new byte[1024];
int length;
while ((length = is.read(buffer)) > 0) {
os.write(buffer, 0, length);//writing to file
}
os.flush();//flush the outputstream
is.close();//close the inputstream
os.close();//close the outputstream
} catch (IOException e) {
throw new Error("Problem copying database file:");
}
}
public void openDatabase() throws SQLException {
String myPath = Database_path + Database_name;
sqlite = SQLiteDatabase.openDatabase(myPath, null, SQLiteDatabase.OPEN_READWRITE);
}
private boolean DBexists() {
SQLiteDatabase db = null;
try {
String databasePath = Database_path + Database_name;
db = SQLiteDatabase.openDatabase(databasePath, null, SQLiteDatabase.OPEN_READWRITE);
db.setLocale(Locale.getDefault());
db.setVersion(1);
db.setLockingEnabled(true);
} catch (SQLException e) {
Log.e("Sqlite", "Database not found");
}
if (db != null)
db.close();///close the opened file
return db != null ? true : false;
}
public long getRowCount() {
SQLiteDatabase db = this.getReadableDatabase();
long x = DatabaseUtils.queryNumEntries(db, "football");
db.close();
return x;
}
}
I'm extending DaoMaster.OpenHelper to manage assets folder database. Since it's not user related data the changes can be huge the only one thing I want to achieve is delete and recreate the database when there is a new version. What I don't understand is that this code works when i'm debugging my app on the emulator or even if i generate the apk and install it on my device manually. But when I deploy my app on the market and I install it on my device from there it looks like the it can't find the database.
Exception java.lang.RuntimeException: Unable to resume activity {com.livos.companionplants/com.livos.companionplants.main.MainActivity}: android.database.sqlite.SQLiteException: no such column: T.definition (code 1): , while compiling: SELECT T."_id",T."plant_id",T."definition" FROM "plant_definition" T ################################################################# Error Code : 1 (SQLITE_ERROR) Caused By : SQL(query) error or missing database. (no such column: T.definition (code 1): , while compiling: SELECT T."_id",T."plant_id",T."definition" FROM "plant_definition" T) #################################################################
#ApplicationScope
public class DatabaseOpenHelper extends DaoMaster.OpenHelper {
private String TAG = DatabaseOpenHelper.class.getSimpleName();
private static final String SP_KEY_DB_VER = "db_ver";
private static final int DATABASE_VERSION = 1;
private Context context;
private SharedPreferences sharedPreferences;
private SQLiteDatabase sqliteDatabase;
private static String DB_PATH;
private static String DB_NAME;
public DatabaseOpenHelper(Context context, SharedPreferences sharedPreferences, String name, SQLiteDatabase.CursorFactory factory) {
super(context, name, factory);
this.context = context;
this.sharedPreferences = sharedPreferences;
DB_NAME = name;
DB_PATH = context.getFilesDir().getAbsolutePath().replace("files", "databases") + File.separator;
try {
createDataBase();
} catch (Exception ioe) {
throw new Error("Unable to create database");
}
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
// TODO Auto-generated method stub
}
/** Open Database for Use */
public void openDatabase() {
String databasePath = DB_PATH + DB_NAME;
sqliteDatabase = SQLiteDatabase.openDatabase(databasePath, null,
(SQLiteDatabase.OPEN_READWRITE));
}
/** Close Database after use */
#Override
public synchronized void close() {
if ((sqliteDatabase != null) && sqliteDatabase.isOpen()) {
sqliteDatabase.close();
}
super.close();
}
/** Get database instance for use */
public SQLiteDatabase getSqliteDatabase() {
return sqliteDatabase;
}
/** Create new database if not present */
public void createDataBase() {
SQLiteDatabase sqliteDatabase;
if (databaseExists()) {
int dbVersion = sharedPreferences.getInt(SP_KEY_DB_VER, 1);
// If different version then delete current database and copy the new one from assets
if (DATABASE_VERSION != dbVersion) {
File dbFile = context.getDatabasePath(DB_NAME);
boolean dbFileDeleted = dbFile.delete();
if (!dbFileDeleted) {
Log.w(TAG, "Unable to update database");
} else {
createDataBase();
}
}
/* Check for Upgrade */
} else {
/* Database does not exists create blank database */
sqliteDatabase = this.getReadableDatabase();
sqliteDatabase.close();
SharedPreferences.Editor editor = sharedPreferences.edit();
editor.putInt(SP_KEY_DB_VER, DATABASE_VERSION);
editor.apply();
copyDataBase();
}
}
/** Check Database if it exists */
private boolean databaseExists() {
SQLiteDatabase sqliteDatabase = null;
try {
String databasePath = DB_PATH + DB_NAME;
sqliteDatabase = SQLiteDatabase.openDatabase(databasePath, null,
SQLiteDatabase.OPEN_READONLY);
} catch (SQLiteException e) {
e.printStackTrace();
}
if (sqliteDatabase != null) {
sqliteDatabase.close();
}
return sqliteDatabase != null;
}
/**
* Copy existing database file in system
*/
public void copyDataBase() {
int length;
byte[] buffer = new byte[1024];
String databasePath = DB_PATH + DB_NAME;
try {
InputStream databaseInputFile = this.context.getAssets().open(DB_NAME);
OutputStream databaseOutputFile = new FileOutputStream(databasePath);
while ((length = databaseInputFile.read(buffer)) > 0) {
databaseOutputFile.write(buffer, 0, length);
databaseOutputFile.flush();
}
databaseInputFile.close();
databaseOutputFile.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
private static boolean isRoboUnitTest() {
return "robolectric".equals(Build.FINGERPRINT);
}
Solution using Kuffs proposition
#ApplicationScope
public class DatabaseOpenHelper extends DaoMaster.OpenHelper {
private String TAG = DatabaseOpenHelper.class.getSimpleName();
private static final String SP_KEY_DB_VER = "db_ver";
private static final int DATABASE_VERSION = 2;
private Context context;
private SharedPreferences sharedPreferences;
private SQLiteDatabase sqliteDatabase;
private static String DB_PATH;
private static String DB_NAME;
public DatabaseOpenHelper(Context context, SharedPreferences sharedPreferences, String name, SQLiteDatabase.CursorFactory factory) {
super(context, name, factory);
this.context = context;
this.sharedPreferences = sharedPreferences;
DB_NAME = name;
try {
createDataBase();
} catch (Exception ioe) {
throw new Error("Unable to create database");
}
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
// TODO Auto-generated method stub
}
/** Open Database for Use */
public void openDatabase() {
String databasePath = context.getDatabasePath(DB_NAME).toString();
sqliteDatabase = SQLiteDatabase.openDatabase(databasePath, null,
(SQLiteDatabase.OPEN_READWRITE));
}
/** Close Database after use */
#Override
public synchronized void close() {
if ((sqliteDatabase != null) && sqliteDatabase.isOpen()) {
sqliteDatabase.close();
}
super.close();
}
/** Get database instance for use */
public SQLiteDatabase getSqliteDatabase() {
return sqliteDatabase;
}
/** Create new database if not present */
public void createDataBase() {
SQLiteDatabase sqliteDatabase;
if (databaseExists()) {
int dbVersion = sharedPreferences.getInt(SP_KEY_DB_VER, 1);
/* If different version then delete current database and copy the new one from assets*/
if (DATABASE_VERSION != dbVersion) {
File dbFile = context.getDatabasePath(DB_NAME);
boolean dbFileDeleted = dbFile.delete();
if (!dbFileDeleted) {
Log.w(TAG, "Unable to update database");
} else {
createDataBase();
}
}
} else {
/* Database does not exists create blank database */
sqliteDatabase = this.getReadableDatabase();
sqliteDatabase.close();
SharedPreferences.Editor editor = sharedPreferences.edit();
editor.putInt(SP_KEY_DB_VER, DATABASE_VERSION);
editor.apply();
copyDataBase();
}
}
/** Check Database if it exists */
private boolean databaseExists() {
SQLiteDatabase sqliteDatabase = null;
try {
String databasePath = context.getDatabasePath(DB_NAME).toString();
sqliteDatabase = SQLiteDatabase.openDatabase(databasePath, null,
SQLiteDatabase.OPEN_READONLY);
} catch (SQLiteException e) {
e.printStackTrace();
}
if (sqliteDatabase != null) {
sqliteDatabase.close();
}
return sqliteDatabase != null;
}
/**
* Copy existing database file in system
*/
public void copyDataBase() {
int length;
byte[] buffer = new byte[1024];
String databasePath = context.getDatabasePath(DB_NAME).toString();
try {
InputStream databaseInputFile = this.context.getAssets().open(DB_NAME);
OutputStream databaseOutputFile = new FileOutputStream(databasePath);
while ((length = databaseInputFile.read(buffer)) > 0) {
databaseOutputFile.write(buffer, 0, length);
databaseOutputFile.flush();
}
databaseInputFile.close();
databaseOutputFile.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
I want to show my data from sqlite to Custom ListView (java , Android studio , sqlite ).
But it's force stop.
picture from my Main Activity:
picture from my Database class:
Please Help me!!!!
(my English is not good sorry but can i understand your words)
first you have to create a custom adapter for your listview and populate that adapter with listview and your code should be like this
and to get the data from database create a method in database class name getdata() take it in a form of cursor
public class UserDbHelper extends SQLiteOpenHelper {
public static final String DATABASENAME = "DATABASENAME2";
public static final int DB_VERSION = 3;
public static final String TABLE_NAME = "student";
public static final String DEVICE = "device"; //your coloumn
public static final String ADDRESS = "address";//your coloumn
public static final String Date = "Date"; //your coloumn
public String CREATE_QUERY = "CREATE TABLE "+TABLE_NAME+"("+DEVICE+" TEXT,"+ADDRESS+" TEXT,"+Date+"TEXT);";
public UserDbHelper(Context context)
{
super(context,DATABASENAME,null,DB_VERSION);
}
#Override
public void onCreate(SQLiteDatabase sqLiteDatabase) {
sqLiteDatabase.execSQL(CREATE_QUERY);
}
public List<Datalist> getdata()
{
List<Datalist> result = new ArrayList<>();
Cursor c = sqLiteDatabase.rawQuery("SELECT * FROM Table_name,null";);
while (c.moveToNext()) {
result.add(
new Datalist(
c.getString(c.getColumnIndex("YOUR COLOUMN")),
c.getString(c.getColumnIndex("YOUR COLOUMN")),
date
)
);
}
c.close();
return result;
}
and populate your database with listview
this will be in your button click that button which retrive the data
List<Datalist> itemFromDatabase = getItemFromDatabase();
MyAdapter adapter = new MyAdapter(getApplicationContext(), 0, itemFromDatabase);
listOfDatabaseObject.setAdapter(adapter);
adapter.notifyDataSetChanged();
MainActivity.java
public class MainActivity extends AppCompatActivity {
DataBaseHelper myDbHelper;
List<String> stringList;
ListView listView;
List<Mivejat> mivejatList;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
myDbHelper = new DataBaseHelper(this);
stringList = new ArrayList<>();
try {
myDbHelper.createDataBase();
} catch (IOException ioe) {
throw new Error("Unable to create database");
}
try {
myDbHelper.openDataBase();
}catch(SQLException sqle){
throw sqle;
}
myDbHelper = new DataBaseHelper(this);
mivejatList = myDbHelper.MiveName();
for (int i = 0 ; 0 < mivejatList.size() ; i++) {
stringList.add(mivejatList.get(i).name);
}
listView = (ListView) findViewById(R.id.listViewMive);
mainListViewClass mainListViewClass = new mainListViewClass(MainActivity.this , stringList);
listView.setAdapter(mainListViewClass);
mainListViewClass.notifyDataSetChanged();
myDbHelper.close();
}
}
MainActivity.java
public class MainActivity extends AppCompatActivity {
DataBaseHelper myDbHelper;
List<String> stringList;
ListView listView;
List<Mivejat> mivejatList;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
myDbHelper = new DataBaseHelper(this);
stringList = new ArrayList<>();
try {
myDbHelper.createDataBase();
} catch (IOException ioe) {
throw new Error("Unable to create database");
}
try {
myDbHelper.openDataBase();
}catch(SQLException sqle){
throw sqle;
}
myDbHelper = new DataBaseHelper(this);
mivejatList = myDbHelper.MiveName();
for (int i = 0 ; 0 < mivejatList.size() ; i++) {
stringList.add(mivejatList.get(i).name);
}
listView = (ListView) findViewById(R.id.listViewMive);
mainListViewClass mainListViewClass = new mainListViewClass(MainActivity.this , stringList);
listView.setAdapter(mainListViewClass);
mainListViewClass.notifyDataSetChanged();
myDbHelper.close();
}
}
DataBaseHelper.java
public class DataBaseHelper extends SQLiteOpenHelper {
private static String DB_PATH = "/data/data/mivejat.rezaahmadpour.ir.mivejat/databases/";
private static String DB_NAME = "KhavasMiveha.db";
public static final int DB_VERS = 1;
private SQLiteDatabase myDataBase;
private final Context myContext;
private static String TAG = "KhavasMiveha.db";
/**
* Constructor Takes and keeps a reference of the passed context in order to
* access to the application assets and resources.
*
* #param context
*/
public DataBaseHelper(Context context) {
super(context, DB_NAME, null, DB_VERS);
this.myContext = context;
}
/**
* Creates an empty database on the system and rewrites it with your own
* database.
*/
public boolean createDataBase() throws IOException {
boolean dbExist = checkDataBase();
if (dbExist) {
Log.d(TAG, "database already exist");
//Running this method causes SQLite class checking for if New DB Version Exists and runs upgrade method
getReadableDatabase();
close();
return true;
} else {
// By calling this method and empty database will be created into
// the default system path
// of your application so we are gonna be able to overwrite that
// database with our database.
this.getReadableDatabase();
try {
copyDataBase();
} catch (IOException e) {
throw new Error("Error copying database");
}
return false;
}
}
/**
* Check if the database already exist to avoid re-copying the file each
* time you open the application.
*
* #return true if it exists, false if it doesn't
*/
private boolean checkDataBase() {
SQLiteDatabase checkDB = null;
try {
String myPath = DB_PATH + DB_NAME;
checkDB = SQLiteDatabase.openDatabase(myPath, null,
SQLiteDatabase.OPEN_READONLY);
} catch (SQLiteException e) {
// database does't exist yet.
}
if (checkDB != null) {
checkDB.close();
}
return checkDB != null ? true : false;
}
/**
* Copies your database from your local assets-folder to the just created
* empty database in the system folder, from where it can be accessed and
* handled. This is done by transferring bytestream.
*/
private void copyDataBase() throws IOException {
// Open your local db as the input stream
InputStream myInput = myContext.getAssets().open(DB_NAME);
// Path to the just created empty db
String outFileName = DB_PATH + DB_NAME;
// Open the empty db as the output stream
OutputStream myOutput = new FileOutputStream(outFileName);
// transfer bytes from the inputfile to the outputfile
byte[] buffer = new byte[1024];
int length;
while ((length = myInput.read(buffer)) > 0) {
myOutput.write(buffer, 0, length);
}
// Close the streams
myOutput.flush();
myOutput.close();
myInput.close();
}
public void openDataBase() throws SQLException {
// Open the database
String myPath = DB_PATH + DB_NAME;
myDataBase = SQLiteDatabase.openDatabase(myPath, null,
SQLiteDatabase.OPEN_READONLY);
}
#Override
public synchronized void close() {
if (myDataBase != null)
myDataBase.close();
super.close();
}
#Override
public void onCreate(SQLiteDatabase db) {
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
Log.d(TAG, "UPGRADING Database...");
try {
copyDataBase();
} catch (IOException e) {
throw new Error("Error copying database");
}
}
public List<Mivejat> MiveName() {
String query = "SELECT Name FROM tbl_mive";
SQLiteDatabase db = this.getReadableDatabase();
Cursor cursor = db.rawQuery(query, null);
List<Mivejat> result = new ArrayList<>();
Mivejat m;
while (cursor.moveToNext()) {
m = new Mivejat();
m.name = cursor.getString(0);
result.add(m);
}
return result;
}
As my first Android project I'm trying to make an RSS reader app in which Listview items can be saved to SQLite, allowing them to be read offline. However, when trying to return news titles in a listView using a query with SimpleCursorAdapter, the listview displays the text "title", rather than the actual title of the news.
This seems to suggest that the items are not being stored to the database, or that the content values are not being properly assigned.
Can anybody see where i might be going wrong?
Thanks in advance!
RssItem.java
public class RssItem {
protected String _id;
public String title;
protected String link;
protected String page;
protected String completeTextLink;
protected String mainBody;
public String get_id() {
return _id;
}
public void set_id(String _id) {
this._id = _id;
}
//Title get/set
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
//Link get/set
public String getLink() {
return link;
}
public void setLink(String link) {
this.link = link;
}
//CompleteTextLink get/set
public String getCompleteTextLink() {
return completeTextLink;
}
public void setCompleteTextLink(String completeTextLink) {
this.completeTextLink = completeTextLink;
}
//MainBody get/set
public String getMainBody() {
return mainBody;
}
public void setMainBody(String mainBody) {
this.mainBody = mainBody;
}
//Page get/set
public String getPage() {
return page;
}
public void setPage(String page) {
this.page = page;
}
#Override
public String toString() {
return title;
}}
MainActivity.java
public class MainActivity extends Activity {
private MainActivity local;
private DatabaseHandler db;
//Method to create main application view
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//set view
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.main);
//**************************create a button to move to the user's saved feeds screen*****************************
Button myFeedsButton = (Button) findViewById(R.id.myFeedsButton);
myFeedsButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View v)
{
startActivity(new Intent(MainActivity.this, MyFeedsScreen.class));
}
});
//***************************************************************************************************************
//Create new instance of database handler
db = new DatabaseHandler(this);
//set local ref to this activity
local = this;
GetRSSDataTask task = new GetRSSDataTask();
//start download Rss task - execute method calls the
task.execute("http://feeds.bbci.co.uk/news/rss.xml?edition=uk");
//debug thread name
Log.d("RssReaderApp", Thread.currentThread().getName());
}
//*******************************************************************************************************************
private class GetRSSDataTask extends AsyncTask<String, Void, List<RssItem>>
{
#Override
protected List<RssItem> doInBackground(String... urls) {
//debug task thread name
Log.d("RssReaderApp", Thread.currentThread().getName());
try {
//create a new reader
RssReader rssReader = new RssReader(urls[0]);
//Parse RSS, get items
return rssReader.getItems();
} catch (Exception e) {
Log.e("RssReaderApp", e.getMessage());
}
return null;
}//doInBackground
//is invoked on UI thread after background tasks are complete.
// Results of background task are passed here as a parameter
#Override
protected void onPostExecute(List<RssItem> result)
{
//Gets listview from main.xml
final ListView listItems = (ListView) findViewById(R.id.listMainView);
//Creates a new list adapter - displays an array of strings in listview
ArrayAdapter<RssItem> adapter = new ArrayAdapter<RssItem>(local, android.R.layout.simple_list_item_1, result);
//Set list adapter for listView
listItems.setAdapter(adapter);
//OnItemClick listener set to allow user to access content from title
listItems.setOnItemClickListener(new ListListener(result, local));
//*******************************LONG CLICK FUNCTIONALITY******************************************
//Set new long click listener which should allow item to be stored to db
listItems.setLongClickable(true);
listItems.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
#Override
public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {
try {
db.open();
RssItem item = new RssItem();
item.title = "title";
item.link = "link";
item.completeTextLink ="completeTextLink";
item.page = "page";
db.insertRssItem(item);
db.close();
} catch (SQLException e)
{
e.printStackTrace();
}
Toast.makeText(getBaseContext(), "Item saved in My Feeds!", Toast.LENGTH_SHORT).show();
return true;
}
});
}//onPostExecute
}}//class
DatabaseHandler.java
public class DatabaseHandler extends SQLiteOpenHelper {
private static final String DATABASE_NAME = "news_db";
public static SQLiteDatabase db;
private static final int DATABASE_VERSION = 32;
protected static final String TABLE_NEWS = "news";
private static final String TAG = "TAG";
private static final String TAG1 = "TAG1";
static String columnTitle = "title";
protected static final String _id = "_id";
//Methods for tables
public DatabaseHandler(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
#Override
public void onCreate(SQLiteDatabase db) {
String CREATE_TABLE_NEWS = "CREATE TABLE " + TABLE_NEWS + "(_id VARCHAR, title TEXT, link TEXT, completeTextLink TEXT, mainBody Text, page TEXT)";
db.execSQL(CREATE_TABLE_NEWS);
Log.w(TAG, "Database has been created");
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL("DROP TABLE IF EXISTS " + TABLE_NEWS);
onCreate(db);
}
public void open() throws SQLException {
db = this.getWritableDatabase();
}
//Method to insert new rssItem object to the database
public void insertRssItem(RssItem rssItem) {
SQLiteDatabase db = this.getWritableDatabase();
ContentValues contentValues = new ContentValues();
contentValues.put("_id", rssItem._id);
contentValues.put("title", rssItem.title);
contentValues.put("link", rssItem.link);
contentValues.put("mainBody", rssItem.mainBody);
contentValues.put("completeTextLink", rssItem.completeTextLink);
contentValues.put("page", rssItem.page);
db.insert(TABLE_NEWS, "title", contentValues);
Log.d(TAG1, "ITEM SAVED IN DATABASE!!!");
}//insert item method
//Method to return all news for a given item
public List<RssItem> getAllNewsForItem(String page) {
List<RssItem> SavedNewsList = new ArrayList<RssItem>();
Cursor cursor = db.rawQuery("select _id, completeTextLink, title, link, mainBody, page" +
" FROM " + TABLE_NEWS + " where page = ?", new String[]{page});
cursor.moveToFirst();
while (!cursor.isAfterLast()) {
RssItem rssItem = new RssItem();
rssItem._id = cursor.getString(0);
rssItem.completeTextLink = cursor.getString(1);
rssItem.title = cursor.getString(2);
rssItem.link = cursor.getString(3);
rssItem.mainBody = cursor.getString(4);
rssItem.page = page;
SavedNewsList.add(rssItem);
cursor.moveToNext();
}
cursor.close();
return SavedNewsList;
}
//get data from database for listview
public Cursor getData() {
SQLiteDatabase db = this.getReadableDatabase();
Cursor cursor = db.rawQuery("SELECT * FROM " + TABLE_NEWS, null);
return cursor;
}}
MyFeedsScreen.java
public class MyFeedsScreen extends ListActivity {
DatabaseHandler dbHandler;
SimpleCursorAdapter dataAdapter;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.my_feeds_screen);
dbHandler = new DatabaseHandler(MyFeedsScreen.this);
displayList();
}
public void displayList() {
dbHandler.getWritableDatabase();
dbHandler = new DatabaseHandler(this);
Cursor cursor = dbHandler.getData();
String from[] = new String[]{dbHandler.columnTitle};
int to[] = new int[]{R.id.textView1};
dataAdapter = new SimpleCursorAdapter(this, R.layout.row_item, cursor, from, to, 0);
ListView lv = getListView();
lv.setAdapter(dataAdapter);
}}
You should call getItemAtPosition(int position) from within your long-press listener. That will get you the Object from the collection that backs the ListView, in this case, the article from your RssReader that the user long-pressed upon. Sorta like:
...
db.open();
RssArticleThing fromList = (RssArticleThing) listItems.getItemAtPosition(position);
RssItem item = new RssItem();
item.title = fromList.title;
...
http://developer.android.com/reference/android/widget/AdapterView.html#getItemAtPosition(int)