How to pass data from sqlite listview to new intent? - android

(this is my lunch.class which populate the listview from database.tell me if there is any mistakes.im still new to this.)
public class Lunch extends Activity implements OnItemClickListener {
DBOpener dbopener;
#Override
protected void onCreate(Bundle savedInstanceState) {
//for fullscreen view
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,WindowManager.LayoutParams.FLAG_FULLSCREEN);
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.dinner);
dbopener = new DBOpener(this);
}
// Open the DB, query all subject codes and refresh the listview
// when app resumes
#Override
protected void onResume() {
super.onResume();
// Configure the listview
ArrayList<String> mealNames = new ArrayList<String>();
ListView lstDine = (ListView)this.findViewById(R.id.dine);
lstDine.setAdapter(new ArrayAdapter<String>(this,
android.R.layout.simple_list_item_1, mealNames));
// Open/create the DB
try {
dbopener.createDatabase(); // Create DB if necessary
dbopener.openDatabase(); // Open the DB
Cursor dinners = dbopener.getLunchNames();
while (dinners.moveToNext()) {
mealNames.add(dinners.getString(0)); // Get the current subj
// code, add to list
}
dinners.close();
// Update the listview
ArrayAdapter<String> ad = (ArrayAdapter<String>)lstDine.getAdapter();
ad.notifyDataSetChanged();
lstDine.setOnItemClickListener(this);
} catch (Exception e) {
Toast.makeText(this, "Could not open DB",
Toast.LENGTH_LONG).show();
}
}
// Close the DB when app pauses
#Override
protected void onPause() {
super.onPause();
dbopener.close();
}
// When user clicks on an item
public void onItemClick(AdapterView<?> parent, View v, int pos, long id) {
// Use subject code from listview to retrieve other
// details with the dbopener
switch(pos)
{
case 0 :
Intent newActivity = new Intent("com.edu.tp.iit.mns.Display");
newActivity.putExtra("1", "2"); // this is where im unaware of the codes.how to pass the strings of value to the next page
startActivity(newActivity);
break;
}
switch(pos)
{
case 1 :
Intent newActivity = new Intent("com.edu.tp.iit.mns.Display");
startActivity(newActivity);
break;
}
switch(pos)
{
case 2 :
Intent newActivity = new Intent("com.edu.tp.iit.mns.Display");
startActivity(newActivity);
break;
}
switch(pos)
{
case 3 :
Intent newActivity = new Intent("com.edu.tp.iit.mns.Display");
startActivity(newActivity);
break;
}
switch(pos)
{
case 4 :
Intent newActivity = new Intent("com.edu.tp.iit.mns.Display");
startActivity(newActivity);
break;
}
switch(pos)
{
case 5 :
Intent newActivity = new Intent("com.edu.tp.iit.mns.Display");
startActivity(newActivity);
break;
}
switch(pos)
{
case 6 :
Intent newActivity = new Intent("com.edu.tp.iit.mns.Display");
startActivity(newActivity);
break;
}
switch(pos)
{
case 7 :
Intent newActivity = new Intent("com.edu.tp.iit.mns.Display");
startActivity(newActivity);
break;
}
}
(this is the display.class (image 2) works like a template to display dynamic info like image,food name, food description and its rating.
public class Display extends Activity {
DBOpener dbopener;
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.display);
dbopener = new DBOpener(this);
}
#Override
protected void onResume() {
super.onResume();
// Configure the listview
// ArrayList<String> mealNames = new ArrayList<String>();
// ListView lstDine = (ListView)this.findViewById(R.id.dine);
// lstDine.setAdapter(new ArrayAdapter<String>(this,
// android.R.layout.simple_list_item_1, mealNames));
// Open/create the DB
try {
// dbopener.createDatabase(); // Create DB if necessary
dbopener.openDatabase(); // Open the DB
Toast.makeText(this, " open DB",
Toast.LENGTH_LONG).show();
Cursor dinners = dbopener.getLunchNames();
while (dinners.moveToNext()) {
// mealNames.add(dinners.getString(0)); // Get the current subj
// code, add to list
}
dinners.close();
// Update the listview
// ArrayAdapter<String> ad = (ArrayAdapter<String>)lstDine.getAdapter();
// ad.notifyDataSetChanged();
//
// lstDine.setOnItemClickListener(this);
} catch (Exception e) {
Toast.makeText(this, "Could not open DB",
Toast.LENGTH_LONG).show();
}
}
// Close the DB when app pauses
#Override
protected void onPause() {
super.onPause();
dbopener.close();
}
}
and lastly my dpopener file:
public class DBOpener extends SQLiteOpenHelper {
private static String DB_PATH =
"/data/data/com.edu.tp.iit.mns/databases/"; //path of our database
private static String DB_NAME ="finals"; // Database name
private final Context myContext;
private SQLiteDatabase db;
#Override
public void onCreate(SQLiteDatabase db) {
// TODO Auto-generated method stub
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
// TODO Auto-generated method stub
}
public DBOpener(Context context) {
super(context, DB_NAME, null, 1);
myContext = context;
}
public void createDatabase() throws IOException {
boolean dbExists = checkDatabase();
if (dbExists) {
// Do nothing, DB already exists
Log.d("DBOpener", "DB exists");
} else {
// By calling this method an empty database will be created
// in the default system path of your application, which we
// will overwrite with our own database.
Log.d("DBOpener", "DB does not exit - copying from assets");
this.getReadableDatabase();
copyDatabase();
}
}
private boolean checkDatabase() {
SQLiteDatabase checkDB = null;
try {
// Try opening the database
String path = DB_PATH + DB_NAME;
checkDB = SQLiteDatabase.openDatabase(path, null,
SQLiteDatabase.OPEN_READONLY);
} catch (SQLiteException e) {
// If it fails, DB does not exist
}
if (checkDB != null)
checkDB.close(); // Close the DB; we don’t need it now
return checkDB != null;
}
private void copyDatabase() throws IOException {
InputStream istream = myContext.getAssets().open(DB_NAME);
OutputStream ostream = new FileOutputStream(DB_PATH + DB_NAME);
// Transfer bytes from istream to ostream
byte[] buffer = new byte[1024];
int length;
while ((length = istream.read(buffer)) > 0) {
ostream.write(buffer, 0, length);
}
// Close streams
istream.close();
ostream.flush();
ostream.close();
}
public void openDatabase() throws SQLiteException {
db = SQLiteDatabase.openDatabase(DB_PATH + DB_NAME, null,
SQLiteDatabase.OPEN_READWRITE);
}
#Override
public synchronized void close() {
if (db != null)
db.close();
super.close();
}
// Retrieve all subject codes
public Cursor getDinnerNames() {
if (db == null)
return null;
return db.query("dinner", new String[] {"name"},
null, null, null, null, null);
}
// Get details of specific subject
public Cursor getDinnerDetails(String name) {
if (db == null)
return null;
return db.query("dinner", new String[] {"name", "nutrition", "rating"},
"name = ?", new String[] {name}, null, null, null);
}
// Retrieve all subject codes
public Cursor getLunchNames() {
if (db == null)
return null;
return db.query("lunch", new String[] {"name"},
null, null, null, null, null);
}
// Get details of specific subject
public Cursor getLunchDetails(String name) {
if (db == null)
return null;
return db.query("dinner", new String[] {"name", "nutrition", "rating"},
"name = ?", new String[] {name}, null, null, null);
}
// Retrieve all subject codes
public Cursor getBreakfastNames() {
if (db == null)
return null;
return db.query("breakfast", new String[] {"name"},
null, null, null, null, null);
}
// Get details of specific subject
public Cursor getBreakfastDetails(String name) {
if (db == null)
return null;
return db.query("breakfast", new String[] {"name", "nutrition", "rating"},
"name = ?", new String[] {name}, null, null, null);
}
}
can u help me kick start with the case 0 so that i can complete the code. example, user click BBQ chicken sandwich. it will navigate to display.class and retrieve the info from db and shows image rating and stuffs.

