I'm new to Android Studio and can't seem to find what I'm asking for.
I want to have a database that stores the data of a few people, e.g.
Steve Hardy, 16 Somewhere Land, Colorado, U.S.A.
I would like this to have headings (Name, Address, City, Country).
I'm just struggling with how to format a table like this and how I would link a database to this.
In android, mostly use sqlite databases. I can give you 3 simple functions I use to create database and table, insert data to table, & to read database values. If there is any unclear thing or you want any clarification, ask. I can help you.
public class MainActivity extends AppCompatActivity {
//Assign below 3 variables as global variables where class start.
SQLiteDatabase db; //Assign as a global variable
String DBName = "MyDB"; //Assign as a global variable
String TableName = "PeopleData"; //Assign as a global variable
//Call 3 function inside oncreate method.
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
createDB_Table(); //calling 3 functions.
InsertDataToDB();
ReadDBData();
}
public void createDB_Table(){ //This function use to create database, table & columns.
db = this.openOrCreateDatabase(DBName, MODE_PRIVATE, null);
db.execSQL("CREATE TABLE IF NOT EXISTS " + TableName + " (ID INTEGER PRIMARY KEY AUTOINCREMENT, Name TEXT, Address TEXT, City TEXT, Country TEXT);");
db.close();
}
public void InsertDataToDB(){ //This function use to inset values to database.
db = this.openOrCreateDatabase(DBName, MODE_PRIVATE, null);
ContentValues cv = new ContentValues();
cv.put("Name","Steve Hardy");
cv.put("Address","16 Somewhere Land");
cv.put("City","Colorado");
cv.put("Country","USA");
db.insert(TableName, null, cv);
db.close();
}
public void ReadDBData() { //This function use to read data from database.
db = this.openOrCreateDatabase(DBName, MODE_PRIVATE, null);
Cursor cursor = db.rawQuery("SELECT * FROM " + TableName, null);
if (cursor.getCount() > 0) { //check cursor is not empty.
cursor.moveToFirst();
String DName = cursor.getString(cursor.getColumnIndex("Name"));
String DAddress = cursor.getString(cursor.getColumnIndex("Address"));
String DCity = cursor.getString(cursor.getColumnIndex("City"));
String DCountry = cursor.getString(cursor.getColumnIndex("Country"));
//Got the values from database. Then you can set those values to text view or something you use.
}
cursor.close();
db.close();
}
}
Related
I want to get a primary key of a saved object in a table in database I wrote a class to handle my database I want to add a function to it for getting the Id (I tried to give id to objects manually it didn't go well so I prefer the primary key id)so how should this function look like?and also if u see a thing that needs changing in my code please let me know.
public class DataBaseHandler extends SQLiteOpenHelper {
private static int _ID =0;
private int ID =0;
private ArrayList<marker_model> markerList=new ArrayList<>();
public DataBaseHandler(Context context) {
super(context, Constans.TABLE_NAME, null, Constans.DATABASE_VERSION);
}
#Override
public void onCreate(SQLiteDatabase db) {
db.execSQL("CREATE TABLE "+Constans.TABLE_NAME+
" ("+Constans.MARKER_ID+" INTEGER PRIMARY KEY, "+
Constans.MARKER_TITLE+" TEXT, " +Constans.MARKER_DESCRIPTION+" TEXT ,"+Constans.My_MARKER_ID+" INT );");
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL("DROP TABLE IF EXISTS "+Constans.TABLE_NAME);
onCreate(db);
}
public void AddMarker(marker_model marker){
marker.set_Id(_ID);
SQLiteDatabase db=this.getWritableDatabase();
ContentValues values=new ContentValues();
values.put(Constans.MARKER_TITLE,marker.getTitle());
values.put(Constans.My_MARKER_ID,marker.get_Id());
values.put(Constans.MARKER_DESCRIPTION,marker.getDescription());
db.insert(Constans.TABLE_NAME,null,values);
db.close();
Log.d(TAG, "AddMarker: Successfully added to DB");
_ID++;
}
public ArrayList<marker_model> getMarkers(){
markerList.clear();
SQLiteDatabase db =getReadableDatabase();
Cursor cursor=db.query(Constans.TABLE_NAME
,new String[]{Constans.My_MARKER_ID,Constans.MARKER_TITLE,
Constans.MARKER_DESCRIPTION},null,null,null,null,null);
if (cursor.moveToFirst()){
do {
ID=0;
marker_model model=new marker_model();
model.set_Id(_ID);
model.setDescription(cursor.getString(cursor.getColumnIndex(Constans.MARKER_DESCRIPTION)));
model.setTitle(cursor.getString(cursor.getColumnIndex(Constans.MARKER_TITLE)));
markerList.add(model);
ID++;
}while(cursor.moveToNext());
}
cursor.close();
db.close();
return markerList;
}
public int getMarkerPrimaryId(Marker marker){
}
}
Assuming that you want to get the _id (the primary key) from the database and that marker is an instance of a marker_model object AND that
marker_model has methods getTitle and getDescription that return a string with the respective values, then something along the lines of the following would work.
public long getMarkerPrimaryId(Marker marker){
long rv = 0;
SQLiteDatabase db = getReadableDatabase();
String[] columns = new String[]{Constans.My_MARKER_ID};
String whereclause = Constans.MARKER_TITLE + "=?" +
Constans.MARKER_DESCRIPTION + "=?";
String[] whereargs = new String[]{
marker.getTitile,
marker.getDescription
}
Cursor cursor = db.query(Constans.TABLE_NAME,
columns,
whereclause,
whereargs,
null,null,null);
if (cursor.getCount() > 0) {
cursor.moveToFirst();
rv = cursor.getLong(cursor.getColumnIndex(Constans.My_MARKER_ID);
}
cursor.close;
db.close;
return rv;
}
However, if your issue is that getMarkers is not setting the Id member appropriately (i.e. to match the id in the database), then changing model.set_Id(_ID);
to
model.set_Id(cursor.getLong(cursor.getColumnIndex(Constans.My_MARKER_ID));
would suffice.
If your expectation is that an automatically generated incrementing _id is to be used the addMarker is a little flawed. Simply by removing the line values.put(Constans.My_MARKER_ID,marker.get_Id()); will result in _id being automatically generated (which how _id's tend to be used).
The following (BACKGROUND paragraph mostly) explains much about automatically generated unique identifiers (even though it is about AUTOINCREMENT you likely DO NOT want to code AUTOINCREMENT).
Id suggest that rather than :-
if (cursor.moveToFirst()){
do {
...
}while(cursor.moveToNext());
using :-
while (cursor.moveToNext() {
....
}
is simpler (a cursor, when created, will be positioned to before the first row (moveToPosition(-1) has the same effect) , moveToNext() will move to the first row the first time, if there are no rows the loop will not be entered (you may wish to consider this and the state of returned markerlist)).
Note! the above has been written without testing, so there may be the odd mistake.
I just need a database for 1 table. To keep names and scores and the names are the primary key.
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_scoreboard);
SQLiteDatabase db = openOrCreateDatabase("scores", Context.MODE_PRIVATE, null);
db.execSQL("CREATE TABLE IF NOT EXISTS scores(_id VARCHAR PRIMARY KEY,score INTEGER);");
db.execSQL("INSERT INTO scores (_id, score) VALUES ('DARR',99);");
Cursor c=db.rawQuery("SELECT * FROM scores;",null);
StringBuffer buffer=new StringBuffer();
while(c.moveToNext())
{
buffer.append("Player: "+c.getString(0)+"\n");
buffer.append("Score: "+c.getInt(1)+"\n");
}
String result = buffer.toString();
TextView scoreRes = (TextView) findViewById(R.id.textViewScoreResult);
scoreRes.setText(result);
}
I suppose, SharedPreferences solves your need. Use the name as 'key' and the score as 'value' to the SharedPreferences.
For more info, refer http://developer.android.com/training/basics/data-storage/shared-preferences.html
Do not use SQLite database unless the app really needs it.
I create a database containing 4 String columns in a separate class called CalDatabaseHelper:
public void onCreate(SQLiteDatabase db) {
updateDatabase(db,0,DATABASE_VERSION);
}
private static void updateDatabase(SQLiteDatabase db, int olderversion, int newerVersion){
if (olderversion < 1){
db.execSQL("CREATE TABLE CAL (_id TEXT PRIMARY KEY,"
+ "ACTIVITY1 TEXT, "
+ "ACTIVITY2 TEXT"
+ "ACTIVITY3 TEXT);");
}
}
private static void insertIntoDatabase(SQLiteDatabase db, String primaryKey, String activityOne, String activityTwo, String activityThree){
ContentValues values = new ContentValues();
values.put("_id",primaryKey);
values.put("ACTIVITY1",activityOne);
values.put("ACTIVITY2",activityTwo);
values.put("ACTIVITY3",activityThree);
db.insert("CAL",null,values);
}
I add data in an Activity called Appointments. For now, I just add to the _id (a String variable) and ACTIVITY1 (a String variable that comes from user input into and EditText) columns:
SQLiteOpenHelper sqLiteOpenHelper = new CalDatabaseHelper(Appointments.this);
SQLiteDatabase db = sqLiteOpenHelper.getWritableDatabase();
values.put("_id",primaryKey);
values.put("ACTIVITY1", activityOne);
db.insert("CAL", null, values);
db.close();
I attempt to retrieve this data in an Adapter Class. Once a widget is clicked, a database is opened, a Cursor finds the two columns(_id, ACTIVITY1) and the data is retrieved. This class contains the primaryKey data that I use to search the database:
SQLiteOpenHelper sqLiteOpenHelper = new CalDatabaseHelper(context);
db = sqLiteOpenHelper.getReadableDatabase();
cursor = db.query("CAL",
new String[]{"_id","ACTIVITY1"},
"_id = ?",
new String[]{month_day_year},
null, null, null);
if (cursor.moveToFirst()){
String actOne = cursor.getString(0);
activityOne.setText(actOne);
}else{
Toast.makeText(context, "NOTHING FOUND DURING OPEN", Toast.LENGTH_LONG).show();
}
cursor.close();
db.close();
Up until this point, everything works fine. I am able to retrieve the data from the first column (_id) by using cursor.getString(0).
When I go to retrieve the data from the 2nd column (ACTIVITY1), I keep getting an empty String. For example, cursor.getString(1) returns "". This should be the data that my user inputted in my Appointments Activity. The data is clearly placed in to ContentValues within that class and then put in to the database. Any idea why nothing is coming up there? Is it because I am using db.insert() instead of the method I created in my databaseHelper class called insertIntoDatabase()? How come the primary key is inserted then anyway? Thank you
I have a task in which i have to display the rows selected using a query in one tab and the remaining rows in another tab. I have displayed the selected rows using SimpleCursorAdapter. When i tried to display the remaining rows in next tab it throws error. I have tried NOT IN but it also doesn't work. I have tried NOT EXISTS also it shows all rows. Anyone who can answer please help. I have posted my code here. Thanks in advance.
This is the activity of first tab which displays selected rows
public class OnlineDevices extends Activity {
ListView listOnline;
DatabaseHelper databaseHelper;
String count;
int conut;
TextView tvOnlineCount;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_online_devices);
listOnline=(ListView)findViewById(R.id.listView3);
tvOnlineCount = (TextView) findViewById(R.id.textView59);
databaseHelper=new DatabaseHelper(this);
SQLiteDatabase db=databaseHelper.getReadableDatabase();
String date= DateFormat.getDateInstance().format(new Date());
String statusQuery="select rowid _id, deviceContact from statusTable where sentTime='"+date+"'";
Cursor cursor1=db.rawQuery(statusQuery,null);
if (cursor1.getCount()>0){
while (cursor1.moveToNext()){
String deviceNo=cursor1.getString(cursor1.getColumnIndex("deviceContact"));
String device=deviceNo.substring(2, 12);
String query="select rowid _id, userName, uSerialNo from bikeTable where uContactNo='"+device+"' AND userName IS NOT NULL";
Cursor cursor2=db.rawQuery(query, null);
SimpleCursorAdapter adapter=new SimpleCursorAdapter(this,R.layout.status_item,cursor2,new String[]{"userName","uSerialNo"},new int[]{R.id.textView51,R.id.textView52});
listOnline.setAdapter(adapter);
}
}
try {
conut = listOnline.getAdapter().getCount();
count = String.valueOf(conut);
tvOnlineCount.setText(count);
}catch (Exception e){
e.printStackTrace();
int i=0;
Toast.makeText(OnlineDevices.this,"No device is active",Toast.LENGTH_SHORT).show();
tvOnlineCount.setText(String.valueOf(i));
}
}
}
Activity for second tab which display the remaining rows are
public class OfflineDevices extends Activity {
ListView listOffline;
DatabaseHelper databaseHelper;
String deviceContact;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_offline_devices);
listOffline=(ListView)findViewById(R.id.listView4);
databaseHelper=new DatabaseHelper(this);
SQLiteDatabase db=databaseHelper.getReadableDatabase();
String date= DateFormat.getDateInstance().format(new Date());
String query="select rowid _id, deviceContact from statusTable where sentTime='"+date+"'";
Cursor cursor1=db.rawQuery(query,null);
if (cursor1.getCount()>0){
while (cursor1.moveToNext()) {
deviceContact = cursor1.getString(cursor1.getColumnIndex("deviceContact"));
}
String device=deviceContact.substring(2, 12);
String query2="select rowid _id, userName, uSerialNo from bikeTable where userName IS NOT NULL AND uContactNo='"+device+"'";
Cursor cursor3=db.rawQuery(query2,null);
String query1="select rowid _id,*from bikeTable where userName IS NOT NULL NOT IN('"+query2+"')";
Cursor cursor2=db.rawQuery(query1,null);
SimpleCursorAdapter adapter=new SimpleCursorAdapter(this,R.layout.status_item,cursor2,new String[]{"userName","uSerialNo"},new int[]{R.id.textView51,R.id.textView52});
listOffline.setAdapter(adapter);
}
}
}
You have syntax errors in your query. In theory the following should work:
String query2 = "SELECT userName FROM bikeTable WHERE userName IS NOT NULL "
+ "AND uContactNo = '" + device + "'";
String query1 = "SELECT * FROM bikeTable WHERE userName IS NOT NULL "
+ "AND userName NOT IN(" + query2 + ")";
Here are the differences:
Your original code has single quotes around query2 inside the parentheses. This makes SQLite treat it as a string literal instead of an inner query.
Since query2 is being used in a NOT IN expression, it needs to
have a single result column, and it seems like userName is the one
you are interested in.
I advise spending some time going through the SQLite language pages. I'm fairly certain you can actually get the results you want using a single query that has a JOIN instead of making one query, checking the result, then making another query.
As an aside, it's considered best practice in Android to load data from a database on a background thread. Typically this is done with the Loader framework. You should also be closing cursors when you are finished with them (not the ones you give to the adapters, but the ones you use just to check for an online device).
Using the typical SQLiteDatabase object in Android's API, what can I do to get the next AUTO_INCREMENT value of a particular column (ie. id) without affecting the value itself. Is there a method for that? Or what query should I execute to get that result. Keep in mind that SQLiteDatabase.query() returns a Cursor object, so I'm not too sure how to deal with that directly if I just want to get a value out of it.
You're right. The first answer (still below) only works without an AUTOINCREMENT for id. With AUTOINCREMENT, the values are stored in a separate table and used for the increment. Here's an example of finding the value:
public void printAutoIncrements(){
String query = "SELECT * FROM SQLITE_SEQUENCE";
Cursor cursor = mDb.rawQuery(query, null);
if (cursor.moveToFirst()){
do{
System.out.println("tableName: " +cursor.getString(cursor.getColumnIndex("name")));
System.out.println("autoInc: " + cursor.getString(cursor.getColumnIndex("seq")));
}while (cursor.moveToNext());
}
cursor.close();
}
See: http://www.sqlite.org/autoinc.html
First Answer:
You can query for the max of the _id column, such as:
String query = "SELECT MAX(id) AS max_id FROM mytable";
Cursor cursor = db.rawQuery(query, null);
int id = 0;
if (cursor.moveToFirst())
{
do
{
id = cursor.getInt(0);
} while(cursor.moveToNext());
}
return id;
This works for row ids that haven't been specified as "INTEGER PRIMARY KEY AUTOINCREMENT" (all tables have a row id column).
This is the best way to get the last ID on auto increment PRIMARY KEY with SQLITE
String query = "select seq from sqlite_sequence WHERE name = 'Table_Name'"
An important remark about the SQLITE_SEQUENCE table.
The documentation says
The SQLITE_SEQUENCE table is created and initialized automatically whenever a normal table that contains an AUTOINCREMENT column is created.
So the SQLITE_SEQUENCE table is created, but NOT the row associated with the table that contains the AUTOINCREMENT column. That row is created with the first insert query (with "seq" value of 1).
That means that you must doing at least one insert operation before looking for the next autoincrement value of a specific table. It could be done for example just after the creation of the table, performing an insert and a delete of a dummy row.
Here is what I use to get the next AUTOINCREMENT value for a specific table:
/**
* Query sqlite_sequence table and search for the AUTOINCREMENT value for <code>tableName</code>
* #param tableName The table name with which the AUTOINCREMENT value is associated.
*
* #return The next AUTOINCREMENT value for <code>tableName</code>
* If an INSERT call was not previously executed on <code>tableName</code>, the value 1 will
* be returned. Otherwise, the returned value will be the next AUTOINCREMENT.
*/
private long getNextAutoIncrement(String tableName) {
/*
* From the docs:
* SQLite keeps track of the largest ROWID using an internal table named "sqlite_sequence".
* The sqlite_sequence table is created and initialized automatically
* whenever a normal table that contains an AUTOINCREMENT column is created.
*/
String sqliteSequenceTableName = "sqlite_sequence";
/*
* Relevant columns to retrieve from <code>sqliteSequenceTableName</code>
*/
String[] columns = {"seq"};
String selection = "name=?";
String[] selectionArgs = { tableName };
Cursor cursor = mWritableDB.query(sqliteSequenceTableName,
columns, selection, selectionArgs, null, null, null);
long autoIncrement = 0;
if (cursor.moveToFirst()) {
int indexSeq = cursor.getColumnIndex(columns[0]);
autoIncrement = cursor.getLong(indexSeq);
}
cursor.close();
return autoIncrement + 1;
}
Inside the SQLiteOpenHelper you use, start a transaction. Insert some data and then rollback.
Such a way, you 'll be able to get the next row id, like this:
public long nextId() {
long rowId = -1;
SQLiteDatabase db = getWritableDatabase();
db.beginTransaction();
try {
ContentValues values = new ContentValues();
// fill values ...
// insert a valid row into your table
rowId = db.insert(TABLE_NAME, null, values);
// NOTE: we don't call db.setTransactionSuccessful()
// so as to rollback and cancel the last changes
} finally {
db.endTransaction();
}
return rowId;
}
It's work.
public static long getNextId(SQLiteDatabase db, String tableName) {
Cursor c = null;
long seq = 0;
try {
String sql = "select seq from sqlite_sequence where name=?";
c = db.rawQuery(sql, new String[] {tableName});
if (c.moveToFirst()) {
seq = c.getLong(0);
}
} finally {
if (c != null) {
c.close();
}
}
return seq + 1;
}
You can use cursor.getInt(i); method
i here is index of the id column
Cursor c = db.rawQuery("Select * From mSignUp", null);
String mail = null;
try {
while (c.moveToNext()) {
mail = c.getString(0);
String pas = c.getString(1);
Toast.makeText(getApplicationContext(), "Name = " + mail + " Pass = " + pas, Toast.LENGTH_SHORT).show();
}
}catch (CursorIndexOutOfBoundsException e){
Log.e("OutOfBound", Log.getStackTraceString(e));
}
finally {
c.close();
}