I'm trying to code a simple randomizer app. I had the randomizer button working, but then I changed some code (which I thought was irrelevant to the randomizer button) and it started crashing and getting the "CursorIndexOutOfBoundsException Index 0 requested, with a size of 0" error. I couldn't find any fixes to this that apply to my code. Can anyone help me fix this?
Here is my main class with the button:
package com.example.randomgamechooser;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.Menu;
import android.view.View;
import android.widget.TextView;
public class MainScreen extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main_screen);
}
public void chooseGame (View view) {
GameList dbUtil = new GameList(this);
dbUtil.open();
String string = dbUtil.getRandomEntry();
//TextView textView = new TextView(this);
TextView textView = (TextView) findViewById(R.id.chosenbox);
textView.setTextSize(40);
textView.setText(string);
//setContentView (textView);
dbUtil.close();
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main_screen, menu);
return true;
}
//starts the Game Selection activity
public void openGames (View view) {
Intent intent = new Intent(this, GameSelction.class);
startActivity(intent);
}
}
Here is the GameList class:
package com.example.randomgamechooser;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.util.Log;
import java.util.Random;
public class GameList {
private static final String TAG = "GameList";
//database name
private static final String DATABASE_NAME = "game_list";
//database version
private static final int DATABASE_VERSION = 1;
//table name
private static final String DATABASE_TABLE = "game_list";
//table columns
public static final String KEY_NAME = "name";
public static final String KEY_GENRE = "genre";
public static final String KEY_ROWID = "_id";
//database creation sql statement
private static final String CREATE_GAME_TABLE =
"create table " + DATABASE_TABLE + " (" + KEY_ROWID + " integer primary key autoincrement, "
+ KEY_NAME +" text not null, " + KEY_GENRE + " text not null);";
//Context
private final Context mCtx;
private DatabaseHelper mDbHelper;
private static SQLiteDatabase mDb;
//Inner private class. Database Helper class for creating and updating database.
private static class DatabaseHelper extends SQLiteOpenHelper {
DatabaseHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
// onCreate method is called for the 1st time when database doesn't exists.
#Override
public void onCreate(SQLiteDatabase db) {
Log.i(TAG, "Creating DataBase: " + CREATE_GAME_TABLE);
db.execSQL(CREATE_GAME_TABLE);
}
//onUpgrade method is called when database version changes.
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
Log.w(TAG, "Upgrading database from version " + oldVersion + " to "
+ newVersion);
}
}
//Constructor - takes the context to allow the database to be opened/created
//#param ctx the Context within which to work
public GameList(Context ctx) {
this.mCtx = ctx;
}
//This method is used for creating/opening connection
//#return instance of GameList
//#throws SQLException
public GameList open() throws SQLException {
mDbHelper = new DatabaseHelper(mCtx);
mDb = mDbHelper.getWritableDatabase();
return this;
}
//This method is used for closing the connection.
public void close() {
mDbHelper.close();
}
//This method is used to create/insert new game.
//#param name
// #param genre
// #return long
public long createGame(String name, String genre) {
ContentValues initialValues = new ContentValues();
initialValues.put(KEY_NAME, name);
initialValues.put(KEY_GENRE, genre);
return mDb.insert(DATABASE_TABLE, null, initialValues);
}
// This method will delete game.
// #param rowId
// #return boolean
public static boolean deleteGame(long rowId) {
return mDb.delete(DATABASE_TABLE, KEY_ROWID + "=" + rowId, null) > 0;
}
// This method will return Cursor holding all the games.
// #return Cursor
public Cursor fetchAllGames() {
return mDb.query(DATABASE_TABLE, new String[] {KEY_ROWID, KEY_NAME,
KEY_GENRE}, null, null, null, null, null);
}
// This method will return Cursor holding the specific game.
// #param id
// #return Cursor
// #throws SQLException
public Cursor fetchGame(long id) throws SQLException {
Cursor mCursor =
mDb.query(true, DATABASE_TABLE, new String[] {KEY_ROWID,
KEY_NAME, KEY_GENRE}, KEY_ROWID + "=" + id, null,
null, null, null, null);
if (mCursor != null) {
mCursor.moveToFirst();
}
return mCursor;
}
public int getAllEntries()
{
Cursor cursor = mDb.rawQuery(
"SELECT COUNT(name) FROM game_list", null);
if(cursor.moveToFirst()) {
return cursor.getInt(0);
}
return cursor.getInt(0);
}
public String getRandomEntry()
{
//id = getAllEntries();
Random random = new Random();
int rand = random.nextInt(getAllEntries());
if(rand == 0)
++rand;
Cursor cursor = mDb.rawQuery(
"SELECT name FROM game_list WHERE _id = " + rand, null);
if(cursor.moveToFirst()) {
return cursor.getString(0);
}
return cursor.getString(0);
}
// This method will update game.
// #param id
// #param name
// #param standard
// #return boolean
public boolean updateGame(int id, String name, String standard) {
ContentValues args = new ContentValues();
args.put(KEY_NAME, name);
args.put(KEY_GENRE, standard);
return mDb.update(DATABASE_TABLE, args, KEY_ROWID + "=" + id, null) > 0;
}
}
And here is the cause part of the error log:
08-01 13:03:38.325: E/AndroidRuntime(278): Caused by: android.database.CursorIndexOutOfBoundsException: Index 0 requested, with a size of 0
08-01 13:03:38.325: E/AndroidRuntime(278): at android.database.AbstractCursor.checkPosition(AbstractCursor.java:580)
08-01 13:03:38.325: E/AndroidRuntime(278): at android.database.AbstractWindowedCursor.checkPosition(AbstractWindowedCursor.java:214)
08-01 13:03:38.325: E/AndroidRuntime(278): at android.database.AbstractWindowedCursor.getString(AbstractWindowedCursor.java:41)
08-01 13:03:38.325: E/AndroidRuntime(278): at com.example.randomgamechooser.GameList.getRandomEntry(GameList.java:153)
EDIT: Here is the ListView class:
public class GameSelction extends Activity
{
GameList dbUtil = new GameList(this);
private SimpleCursorAdapter dataAdapter;
//#SuppressWarnings("deprecation")
#SuppressLint("NewApi")
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_game_selction);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB){
getActionBar() .setDisplayHomeAsUpEnabled(true);
}
displayListView();
}
private void displayListView() {
dbUtil.open();
Cursor cursor = dbUtil.fetchAllGames();
// The desired columns to be bound
String[] columns = new String[] {
GameList.KEY_NAME,
GameList.KEY_GENRE,
};
// the XML defined views which the data will be bound to
int[] to = new int[] {
R.id.name,
R.id.genre,
};
// create the adapter using the cursor pointing to the desired data
//as well as the layout information
dataAdapter = new SimpleCursorAdapter(
this, R.layout.game_info,
cursor,
columns,
to,
0);
ListView listView = (ListView) findViewById(R.id.listView1);
// Assign adapter to ListView
listView.setAdapter(dataAdapter);
listView.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> listView, View view,
int position, long rowId) {
// Get the cursor, positioned to the corresponding row in the result set
//Cursor cursor = (Cursor) listView.getItemAtPosition(position);
GameList.deleteGame(rowId);
}
});
}
/**
* Set up the {#link android.app.ActionBar}, if the API is available.
*/
#TargetApi(Build.VERSION_CODES.HONEYCOMB)
private void setupActionBar() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
getActionBar().setDisplayHomeAsUpEnabled(true);
}
}
//opens the AddGame activity
public void openAddgame (View view) {
Intent intent = new Intent(this, AddGame.class);
startActivity(intent);
}
public void buttonBackMain (View view) {
Intent intent = new Intent(this, MainScreen.class);
startActivity(intent);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.game_selction, menu);
return true;
}
}
The problem is in this section of code:
public String getRandomEntry()
{
//...
Cursor cursor = mDb.rawQuery(
"SELECT name FROM game_list WHERE _id = " + rand, null);
if(cursor.moveToFirst()) {
return cursor.getString(0);
}
return cursor.getString(0);
}
What you ended up doing was saying return cursor.getString(0); whether or not there were results in the cursor. So remove the second occurrence, and it should work.
EDIT:
After scanning your code, it seems that the only place you use this method is to fill a TextView. In that case you can use this as a chance to communicate a visual error message to yourself or your users, or do anything else with it that you want. So I would suggest using something to the effect of
public String getRandomEntry()
{
//EDIT: This will make your random generator less biased toward 1.
Random random = new Random();
int rand = random.nextInt(getAllEntries()) + 1;
/* Assuming your _id starts at 1 and auto-increments, this will
* start the random digits at 1 and go as high as your highest _id */
Cursor cursor = mDb.rawQuery(
"SELECT name FROM game_list WHERE _id = " + rand, null);
if(cursor.moveToFirst()) {
return cursor.getString(0);
}
return "There were no games in the database to choose from.";
}
EDIT:
Try using this. Notice that this code uses mDb.query(), which you used elsewhere. I'm not sure why rawQuery() would refuse to work, but maybe this will do it.
public String getRandomEntry()
{
Random random = new Random();
int rand = random.nextInt(getAllEntries()) + 1;
Cursor cursor = mDb.query(true, DATABASE_TABLE, new String[] {KEY_NAME},
KEY_ROWID + "=" + rand, null, null, null, null, null);
if(cursor.moveToFirst()) {
return cursor.getString(0);
}
return "There were no games in the database to choose from.";
}
Based on the initial look, the SQLiteDatabase object represented by mDB appears to be empty, as that's what is throwing the error.
What the error is saying is that your code is requesting the item at index 0 (basically, the first item), but the size of your index is 0 (basically, there are no items in the index).
Somewhere along the line, your database object is either emptied or not populated. To test this, run your fetchAllGames method and verify the contents of the index.
Didn't read the whole code, but I guess the problem is that, you are trying to get first element, from empty database.
Just check if the size of cursor greater than 0, before getting element.
if (cursor.getColumnCount() > 0)
return cursor.getString(0);
else return "no items";
Related
I want all edit text content that I have saved in SQL to be displayed on the edit bills activity when I click on the list item, but I am only able to retrieve the name and display it again in the intent. Rather than saving another data it should update the record with the new data if I save the existing record another time in the editbills_activity.
Here is my DBAdapter.java
package com.example.dhruv.bills;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.util.Log;
public class DBAdapter {
public static final String KEY_ROWID = "id";
public static final String KEY_NAME = "name";
public static final String KEY_AMOUNT = "amount";
public static final String KEY_DUEDATE = "duedate";
private static final String TAG = "DBAdapter";
private static final String DATABASE_NAME = "billsdb";
private static final String DATABASE_TABLE = "bills";
private static final int DATABASE_VERSION = 2;
private static final String DATABASE_CREATE =
"create table if not exists assignments (id integer primary key autoincrement, "
+ "name VARCHAR not null, amount VARCHAR, duedate date );";
// Replaces DATABASE_CREATE using the one source definition
private static final String TABLE_CREATE =
"CREATE TABLE IF NOT EXISTS " + DATABASE_TABLE + "(" +
KEY_ROWID + " INTEGER PRIMARY KEY, " + // AUTOINCREMENT NOT REQD
KEY_NAME + " DATE NOT NULL, " +
KEY_AMOUNT + " VARCHAR ," +
KEY_DUEDATE + " DATE " +
")";
private final Context context;
private DatabaseHelper DBHelper;
private SQLiteDatabase db;
public DBAdapter(Context ctx)
{
this.context = ctx;
DBHelper = new DatabaseHelper(context);
}
private static class DatabaseHelper extends SQLiteOpenHelper
{
DatabaseHelper(Context context)
{
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
#Override
public void onCreate(SQLiteDatabase db)
{
db.execSQL(TABLE_CREATE); // NO need to encapsulate in try clause
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion)
{
Log.w(TAG, "Upgrading database from version " + oldVersion + " to "
+ newVersion + ", which will destroy all old data");
db.execSQL("DROP TABLE IF EXISTS contacts"); //????????
db.execSQL("DROP TABLE IF EXISTS " + DATABASE_TABLE);
onCreate(db);
}
}
//---opens the database---
public DBAdapter open() throws SQLException
{
db = DBHelper.getWritableDatabase();
return this;
}
//---closes the database---
public void close()
{
DBHelper.close();
}
//---insert a record into the database---
public long insertRecord(String name, String amount, String duedate)
{
ContentValues initialValues = new ContentValues();
initialValues.put(KEY_NAME, name);
initialValues.put(KEY_AMOUNT, amount);
initialValues.put(KEY_DUEDATE, duedate);
//return db.insert(DATABASE_TABLE, null, initialValues);
// Will return NULL POINTER EXCEPTION as db isn't set
// Replaces commented out line
return DBHelper.getWritableDatabase().insert(DATABASE_TABLE,
null,
initialValues
);
}
//---deletes a particular record---
public boolean deleteContact(long rowId)
{
return db.delete(DATABASE_TABLE, KEY_ROWID + "=" + rowId, null) > 0;
}
//---retrieves all the records--- SEE FOLLOWING METHOD
public Cursor getAllRecords()
{SQLiteDatabase db = DBHelper.getWritableDatabase();
String query ="SELECT * FROM " + DATABASE_TABLE;
Cursor data = db.rawQuery(query,null);
return data;
}
//As per getAllRecords but using query convenience method
public Cursor getAllAsCursor() {
return DBHelper.getWritableDatabase().query(
DATABASE_TABLE,
null,null,null,null,null,null
);
}
public Cursor getItemID(String name) {
SQLiteDatabase db = DBHelper.getWritableDatabase();
String query = "SELECT " + KEY_ROWID + " FROM " + DATABASE_TABLE +
" WHERE " + KEY_NAME + " = '" + name + "'";
Cursor data = db.rawQuery(query, null);
return data;
}
//---retrieves a particular record--- THIS WILL NOT WORK - NO SUCH TABLE
/* public Cursor getRecord()
{String query1 ="SELECT * FROM" + KEY_TITLE;
Cursor mCursor = db.rawQuery(query1,null);
if (mCursor != null) {
mCursor.moveToFirst();
}
return mCursor;
}*/
// Retrieve a row (single) according to id
public Cursor getRecordById(long id) {
return DBHelper.getWritableDatabase().query(
DATABASE_TABLE,
null,
KEY_ROWID + "=?",
new String[]{String.valueOf(id)},
null,null,null
);
}
//---updates a record---
/* public boolean updateRecord(long rowId, String name, String amount, String duedate)
{
ContentValues args = new ContentValues();
args.put(KEY_NAME, name);
args.put(KEY_AMOUNT, amount);
args.put(KEY_DUEDATE, duedate);
String whereclause = KEY_ROWID + "=?";
String[] whereargs = new String[]{String.valueOf(rowId)};
// Will return NULL POINTER EXCEPTION as db isn't set
//return db.update(DATABASE_TABLE, args, KEY_ROWID + "=" + rowId, null) > 0;
// Replaces commented out line
return DBHelper.getWritableDatabase().update(DATABASE_TABLE,
args,
whereclause,
whereargs
) > 0;
}*/
}
Here is my Bills.java
(MainActivity)
Problem: Bills.java has the list view that shows the intent whenever the item in list view is clicked, but it does not put the amount and date or update the record. Instead it saves another record.
Solution: I want to retrieve it and display all (name ,amount,duedate) and instead of saving another record it should update it.
package com.example.dhruv.bills;
import android.content.Intent;
import android.database.Cursor;
import android.os.Bundle;
import android.support.design.widget.FloatingActionButton;
import android.support.design.widget.Snackbar;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.Toolbar;
import android.util.Log;
import android.view.View;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ListAdapter;
import android.widget.ListView;
import android.widget.Toast;
import java.util.ArrayList;
public class bills extends AppCompatActivity {
DBAdapter dbAdapter;
ListView mrecycleview;
private static final String TAG ="assignments";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_bills);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
mrecycleview =(ListView) findViewById(R.id.mRecycleView);
dbAdapter = new DBAdapter(this);
// mlistview();
FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent i = new Intent(getApplicationContext(),Editbills.class);
startActivity(i);
}
});
mlistview();
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_bills, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
private void mlistview(){
Log.d(TAG,"mlistview:Display data in listview");
Cursor mCursor = dbAdapter.getAllRecords();
ArrayList<String> listData = new ArrayList<>();
while (mCursor.moveToNext()){
listData.add(mCursor.getString(1));
}
ListAdapter adapter = new ArrayAdapter<>(this,android.R.layout.simple_list_item_1,listData);
mrecycleview.setAdapter(adapter);
mrecycleview.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
String name = adapterView.getItemAtPosition(i).toString();
Log.d(TAG, "onItemClick: You Clicked on " + name);
Cursor data = dbAdapter.getItemID(name); //get the id associated with that name
int itemID = -1;
while(data.moveToNext()){
itemID = data.getInt(0);
}
if(itemID > -1){
Log.d(TAG, "onItemClick: The ID is: " + itemID);
Intent editScreenIntent = new Intent(bills.this, Editbills.class);
editScreenIntent.putExtra("id",itemID);
editScreenIntent.putExtra("name",name);
startActivity(editScreenIntent);
}
else{
}
}
});
}
}
here is my editbills.java code
package com.example.dhruv.bills;
import android.content.ContentValues;
import android.content.Intent;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.Toast;
import java.util.ArrayList;
public class Editbills extends AppCompatActivity {
Button button;
private static final String Tag= "assignments";
DBAdapter db = new DBAdapter(this);
private String selectedName;
private int selectedID;
DBAdapter dbAdapter;
private EditText editText,editText2,editText3;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_editbills);
button=(Button)findViewById(R.id.button);
editText =(EditText)findViewById(R.id.editText);
editText2=(EditText)findViewById(R.id.editText2);
editText3 =(EditText)findViewById(R.id.editText3);
//get the intent extra from the ListDataActivity
Intent receivedIntent = getIntent();
//now get the itemID we passed as an extra
selectedID = receivedIntent.getIntExtra("id",-1); //NOTE: -1 is just the default value
//now get the name we passed as an extra
selectedName = receivedIntent.getStringExtra("name");
//set the text to show the current selected name
editText.setText(selectedName);
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Log.d("test", "adding");
db.open();
long id = db.insertRecord(editText.getText().toString(), editText2.getText().toString(), editText3.getText().toString());
db.close();
Toast.makeText(Editbills.this," Added", Toast.LENGTH_LONG).show();
Intent q = new Intent(getApplicationContext(),bills.class);
startActivity(q);
}
});
}
}
There are two parts/questions.
First to retrieve the data, so that it can be displayed in the editbills activity, you can utilise the row's id that is passed to the activity in conjunction with the getRecordById method.
I'd suggest that adding a method to the editbills class will simplyfy matters.
private void populateDisplay(int id) {
Cursor csr = dbAdapter.getRecordById(id);
if (csr.moveToFirst()) {
editText.setText(csr.getString(csr.getColumnIndex(DBAdapter.KEY_NAME)));
editText2.setText(csr.getString(csr.getColumnIndex(DBAdapter.KEY_AMOUNT)));
editText3.setText(csr.getString(csr.getColumnIndex(DBAdapter.KEY_DUEDATE)));
}
csr.close();
}
You could invoke the above method after retrieving the id from the Intent using :-
populateDisplay(selectedID);
To update based upon the content's of the EditTexts un-comment the updateRecord method in DBAdapter.java and the change :-
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Log.d("test", "adding");
db.open();
long id = db.insertRecord(editText.getText().toString(), editText2.getText().toString(), editText3.getText().toString());
db.close();
Toast.makeText(Editbills.this," Added", Toast.LENGTH_LONG).show();
Intent q = new Intent(getApplicationContext(),bills.class);
startActivity(q);
}
});
to :-
mButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (dbAdapter.updateRecord(
selectedId,
editText.getText().toString(),
editText2.getText().toString(),
editText3.getText().toString())
) {
Log.d("TEST","Row successfully updated.");
Toast.makeText(getApplicationContext(),"Row Updated.",Toast.LENGTH_LONG).show();
populateDisplay(selectedId);
} else {
Toast.makeText(getApplicationContext(),"Row not Updated",Toast.LENGTH_LONG).show();
}
Intent q = new Intent(getApplicationContext(),bills.class);
startActivity(q);
}
});
You will additionally have to add a line initialise the dbAdapter i.e. dbAdapter = new DBAdapter(this); i.d suggest adding this line immediately after the line setContentView(R.layout.activity_editbills);
Note the above code is in-principle and has not been thoroughly tested so it may contains errors.
Edit complete working example :-
The following code is basically an implementation of the above, except modified to utilise a Bill class. Rather than an ArrayList<String> as the source for the Adapter it has ArrayList<Bill>.
Thus all the data (id, name, amount and duedate) is available.
You should notice that I've overridden the toString method to return a String that combines the name, amount and duedate. The ArrayAdapter uses the object's toString method to populate the view.
Saying that the critical value is the rowid or an alias of rowid as this can be used to identify a row even if the other data is identical (as would happen when running this example more than once due to the addSomeData method). Hence, only the id is extracted and passed to the Editbills activity when an item in the list is long clicked (changed from just clicked to reduce the potential for accidental use).
Bill.java
public class Bill {
private long id;
private String name;
private String amount;
private String duedate;
public Bill(long id, String name, String amount, String duedate) {
this.id = id;
this.name = name;
this.amount = amount;
this.duedate = duedate;
}
/*
Note if this Constructor used then setId should be used
*/
public Bill(String name, String amount, String duedate) {
new Bill(0,name,amount,duedate);
}
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAmount() {
return amount;
}
public void setAmount(String amount) {
this.amount = amount;
}
public String getDuedate() {
return duedate;
}
public void setDuedate(String duedate) {
this.duedate = duedate;
}
/*
As ArrayAdapter uses toString method change this
to return all items
*/
#Override
public String toString() {
return name + " " + amount + " " + duedate;
}
}
MainActivity.java
This is the equivalent to your Bills.java without a lot of the bloat such as FAB. :-
public class MainActivity extends AppCompatActivity {
public static final String ID_INTENTEXTRA = DBAdapter.KEY_ROWID + "_INTENTEXTRA"; //<<<< ADDED
DBAdapter mDBAdapter;
Cursor mCsr;
ListView mrecycleview;
ArrayAdapter adapter; //<<<< NOT ListAdapter
Context context; // ADDED
private static final String TAG ="assignments";
ArrayList<Bill> mBillList = new ArrayList<>();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
context = this;
mrecycleview = this.findViewById(R.id.mRecycleView);
mDBAdapter = new DBAdapter(this);
addSomeData();
adapter = new ArrayAdapter<Bill>(
this,
android.R.layout.simple_list_item_1,
mBillList
);
mrecycleview.setAdapter(adapter);
mrecycleview.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
#Override
public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {
Bill b = (Bill) adapter.getItem(position);
Intent i = new Intent(context,Editbills.class);
i.putExtra(ID_INTENTEXTRA,b.getId()); //Get ID
startActivity(i);
return true;
}
});
rebuildBillList();
}
//<<<< ADDED Method to refresh the ListView resumed
#Override
protected void onResume() {
super.onResume();
rebuildBillList();
}
// Add some data (note will add 2 rows each time it is run)
private void addSomeData() {
mDBAdapter.insertRecord("Bill1","2018-10-02","English");
mDBAdapter.insertRecord("Bill2","2018-09-03","Mathematics");
mDBAdapter.insertRecord("Bill3","2018-11-04", "Geography");
}
public void rebuildBillList() {
mBillList.clear();
mCsr = mDBAdapter.getAllAsCursor();
while (mCsr.moveToNext()) {
mBillList.add(new Bill(
mCsr.getLong(mCsr.getColumnIndex(DBAdapter.KEY_ROWID)),
mCsr.getString(mCsr.getColumnIndex(DBAdapter.KEY_NAME)),
mCsr.getString(mCsr.getColumnIndex(DBAdapter.KEY_AMOUNT)),
mCsr.getString(mCsr.getColumnIndex(DBAdapter.KEY_DUEDATE))
)
);
}
adapter.notifyDataSetChanged();
}
}
Note the above adds 3 rows each time it is run.
Editbills.java
public class Editbills extends AppCompatActivity {
Button button;
private static final String Tag = "assignments";
DBAdapter db = new DBAdapter(this);
private String selectedName;
private long selectedID;
DBAdapter dbAdapter;
private EditText editText,editText2,editText3;
Context context;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_editbills);
context = this;
dbAdapter = new DBAdapter(this); //<<<< ADDED
button=(Button)findViewById(R.id.button);
editText =(EditText)findViewById(R.id.edittext);
editText2=(EditText)findViewById(R.id.edittext2);
editText3 =(EditText)findViewById(R.id.edittext3);
//get the intent extra from the ListDataActivity
Intent receivedIntent = getIntent();
//now get the itemID we passed as an extra
selectedID = receivedIntent.getLongExtra(MainActivity.ID_INTENTEXTRA,-1L); //NOTE: -1 is just the default value
populateDisplay(selectedID);
//now get the name we passed as an extra
//selectedName = receivedIntent.getStringExtra("name");
//set the text to show the current selected name
//editText.setText(selectedName); <<<< commented out
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
/*
Log.d("test", "adding");
db.open();
long id = db.insertRecord(editText.getText().toString(), editText2.getText().toString(), editText3.getText().toString());
db.close();
Toast.makeText(Editbills.this," Added", Toast.LENGTH_LONG).show();
*/
/*
* <<<< Not the way as it ends/closes the existing activity
Intent q = new Intent(getApplicationContext(),MainActivity.class);
startActivity(q);
*/
String toast = "Updated.";
if (dbAdapter.updateRecord(selectedID,
editText.getText().toString(),
editText2.getText().toString(),
editText3.getText().toString())) {
} else {
toast = "Not Updated.";
}
Toast.makeText(context,toast,Toast.LENGTH_LONG).show();
finish(); //<<<< ends/closes this activity and returns to calling activity
}
});
}
private void populateDisplay(long id) {
Cursor csr = dbAdapter.getRecordById(id);
if (csr.moveToFirst()) {
editText.setText(csr.getString(csr.getColumnIndex(DBAdapter.KEY_NAME)));
editText2.setText(csr.getString(csr.getColumnIndex(DBAdapter.KEY_AMOUNT)));
editText3.setText(csr.getString(csr.getColumnIndex(DBAdapter.KEY_DUEDATE)));
}
csr.close();
}
}
Basically as per the original answer.
DBAdapter.java
public class DBAdapter {
public static final String KEY_ROWID = "id";
public static final String KEY_NAME = "name";
public static final String KEY_AMOUNT = "amount";
public static final String KEY_DUEDATE = "duedate";
private static final String TAG = "DBAdapter";
private static final String DATABASE_NAME = "billsdb";
private static final String DATABASE_TABLE = "bills";
private static final int DATABASE_VERSION = 2;
// Replaces DATABASE_CREATE using the one source definition
private static final String TABLE_CREATE =
"CREATE TABLE IF NOT EXISTS " + DATABASE_TABLE + "(" +
KEY_ROWID + " INTEGER PRIMARY KEY, " + // AUTOINCREMENT NOT REQD
KEY_NAME + " DATE NOT NULL, " +
KEY_AMOUNT + " VARCHAR ," +
KEY_DUEDATE + " DATE " +
")";
private Context context;
private DatabaseHelper DBHelper;
private SQLiteDatabase db;
public DBAdapter(Context ctx)
{
this.context = ctx;
DBHelper = new DatabaseHelper(context);
}
private static class DatabaseHelper extends SQLiteOpenHelper
{
DatabaseHelper(Context context)
{
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
#Override
public void onCreate(SQLiteDatabase db)
{
db.execSQL(TABLE_CREATE); // NO need to encapsulate in try clause
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion)
{
Log.w(TAG, "Upgrading database from version " + oldVersion + " to "
+ newVersion + ", which will destroy all old data");
db.execSQL("DROP TABLE IF EXISTS contacts"); //????????
db.execSQL("DROP TABLE IF EXISTS " + DATABASE_TABLE);
onCreate(db);
}
}
//---opens the database--- NOT NEEDED
public DBAdapter open() throws SQLException
{
db = DBHelper.getWritableDatabase();
return this;
}
//---closes the database--- NOT NEEDED
public void close()
{
DBHelper.close();
}
//---insert a record into the database---
public long insertRecord(String name, String amount, String duedate)
{
ContentValues initialValues = new ContentValues();
initialValues.put(KEY_NAME, name);
initialValues.put(KEY_AMOUNT, amount);
initialValues.put(KEY_DUEDATE, duedate);
return DBHelper.getWritableDatabase().insert(DATABASE_TABLE,
null,
initialValues
);
}
//---deletes a particular record---
public boolean deleteContact(long rowId)
{
return db.delete(DATABASE_TABLE, KEY_ROWID + "=" + rowId, null) > 0;
}
//---retrieves all the records--- SEE FOLLOWING METHOD
public Cursor getAllRecords()
{SQLiteDatabase db = DBHelper.getWritableDatabase();
String query ="SELECT * FROM " + DATABASE_TABLE;
Cursor data = db.rawQuery(query,null);
return data;
}
//As per getAllRecords but using query convenience method
public Cursor getAllAsCursor() {
return DBHelper.getWritableDatabase().query(
DATABASE_TABLE,
null,null,null,null,null,null
);
}
public Cursor getItemID(String name) {
SQLiteDatabase db = DBHelper.getWritableDatabase();
String query = "SELECT " + KEY_ROWID + " FROM " + DATABASE_TABLE +
" WHERE " + KEY_NAME + " = '" + name + "'";
Cursor data = db.rawQuery(query, null);
return data;
}
// Retrieve a row (single) according to id
public Cursor getRecordById(long id) {
return DBHelper.getWritableDatabase().query(
DATABASE_TABLE,
null,
KEY_ROWID + "=?",
new String[]{String.valueOf(id)},
null,null,null
);
}
//---updates a record---
public boolean updateRecord(long rowId, String name, String amount, String duedate) {
ContentValues args = new ContentValues();
args.put(KEY_NAME, name);
args.put(KEY_AMOUNT, amount);
args.put(KEY_DUEDATE, duedate);
String whereclause = KEY_ROWID + "=?";
String[] whereargs = new String[]{String.valueOf(rowId)};
return DBHelper.getWritableDatabase().update(DATABASE_TABLE,
args,
whereclause,
whereargs
) > 0;
}
}
Basically as was except that upDateRecord has been un-commented, again as per the original answer.
Results
1st Run - MainActivity (Bills) :-
Long Click Bill2 (note changed from Click as Long Click is less prone to accidental use)
Change data (Update button not clicked)
Update Button Clicked (Toast was Updated.)
Note use of finish() to return to the invoking activity and then the use of onResume to refresh the list according to the updated data (possibly your next question).
using startActivity will simply result in issues.
Note Values are date and course rather then amount and duedate because I didn't change the values in the addSomeData method (easily done).
the actual data itself is irrelevant to the process.
hi I want to remove(delete) an item from listview from a second activity which I previously saved from another activity. I found similar question on deleting row from database but I think there is a little bit change in my database and the one's given in other questions and answers. here is my code.
the activity from where I am saving and deleting the row. here I want to delete the row from listview.
case R.id.id_favorit:
// Add it to the DB and re-draw the ListView
myDb.insertRow("Atherosclerosis", 0, "");
Toast.makeText(getApplicationContext(), "Item Added to favorite list!", Toast.LENGTH_SHORT).show();
favClicked=true;
editor.putBoolean("menu_item", favClicked);
editor.commit();
invalidateOptionsMenu();
return true;
case R.id.id_favorit2:
myDb.deleteRow(??);
Toast.makeText(getApplicationContext(), "Item deleted from favorite list!", Toast.LENGTH_SHORT).show();
favClicked=false;
editor.putBoolean("menu_item", favClicked);
editor.commit();
invalidateOptionsMenu();
return super.onOptionsItemSelected(item);
}
return true;
}
here is my database
public class DBAdapter {
/////////////////////////////////////////////////////////////////////
// Constants & Data
/////////////////////////////////////////////////////////////////////
// For logging:
private static final String TAG = "DBAdapter";
// DB Fields
public static final String KEY_ROWID = "_id";
public static final int COL_ROWID = 0;
/*
* CHANGE 1:
*/
// TODO: Setup your fields here:
public static final String KEY_NAME = "name";
public static final String KEY_STUDENTNUM = "studentnum";
public static final String KEY_FAVCOLOUR = "favcolour";
// TODO: Setup your field numbers here (0 = KEY_ROWID, 1=...)
public static final int COL_NAME = 1;
public static final int COL_STUDENTNUM = 2;
public static final int COL_FAVCOLOUR = 3;
public static final String[] ALL_KEYS = new String[] {KEY_ROWID, KEY_NAME, KEY_STUDENTNUM, KEY_FAVCOLOUR};
// DB info: it's name, and the table we are using (just one).
public static final String DATABASE_NAME = "MyDb";
public static final String DATABASE_TABLE = "mainTable";
// Track DB version if a new version of your app changes the format.
public static final int DATABASE_VERSION = 2;
private static final String DATABASE_CREATE_SQL =
"create table " + DATABASE_TABLE
+ " (" + KEY_ROWID + " integer primary key autoincrement, "
/*
* CHANGE 2:
*/
// TODO: Place your fields here!
// + KEY_{...} + " {type} not null"
// - Key is the column name you created above.
// - {type} is one of: text, integer, real, blob
// (http://www.sqlite.org/datatype3.html)
// - "not null" means it is a required field (must be given a value).
// NOTE: All must be comma separated (end of line!) Last one must have NO comma!!
+ KEY_NAME + " text not null, "
+ KEY_STUDENTNUM + " integer not null, "
+ KEY_FAVCOLOUR + " string not null"
// Rest of creation:
+ ");";
// Context of application who uses us.
private final Context context;
private DatabaseHelper myDBHelper;
private SQLiteDatabase db;
/////////////////////////////////////////////////////////////////////
// Public methods:
/////////////////////////////////////////////////////////////////////
public DBAdapter(Context ctx) {
this.context = ctx;
myDBHelper = new DatabaseHelper(context);
}
// Open the database connection.
public DBAdapter open() {
db = myDBHelper.getWritableDatabase();
return this;
}
// Close the database connection.
public void close() {
myDBHelper.close();
}
// Add a new set of values to the database.
#SuppressLint("NewApi")
public long insertRow(String name, int studentNum, String favColour) {
Cursor c= db.query(true, DATABASE_TABLE, ALL_KEYS, KEY_NAME + "='" + name +"'", null, null, null, null, null, null);
if(c.getCount()>0){
return -1;
}
c.close();
/*
* CHANGE 3:
*/
// TODO: Update data in the row with new fields.
// TODO: Also change the function's arguments to be what you need!
// Create row's data:
ContentValues initialValues = new ContentValues();
initialValues.put(KEY_NAME, name);
initialValues.put(KEY_STUDENTNUM, studentNum);
initialValues.put(KEY_FAVCOLOUR, favColour);
// Insert it into the database.
return db.insert(DATABASE_TABLE, null, initialValues);
}
// Delete a row from the database, by rowId (primary key)
public boolean deleteRow(long rowId) {
String where = KEY_ROWID + "=" + rowId;
return db.delete(DATABASE_TABLE, where, null) != 0;
}
public void deleteAll() {
Cursor c = getAllRows();
long rowId = c.getColumnIndexOrThrow(KEY_ROWID);
if (c.moveToFirst()) {
do {
deleteRow(c.getLong((int) rowId));
} while (c.moveToNext());
}
c.close();
}
// Return all data in the database.
#SuppressLint("NewApi")
public Cursor getAllRows() {
String where = null;
Cursor c = db.query(true, DATABASE_TABLE, ALL_KEYS,
where, null, null, null, KEY_ROWID + " DESC", null, null);
if (c != null) {
c.moveToFirst();
}
return c;
}
// Get a specific row (by rowId)
public Cursor getRow(long rowId) {
String where = KEY_ROWID + "=" + rowId;
Cursor c = db.query(true, DATABASE_TABLE, ALL_KEYS,
where, null, null, null, null, null);
if (c != null) {
c.moveToFirst();
}
return c;
}
// Change an existing row to be equal to new data.
public boolean updateRow(long rowId, String name, int studentNum, String favColour) {
String where = KEY_ROWID + "=" + rowId;
/*
* CHANGE 4:
*/
// TODO: Update data in the row with new fields.
// TODO: Also change the function's arguments to be what you need!
// Create row's data:
ContentValues newValues = new ContentValues();
newValues.put(KEY_NAME, name);
newValues.put(KEY_STUDENTNUM, studentNum);
newValues.put(KEY_FAVCOLOUR, favColour);
// Insert it into the database.
return db.update(DATABASE_TABLE, newValues, where, null) != 0;
}
/////////////////////////////////////////////////////////////////////
// Private Helper Classes:
/////////////////////////////////////////////////////////////////////
/**
* Private class which handles database creation and upgrading.
* Used to handle low-level database access.
*/
private static class DatabaseHelper extends SQLiteOpenHelper
{
DatabaseHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
#Override
public void onCreate(SQLiteDatabase _db) {
_db.execSQL(DATABASE_CREATE_SQL);
}
#Override
public void onUpgrade(SQLiteDatabase _db, int oldVersion, int newVersion) {
Log.w(TAG, "Upgrading application's database from version " + oldVersion
+ " to " + newVersion + ", which will destroy all old data!");
// Destroy old database:
_db.execSQL("DROP TABLE IF EXISTS " + DATABASE_TABLE);
// Recreate new database:
onCreate(_db);
}
}
}
and now my listview another activity
private void populateListViewFromDB() {
Cursor cursor = myDb.getAllRows();
// Allow activity to manage lifetime of the cursor.
// DEPRECATED! Runs on the UI thread, OK for small/short queries.
startManagingCursor(cursor);
// Setup mapping from cursor to view fields:
String[] fromFieldNames = new String[]
{DBAdapter.KEY_NAME, DBAdapter.KEY_STUDENTNUM};
int[] toViewIDs = new int[]
{R.id.item_name};
// Create adapter to may columns of the DB onto elemesnt in the UI.
SimpleCursorAdapter myCursorAdapter =
new SimpleCursorAdapter(
this, // Context
R.layout.item_layout, // Row layout template
cursor, // cursor (set of DB records to map)
fromFieldNames, // DB Column names
toViewIDs // View IDs to put information in
);
// Set the adapter for the list view
ListView myList = (ListView) findViewById(R.id.favlistView1);
myList.setAdapter(myCursorAdapter);
}
private void registerListClickCallback() {
ListView myList = (ListView) findViewById(R.id.favlistView1);
//This code is for to delete the single item from the listview of favorite list
myList.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
#Override
public boolean onItemLongClick(AdapterView<?> arg0, View arg1,
int arg2, final long arg3) {
Cursor cursor = myDb.getRow(arg3);
if (cursor.moveToFirst()) {
new AlertDialog.Builder(FavoriteDiseases.this)
.setTitle("Delete Item")
.setMessage("Do you want to delete this disease?")
.setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
// continue with delete
myDb.deleteRow(arg3);
populateListViewFromDB();
}
})
.setNegativeButton(android.R.string.no, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
// do nothing
}
})
.show();
}
return true;
}
});
If you use LoaderManager and CursorLoader to load your data from the database, it will update the cursor, and you can update your ListView automatically when the database changes. Here is a link: Loaders
Hi Stackoverflow members i created an app where user can add favorite items to the favorite list. but the problem i am facing is that when i click on add to favorite button, the item adds to the bottom of the list and not on the top.
Second when i click the same item add to favorite item many time, this add the item multiple time and not just only one time. how can i add it to the list just only one time and not multiple time.
here is my code for activity and database.
My DBAdapter.class
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.util.Log;
// TO USE:
// Change the package (at top) to match your project.
// Search for "TODO", and make the appropriate changes.
public class DBAdapter {
/////////////////////////////////////////////////////////////////////
// Constants & Data
/////////////////////////////////////////////////////////////////////
// For logging:
private static final String TAG = "DBAdapter";
// DB Fields
public static final String KEY_ROWID = "_id";
public static final int COL_ROWID = 0;
/*
* CHANGE 1:
*/
// TODO: Setup your fields here:
public static final String KEY_NAME = "name";
public static final String KEY_STUDENTNUM = "studentnum";
public static final String KEY_FAVCOLOUR = "favcolour";
// TODO: Setup your field numbers here (0 = KEY_ROWID, 1=...)
public static final int COL_NAME = 1;
public static final int COL_STUDENTNUM = 2;
public static final int COL_FAVCOLOUR = 3;
public static final String[] ALL_KEYS = new String[] {KEY_ROWID, KEY_NAME, KEY_STUDENTNUM, KEY_FAVCOLOUR};
// DB info: it's name, and the table we are using (just one).
public static final String DATABASE_NAME = "MyDb";
public static final String DATABASE_TABLE = "mainTable";
// Track DB version if a new version of your app changes the format.
public static final int DATABASE_VERSION = 2;
private static final String DATABASE_CREATE_SQL =
"create table " + DATABASE_TABLE
+ " (" + KEY_ROWID + " integer primary key autoincrement, "
/*
* CHANGE 2:
*/
// TODO: Place your fields here!
// + KEY_{...} + " {type} not null"
// - Key is the column name you created above.
// - {type} is one of: text, integer, real, blob
// (http://www.sqlite.org/datatype3.html)
// - "not null" means it is a required field (must be given a value).
// NOTE: All must be comma separated (end of line!) Last one must have NO comma!!
+ KEY_NAME + " text not null, "
+ KEY_STUDENTNUM + " integer not null, "
+ KEY_FAVCOLOUR + " string not null"
// Rest of creation:
+ ");";
// Context of application who uses us.
private final Context context;
private DatabaseHelper myDBHelper;
private SQLiteDatabase db;
/////////////////////////////////////////////////////////////////////
// Public methods:
/////////////////////////////////////////////////////////////////////
public DBAdapter(Context ctx) {
this.context = ctx;
myDBHelper = new DatabaseHelper(context);
}
// Open the database connection.
public DBAdapter open() {
db = myDBHelper.getWritableDatabase();
return this;
}
// Close the database connection.
public void close() {
myDBHelper.close();
}
// Add a new set of values to the database.
public long insertRow(String name, int studentNum, String favColour) {
/*
* CHANGE 3:
*/
// TODO: Update data in the row with new fields.
// TODO: Also change the function's arguments to be what you need!
// Create row's data:
ContentValues initialValues = new ContentValues();
initialValues.put(KEY_NAME, name);
initialValues.put(KEY_STUDENTNUM, studentNum);
initialValues.put(KEY_FAVCOLOUR, favColour);
// Insert it into the database.
return db.insert(DATABASE_TABLE, null, initialValues);
}
// Delete a row from the database, by rowId (primary key)
public boolean deleteRow(long rowId) {
String where = KEY_ROWID + "=" + rowId;
return db.delete(DATABASE_TABLE, where, null) != 0;
}
public void deleteAll() {
Cursor c = getAllRows();
long rowId = c.getColumnIndexOrThrow(KEY_ROWID);
if (c.moveToFirst()) {
do {
deleteRow(c.getLong((int) rowId));
} while (c.moveToNext());
}
c.close();
}
// Return all data in the database.
public Cursor getAllRows() {
String where = null;
Cursor c = db.query(true, DATABASE_TABLE, ALL_KEYS,
where, null, null, null, null, null);
if (c != null) {
c.moveToFirst();
}
return c;
}
// Get a specific row (by rowId)
public Cursor getRow(long rowId) {
String where = KEY_ROWID + "=" + rowId;
Cursor c = db.query(true, DATABASE_TABLE, ALL_KEYS,
where, null, null, null, null, null);
if (c != null) {
c.moveToFirst();
}
return c;
}
// Change an existing row to be equal to new data.
public boolean updateRow(long rowId, String name, int studentNum, String favColour) {
String where = KEY_ROWID + "=" + rowId;
/*
* CHANGE 4:
*/
// TODO: Update data in the row with new fields.
// TODO: Also change the function's arguments to be what you need!
// Create row's data:
ContentValues newValues = new ContentValues();
newValues.put(KEY_NAME, name);
newValues.put(KEY_STUDENTNUM, studentNum);
newValues.put(KEY_FAVCOLOUR, favColour);
// Insert it into the database.
return db.update(DATABASE_TABLE, newValues, where, null) != 0;
}
/////////////////////////////////////////////////////////////////////
// Private Helper Classes:
/////////////////////////////////////////////////////////////////////
/**
* Private class which handles database creation and upgrading.
* Used to handle low-level database access.
*/
private static class DatabaseHelper extends SQLiteOpenHelper
{
DatabaseHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
#Override
public void onCreate(SQLiteDatabase _db) {
_db.execSQL(DATABASE_CREATE_SQL);
}
#Override
public void onUpgrade(SQLiteDatabase _db, int oldVersion, int newVersion) {
Log.w(TAG, "Upgrading application's database from version " + oldVersion
+ " to " + newVersion + ", which will destroy all old data!");
// Destroy old database:
_db.execSQL("DROP TABLE IF EXISTS " + DATABASE_TABLE);
// Recreate new database:
onCreate(_db);
}
}
}
My favorite list activity..
DBAdapter myDb;
#SuppressLint("NewApi")
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.favoritediseases);
openDB();
populateListViewFromDB();
registerListClickCallback();
// this code is used for the action bar color change//
ActionBar bar = getActionBar();
bar.setBackgroundDrawable(new ColorDrawable(Color.parseColor("#6B8E23")));
getActionBar().setDisplayHomeAsUpEnabled(true);
getActionBar().setHomeButtonEnabled(true);
}
#Override
protected void onDestroy() {
super.onDestroy();
closeDB();
}
private void openDB() {
myDb = new DBAdapter(this);
myDb.open();
}
private void closeDB() {
myDb.close();
}
/*
* UI Button Callbacks
*/
private void populateListViewFromDB() {
Cursor cursor = myDb.getAllRows();
// Allow activity to manage lifetime of the cursor.
// DEPRECATED! Runs on the UI thread, OK for small/short queries.
startManagingCursor(cursor);
// Setup mapping from cursor to view fields:
String[] fromFieldNames = new String[]
{DBAdapter.KEY_NAME, DBAdapter.KEY_STUDENTNUM};
int[] toViewIDs = new int[]
{R.id.item_name};
// Create adapter to may columns of the DB onto elemesnt in the UI.
SimpleCursorAdapter myCursorAdapter =
new SimpleCursorAdapter(
this, // Context
R.layout.item_layout, // Row layout template
cursor, // cursor (set of DB records to map)
fromFieldNames, // DB Column names
toViewIDs // View IDs to put information in
);
// Set the adapter for the list view
ListView myList = (ListView) findViewById(R.id.favlistView1);
myList.setAdapter(myCursorAdapter);
}
private void registerListClickCallback() {
ListView myList = (ListView) findViewById(R.id.favlistView1);
//This code is for to delete the single item from the listview of favorite list
myList.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
#Override
public boolean onItemLongClick(AdapterView<?> arg0, View arg1,
int arg2, final long arg3) {
Cursor cursor = myDb.getRow(arg3);
if (cursor.moveToFirst()) {
new AlertDialog.Builder(FavoriteDiseases.this)
.setTitle("Delete Item")
.setMessage("Do you want to delete this disease?")
.setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
// continue with delete
myDb.deleteRow(arg3);
populateListViewFromDB();
}
})
.setNegativeButton(android.R.string.no, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
// do nothing
}
})
.show();
}
return true;
}
});
//this is the code used from starting activity from the favorite list database.
myList.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View viewClicked,
int position, long idInDB) {
Cursor cursor = myDb.getRow(idInDB);
if (cursor.moveToFirst()) {
String name = cursor.getString(DBAdapter.COL_NAME);
if (name.equals("Atherosclerosis")){
startActivity(new Intent(FavoriteDiseases.this,Atherosclerosis.class));
}else if
(name.equals("Coronary Heart Disease")){
startActivity(new Intent(FavoriteDiseases.this,CoronaryHeartDisease.class));
}else if (name.equals("Stable Angina")){
startActivity(new Intent(FavoriteDiseases.this,StableAngina.class));
}else if (name.equals("Acute Coronary Syndrome")){
startActivity(new Intent(FavoriteDiseases.this,AcuteCoronarySyndrome.class));
}else if (name.equals("Myocardial Infarction")){
startActivity(new Intent(FavoriteDiseases.this,MyocardialInfarction.class));
}else if (name.equals("Unstable Angina")){
startActivity(new Intent(FavoriteDiseases.this,UnstableAngina.class));
}else if (name.equals("Acute Heart Failure")){
startActivity(new Intent(FavoriteDiseases.this,AcuteHeartFailure.class));
}
}
cursor.close();
updateItemForId(idInDB);
}
});}
private void updateItemForId(long idInDB) {
Cursor cursor = myDb.getRow(idInDB);
if (cursor.moveToFirst()) {
cursor.getLong(DBAdapter.COL_ROWID);
String name = cursor.getString(DBAdapter.COL_NAME);
int studentNum = cursor.getInt(DBAdapter.COL_STUDENTNUM);
String favColour = cursor.getString(DBAdapter.COL_FAVCOLOUR);
favColour += "!";
myDb.updateRow(idInDB, name, studentNum, favColour);
}
cursor.close();
populateListViewFromDB();
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.favorite_diseases, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Take appropriate action for each action item click
switch (item.getItemId()) {
case R.id.action_clear:
new AlertDialog.Builder(this)
.setTitle("Delete List")
.setMessage("Do you want to clear all?")
.setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
// continue with delete
myDb.deleteAll();
populateListViewFromDB();
}
})
.setNegativeButton(android.R.string.no, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
// do nothing
}
})
.show();
return true;
}
return true;
}}
the final code from where i adding to the list
case R.id.id_favorit:
// Add it to the DB and re-draw the ListView
myDb.insertRow("Atherosclerosis", 0, "");
Toast.makeText(getApplicationContext(), "Item Added to Favorite List!", Toast.LENGTH_SHORT).show();
favClicked=true;
invalidateOptionsMenu();
return true;
Seems like you just want to get your results from the DB in reverse order. Changing the function that retrieves them to ORDER BY your rowid in descending order will do the trick:
// Return all data in the database.
public Cursor getAllRows() {
String where = null;
Cursor c = db.query(true, DATABASE_TABLE, ALL_KEYS,
where, null, null, null, KEY_ROWID + " DESC", null);
if (c != null) {
c.moveToFirst();
}
return c;
}
Regarding your second question, you should check if the favorite exists before inserting it. The question is how you define your uniqueness. For example, if you don't want two "favorites" with the same name, you'll want to add a check in your insert function:
// Add a new set of values to the database, unless the name already exists.
public long insertRow(String name, int studentNum, String favColour) {
Cursor c = db.query(true, DATABASE_TABLE, ALL_KEYS,
KEY_NAME + "='" + name + "'", null, null, null, null, null);
if (c.getCount() > 0) {
return -1;
}
c.close();
/*
* CHANGE 3:
*/
// TODO: Update data in the row with new fields.
// TODO: Also change the function's arguments to be what you need!
// Create row's data:
ContentValues initialValues = new ContentValues();
initialValues.put(KEY_NAME, name);
initialValues.put(KEY_STUDENTNUM, studentNum);
initialValues.put(KEY_FAVCOLOUR, favColour);
// Insert it into the database.
return db.insert(DATABASE_TABLE, null, initialValues);
}
I am having a problem validating my login for my android app. I have 2 fields that require user to enter email and password, if both exist in db then they will be taken to mainscreen (log in successful) if incorrect error will appear. I have tried everything but still doesnt work! Please help I have posted my code below.
package com.example.finalproject;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
public class LoginActivity extends Activity implements OnClickListener{
EditText mEmailAdd;
EditText mPassword;
private SQLiteAdapter mydb = null;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.login_activity);
//addListenerOnButton();
}
public void onCreateMainscreen(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.screenmain_activity);
Button mNewUser = (Button)findViewById(R.id.btnLogMain);
mNewUser.setOnClickListener(this);
}
public void onClick(View v) {
switch(v.getId()){
case R.id.btnLogMain:
mEmailAdd = (EditText)findViewById(R.id.email);
mPassword = (EditText)findViewById(R.id.password);
String uname = mEmailAdd.getText().toString();
String pass = mPassword.getText().toString();
if(uname.equals("") || uname == null){
Toast.makeText(getApplicationContext(), "email Empty", Toast.LENGTH_SHORT).show();
}else if(pass.equals("") || pass == null){
Toast.makeText(getApplicationContext(), "Password Empty", Toast.LENGTH_SHORT).show();
}else{
boolean validLogin = validateLogin(uname, pass, LoginActivity.this);
if(validLogin){
System.out.println("In Valid");
Intent i = new Intent(LoginActivity.this, MainMenuActivity.class);
startActivity(i);
finish();
}
}
break;
}
}
// #SuppressWarnings("deprecation")
public boolean validateLogin(String uemail, String pass, Context context) {
mydb = new SQLiteAdapter(this);
SQLiteAdapter db = mydb.openToWrite();
//SELECT
String[] columns = {"_id"};
//WHERE clause
String selection = "email=? AND password=?";
//WHERE clause arguments
String[] selectionArgs = {uemail,pass};
Cursor cursor = null;
try{
//SELECT _id FROM login WHERE email=uemail AND password=pass
cursor = db.query(SQLiteAdapter.MYDATABASE_TABLE, columns, selection, selectionArgs, null, null, null);
// startManagingCursor(cursor);
}catch(Exception e){
e.printStackTrace();
}
int numberOfRows = cursor.getCount();
if(numberOfRows <= 0){
Toast.makeText(getApplicationContext(), "Failed..\nTry Again", Toast.LENGTH_SHORT).show();
return false;
}
return true;
}
public void onDestroy(){
super.onDestroy();
mydb.close();
}
}
DATABASE CLASS
package com.example.finalproject;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.database.sqlite.SQLiteDatabase.CursorFactory;
public class SQLiteAdapter {
public static final String MYDATABASE_NAME = "MY_PROJECT_DATABASE";
public static final String MYDATABASE_TABLE = "MY_USERS_TABLE";
public static final int MYDATABASE_VERSION = 1;
public static final String KEY_ID = "_id";
public static final String KEY_NAME = "name";
public static final String KEY_EMAIL = "email";
public static final String KEY_PASSWORD = "password";
//create table MY_DATABASE (ID integer primary key, Content text not null);
private static final String SCRIPT_CREATE_DATABASE =
"create table " + MYDATABASE_TABLE + " ("
+ KEY_ID + " integer primary key autoincrement, "
+ KEY_NAME + " text not null, "
+ KEY_EMAIL + " text not null, "
+ KEY_PASSWORD + " text not null);";
private SQLiteHelper sqLiteHelper;
private SQLiteDatabase sqLiteDatabase;
private Context context;
public SQLiteAdapter(Context c){
context = c;
}
public SQLiteAdapter openToRead() throws android.database.SQLException {
sqLiteHelper = new SQLiteHelper(context, MYDATABASE_NAME, null, MYDATABASE_VERSION);
sqLiteDatabase = sqLiteHelper.getReadableDatabase();
return this;
}
public SQLiteAdapter openToWrite() throws android.database.SQLException {
sqLiteHelper = new SQLiteHelper(context, MYDATABASE_NAME, null, MYDATABASE_VERSION);
sqLiteDatabase = sqLiteHelper.getWritableDatabase();
return this;
}
public void close(){
sqLiteHelper.close();
}
public long insert(String name, String email, String password){
ContentValues contentValues = new ContentValues();
contentValues.put(KEY_NAME, name);
contentValues.put(KEY_EMAIL, email);
contentValues.put(KEY_PASSWORD, password);
return sqLiteDatabase.insert(MYDATABASE_TABLE, null, contentValues);
}
public int deleteAll(){
return sqLiteDatabase.delete(MYDATABASE_TABLE, null, null);
}
public Cursor queueAll(){
String[] columns = new String[]{KEY_ID, KEY_NAME, KEY_EMAIL,KEY_PASSWORD};
Cursor cursor = sqLiteDatabase.query(MYDATABASE_TABLE, columns,
null, null, null, null, null);
return cursor;
}
public class SQLiteHelper extends SQLiteOpenHelper {
public SQLiteHelper(Context context, String name,
CursorFactory factory, int version) {
super(context, name, factory, version);
}
#Override
public void onCreate(SQLiteDatabase db) {
// TODO Auto-generated method stub
db.execSQL(SCRIPT_CREATE_DATABASE);
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
// TODO Auto-generated method stub
}
}
}
not your error, but change
if(uname.equals("") || uname == null){ // throws nullpointerexception if uname == null
to
if(uname == null || uname.length() == 0 ){ // throws no exception and also checks the " "
Not sure if this was just a copy-paste error but the code as provided not only doesn't compile, but never sets up the click listener for the login button either. Here's what I modified to make it both compile and query the database.
In SQLiteAdapter:
public SQLiteDatabase openToWrite() throws android.database.SQLException {
sqLiteHelper = new SQLiteHelper(context, MYDATABASE_NAME, null,
MYDATABASE_VERSION);
sqLiteDatabase = sqLiteHelper.getWritableDatabase();
return sqLiteDatabase;
}
In LoginActivity:
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.login_activity);
//addListenerOnButton();
Button mNewUser = (Button)findViewById(R.id.btnLogMain);
mNewUser.setOnClickListener(this);
}
public void onCreateMainscreen(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.screenmain_activity);
Button mNewUser = (Button)findViewById(R.id.btnLogMain);
mNewUser.setOnClickListener(this);
}
public boolean validateLogin(String uemail, String pass, Context context) {
mydb = new SQLiteAdapter(this);
SQLiteDatabase db = mydb.openToWrite();
//SELECT
String[] columns = {"_id"};
//WHERE clause
String selection = "email=? AND password=?";
//WHERE clause arguments
String[] selectionArgs = {uemail,pass};
Cursor cursor = null;
try{
//SELECT _id FROM login WHERE email=uemail AND password=pass
cursor = db.query(SQLiteAdapter.MYDATABASE_TABLE, columns, selection, selectionArgs, null, null, null);
// startManagingCursor(cursor);
}catch(Exception e){
e.printStackTrace();
}
int numberOfRows = cursor.getCount();
if(numberOfRows <= 0){
Toast.makeText(getApplicationContext(), "Failed..\nTry Again", Toast.LENGTH_SHORT).show();
return false;
}
return true;
}
Note also that this code will never insert anything into the database, either. I assume this will be done elsewhere. Further there are many naming convention and general good practices being broken here.
A few issues:
Never do database work on the main thread.
Variables prefixed with 'm' indicate they are member variables of the class.
Be sure to use the #Override notation when appropriate.
So I've run into a peculiar problem. I am trying to write a data file to the device. I developed the app in eclipse under 2.2, my device is 2.3.3, so I made the emulator run at 2.3.3, it writes files fine. Why does this not work on the device? It also is coded to copy the database file on the device to a php server. On the server the file is essentially empty, i pulled the db file from the device as well and it's empty. The only time it works is on the emulator, i get a legit file on the server and when i pull the database it's got data in it. I'm so lost. If you want to see some code then ask, I would have posted some but with 40+ classes I really don't know where to begin.
Thanks in advance.
Here is code relating to the database creation
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.util.Log;
public class DbHelper extends SQLiteOpenHelper {
private static final String DATABASE_NAME = "database";
private static final int DATABASE_VERSION = 1;
// Database creation sql statement
private static final String DATABASE_CREATE = "create table database (_id integer primary key autoincrement," +
"name text not null);";
public DbHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
// Method is called during creation of the database
#Override
public void onCreate(SQLiteDatabase database) {
database.execSQL(DATABASE_CREATE);
}
// Method is called during an upgrade of the database, e.g. if you increase
// the database version
#Override
public void onUpgrade(SQLiteDatabase database, int oldVersion,
int newVersion) {
Log.w(DbHelper.class.getName(),
"Upgrading database from version " + oldVersion + " to "
+ newVersion + ", which will destroy all old data");
database.execSQL("DROP TABLE IF EXISTS database");
onCreate(database);
}
}
here is the adapter..
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
public class DbAdapter {
// Database fields
public static final String KEY_ROWID = "_id";
public static final String KEY_NAME = "name";
static final String DATABASE_TABLE = "database";
private Context context;
private SQLiteDatabase database;
private DbHelper dbHelper;
public DbAdapter(Context ctx) {
context = ctx;
}
public SQLiteDatabase openToRead() throws SQLException {
dbHelper = new DbHelper(context);
database = dbHelper.getReadableDatabase();
return database;
}
public SQLiteDatabase open() throws SQLException {
dbHelper = new DbHelper(context);
database = dbHelper.getWritableDatabase();
return database;
}
public void close() {
dbHelper.close();
}
//
/**
* Create a new todo If the todo is successfully created return the new
* rowId for that note, otherwise return a -1 to indicate failure.
*/
public long createRow(String name) {
ContentValues initialValues = createContentValues(name);
return database.insert(DATABASE_TABLE, null, initialValues);
}
/**
* Update the todo
*/
public boolean updateRows(long rowId,
String name) {
ContentValues updateValues = createContentValues(
name);
return database.update(DATABASE_TABLE, updateValues, KEY_ROWID + "="
+ rowId, null) > 0;
}
/**
* Deletes todo
*/
public boolean deleteRow(long rowId) {
return database.delete(DATABASE_TABLE, KEY_ROWID + "=" + rowId, null) > 0;
}
/**
* Return a Cursor over the list of all todo in the database
*
* #return Cursor over all notes
*/
public Cursor fetchAllRows() {
return database.query(DATABASE_TABLE, new String[] {KEY_ROWID, KEY_NAME}, null, null, null,
null, null);
}
/**
* Return a Cursor positioned at the defined todo
*/
public Cursor fetchRow(long rowId) throws SQLException {
Cursor mCursor = database.query(true, DATABASE_TABLE, new String[] {
KEY_ROWID ,KEY_NAME},
KEY_ROWID + "=" + rowId, null, null, null, null, null);
if (mCursor != null) {
mCursor.moveToFirst();
}
return mCursor;
}
/**fetches keyword**/
public Cursor fetchKeyword(String keyword, String column, String[] columns) throws SQLException {
Cursor mCursor = database.query(DATABASE_TABLE, columns, column + "='" + keyword + "'",
null, null, null, null);
if (mCursor != null) {
mCursor.moveToFirst();
}
return mCursor;
}
private ContentValues createContentValues(String name){
ContentValues values = new ContentValues();
values.put(KEY_NAME, name);
return values;
}
//returns (an) entire column(s), all rows
public Cursor fetchColumns(String[] colnames) {
Cursor mCursor = database.query(DATABASE_TABLE, colnames, null,
null, null, null, null);
if (mCursor != null) {
mCursor.moveToFirst();
}
return mCursor;
}
}
Ok, I've Isolated it to these three classes.. below is the class that creates the entry and uploads it to the server. as far as i can tell the database isn't being created the right way.. as in there are no tables in the file
public class CreateName extends Activity{
//variables
private DbAdapter mDbHelper;
EditText textField;
TextView txtEnter2;
TextView txtEnter;
Button btnSubmit;
Context context;
SharedPreferences prefs;
SharedPreferences.Editor spe;
SQLiteDatabase db;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.submit);
//constructors
context = getApplicationContext();
prefs = PreferenceManager.getDefaultSharedPreferences(context);
spe = prefs.edit();
init();
listen();
}
public void checker() {
Intent i = new Intent(this, MoveForward.class);
startActivity(i);
}
private void listen() {
btnSubmit.setOnClickListener(new Button.OnClickListener()
{
public void onClick (View v)
{
mDbHelper = new DbAdapter(context);
String words = textField.getText().toString();
Log.v(words, words);
mDbHelper.open();
mDbHelper.createRow(words);
mDbHelper.close();
spe.putString("name", words);
spe.commit();
PHPBuddy buddy = new PHPBuddy();
try {
buddy.uploadFile("database");
} catch (Exception e) {
// ask the user to retry
e.printStackTrace();
}
checker();
}
}
);
}
private void init() {
textField = (EditText)findViewById(R.id.edtTxt);
txtEnter2 = (TextView)findViewById(R.id.txtEnter2);
txtEnter = (TextView)findViewById(R.id.txtEnter);
btnSubmit =(Button)findViewById(R.id.btnSubmit);
txtEnter.setText("Enter your proper name");
txtEnter2.setText("ex: John Smith");
}
}
Maybe there is a cursor or db i'm forgetting to close?
Here is more code..
public class SBMain extends Activity {
Button btnSpinner;
String[] items;
String text;
Spinner s;
Intent i, j;
int activity;
SharedPreferences prefs;
SharedPreferences.Editor spe;
SQLiteDatabase db;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.spinnerscreen);
prefs = PreferenceManager.getDefaultSharedPreferences(this);
spe = prefs.edit();
init();
fillSpinner();
btnSpinner.setOnClickListener(new Button.OnClickListener()
{
public void onClick (View v)
{
Cursor cc = (Cursor)(s.getSelectedItem());
if (cc != null) {
text = cc.getString(cc.getColumnIndex("name"));
}
checker();
}
});
}
public void checker() {
if (text .equals("Create Name")){
i = new Intent(this, GetName.class);
spe.putString("name", text);
spe.commit();
startActivity(i);
}else{
spe.putString("name", text);
spe.commit();
i = new Intent(this, MoveForward.class);
startActivity(i);
}
}
private void fillSpinner(){
DbAdapter mDbHelper = new DbAdapter(this);
mDbHelper.open();
Cursor c = mDbHelper.fetchColumns(new String[] {"_id","name"});;
if ( ! c.moveToFirst() ){
c.close();
mDbHelper.createRow("Create Name");
mDbHelper.close();
c = mDbHelper.fetchColumns(new String[] {"_id","name"});
}else{
mDbHelper.close();
}
// create an array to specify which fields we want to display
String[] from = new String[]{"name"};
// create an array of the display item we want to bind our data to
int[] to = new int[]{android.R.id.text1};
// create simple cursor adapter
SimpleCursorAdapter adapter =
new SimpleCursorAdapter(this, android.R.layout.simple_spinner_item, c, from, to );
adapter.setDropDownViewResource( android.R.layout.simple_spinner_dropdown_item );
// get reference to our spinner
s.setAdapter(adapter);
}
private void init() {
btnSpinner = (Button)findViewById(R.id.btnSpinner);
s = (Spinner) findViewById( R.id.spinner1 );
}
}
Here is the splash activity that downloads the file
public class Splash extends Activity{
String file_url = "http://ipaddress/xampp/uploads/";
Context context = this;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.splash);
Thread splashThread = new Thread() {
#Override
public void run() {
float percent = 0;
try {
int waited = 0;
int time = 1000;
while (waited < time) {
sleep(100);
waited += 100;
String perc = Integer.toString(waited / time);
}
} catch (InterruptedException e) {
// do nothing
} finally {
//if this is the apps first time running, get a list of names.
if(isFirstRun()){
PHPBuddy buddy = new PHPBuddy();
try {
buddy.downloadFile("database");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//ToDo add spared prefs editor to set isfirstrun to true
Intent i = new Intent();
i.setClassName("com.project",
"com.project.SBMain");
startActivity(i);
}else{
//make registered user page
Intent i = new Intent();
//ToDo add spared prefs editor to set isfrstrun to false
//ToDo add intent for true
}
finish();
}
}
};
splashThread.start();
}
public boolean isFirstRun(){
String rb = "isfirstrun";
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
SharedPreferences.Editor spe;
spe = prefs.edit();
//spe.putBoolean("isfirstrun", true);
//boolean test = prefs.getBoolean(rb, true);
return true;//prefs.getBoolean(rb, true);
}
}
here is the php
<?php
$myFile = "requestslog.txt";
$fh = fopen($myFile, 'a') or die("can't open file");
fwrite($fh, "\n\n---------------------------------------------------------------\n");
foreach($_SERVER as $h=>$v)
if(ereg('HTTP_(.+)',$h,$hp))
fwrite($fh, "$h = $v\n");
fwrite($fh, "\r\n");
fwrite($fh, file_get_contents('php://input'));
fclose($fh);
echo "<html><head /><body><iframe src=\"$myFile\" style=\"height:100%; width:100%;\"> </iframe></body></html>"
?>
<?php
if (is_uploaded_file($_FILES['userfile']['tmp_name'])) {
echo "File ". $_FILES['userfile']['name'] ." uploaded successfully.\n";
move_uploaded_file ($_FILES['userfile'] ['tmp_name'], $_FILES['userfile'] ['name']);
} else {
echo "Possible file upload attack: ";
echo "filename '". $_FILES['userfile']['tmp_name'] . "'.";
print_r($_FILES);
}
?>
my first guess is that you are trying to write the database somewhere where you don't have permission.
i would recommend using the method File getDir (String name, int mode) of your Activity to get a folder inside your app where you can read and write.
I think I figured it out.
First I set up a class that would copy the database to the SD card right after it was created; from there, I examined the file and saw that it was indeed intact.
Then, I moved the copy call to the place right before the database gets sent to the server. It didn't look fine in "SQLite Database Browser," so I opened it up in Firefox's SQLite manager and voila, all the data was there. So, with Firefox I go and look at the file that was uploaded to the server. What looked empty in the SQLite Database Browser has data in it!