To pass arguments to the new activity via intent you use the putExtra(), like you put on your code:
newActivity.putExtra("1", "2");
The first parameter should be an String constant to identify your parameter, you will use this String to get the value later. The second parameter is the value, android has methods for all the primitives.
On the new activity, you use getExtra("1", "2"), where 1 is the constant you used earlier and 2 is the default value, in case it doesn't finds the value or the constant you used.

Related

Listview gets popuplated from the database everytime I start the activity

I am fetching some json data into an EventApp and I am trying to store in SQLite database some of the events. I am showing the events in another activity, not the main one and whenever I go back from that activity to the main one and the I go back to the activity with the listview, the data gets duplicated every time. SO if I click to go to that activity 10 time, my data gets 10 times in the listview and in the database as well. How can I fix this?
SQLiteDatabase db = getWritableDatabase();
public DatabaseHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
#Override
public void onCreate(SQLiteDatabase db) {
db.execSQL(CREATE_TABLE);
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL("DROP TABLE IF EXISTS " + TABLE_NAME);
onCreate(db);
}
//Add new row to the database
public void addEvent(Event ev){
ContentValues contentValues = new ContentValues();
contentValues.put(DatabaseHelper.TITLE, ev.getTitle());
contentValues.put(DatabaseHelper.START_DATE, ev.getStartTime());
contentValues.put(DatabaseHelper.END_DATE, ev.getEndTime());
contentValues.put(DatabaseHelper.IMAGE_URL, ev.getImageURL());
contentValues.put(DatabaseHelper.URL, ev.getUrl());
contentValues.put(DatabaseHelper.SUBTITLE, ev.getSubtitle());
contentValues.put(DatabaseHelper.DESCRIPTION, ev.getDescription());
db.insert(TABLE_NAME, null, contentValues);
//db.close();
}
//Delete event from database
public void deleteEvent(String eventTitle){
db.execSQL("DELETE FROM " + TABLE_NAME + "WHERE " + TITLE + "=\"" + eventTitle + "\";" );
}
public int deleteEvents() {
return db.delete(DatabaseHelper.TABLE_NAME, null, null);
}
//Print the database as string
public String databaseToString(){
String dbString="";
//points to a location in results
Cursor c = getEvents();
while (c.moveToNext()){
if(c.getString(c.getColumnIndex("Title")) != null){
dbString += c.getString(c.getColumnIndex("Title"));
dbString += "\n";
}
}
//db.close();
return dbString;
}
public Cursor getEvents(){
return db.query(TABLE_NAME, ALL_COLUMNS, null, null, null, null, null, null);
}
}
This is the activity where I show the data from the database
public class StoredEventsActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.stored_events);
ListView listView = (ListView) findViewById(R.id.lv_stored_events);
Intent intent = getIntent();
ArrayList<Event> events = new ArrayList<Event>();
events = (ArrayList<Event>) intent.getSerializableExtra("storedEvents");
EventAdapter adapter = new EventAdapter(this, R.layout.list_view_row, R.id.stored, events );
listView.setAdapter(adapter);
}
}
Here is the method that returns the stored events
public static ArrayList<Event> returnStoredEvents(){
long id = -1;
//getStoredEvents();
Cursor c = eventsDB.getEvents();
while (c.moveToNext()){
id = c.getInt(c.getColumnIndex(eventsDB.ID));
String title = c.getString(c.getColumnIndex(eventsDB.TITLE));
String start = c.getString(c.getColumnIndex(eventsDB.START_DATE));
String end = c.getString(c.getColumnIndex(eventsDB.END_DATE));
organizeEvents.add(new Event(title, start, end, true));
}
c.close();
Log.d("DATABASE", organizeEvents.toString());
return organizeEvents;
}
Here is where I actually add some of the events:
private void readEvents(String str){
Event ev = null;
try {
JSONObject geoJSON = new JSONObject(str);
JSONArray jsonEvents = geoJSON.getJSONArray("events");
for (int i = 0; i < jsonEvents.length(); i++) {
JSONObject event = jsonEvents.getJSONObject(i);
JSONArray timeJsonEvent = event.getJSONArray("datelist");
JSONObject time = timeJsonEvent.getJSONObject(0);
title = event.getString("title_english");
Date date = new Date(time.getLong("start"));
startDate = dateFormat.format(date);
date = new Date(time.getLong("end"));
endDate = dateFormat.format(date);
imageURL = event.getString("picture_name");
url = event.getString("url");
subtitle = event.getString("subtitle_english");
description = event.getString("description_english");
if (title.charAt(0) == 'T') {
ev = new Event(title, startDate, endDate, true);
eventsDB.addEvent(ev);
}else {
ev = new Event(title, startDate, endDate, false);
}
// Process a newly found event
final Event finalEv = ev;
handler.post(new Runnable() {
public void run() {
addNewEvent(finalEv);
}
});
}
}catch (Exception e) {
Log.d(null, e.getMessage());
}
}
And here is my main:
public class MainActivity extends AppCompatActivity{
DatabaseHelper eventsDB;
ListFragment listFragment;
SimpleCursorAdapter adapter;
Intent intent;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
eventsDB = new DatabaseHelper(this);
//storedEvents.addAll(EventsListFragment.returnStoredEvents());
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main_menu, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
if (item.getTitle().equals("Sort by name")){
Toast.makeText(this, "ITEM 2 CLICKED", Toast.LENGTH_LONG).show();
EventsListFragment.sort(-1);
}else if (item.getTitle().equals("Sort by date")) {
EventsListFragment.sort(1);
}else if (item.getTitle().equals("Stored events")){
showSavedEvents();
Toast.makeText(this, "ITEM 3 CLICKED", Toast.LENGTH_LONG).show();
}
return true;
}
public void showSavedEvents(){
intent = new Intent(this, StoredEventsActivity.class);
intent.putExtra("storedEvents", EventsListFragment.returnStoredEvents());
startActivity(intent);
}
}

