I want to pass my Listview clicked item ID to other activity using intent. HoW could I do this?
You get the id and add it to the Intent as an Extra using the respective (long) putExtra, with a suitable key (first parameter).
In the other Activity you get the Intent and then get the value from the Extra using the getLongExtra using the same key (first parameter) noting that the default value should be a value (e.g. -1) that will not be an id.
Working Example
The following is a working example :-
The Database Helper DBOpenHelper.java
public class DBOpenHelper extends SQLiteOpenHelper {
public static final String DBNAME = "notes.db";
public static final int DBVERSION = 1;
public static final String TBL_NOTE = "note_table";
public static final String COL_NOTE_ID = BaseColumns._ID;
public static final String COL_NOTE_TEXT = "note_text";
private final String create_table = "CREATE TABLE IF NOT EXISTS " + TBL_NOTE + "(" +
COL_NOTE_ID + " INTEGER PRIMARY KEY, " +
COL_NOTE_TEXT + " TEXT " +
")";
private static final String drop_table = "DROP TABLE IF EXISTS " + TBL_NOTE;
public DBOpenHelper(Context context) {
super(context, DBNAME, null, DBVERSION);
}
public void onCreate(SQLiteDatabase db) {
db.execSQL(create_table);
}
public void onUpgrade(SQLiteDatabase db, int version_old, int version_new) { }
public long addNote(String note) {
SQLiteDatabase db = this.getWritableDatabase();
ContentValues cv = new ContentValues();
cv.put("NOTE_TEXT",note);
return db.insert("note_table",null,cv);
}
public Cursor getAllNotes() {
SQLiteDatabase db = this.getWritableDatabase();
return db.query(TBL_NOTE,null,null,null,null,null,null);
}
}
An instantiated instance of this is used to :
open the database (in the example it is named notes.db), it will create the database if it doesn't exist.
add data via the addNote method.
return a Cursor containing all the Notes via the getAllNotes method.
The initial activity MainActivity.java :-
public class MainActivity extends AppCompatActivity {
private ListView mListView;
private SimpleCursorAdapter MSCA;
private Cursor mCsr;
private DBOpenHelper mDBHelper;
public static final String INTENTEXTRAKEY_NOTE_ID = "iek_noteid";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mDBHelper = new DBOpenHelper(this);
mListView = findViewById(R.id.listView);
addSomeTestData(); //Adds a row every time the App is run (for testing)
ViewData();
}
private void ViewData(){
mCsr = mDBHelper.getAllNotes();
if (MSCA == null) {
MSCA = new SimpleCursorAdapter(
this,
android.R.layout.simple_list_item_1,
mCsr,
new String[]{DBOpenHelper.COL_NOTE_TEXT},
new int[]{android.R.id.text1},
0);
mListView.setAdapter(MSCA);
mListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Intent i = new Intent(MainActivity.this,OtherActivity.class);
i.putExtra(INTENTEXTRAKEY_NOTE_ID,id);
startActivity(i);
}
});
} else {
MSCA.swapCursor(mCsr);
}
}
private void addSomeTestData() {
if(DatabaseUtils.queryNumEntries(mDBHelper.getWritableDatabase(),DBOpenHelper.TBL_NOTE) < 1) {
mDBHelper.addNote("My Note");
mDBHelper.addNote("Another Note");
mDBHelper.addNote("Yet Another Note");
mDBHelper.addNote("And so on.");
}
}
#Override
protected void onDestroy() {
super.onDestroy();
mCsr.close();
}
#Override
public void onResume()
{
super.onResume();
ViewData();
}
}
This activity :-
Adds some notes to the database (if none already exist)
Lists all of the notes in the database
sets a onItemClickListener to call the activity OtherActivity passing the id via an IntenExtra.
Notes
A CursorAdpater (SimpleCursorAdapter) in this case is ideally suited as the id is passed to the onItemClick method by the listener. NOTE this requires a column, named specifically _id (as per BaseColumns._ID) and that the column is an alias of the rowid column.
The onDestroy method has been overridden to close the Cursor when done with it (i.e. when the Activity is detsroyed). This isn't so important in the initial actiivty as it's lifetime would typically be for the entire App (closing the Cursor in hierarchically lower Activities is more important).
The ViewData method manages a single instance of the adapter (i.e. creating it only when it hasn't been instantiated) and also refreshing of the ListView. Hence why it is called in the overridden onResume method. i.e. another activity may add. delete or update the database so the ListView will updated upon return.
The activity called from the initial activity OtherActivity.java
public class OtherActivity extends AppCompatActivity {
TextView mNoteId;
Button mDone;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_other);
mNoteId = this.findViewById(R.id.noteid);
mDone = this.findViewById(R.id.done);
mDone.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
finish();
}
});
Intent i = this.getIntent();
long id = i.getLongExtra(MainActivity.INTENTEXTRAKEY_NOTE_ID,-1);
mNoteId.setText(String.valueOf(id));
}
}
This activity :-
sets the onClickListener of the button to return to the calling/invoking activity.
extracts the id from the Intent Extras passed to the activity from the calling activity and sets the noteid TextView with the extracted value (the passed id).
Result
Initially :-
Clicking Yet Another Note :-
As Yet Another Note was the third note added it's id is 3.
Related
I am making a "Note" program to practice and learn - my first "freestyle" project after reading a book on the subject. The way i figured i would do this is to store the title and content of the note in a SQLite table, and insert and remove from the table as needed.
The first activity consists of a ListView which gets all the notes(rows) from the DB. The user is supposed to press a button at the first activity, which says "New note", which then leads to another activity where you can enter the title and the content of the note, press the "Save" button, and then with an intent, return to the activity with the ListView where the newly added note plus all earlier created notes are displayed in the ListView.
My problem is that when the intent starts the activity with the ListView from the NewNote activity, the newly added note wont show in the ListView at once. If i then add a new note again, it returns to the first activity, but then the note i added first is displayed. And so it goes on. In other words the list on the first activity is always "one note behind", as it only adds the note i added the last time and not the one i recently added. Maybe its a bad explanation, but i think thats as clear as it gets. I spent alot of time today logging and trying to find the problem but i cant seem to figure this out on my own.
Here is my code.
Starting with my database class:
public class DatabaseHandler extends SQLiteOpenHelper {
private static final String DATABASE_NAME = "DB";
private static final int DATABASE_VERSION = 1;
private static final String TABLE_NOTES = "Notes";
private static final String KEY_ID = "id";
private static final String KEY_TITLE = "title";
private static final String KEY_CONTENT = "content";
public DatabaseHandler(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
#Override
public void onCreate(SQLiteDatabase db) {
String CREATE_PERSON_TABLE = "CREATE TABLE " + TABLE_NOTES + "(" + KEY_ID + " INTEGER PRIMARY KEY," + KEY_TITLE + " TEXT," + KEY_CONTENT + " INTEGER" + ")";
db.execSQL(CREATE_PERSON_TABLE);
}
public void dropTable() {
SQLiteDatabase db = this.getReadableDatabase();
db.execSQL("DROP TABLE IF EXISTS " + TABLE_NOTES);
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL("DROP TABLE IF EXISTS " + TABLE_NOTES);
onCreate(db);
}
public void newNote(String title, String content) {
SQLiteDatabase db = this.getReadableDatabase();
ContentValues values = new ContentValues();
values.put(KEY_TITLE, title);
values.put(KEY_CONTENT, content);
db.insert(TABLE_NOTES, null, values);
db.close();
}
public void deleteNote(String id) {
SQLiteDatabase db = getReadableDatabase();
db.delete(TABLE_NOTES, KEY_ID + "=" + id, null);
}
public ArrayList<Note> getNotes() {
SQLiteDatabase db = this.getReadableDatabase();
ArrayList<Note> notes = new ArrayList<>();
Cursor cursor = db.query(TABLE_NOTES, new String[]{KEY_ID, KEY_TITLE, KEY_CONTENT}, null, null, null, null, KEY_ID + " DESC", null);
if (cursor != null) {
cursor.moveToFirst();
}
while(cursor.moveToNext()) {
Note note = new Note(cursor.getString(0), cursor.getString(1), cursor.getString(2));
notes.add(note);
}
db.close();
return notes;
}
public void deleteAll() {
SQLiteDatabase db = this.getReadableDatabase();
db.execSQL("delete from " + TABLE_NOTES);
db.close();
}
}
My Main activity, ListActivity:
public class ListActivity extends AppCompatActivity {
private DatabaseHandler dbh;
private ListView list;
private ArrayAdapter<Note> listAdapter;
private Button newBtn;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_list);
dbh = new DatabaseHandler(this);
Intent intent = getIntent();
String id = intent.getStringExtra("Id");
String title = intent.getStringExtra("Title");
String content = intent.getStringExtra("Content");
//If save button is pressed at NewNote
if (title != null && content != null) {
dbh.newNote(title, content);
Log.d("note", title + " added");
}
//If delete button is pressed at NewNote
if (id != null) {
dbh.deleteNote(id);
}
initWidgets();
}
public void initWidgets() {
list = findViewById(R.id.list);
newBtn = findViewById(R.id.newButton);
newBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent newButtonIntent = new Intent(ListActivity.this, NewNote.class);
startActivity(newButtonIntent);
}
});
list.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
Note note = listAdapter.getItem(i);
Intent editIntent = new Intent(ListActivity.this, EditNote.class);
editIntent.putExtra("Title", note.getTitle());
editIntent.putExtra("Content", note.getContent());
editIntent.putExtra("Id", note.getId());
startActivity(editIntent);
}
});
refreshList();
}
public void refreshList() {
listAdapter = new ArrayAdapter(this, R.layout.list_item, dbh.getNotes());
list.setAdapter(listAdapter);
Log.d("note", "View updated");
}
}
My NewNote class:
public class NewNote extends AppCompatActivity {
private EditText title;
private EditText content;
private Button btnSave;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_new_note);
initWidgets();
}
public void initWidgets() {
title = findViewById(R.id.title);
content = findViewById(R.id.content);
btnSave = findViewById(R.id.saveButton);
btnSave.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent i = new Intent(NewNote.this, ListActivity.class);
i.putExtra("Title", title.getText().toString());
i.putExtra("Content", content.getText().toString());
startActivity(i);
}
});
}
}
Not really relevant as i have not implemented it fully, if you are just reading through the code you can 100% just ignore this class - my EditNote class:
public class EditNote extends AppCompatActivity {
private EditText title;
private EditText content;
private Button saveBtn;
private Button deleteBtn;
private String noteId;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_edit_note);
initWidgets();
Intent intent = getIntent();
title.setText(intent.getStringExtra("Title"));
content.setText(intent.getStringExtra("Content"));
noteId = intent.getStringExtra("Id");
}
public void initWidgets() {
title = findViewById(R.id.titleEdit);
content = findViewById(R.id.contentEdit);
deleteBtn = findViewById(R.id.deleteButton);
deleteBtn.setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View view) {
Intent i = new Intent(EditNote.this, ListActivity.class);
i.putExtra("Id", noteId);
startActivity(i);
}
});
}
}
Also there are my XML files, and a Note class which only consists of member variables and setters/getters, either of them i consider relevant. I think the problem is somewhere in the DB class, ListActivity class, or NewNote class.
Maybe this is alot to read for you and maybe its messy or im doing something wrong with the posting but i would be grateful for help on how to resolve this issue. Also if you see other things i can do better please point them out!
Thanks!
I am trying to implement simple database CRUD operations, in case of UPDATE operation user moves to another screen where he inputs the new and old values for the column he wants to update, So while moving to next activity I want to pass the object of database class created in MainActivity to UpdateActivity, I tried it by implementing the Database class Serializbale but it crashes.
java.lang.RuntimeException: Parcelable encountered IOException reading a Serializable object
Here is the code i tried
MainActivity
MyDbHandler dbObj = new MyDBHandler(this, null, null, 1);
public void updateBtnClicked(View view)
{
Intent intent = new Intent(MainActivity.this, ActivityUpdate.class);
intent.putExtra("Object", dbObj);
startActivity(intent);
}
ActivityUpdate
intent = getIntent();
dbObj2 = (MyDBHandler) intent.getSerializableExtra("Object");
public void doneButtonClicked(View view)
{
String str1 = newValue.getText().toString();
String str2 = oldValue.getText().toString();
dbObj2.updateProduct(str1, str2);
finish();
}
So how could the database class object be passed from one to another activity? Thanks
how could the database class object be passed from one to another activity
You don't serialize Database objects. You request them again.
MyDbHandler dbHandler = new MyDbHandler(MainActivity.this); // pass your Activity here
dbHandler.update(new Foo(42));
Where MyDbHandler is some extension of SQLiteOpenHelper written like so
public class MyDbHandler extends SQLiteOpenHelper {
// Database Info
private static final String DATABASE_NAME = "DatabaseName";
private static final int DATABASE_VERSION = 1;
public MyDbHandler(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
#Override
public void onCreate(SQLiteDatabase db) {
// TODO
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
if (oldVersion != newVersion) {
// TODO
}
/**
* Update method defined here
**/
public void update(Foo bar) {
SQLiteDatabase db = getWritableDatabase();
// TODO: Write to & close the database
}
}
MyDbHandler must extend Serializable to be correctly serialized.
I'm new to android. Here's one of my OnClickListeners. The thing is I don't know how to make it save when clicking the button. When I call createEventT(Event event), it says "non-static method cannot be referenced from a static context". Sometimes there's no error message, but the app crashes when clicking this button. Any ideas? Thanks.
OnClickListener:
OnClickListener doneT = new OnClickListener(){
#Override
public void onClick(View v) {
event.setTitle(inputToday.toString());
event.setYY(bearsCalendar.get(Calendar.YEAR));
event.setMM(bearsCalendar.get(Calendar.MONTH));
event.setDD(bearsCalendar.get(Calendar.DAY_OF_MONTH));
dateToday.setText(EventDBAdapter.createEventT(event));
}
};
And the event class:
public class Event {
int YY,MM,DD;
private String title;
public void setYY(int YY){this.YY=YY;}
public void setMM(int MM){this.MM=MM;}
public void setDD(int DD){this.DD=DD;}
public void setTitle(String title){this.title=title;};
public int getYY(){return YY;}
public int getMM(){return MM;}
public int getDD(){return DD;}
public String getTitle(){return title;}
}
public class EventDBAdapter{
private final Context mCtx;
static final String dbName="BearDatabase";
static final String eventTable="Events";
static final int dbVersion=1;
static final String colID="EventId";
static final String colTitle="Title";
static final String colDetails="Details";
static final String colYear="YY";
static final String colMonth="MM";
static final String colDay="DD";
static final String colHour="HH";
static final String colMinute="TT";
public DatabaseHelper mDbHelper;
public SQLiteDatabase mDb;
public EventDBAdapter(Context context){
mCtx=context;
}
private static class DatabaseHelper extends SQLiteOpenHelper{
DatabaseHelper(Context context){
super(context,dbName,null,dbVersion);
}
#Override
public void onCreate(SQLiteDatabase db) {
db.execSQL("CREATE TABLE "+eventTable+" ("+colID+" INTEGER PRIMARY KEY , "
+colTitle+" TEXT NOT NULL , "+colDetails+" TEXT , "
+colYear+" INTEGER , "+colMonth+" INTEGER , "+colDay+" INTEGER , "
+colHour+" INTEGER , "+colMinute+" INTEGER );");
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL("DROP TABLE IF EXISTS " + eventTable);
onCreate(db);
}
}
public EventDBAdapter open() throws SQLException{
mDbHelper = new DatabaseHelper(mCtx);
mDb = mDbHelper.getWritableDatabase();
return this;
}
public void close() {
mDbHelper.close();
}
public void upgrade(){
mDbHelper = new DatabaseHelper(mCtx);
mDb = mDbHelper.getWritableDatabase();
mDbHelper.onUpgrade(mDb, 1, 0);
}
public long createEventT(Event event){
ContentValues values = new ContentValues();
values.put(colTitle,event.getTitle());
values.put(colYear,event.getYY());
values.put(colMonth, event.getMM());
values.put(colDay, event.getDD());
return mDb.insert(eventTable,null,values);
}
public long createEventI(Event event){
ContentValues values = new ContentValues();
values.put(colTitle,event.getTitle());
return mDb.insert(eventTable,null,values);
}
}
Update:
Any problems in the database? After I made the changes, the whole thing crush.
change below to
dateToday.setText(EventDBAdapter.createEventT(event));
with below and it will work.
dateToday.setText(String.valueOf(EventDBAdapter.createEventT(event)));
I hope you are initializing event object before using it in onClick. if not, then initialize it like event = new Event(); before
event.setTitle(inputToday.toString());
Unless EventDBAdapter in your question is an instance of the EventDBAdapter class, then you are attempting to use a non-static method (public long createEventT()) in a static way (by accessing it through the class name).
To access it, you first need to create an instance of EventDBAdapter. One way to achieve this would probably be (assuming you are calling this method from inside an Activity):
long date = new EventDBAdapter(this).createEventT(event);
dateToday.setText(String.valueOf(date));
There are more answers on this topic here.
I am new on Android programming. So that, I'll use wrong technical words, sorry for that ;)
i ve an app. in this app, onCreate, im checking if my db is created ( this check is for first time use ), if my db isn't created yet I'm routing user to a second layout( or activty. i couldnt be sure whch one is right word ). in this activity, when i try to create a SQLiteDatabase parameter im having a null pointer exception.
Here is a part of MainActivity.java
public class MainActivity extends Activity
{
VeriTabani veritabani; // vertiabani means database in turkish
#Override
protected void onCreate(Bundle savedInstanceState)
{
if(db_flag==0)
{
Intent intent = new Intent(MainActivity.this, SecondClass.class);
startActivity(intent);
//...
}
}
}
Here is my VeriTabani.java;
public class VeriTabani extends SQLiteOpenHelper
{
static final String VeriTabani="DATABASENAME";
static final int version=1;
public VeriTabani(Context context) {
super(context, VeriTabani, null, version);
}
#Override
public void onCreate(SQLiteDatabase db) {
db.execSQL("CREATE TABLE TABLENAME ( id INTEGER PRIMARY KEY AUTOINCREMENT, xxx STRING,yyy STRING );");
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL("DROP TABLE IF EXIST TABLENAME");
onCreate(db);
}
}
And, here is my SecondClass.java;
public class SecondClass extends Activity
{
VeriTabani veritabani;
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
button.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View v)
{
SQLiteDatabase db=veritabani.getWritableDatabase();
ContentValues cv=new ContentValues();
cv.put("xxx", another_parameter);
//...
}
//...
}
}
}
im having error on this line;
SQLiteDatabase db=veritabani.getWritableDatabase();
I'm using same VeriTabani class to insert records to DB in MainActivity and it works perfectly. i couldnt undertand what is wrong when i use same code block in another activity.
i guess solve is simple but i couldnt get it.
Thanks for your help.
you have just declared your variable
VeriTabani veritabani;
you haven't initialized that variable. you need to initialize it on onCreate() method.
veritabani = new VeriTabani(YourActivityName.this);
im having error on this line;
SQLiteDatabase db=veritabani.getWritableDatabase();
Looks like you didn't initialize your veritabani variable.
Add the following to that activity's onCreate():
veritabani = new VeriTabani(this);
Hi I am new to android and I want to know how I can add buttons to my app programmatically . Actually the scenario is like this: In my app, I am having several default categories(given as buttons) to save data. I must provide an option add categories. When I click on the add categories button I must get an option to specify the category name and the sub category name(which i can do). But the thing is that I must get a new button with the entered name and it should not get deleted when i leave the application. Any help is highly appreciated.
To create database: refer How do I create a database in android?
Then you need to use DatabaseHelper class to insert,update or delete data on your database.
refer http://developer.android.com/reference/android/database/sqlite/SQLiteOpenHelper.html
Now you must be able to manage your data using DatabaseHelper class's object in your activity.
1.DatabaseCreator.java
public class DatabaseCreator extends SQLiteOpenHelper{
private static final String DB_NAME="database_name";
private static final int DB_VER=1;
private static final String TABLE_NAME="create table table_name(_id integer primary key autoincrement,field1 text not null,field2 text not null)";
public DatabaseCreator(Context context)
{
super(context,DB_NAME, null, DB_VER);
}
#Override
public void onCreate(SQLiteDatabase database)
{
database.execSQL(TABLE_NAME);
}
#Override
public void onUpgrade(SQLiteDatabase database, int arg1, int arg2) {
database.execSQL("DROP TABLE IF EXISTS table_name");
onCreate(database);
}
}
2.DatabaseHelper.java
public class DatabaseHelper
{
public static final String TABLENAME_DB="table_name";
public static final String KEY_ID="_id";
public static final String KEY_FIELD1="field1";
public static final String KEY_FIELD2="field2";
Context context;
SQLiteDatabase sqdb;
DatabaseCreator dbcreator;
public DatabaseHelper(Context context)
{
this.context=context;
}
public DatabaseHelper open() throws SQLException
{
dbcreator=new DatabaseCreator(context);
sqdb=dbcreator.getWritableDatabase();
return this;
}
public void close()
{
dbcreator.close();
}
public long addItem(String field1,String field2)
{
ContentValues values=new ContentValues();
values.put(KEY_FIELD1,field1);
values.put(KEY_FIELD2,field2);
return sqdb.insert(TABLENAME_DB,null,values);
}
public long deletItem(long _id)
{
return sqdb.delete(TABLENAME_DB, "_id="+_id,null);
}
}
Use this in your activity like:
DatabaseHelper db_helper=new DatabaseHelper(getApplicationContext());
db_helper.open();
db_helper.addItem("field1_value","field2_value");
db_helper.close();