The application worked fine, but then the method Cursor.moveToFirst()
started returning false, and the Application's list has stopped appearing in a Fragment.
I think it all started after I changed a constat's name: IMAGE_URI
to IMAGE_URL
, and imageUri
to imageUrl
. Not sure though.
I tried debugging and searching for similar cases but there are many varied causes. When debugging, I couldn't get to the onCreate
of the SQLiteHelper
class in order to find out what happens during the population of the table (It seems that the table exists since an empty db of the table is being created), So I can't debug nor search for similar issues since no relevant output is found in the Logcat
.
GetDatabase
This class is used for some of the communication with the SQLiteOpenHelper
class.
public class GetDatabase {
private static final int DB_VERSION = 1; //required for the constructor
public static final String dbName = "moviesList";
private SQLiteOpenHelper sqLiteOpenHelper;
private SQLiteDatabase db ;
public GetDatabase(Context context) {
Log.d("GetDatabase", "Cont.");
this.sqLiteOpenHelper = new SQLiteHelper(context, dbName, null, DB_VERSION);
}
public void open() {
db = sqLiteOpenHelper.getWritableDatabase();
}
public void close() {
if (sqLiteOpenHelper != null) {
sqLiteOpenHelper.close();
}
}
public ArrayList<Movie> getMovies() {
String[] columns = {
Movie.ID,
Movie.TITLE,
Movie.IMAGE_URL,
Movie.RATING,
Movie.RELEASE_YEAR,
Movie.GENRE
};
// sorting orders
String sortOrder =
Movie.RELEASE_YEAR + " ASC";
ArrayList<Movie> moviesList = new ArrayList<>();
Cursor cursor = db.query(TABLE_NAME, //Table to query
columns,
null,
null,
null,
null,
sortOrder);
if (cursor.moveToFirst()) {
do {
Movie movie = new Movie();
movie.setMovieId(Integer.parseInt(cursor.getString(cursor.getColumnIndex(Movie.ID))));
movie.setTitle(cursor.getString(cursor.getColumnIndex(Movie.TITLE)));
movie.setImageUrl(cursor.getString(cursor.getColumnIndex(Movie.IMAGE_URL)));
movie.setRating(cursor.getDouble(cursor.getColumnIndex(Movie.RATING)));
movie.setReleaseYear(cursor.getInt(cursor.getColumnIndex(Movie.RELEASE_YEAR)));
movie.setGenre(cursor.getString(cursor.getColumnIndex(Movie.GENRE)));
// Adding a movie to the list
moviesList.add(movie);
} while (cursor.moveToNext());
}
Log.d(TAG, "The movies list from sqlite: " + moviesList);
cursor.close();
db.close();
return moviesList;
}
private Cursor getData(int id) {
return db.rawQuery( "select * from " + TABLE_NAME + " where id="+id+"", null );
}
public Cursor getMovieDetails(int movieId) {// For viewing details of a specific item
Cursor cursor = getData(movieId);
cursor.moveToFirst();
return cursor;
}
}
SQliteHelper
The SQLiteOpenHelper class
public class SQLiteHelper extends SQLiteOpenHelper {
private static final String DB_NAME = "movies.db";
private static final int DB_VERSION = 1; //required for the constructor
private static final String TABLE_NAME = "movies";
private String fileName = "movies.json";
private String appName = "MoviesList";
private String path = getExternalStorageDirectory() + "/" + appName + "/" + fileName;
private String jsonString = null;
private SQLiteDatabase db;
// The cont. for saving to SQLite .Called from SplashActivity after downloading the JSON
public SQLiteHelper(Context context, String dbName, SQLiteDatabase.CursorFactory factory, int version) {
super(context, DB_NAME, null, DB_VERSION);
}
@Override
public void onCreate(SQLiteDatabase db) {
Log.d(TAG, "At SQLiteHelper");
createSQLIteTable(db);
if(tableIsEmpty(db)) {
try {
parseJsonAndInsertToSQLIte(db);
} catch (JSONException e) {
e.printStackTrace();
}
}
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
}
private void createSQLIteTable(SQLiteDatabase db) {
//creating a table for SQLite
String CREATE_SQL_TABLE_STRING = "CREATE TABLE IF NOT EXISTS "+TABLE_NAME
+ " ("
+ Movie.ID + " INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL ,"
+ Movie.TITLE + " TEXT,"
+ Movie.IMAGE_URL + " TEXT,"
+ Movie.RATING + " TEXT,"
+ Movie.RELEASE_YEAR + " TEXT,"
+ Movie.GENRE + " TEXT "
+ ")";
Log.i(TAG,"created sql table: "+CREATE_SQL_TABLE_STRING);
db.execSQL(CREATE_SQL_TABLE_STRING);
}
private void parseJsonAndInsertToSQLIte(SQLiteDatabase db) throws JSONException {
// parsing the json
String jsonString = getJsonFileData();
JSONArray moviesArray = new JSONArray(jsonString);
ContentValues insertValues;
for (int i = 0; i < moviesArray.length(); i++) {
JSONObject jsonObject = moviesArray.getJSONObject(i);
String title = jsonObject.getString("title");
String imageUrl = jsonObject.getString("imageUrl");
String rating = jsonObject.getString("rating");
String releaseYear = jsonObject.getString("releaseYear");
String genre = jsonObject.getString("genre");
insertValues = new ContentValues();
insertValues.put(Movie.TITLE, title);
insertValues.put(Movie.IMAGE_URL, imageUrl);
insertValues.put(Movie.RATING, rating);
insertValues.put(Movie.RELEASE_YEAR, releaseYear);
insertValues.put(Movie.GENRE, genre);
long res = db.insert(TABLE_NAME, null, insertValues);
Log.i(TAG, "parsed and inserted to sql - row: " + res);
}
}
private String getJsonFileData() {
//loading the jsonString
try {
InputStream in = new FileInputStream(new File(path));
BufferedReader reader = new BufferedReader(new InputStreamReader(in));
StringBuilder output = new StringBuilder();
while ((jsonString = reader.readLine()) != null) {
output.append(jsonString);
}
System.out.println(output.toString()); //Prints the string content read from input stream
jsonString = output.toString();
Log.d(TAG, "the jsonString was loaded");
} catch (IOException ex) {
ex.printStackTrace();
}
return jsonString;
}
}
If I don't solve this, I think the entire application is worthless, since I don't know what mistake needs to be corrected.
Thanks!
Clear your application data from setting and run your application again. Since you have made changes in database column, it will not reflect unless you clear data.
Or
Do proper handling with DB version. Drop all tables in onUpgrade method and increase DB version every time you made changes in DB structure.
EDIT: Clear Data window