How to check if database is empty in SQLite Android with DatabaseConnector class

I have a DatabaseConnector class where I want to check if the database is empty and then show an alert and a click on it will close the activity.
This is my DatabaseConnector class
public class DatabaseConnector {
// Declare Variables
private static final String DB_NAME = "MyNotes";
private static final String TABLE_NAME = "tablenotes";
private static final String TITLE = "title";
private static final String ID = "_id";
private static final String NOTE = "note";
private static final int DATABASE_VERSION = 2;
private SQLiteDatabase database;
private DatabaseHelper dbOpenHelper;
public static final String MAINCAT = "maincat";
public static final String SUBCAT = "subcat";
public DatabaseConnector(Context context) {
dbOpenHelper = new DatabaseHelper(context, DB_NAME, null,
DATABASE_VERSION);
}
// Open Database function
public void open() throws SQLException {
// Allow database to be in writable mode
database = dbOpenHelper.getWritableDatabase();
}
// Close Database function
public void close() {
if (database != null)
database.close();
}
// Create Database function
public void InsertNote(String title, String note , String maincat, String subcat) {
ContentValues newCon = new ContentValues();
newCon.put(TITLE, title);
newCon.put(NOTE, note);
newCon.put(MAINCAT, maincat);
newCon.put(SUBCAT, subcat);
open();
database.insert(TABLE_NAME, null, newCon);
close();
}
// Update Database function
public void UpdateNote(long id, String title, String note) {
ContentValues editCon = new ContentValues();
editCon.put(TITLE, title);
editCon.put(NOTE, note);
open();
database.update(TABLE_NAME, editCon, ID + "=" + id, null);
close();
}
// Delete Database function
public void DeleteNote(long id) {
open();
database.delete(TABLE_NAME, ID + "=" + id, null);
close();
}
// List all data function
//String selection = dbOpenHelper.MAINCAT + " = 'quiz'"
// +" AND " + dbOpenHelper.SUBCAT + " = 'test'";
// public Cursor ListAllNotes() {
// return database.query(TABLE_NAME, new String[] { ID, TITLE }, null,
// null, null, null, TITLE);
// }
public Cursor ListAllNotes(String selection) {
return database.query(TABLE_NAME, new String[] { ID, TITLE }, selection,
null, null, null, TITLE);
}
// Capture single data by ID
public Cursor GetOneNote(long id) {
return database.query(TABLE_NAME, null, ID + "=" + id, null, null,
null, null);
}
And here is the ListActivity wherein I want to close the Activity with an alert
public class dbMainactivty extends ListActivity {
// Declare Variables
public static final String ROW_ID = "row_id";
private static final String TITLE = "title";
private ListView noteListView;
private CursorAdapter noteAdapter;
#SuppressWarnings("deprecation")
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Tracker t = ((AnalyticsSampleApp)this.getApplication()).getTracker(TrackerName.APP_TRACKER);
t.setScreenName("dbMainactivty");
t.send(new HitBuilders.AppViewBuilder().build());
// Locate ListView
noteListView = getListView();
// setContentView(R.layout.list_note);
//noteListView = (ListView) findViewById(R.id.listview);
// Prepare ListView Item Click Listener
noteListView.setOnItemClickListener(viewNoteListener);
// Map all the titles into the ViewTitleNotes TextView
String[] from = new String[] { TITLE };
int[] to = new int[] { R.id.ViewTitleNotes };
// Create a SimpleCursorAdapter
noteAdapter = new SimpleCursorAdapter(dbMainactivty.this,
R.layout.list_note, null, from, to);
// Set the Adapter into SimpleCursorAdapter
setListAdapter(noteAdapter);
}
// Capture ListView item click
OnItemClickListener viewNoteListener = new OnItemClickListener() {
public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,
long arg3) {
// Open ViewNote activity
Intent viewnote = new Intent(dbMainactivty.this, ViewNote.class);
// Pass the ROW_ID to ViewNote activity
viewnote.putExtra(ROW_ID, arg3);
startActivity(viewnote);
}
};
#Override
protected void onResume() {
super.onResume();
// Execute GetNotes Asynctask on return to MainActivity
new GetNotes().execute((Object[]) null);
GoogleAnalytics.getInstance(dbMainactivty.this).reportActivityStart(this);
}
#Override
protected void onStop() {
Cursor cursor = noteAdapter.getCursor();
// Deactivates the Cursor
if (cursor != null)
cursor.deactivate();
noteAdapter.changeCursor(null);
super.onStop();
GoogleAnalytics.getInstance(dbMainactivty.this).reportActivityStop(this);
}
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
Intent i = null;
switch (item.getItemId()) {
case R.id.action_rate:
String webpage = "http://developer.android.com/index.html";
Intent intent2 = new Intent(Intent.ACTION_VIEW, Uri.parse(webpage));
startActivity(intent2);
overridePendingTransition(R.anim.slide_in, R.anim.slide_out);
case R.id.action_share:
i = new Intent();
i.setAction(Intent.ACTION_SEND);
//i.putExtra(Intent.EXTRA_TEXT, feed.getItem(pos).getTitle().toString()+ " to know the answer download http://developer.android.com/index.html");
i.setType("text/plain");
startActivity(i);
return true;
}
return super.onOptionsItemSelected(item);
};
// GetNotes AsyncTask
private class GetNotes extends AsyncTask<Object, Object, Cursor> {
DatabaseConnector dbConnector = new DatabaseConnector(dbMainactivty.this);
#Override
protected Cursor doInBackground(Object... params) {
// Open the database
dbConnector.open();
return dbConnector.ListAllNotes("maincat LIKE 'quiz' AND subcat LIKE 'test'");
}
#Override
protected void onPostExecute(Cursor result) {
noteAdapter.changeCursor(result);
// Close Database
dbConnector.close();
}
}
#Override
protected void onStart() {
super.onStart();
ConnectivityManager conMgr = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
if (conMgr.getActiveNetworkInfo() == null) {
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setMessage(
"Please check your Internet Connection.")
.setTitle("tilte")
.setCancelable(false)
.setPositiveButton("Exit",
new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog,
int id) {
//loader.cancel(true);
finish();
}
});
AlertDialog alert = builder.create();
alert.show();
} else {
Cursor cursor = noteAdapter.getCursor();
if(cursor != null && cursor.getCount() > 0){
cursor.moveToFirst();
//do your action
//Fetch your data
GoogleAnalytics.getInstance(dbMainactivty.this).reportActivityStart(this);
Toast.makeText(getBaseContext(), "Yipeee!", Toast.LENGTH_SHORT).show();
}
else {
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setMessage(
"oops nothing pinned yet! ....")
.setTitle("title")
.setCancelable(false)
.setPositiveButton("Exit",
new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog,
int id) {
//loader.cancel(true);
finish();
}
});
AlertDialog alert = builder.create();
alert.show();
Toast.makeText(getBaseContext(), "No records yet!", Toast.LENGTH_SHORT).show();
}
}
}
}
I am trying to check
cursor != null && cursor.getCount()>0 and if it turns false then show the alert that
nothing has been pinned yet
Should show up however even though if the cursor returns data the alert still shows up.
First step, take a look at the lifecycle of your activity: http://www.android-app-market.com/wp-content/uploads/2012/03/Android-Activity-Lifecycle.png
As you can see onResume() is called after onStart() which means that checking the cursor on the onStart() can not work.
Secondly you are starting an AsyncTask (GetNotes) on the onResume() method which means you are running a parallel thread at this point and can't check for the result after calling new GetNotes().execute((Object[]) null);
Your problem is you need to check the emptiness of your cursor (cursor != null && cursor.getCount()>0) AFTER the data is loader which mean after the AsyncTask has completed. In other words, move the check for emptiness on your cursor inside the onPostExecute(Cursor result) method.

Getting a column from .sqlite containing multiple tables with multiple columns

!Database consists of multiple tables and multiple columns as shown & i have pasted this law.sqlite in assets folder.
Database consists of multiple tables and multiple columns as shown & i have pasted this law.sqlite in assets folder.
Suppose i want to access all the elements of column AS_name as shown . So how should i code for it?
Try this:
Cursor cursor = db.rawQuery("SELECT DISTINCT AS_name FROM Articles",null);
// If you want in order then add "ORDER BY AS_name AESC" in sql query.
cursor.moveToFirst();
while(cursor.moveToNext()) {
// do Something
}
I tried and now the problem is solved :
For anyone facing similar type of problem can try my implementation :
Step 1:
Make a GetterSetter class (named GS here) & generate the Getter-Setters of variables used.
Like in my case:
public class GS {
String AS_name;
public String getAS_name() {
return AS_name;
}
public void setAS_name(String aS_name) {
AS_name = aS_name;
}
}
Step 2:
Make a DBAdapter class which extends SQLiteOpenHelper & in that assign the your name of the file with extension .sqlite !
Rest you need only to copy my DBAdapter.java code & take care to implement the method getData() in which the data from database is fetched !
public class DBAdapter extends SQLiteOpenHelper
{
CustomAdapter adapter;
static String name = "law.sqlite"; //--Replace it with ur sqlite name
static String path = "";
static ArrayList<GS> gs;
static SQLiteDatabase sdb;
#Override
public void onCreate(SQLiteDatabase db)
{
// TODO Auto-generated method stub
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion)
{
// TODO Auto-generated method stub
}
private DBAdapter(Context v)
{
super(v, name, null, 1);
path = "/data/data/" + v.getApplicationContext().getPackageName() + "/databases";
}
public boolean checkDatabase()
{
SQLiteDatabase db = null;
try
{
db = SQLiteDatabase.openDatabase(path + "/" + name, null, SQLiteDatabase.OPEN_READONLY);
} catch (Exception e)
{
e.printStackTrace();
}
if (db == null)
{
return false;
}
else
{
db.close();
return true;
}
}
public static synchronized DBAdapter getDBAdapter(Context v)
{
return (new DBAdapter(v));
}
public void createDatabase(Context v)
{
this.getReadableDatabase();
try
{
InputStream myInput = v.getAssets().open(name);
// Path to the just created empty db
String outFileName = path +"/"+ 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();
} catch (IOException e)
{
System.out.println(e);
}
}
public void openDatabase()
{
try
{
sdb = SQLiteDatabase.openDatabase(path + "/" + name, null,
SQLiteDatabase.OPEN_READWRITE);
} catch (Exception e)
{
System.out.println(e);
}
}
public ArrayList<GS> getData()
{
try{
Cursor c1 = sdb.rawQuery("SELECT DISTINCT * FROM Articles", null);
gs = new ArrayList<GS>();
while (c1.moveToNext())
{
GS q1 = new GS();
q1.setAS_name(c1.getString(3)); //--- here 3 represents column no.
Log.v("AS_name",q1.AS_name+"");
gs.add(q1);
}
}
catch (Exception e) {
e.printStackTrace();
}
return gs;
}
}
Step 3:
The class MainActivity.java :
public class MainActivity extends Activity {
ArrayList<GS> q = new ArrayList<GS>();
CustomAdapter adapter;
ListView lv;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Get ListView object from xml
lv = (ListView) findViewById(R.id.listView1);
DBAdapter db = DBAdapter.getDBAdapter(getApplicationContext());
if (!db.checkDatabase())
{
db.createDatabase(getApplicationContext());
}
db.openDatabase();
q = db.getData();
for(int i=0;i<q.size();i++)
{
Log.i("outside",""+q.get(i).getAS_name());
}
lv = (ListView) findViewById(R.id.listView1);
lv.setAdapter(new CustomAdapter(MainActivity.this,q));
//lv.setAdapter(adapter);
}
class CustomAdapter extends ArrayAdapter<GS>
{
ArrayList<GS> list;
LayoutInflater mInfalter;
public CustomAdapter(Context context, ArrayList<GS> list)
{
super(context,R.layout.customlayout,list);
this.list= list;
mInfalter = LayoutInflater.from(context);
for(int i=0;i<list.size();i++)
{
Log.i("................",""+list.get(i).getAS_name());
}
}
// public int getCount(){
// return list.size();
// }
#Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
Log.i("..........","Hello in getView");
if(convertView==null)
{
convertView = mInfalter.inflate(R.layout.customlayout,parent,false);//--customlayout.xml must have a textView
holder = new ViewHolder();
holder.tv1 = (TextView)convertView.findViewById(R.id.textView1);
convertView.setTag(holder);
}else{
holder = (ViewHolder)convertView.getTag();
}
holder.tv1.setText(list.get(position).getAS_name());
return convertView;
}
}
static class ViewHolder
{
TextView tv1;
}
}
Run this code & finally the list in the listview will be displayed ! :)
Cursor c = db.query(
TABLE_NAME, // The table to query
projection, // The columns to return
null, // The columns for the WHERE clause
null, // The values for the WHERE clause
null, // don't group the rows
null, // don't filter by row groups
sortOrder // The sort order
);
Specify the table name in TABLE_NAME field. Then access the elements using
c.moveToFirst();
for(int i=0;i<c.getCount();i++)
{
//access elements of column here
long itemId = c.getLong(c.getColumnIndexOrThrow(Column_Name)); //Example with long, corresponding function for string etc also exists.
c.moveToNext();
}
c.close();
Specify the column name in Column_name.
NOTE: If this column is in multiple tables, just put both these code snippets in a loop and iterate through it. May be you can store the table names in an arraylist and access each table in each iteration of the outermost loop. Hope this helps you!!!

Loader not loading data when sqlite data changes

I have a DialogFragment that I'm working on to display two spinners, side by side, one displays a list of drivers, the other a list of vehicles.
The data to populate these spinners is retrieved from a sqlite database. I am trying to use a LoaderManager to keep the spinners updated or in sync with the database tables, (drivers and vehicles).
When I add/delete/edit a record in either the drivers table or vehicles table in the database, the spinners don't get updated, the driver or vehicle remains unchanged in the spinner.
I'm not sure what I'm missing because I thought LoaderManager is supposed to keep the lists updated or in sync with the database tables automatically right?
I created a button called addDriverVehicle() which is supposed to allow the user to add another driver/vehicle in the future but for now I'm using it as a test to delete a driver to kind of simulate the database tables changing just so i can see if the spinner gets updated automatically but it's not happening. The record is being deleted but the spinner continues to show it.
public class DriverVehiclePickersDialogFragment extends DialogFragment implements LoaderManager.LoaderCallbacks<Cursor>, OnItemSelectedListener {
public static final String ARG_LISTENER_TYPE = "listenerType";
public static final String ARG_DIALOG_TYPE = "dialogType";
public static final String ARG_TITLE_RESOURCE = "titleResource";
public static final String ARG_SET_DRIVER = "setDriver";
public static final String ARG_SET_VEHICLE = "setVehicle";
private static final int DRIVERS_LOADER = 0;
private static final int VEHICLES_LOADER = 1;
private DriverVehicleDialogListener mListener;
// These are the Adapter being used to display the driver's and vehicle's data.
SimpleCursorAdapter mDriversAdapter, mVehiclesAdapter;
// Define Dialog view
private View mView;
// Store Driver and Vehicle Selected
private long[] mDrivers, mVehicles;
// Spinners Containing Driver and Vehicle List
private Spinner driversSpinner;
private Spinner vehiclesSpinner;
private static enum ListenerType {
ACTIVITY, FRAGMENT
}
public static enum DialogType {
DRIVER_SPINNER, VEHICLE_SPINNER, DRIVER_VEHICLE_SPINNER
}
public interface DriverVehicleDialogListener {
public void onDialogPositiveClick(long[] mDrivers, long[] mVehicles);
}
public DriverVehiclePickersDialogFragment() {
// Empty Constructor
Log.d("default", "default constructor ran");
}
public static DriverVehiclePickersDialogFragment newInstance(DriverVehicleDialogListener listener, Bundle dialogSettings) {
final DriverVehiclePickersDialogFragment instance;
if (listener instanceof Activity) {
instance = createInstance(ListenerType.ACTIVITY, dialogSettings);
} else if (listener instanceof Fragment) {
instance = createInstance(ListenerType.FRAGMENT, dialogSettings);
instance.setTargetFragment((Fragment) listener, 0);
} else {
throw new IllegalArgumentException(listener.getClass() + " must be either an Activity or a Fragment");
}
return instance;
}
private static DriverVehiclePickersDialogFragment createInstance(ListenerType listenerType, Bundle dialogSettings) {
DriverVehiclePickersDialogFragment fragment = new DriverVehiclePickersDialogFragment();
if (!dialogSettings.containsKey(ARG_LISTENER_TYPE)) {
dialogSettings.putSerializable(ARG_LISTENER_TYPE, listenerType);
}
if (!dialogSettings.containsKey(ARG_DIALOG_TYPE)) {
dialogSettings.putSerializable(ARG_DIALOG_TYPE, DialogType.DRIVER_VEHICLE_SPINNER);
}
if (!dialogSettings.containsKey(ARG_TITLE_RESOURCE)) {
dialogSettings.putInt(ARG_TITLE_RESOURCE, 0);
}
fragment.setArguments(dialogSettings);
return fragment;
}
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
// Find out how to get the DialogListener instance to send the callback events to
Bundle args = getArguments();
ListenerType listenerType = (ListenerType) args.getSerializable(ARG_LISTENER_TYPE);
switch (listenerType) {
case ACTIVITY: {
// Send callback events to the hosting activity
mListener = (DriverVehicleDialogListener) activity;
break;
}
case FRAGMENT: {
// Send callback events to the "target" fragment
mListener = (DriverVehicleDialogListener) getTargetFragment();
break;
}
}
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onActivityCreated(savedInstanceState);
Button btnAddDriverVehicle = (Button) mView.findViewById(R.id.addDriverVehicleButton);
btnAddDriverVehicle.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
DatabaseHelper1 mOpenHelper = new DatabaseHelper1(getActivity());
try {
SQLiteDatabase db = mOpenHelper.getWritableDatabase();
db.delete("drivers", " driver_number = 70", null);
} catch (SQLException e) {
}
}
});
}
#Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
super.onSaveInstanceState(savedInstanceState);
Bundle args = getArguments();
int titleResource = args.getInt(ARG_TITLE_RESOURCE);
DialogType dialogType = (DialogType) args.getSerializable(ARG_DIALOG_TYPE);
if (args.containsKey(ARG_SET_DRIVER)) {
mDrivers = args.getLongArray(ARG_SET_DRIVER);
}
if (args.containsKey(ARG_SET_VEHICLE)) {
mVehicles = args.getLongArray(ARG_SET_VEHICLE);
}
mView = LayoutInflater.from(getActivity()).inflate(R.layout.driver_vehicle_dialog, null);
if ((dialogType == DialogType.DRIVER_SPINNER) || (dialogType == DialogType.DRIVER_VEHICLE_SPINNER)) {
driversSpinner = (Spinner) mView.findViewById(R.id.driversSpinner);
vehiclesSpinner = (Spinner) mView.findViewById(R.id.vehiclesSpinner);
driversSpinner.setVisibility(View.VISIBLE);
mDriversAdapter = new SimpleCursorAdapter(getActivity(), R.layout.driver_listview_row, null, new String[] { ConsoleContract.Drivers.DRIVER_NUMBER,
ConsoleContract.Drivers.DRIVER_NAME }, new int[] { R.id.driver_number, R.id.driver_name }, 0);
driversSpinner.setAdapter(mDriversAdapter);
driversSpinner.setOnItemSelectedListener(this);
}
if ((dialogType == DialogType.VEHICLE_SPINNER) || (dialogType == DialogType.DRIVER_VEHICLE_SPINNER)) {
vehiclesSpinner.setVisibility(View.VISIBLE);
mVehiclesAdapter = new SimpleCursorAdapter(getActivity(), R.layout.vehicle_listview_row, null, new String[] { ConsoleContract.Vehicles.VEHICLE_NUMBER,
ConsoleContract.Vehicles.VEHICLE_VIN }, new int[] { R.id.vehicle_number, R.id.vehicle_vin }, 0);
vehiclesSpinner.setAdapter(mVehiclesAdapter);
vehiclesSpinner.setOnItemSelectedListener(this);
}
// Prepare the loader. Either re-connect with an existing one, or start a new one.
getLoaderManager().initLoader(DRIVERS_LOADER, null, this);
getLoaderManager().initLoader(VEHICLES_LOADER, null, this);
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
builder.setView(mView);
if (titleResource == 0) {
builder.setMessage("Select Driver and Vehicle");
} else {
builder.setMessage(getString(titleResource));
}
builder.setPositiveButton(android.R.string.ok, new OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
mListener.onDialogPositiveClick(mDrivers, mVehicles);
}
});
builder.setNegativeButton(android.R.string.cancel, null);
return builder.create();
}
private static class DatabaseHelper1 extends SQLiteOpenHelper {
private static final String DATABASE_NAME = "test.db";
private static final int DATABASE_VERSION = 1;
DatabaseHelper1(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
#Override
public void onCreate(SQLiteDatabase db) {
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
}
}
#Override
public void onDetach() {
super.onDetach();
mListener = null;
}
// These are the Contacts rows that we will retrieve.
static final String[] DRIVERS_SUMMARY_PROJECTION = new String[] { ConsoleContract.Drivers._ID, ConsoleContract.Drivers.DRIVER_ID, ConsoleContract.Drivers.DRIVER_NUMBER,
ConsoleContract.Drivers.DRIVER_NAME };
static final String[] VEHICLES_SUMMARY_PROJECTION = new String[] { ConsoleContract.Vehicles._ID, ConsoleContract.Vehicles.VEHICLE_ID, ConsoleContract.Vehicles.VEHICLE_NUMBER,
ConsoleContract.Vehicles.VEHICLE_VIN };
#Override
public Loader<Cursor> onCreateLoader(int id, Bundle args) {
// This is called when a new Loader needs to be created. This
// sample only has one Loader, so we don't care about the ID.
// First, pick the base URI to use depending on whether we are
// currently filtering.
Uri baseUri = null;
String select = null, sortOrder = null;
String[] projection = null;
switch (id) {
case DRIVERS_LOADER:
baseUri = ConsoleContract.Drivers.CONTENT_URI;
select = "((" + Drivers.DRIVER_NAME + " NOT NULL) AND (" + Drivers.DRIVER_NAME + " != '' ))";
sortOrder = Drivers.DRIVER_NUMBER;
projection = DRIVERS_SUMMARY_PROJECTION;
break;
case VEHICLES_LOADER:
baseUri = ConsoleContract.Vehicles.CONTENT_URI;
select = "((" + Vehicles.VEHICLE_NUMBER + " NOT NULL) AND (" + Vehicles.VEHICLE_NUMBER + " != '' ))";
sortOrder = Vehicles.VEHICLE_NUMBER;
projection = VEHICLES_SUMMARY_PROJECTION;
break;
}
return new CursorLoader(getActivity(), baseUri, projection, select, null, sortOrder);
}
#Override
public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
// Swap the new cursor in. (The framework will take care of closing the
// old cursor once we return.)
int id = loader.getId();
MatrixCursor newCursor = null;
switch (id) {
case DRIVERS_LOADER:
newCursor = new MatrixCursor(DRIVERS_SUMMARY_PROJECTION);
break;
case VEHICLES_LOADER:
newCursor = new MatrixCursor(VEHICLES_SUMMARY_PROJECTION);
break;
}
newCursor.addRow(new String[] { "0", "0", "", "" });
Cursor[] cursors = { newCursor, data };
Cursor mergedCursor = new MergeCursor(cursors);
switch (id) {
case DRIVERS_LOADER:
mDriversAdapter.swapCursor(mergedCursor);
break;
case VEHICLES_LOADER:
mVehiclesAdapter.swapCursor(mergedCursor);
break;
}
}
#Override
public void onLoaderReset(Loader<Cursor> loader) {
// This is called when the last Cursor provided to onLoadFinished()
// above is about to be closed. We need to make sure we are no
// longer using it.
int id = loader.getId();
switch (id) {
case DRIVERS_LOADER:
mDriversAdapter.swapCursor(null);
break;
case VEHICLES_LOADER:
mVehiclesAdapter.swapCursor(null);
break;
}
}
#Override
public void onItemSelected(AdapterView<?> parent, View view, int pos, long id) {
if (parent.getId() == R.id.driversSpinner) {
mDriver = id;
} else {
mVehicle = id;
}
}
#Override
public void onNothingSelected(AdapterView<?> parent) {
}
}
Make sure in your ContentProvider to call the notifyChange() method inside the insert, delete and update methods.
Here a snippet taken from Grokking Android Blog
public Uri insert(Uri uri, ContentValues values) {
if (URI_MATCHER.match(uri) != LENTITEM_LIST) {
throw new IllegalArgumentException("Unsupported URI for insertion: " + uri);
}
long id = db.insert(DBSchema.TBL_ITEMS, null, values);
if (id > 0) {
// notify all listeners of changes and return itemUri:
Uri itemUri = ContentUris.withAppendedId(uri, id);
getContext().getContentResolver().notifyChange(itemUri, null);
return itemUri;
}
// s.th. went wrong:
throw new SQLException("Problem while inserting into " + DBSchema.TBL_ITEMS + ", uri: " + uri); // use another exception here!!!
}
Conversely your Loader won't "heard" DB changes.
#rciovati's answer is good to me. But for me,I used Cursor Loader in my list view so it also need at query method in My ContentProvider.
In your ContentProvider class, query method also need to call notify after query like the code below-
#Override
public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sort) {
SQLiteQueryBuilder queryBuilder=new SQLiteQueryBuilder();
Cursor cursor=queryBuilder.query(dbHelper.getReadableDatabase(),
projection,
selection,
selectionArgs,
null,
null,
sort);
cursor.setNotificationUri(getContext().getContentResolver(), uri);
return cursor;
}

putExtra method values?

public class Breakfast extends Activity implements OnItemClickListener {
DBOpener dbopener;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//for fullscreen view
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,WindowManager.LayoutParams.FLAG_FULLSCREEN);
setContentView(R.layout.dinner);
dbopener = new DBOpener(this);
}
// Open the DB, query all subject codes and refresh the listview when app resumes
#Override
protected void onResume() {
super.onResume();
// Configure the listview
ArrayList<String> mealNames = new ArrayList<String>();
ListView lstDine = (ListView)this.findViewById(R.id.dine);
lstDine.setAdapter(new ArrayAdapter<String>(this,android.R.layout.simple_list_item_1, mealNames));
// Open/create the DB
try
{
dbopener.createDatabase(); // Create DB if necessary
dbopener.openDatabase(); // Open the DB
Cursor dinners = dbopener.getBreakfastNames();
while (dinners.moveToNext()) {
mealNames.add(dinners.getString(0)); // Get the Lunch Name & adds to list
}
dinners.close();
// Update the listview
ArrayAdapter<String> ad = (ArrayAdapter<String>)lstDine.getAdapter();
ad.notifyDataSetChanged();
lstDine.setOnItemClickListener(this);
}
catch (Exception e)
{
Toast.makeText(this, "Could not open DB", //Display when Database Cannot be opened
Toast.LENGTH_LONG).show();
}
}
//Close the DB when app pauses
#Override
protected void onPause() {
super.onPause();
dbopener.close();
}
// When user clicks on an item
public void onItemClick(AdapterView<?> parent, View v, int pos, long id) {
switch(pos)
{
case 0 :
Intent event1 = new Intent("com.edu.tp.iit.mns.Display");
//event1.putExtra("name" , ???);
//event1.putExtra("nutrition" , ???);
//event1.putExtra("rating" , ???);
startActivity(event1);
break;
this is only part of the code. i want to know what should i put inside the (???). its a list view item..so for case 0 i want the name nutrition and rating to be displayed in Display class. and this is my database done using SQLite Database browser.
public class DBOpener extends SQLiteOpenHelper {
private static String DB_PATH =
"/data/data/com.edu.tp.iit.mns/databases/"; //path of our database
private static String DB_NAME ="finals"; // Database name
private final Context myContext;
private SQLiteDatabase db;
#Override
public void onCreate(SQLiteDatabase db) {
// TODO Auto-generated method stub
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
// TODO Auto-generated method stub
}
public DBOpener(Context context) {
super(context, DB_NAME, null, 1);
myContext = context;
}
public void createDatabase() throws IOException {
boolean dbExists = checkDatabase();
if (dbExists) {
// Do nothing, DB already exists
Log.d("DBOpener", "DB exists");
} else {
// By calling this method an empty database will be created
// in the default system path of your application, which we
// will overwrite with our own database.
Log.d("DBOpener", "DB does not exit - copying from assets");
this.getReadableDatabase();
copyDatabase();
}
}
private boolean checkDatabase() {
SQLiteDatabase checkDB = null;
try {
// Try opening the database
String path = DB_PATH + DB_NAME;
checkDB = SQLiteDatabase.openDatabase(path, null,
SQLiteDatabase.OPEN_READONLY);
} catch (SQLiteException e) {
// If it fails, DB does not exist
}
if (checkDB != null)
checkDB.close(); // Close the DB; we don’t need it now
return checkDB != null;
}
private void copyDatabase() throws IOException {
InputStream istream = myContext.getAssets().open(DB_NAME);
OutputStream ostream = new FileOutputStream(DB_PATH + DB_NAME);
// Transfer bytes from istream to ostream
byte[] buffer = new byte[1024];
int length;
while ((length = istream.read(buffer)) > 0) {
ostream.write(buffer, 0, length);
}
// Close streams
istream.close();
ostream.flush();
ostream.close();
}
public void openDatabase() throws SQLiteException {
db = SQLiteDatabase.openDatabase(DB_PATH + DB_NAME, null,
SQLiteDatabase.OPEN_READWRITE);
}
#Override
public synchronized void close() {
if (db != null)
db.close();
super.close();
}
// Retrieve all subject codes
public Cursor getDinnerNames() {
if (db == null)
return null;
return db.query("dinner", new String[] {"name"},
null, null, null, null, null);
}
// Get details of specific subject
public Cursor getDinnerDetails(String name) {
if (db == null)
return null;
return db.query("dinner", new String[] {"name", "nutrition", "rating"},
"name = ?", new String[] {name}, null, null, null);
}
// Retrieve all subject codes
public Cursor getLunchNames() {
if (db == null)
return null;
return db.query("lunch", new String[] {"name"},
null, null, null, null, null);
}
// Get details of specific subject
public Cursor getLunchDetails(String name) {
if (db == null)
return null;
return db.query("dinner", new String[] {"name", "nutrition", "rating"},
"name = ?", new String[] {name}, null, null, null);
}
// Retrieve all subject codes
public Cursor getBreakfastNames() {
if (db == null)
return null;
return db.query("breakfast", new String[] {"name"},
null, null, null, null, null);
}
// Get details of specific subject
public Cursor getBreakfastDetails(String name) {
if (db == null)
return null;
return db.query("breakfast", new String[] {"name", "nutrition", "rating"},
"name = ?", new String[] {name}, null, null, null);
}
}
So putExtra() method add extended data to the intent. So you use it when you want to pass data through Activities, you can put all primitive types like float, integer, short or also reference types like String. You can add Bundle object with method putExtras() also other Objects. So you add to intent datatypes you need to.
See this:
Example of add Object to Intent:
Intent intent = new Intent(DownloadingActivity.this, DownloadService.class);
intent.putExtra("url", "http://dl.dropbox.com/u/67617541/DOR0023.rar");
intent.putExtra("receiver", new DownloadReceiver(new Handler()));
You should read something about Intent here
So you created ArrayAdapter of Strings and you use getBreakfastNames() that return only name of breakfast so you can add to intent only
String name = (String) parent.getItemAtPosition(pos);
event1.putExtra("name", name);
but i recommend to you create class that extend from for example SimpleCursorAdapter and use design pattern Holder to full control over your data in ListView. It's cleaner, faster.

Categories

Resources