I am trying to make an app named 'moviesinfo', in which I have a login page, with sign up and forgot password option. When I try to log in, the app crashes. I also don't know if the data entered on the sign-up page is being stored in the database or not.
This is my mainactivity.java
package com.example.moviesinfo;
import android.content.Intent;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
public class MainActivity extends AppCompatActivity {
SQLiteDatabase db;
SQLiteOpenHelper openHelper;
private EditText user;
private EditText password;
private Button btn;
private Button btn2;
private Button forgot;
Cursor cursor;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
forgot=findViewById(R.id.forgot);
btn2=(Button) findViewById(R.id.signup);
user= (EditText) findViewById(R.id.username);
password = (EditText) findViewById(R.id.password);
btn = (Button) findViewById(R.id.login);
openHelper= new DatabaseHelper(this);
db=openHelper.getReadableDatabase();
btn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
String username1= user.getText().toString();
String password1= password.getText().toString();
cursor = db.rawQuery("SELECT * FROM " +DatabaseHelper.TABLENAME + " WHERE " + DatabaseHelper.COL2 + "=? AND " + DatabaseHelper.COL3+"=?", new String[]{username1,password1});
if (cursor!=null){
if (cursor.getCount()>0){
cursor.moveToNext();
Intent intent = new Intent(MainActivity.this,listmenu.class);
startActivity(intent);
//Toast.makeText(getApplicationContext(),"Login Successful", Toast.LENGTH_SHORT).show();//
}else{
Toast.makeText(getApplicationContext(),"Error" , Toast.LENGTH_SHORT).show();
}
}
}
});
btn2.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
sign_up();
}
});
forgot.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
forgot();
}
});
}
private void sign_up()
{
Intent intent= new Intent(MainActivity.this, signup.class);
startActivity(intent);
}
private void forgot()
{
Intent intent= new Intent(MainActivity.this, forgot.class);
startActivity(intent);
}
}
This is the signup.java class
package com.example.moviesinfo;
import android.content.ContentValues;
import android.content.Intent;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
import java.lang.String;
import java.util.ArrayList;
public class signup extends AppCompatActivity {
SQLiteOpenHelper openHelper;
DatabaseHelper db;
SQLiteDatabase db1;
public String uname = "";
public String pwd = "";
public ArrayList<String> cpwd = new ArrayList<String>();
EditText e1, e2, e3;
Button b1,b2;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_signup);
openHelper= new DatabaseHelper(this);
e1 = (EditText) findViewById(R.id.username);
e2 = (EditText) findViewById(R.id.password);
e3 = (EditText) findViewById(R.id.cpwd);
b1 = (Button) findViewById(R.id.save);
b2 = (Button) findViewById(R.id.login2);
b1.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
db1=openHelper.getWritableDatabase();
String username =e1.getText().toString();
String password =e2.getText().toString();
String confirm_password =e3.getText().toString();
insert_data(username,password,confirm_password);
}
});
b2.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(signup.this,MainActivity.class);
startActivity(intent);
}
});
}
public void insert_data(String username, String password, String confirm_password)
{
ContentValues contentValues = new ContentValues();
contentValues.put(DatabaseHelper.COL2, username);
contentValues.put(DatabaseHelper.COL3, password);
contentValues.put(DatabaseHelper.COL4, confirm_password);
long id=db1.insert(DatabaseHelper.TABLENAME, null, contentValues);
}
}
This is the DatabseHelper.java class
package com.example.moviesinfo;
import com.example.moviesinfo.signup;
import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
public class DatabaseHelper extends SQLiteOpenHelper {
public static final String DATABASE_NAME="userdetails.db";
public static final String TABLENAME="user details";
public static final String COL1="id";
public static final String COL2="username";
public static final String COL3="password";
public static final String COL4="confirmpassword";
public DatabaseHelper(Context context) {
super(context, DATABASE_NAME, null,1);
}
#Override
public void onCreate(SQLiteDatabase db) {
db.execSQL("CREATE TABLE " + "TABLENAME(ID INTEGER PRIMARY KEY AUTOINCREMENT,USERNAME TEXT,PASSWORD TEXT,CONFIRMPASSWORD TEXT)");
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL("DROP TABLE IF EXISTS " +TABLENAME);
onCreate(db);
}
}
I expect that when I click the login button it should jump to the next activity with checking the login details from the database.
Issue 1
The first issue you will encounter is that the table name user details has a space. user will be extracted as the identifier but then the SQL parser is not expecting details, it is not a keyword or clause and thus a syntax error as per the following which would be found in the log :-
5-19 14:09:14.335 26779-26779/s.e.so56180693anotheractivity E/AndroidRuntime: FATAL EXCEPTION: main
Process: s.e.so56180693anotheractivity, PID: 26779
java.lang.RuntimeException: Unable to start activity ComponentInfo{s.e.so56180693anotheractivity/s.e.so56180693anotheractivity.MainActivity}: android.database.sqlite.SQLiteException: near "details": syntax error (code 1 SQLITE_ERROR): , while compiling: CREATE TABLE IF NOT EXISTS user details(_id INTEGER PRIMARY KEY,username TEXT,password TEXT, confirmpassword TEXT)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2913)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3048)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:78)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:108)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:68)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1808)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:193)
at android.app.ActivityThread.main(ActivityThread.java:6669)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)
Caused by: android.database.sqlite.SQLiteException: near "details": syntax error (code 1 SQLITE_ERROR): , while compiling: CREATE TABLE IF NOT EXISTS user details(_id INTEGER PRIMARY KEY,username TEXT,password TEXT, confirmpassword TEXT)
at android.database.sqlite.SQLiteConnection.nativePrepareStatement(Native Method)
at android.database.sqlite.SQLiteConnection.acquirePreparedStatement(SQLiteConnection.java:903)
at android.database.sqlite.SQLiteConnection.prepare(SQLiteConnection.java:514)
at android.database.sqlite.SQLiteSession.prepare(SQLiteSession.java:588)
at android.database.sqlite.SQLiteProgram.<init>(SQLiteProgram.java:58)
at android.database.sqlite.SQLiteStatement.<init>(SQLiteStatement.java:31)
at android.database.sqlite.SQLiteDatabase.executeSql(SQLiteDatabase.java:1769)
at android.database.sqlite.SQLiteDatabase.execSQL(SQLiteDatabase.java:1698)
at s.e.so56180693anotheractivity.DatabaseHelper.onCreate(DatabaseHelper.java:33)
at android.database.sqlite.SQLiteOpenHelper.getDatabaseLocked(SQLiteOpenHelper.java:393)
at android.database.sqlite.SQLiteOpenHelper.getReadableDatabase(SQLiteOpenHelper.java:322)
at s.e.so56180693anotheractivity.MainActivity.onCreate(MainActivity.java:35)
at android.app.Activity.performCreate(Activity.java:7136)
see Debug your app
An identifier can have normally unacceptable characters, such as a space, start with a number, if it is enclosed in specific characters as per :-
If you want to use a keyword as a name, you need to quote it. There are four ways of quoting keywords in SQLite:
'keyword' A keyword in single quotes is a string literal.
"keyword" A keyword in double-quotes is an identifier.
[keyword] A keyword enclosed in square brackets is an identifier. This is not
standard SQL. This quoting mechanism is used by MS Access and SQL
Server and is included in SQLite for compatibility.
keyword A keyword enclosed in grave accents (ASCII code 96) is an identifier.
This is not standard SQL. This quoting mechanism is used by MySQL and is included in SQLite for compatibility.
e.g. you could have :-
public static final String TABLENAME="user details"; //<<<<<<<<<< cannot have spaces in a name unless enclosed
//!!!!NOTE!!!! ONLY 1 of the below would be allowed
public static final String TABLENAME="`user details`"; //<<<<<<<<<< e.g (with space)
public static final String TABLENAME= "[user details]";
public static final String TABLENAME = "\"user details\"";
public static final String TABLENAME = "'user details'";
public static final String TABLENAME="user_details"; //<<<<<<<<<< changed to this for testing.
Read the comments
Fix for Issue 1
public static final String TABLENAME="user details";
was changed to :-
public static final String TABLENAME="user_details";
The App was uninstalled and rerun.
Issue 2
The next issue is that the SQL to create the table will not create a table named according to the value that the constant TABLENAME (user_details after applying the Fix 1) has. The table is named TABLENAME as the word TABLENAME is in quotes.
It results in the exception :-
2019-05-19 13:56:15.118 26443-26443/s.e.so56180693anotheractivity E/SQLiteLog: (1) no such table: user_details
Fix for Issue 2
The following is how it would be suggested that the CREATE TABLE sql is setup:-
//Uses the identifiers (names) as per the variables
db.execSQL("CREATE TABLE IF NOT EXISTS " + TABLENAME + "(" +
COL1 + " INTEGER PRIMARY KEY," + // NO NEED FOR INEFFICIENT AUTOINCREMENT
COL2 + " TEXT UNIQUE," + //ADDED UNIQUE so that user names are not duplicated
COL3 + " TEXT, " +
COL4 + " TEXT" +
")"
);
That is constants are used for the names.
IMPORTANT as this is a change to the database schema and that the database exists you MUST delete the database so that the DatabaseHelper onCreate method will run.
The keyword UNIQUE has been added, otherwise the same user could be added multiple times
Question
I also don't know if the data entered on the sign-up page is being
stored in the database or not.
To enable you to know or not and as you should now be aware of looking in the log then amending the insert_data method as follows will enable you to see if the data is being stored.
public long insert_data(String username, String password, String confirm_password) // Signature changed to return long (id)
{
ContentValues contentValues = new ContentValues();
contentValues.put(DatabaseHelper.COL2, username);
contentValues.put(DatabaseHelper.COL3, password);
contentValues.put(DatabaseHelper.COL4, confirm_password);
long id=db1.insert(DatabaseHelper.TABLENAME, null, contentValues);
//TODO REMOVE LOGGING BEFORE PUBLISHING THE APP
if (id > 0) {
Log.d("INSERTUSERDETAILSROW","The row was successfully inserted into the " + DatabaseHelper.TABLENAME + " table.");
} else {
Log.d("INSERTUSERDETAILSROW","Row not inserted!!!!!!!!!!");
}
return id; // Can be useful to have access to the id that was generated. Note method signature change
}
Example output :-
in the log :-
D/INSERTUSERDETAILSROW: The row was successfully inserted into the user_details table.
Issue 4
If the password and confirm_password values do not match, the row is still added i.e. the confirm_password values serves no purpose.
Fix for Issue 4
A check is added to only add data if the password and confirm_password values match. If they do not then a Toast is issued.
b1.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
db1=openHelper.getWritableDatabase();
String username =e1.getText().toString();
String password =e2.getText().toString();
String confirm_password =e3.getText().toString();
if (password.equals(confirm_password)) {
insert_data(username, password, confirm_password);
} else {
Toast.makeText(v.getContext(),"Password and Confirm Password do not match. Data not added.",Toast.LENGTH_LONG).show();
}
}
});
Issue 5
Although it won't appear to be a problem your should not start the activity when you want to return from an activity as that will destroy the initial activity and start another. The correct way is to finish the activity and it will then return to the actual activity from which it is was started from.
Fix for Issue 5
b2.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//Intent intent = new Intent(signup.this,MainActivity.class);
//startActivity(intent);
finish(); //<<<<<<<<<< Proper way to return
}
});
Done
That's it. The App should now be relatively functional as far as logging in and signing up is concerned.
Related
I've been following a tutorial on how to save data to the Firebase Realtime Database in Android.
With the tutorial i have managed to get this data to save etc however it only shows the last submitted item.
MainActivity code:
import android.os.Bundle;
import android.text.TextUtils;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import com.google.firebase.database.DataSnapshot;
import com.google.firebase.database.DatabaseError;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;
import com.google.firebase.database.ValueEventListener;
public class MainActivity extends AppCompatActivity {
// creating variables for
// EditText and buttons.
private EditText employeeNameEdt, employeePhoneEdt, employeeAddressEdt;
private Button sendDatabtn;
// creating a variable for our
// Firebase Database.
FirebaseDatabase firebaseDatabase;
// creating a variable for our Database
// Reference for Firebase.
DatabaseReference databaseReference;
// creating a variable for
// our object class
EmployeeInfo employeeInfo;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// initializing our edittext and button
employeeNameEdt = findViewById(R.id.idEdtEmployeeName);
employeePhoneEdt = findViewById(R.id.idEdtEmployeePhoneNumber);
employeeAddressEdt = findViewById(R.id.idEdtEmployeeAddress);
// below line is used to get the
// instance of our FIrebase database.
firebaseDatabase = FirebaseDatabase.getInstance();
// below line is used to get reference for our database.
databaseReference = firebaseDatabase.getReference("EmployeeInfo");
// initializing our object
// class variable.
employeeInfo = new EmployeeInfo();
sendDatabtn = findViewById(R.id.idBtnSendData);
// adding on click listener for our button.
sendDatabtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// getting text from our edittext fields.
String name = employeeNameEdt.getText().toString();
String phone = employeePhoneEdt.getText().toString();
String address = employeeAddressEdt.getText().toString();
// below line is for checking weather the
// edittext fields are empty or not.
if (TextUtils.isEmpty(name) && TextUtils.isEmpty(phone) && TextUtils.isEmpty(address)) {
// if the text fields are empty
// then show the below message.
Toast.makeText(MainActivity.this, "Please add some data.", Toast.LENGTH_SHORT).show();
} else {
// else call the method to add
// data to our database.
addDatatoFirebase(name, phone, address);
}
}
});
}
private void addDatatoFirebase(String name, String phone, String address) {
// below 3 lines of code is used to set
// data in our object class.
employeeInfo.setEmployeeName(name);
employeeInfo.setEmployeeContactNumber(phone);
employeeInfo.setEmployeeAddress(address);
// we are use add value event listener method
// which is called with database reference.
databaseReference.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot snapshot) {
// inside the method of on Data change we are setting
// our object class to our database reference.
// data base reference will sends data to firebase.
databaseReference.setValue(employeeInfo);
// after adding this data we are showing toast message.
Toast.makeText(MainActivity.this, "data added", Toast.LENGTH_SHORT).show();
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
// if the data is not added or it is cancelled then
// we are displaying a failure toast message.
Toast.makeText(MainActivity.this, "Fail to add data " + error, Toast.LENGTH_SHORT).show();
}
});
}
}
EmployeeInfo code:
public class EmployeeInfo {
// string variable for
// storing employee name.
private String employeeName;
// string variable for storing
// employee contact number
private String employeeContactNumber;
// string variable for storing
// employee address.
private String employeeAddress;
// an empty constructor is
// required when using
// Firebase Realtime Database.
public EmployeeInfo() {
}
// created getter and setter methods
// for all our variables.
public String getEmployeeName() {
return employeeName;
}
public void setEmployeeName(String employeeName) {
this.employeeName = employeeName;
}
public String getEmployeeContactNumber() {
return employeeContactNumber;
}
public void setEmployeeContactNumber(String employeeContactNumber) {
this.employeeContactNumber = employeeContactNumber;
}
public String getEmployeeAddress() {
return employeeAddress;
}
public void setEmployeeAddress(String employeeAddress) {
this.employeeAddress = employeeAddress;
}
}
Has anyone ever encountered this in Firebase. I have been looking for other tutorials which had ended up exactly like this so I'm not sure whether it is something in the code that is wrong or with my Firebase database.
As firebase overwrites the previous data you have entered.
You can use a .push() function like this before your setValue.
DatabaseReference database = FirebaseDatabase.getInstance().getReference("EmployeeInfo");
Then,
database.push().setValue(employeeObject);
The .push() method creates a child with a unique key in your database.
Try checking firebase docs for more info
Save Data on Firebase
, Read and Write on firebase
The key is like this Firebase RTDB
I'm working with Firebase's realtime database in order to make a recipe application in android studio. The code runs fine and nothing crashes, but every time it's supposed to send information to the database, it does not. I attempted to create a shell for it to put data into, and instead, I saw it erase it once it got past the part where it was supposed to send the data. I've done all the required imports, implementations and dependencies according to their documentation, as well as wrote the code according to it too, but it doesn't seem to work.
Firebase Realtime Database before I send data, plus rules screenshot:
Firebase RD before
Firebase RD rules
After it runs the logic to send the data, I see it go red and disappear, like it was deleted, and nothing is left behind.
Here is my HomeScreen.java code:
package com.capteamfour.recipeappdatabase;
import android.content.Intent;
import android.os.Bundle;
import com.google.android.material.floatingactionbutton.FloatingActionButton;
import com.google.firebase.auth.FirebaseAuth;
import com.google.firebase.auth.FirebaseUser;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;
import androidx.appcompat.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;
import android.widget.ImageButton;
import android.widget.TextView;
public class HomeScreen extends AppCompatActivity {
final FirebaseDatabase mDatabase = FirebaseDatabase.getInstance();
DatabaseReference mDatabaseUsers = mDatabase.getReference("USERS");
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_home_screen);
newUser(FirebaseAuth.getInstance().getCurrentUser().getDisplayName(),
FirebaseAuth.getInstance().getCurrentUser().getEmail());
String username = FirebaseAuth.getInstance().getCurrentUser().getDisplayName();
String email = FirebaseAuth.getInstance().getCurrentUser().getEmail();
TextView userWelcome = (TextView) findViewById(R.id.userWelcome);
FloatingActionButton addRecipe = (FloatingActionButton) findViewById(R.id.addRecipeButton);
ImageButton userProfile = (ImageButton) findViewById(R.id.userProfileButton);
// Welcomes the current user
userWelcome.setText("Welcome, " + username + "!");
// Creates a listener for the "add recipe" button; takes user to recipe form activity
addRecipe.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent toRecipeForm = new Intent(HomeScreen.this, recipeForm.class);
startActivity(toRecipeForm);
}
});
// Creates a listener for the "user Profile Button" button; takes user to profile activity
userProfile.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent ToProfile = new Intent(HomeScreen.this, Profile.class);
startActivity(ToProfile);
}
});
}
public void newUser(String name, String email)
{
userProfile user = new userProfile(name, email);
System.out.println("This is what I need to send: " + mDatabaseUsers.setValue(user));
mDatabaseUsers.setValue(user);
}
}
I declare a database instance and create a reference to the USERS path as global variables, and then made a function newUser(String name, String email) that creates an instance of a userProfile() class for me and is supposed to then send it to the database using the next line (the Sys.out was me trying to see what it was attempting to send if anything at all).
userProfile class code:
package com.capteamfour.recipeappdatabase;
import com.google.firebase.database.IgnoreExtraProperties;
import java.util.ArrayList;
import java.util.List;
#IgnoreExtraProperties
public class userProfile {
private String username;
private String email;
private List<Recipe> subRecipes = new ArrayList<>();
// Not yet implemented
private List<Recipe> favRecipes = new ArrayList<>();
private List<Recipe> savedRecipes = new ArrayList<>();
// A user profile will include their name, the recipes they've submitted, as well as recipes they've
// favorited or saved to their profile. Saved recipes are private to the user.
public userProfile() {
// Default constructor for DataSnapshot.getValue(userProfile.class) calls
}
public userProfile(String usernameIn, String emailIn)
{
this.username = username;
this.email = email;
}
public String getUsername () {
return this.username;
}
public String getEmail() {
return this.email;
}
/*
Each of these add functions will check the length of the given array and either
add to the end of it if there's already results, or just adds it on the empty array.
Example: array empty, then array[0] = recipe
array has values, then array[length + 1] = recipe
*/
public void addSubRecipe (Recipe recipe) {
int size = this.subRecipes.size();
if (size == 0) {
subRecipes.add(recipe);
}
else {
subRecipes.add(size+1, recipe);
}
}
public List<Recipe> getSubRecipes() {
return subRecipes.subList(0, (subRecipes.size()));
}
/*
These are commented out to prevent additional bugs and confusion while they're not implemented
public void addSavedRecipe (Recipe recipe) {
int size = this.savedRecipes.size();
if (size == 0) {
savedRecipes.add(recipe);
}
else {
savedRecipes.add(size + 1, recipe);
}
}
public List<Recipe> getSavedRecipes() {
return this.savedRecipes.subList(0, (subRecipes.size() + 1));
}
/*public void addFavRecipe (Recipe recipe) {
int size = this.favRecipes.size();
if (size == 0) {
favRecipes.add(recipe);
}
else {
favRecipes.add(size + 1, recipe);
}
}
public List<Recipe> getFavRecipes() {
return this.favRecipes.subList(0, (subRecipes.size() + 1));
}*/
}
In this class, I made sure to have an empty constructor with additional constructors and the usual get/set functions so that the database could work with it.
I appreciate any and all pointers that anyone could provide on how to fix this issue. This is for my college capstone course, and it's holding us up quite drastically for what appears to be no good reason. Thanks everyone.
I've done firebase authentication for login and sign up and now i want
to save user profile in local sqlite database. I've fetched the user
information from firebase and storing them in a string variable and
passing these variables to the Adduser function to save this data in
the local database.But data is not getting stored and showing "Error
with saving user" ,that is rowid is "-1" always. i'm new to android.
please help me to solve this issue. thanks in advance
java file
package com.example.mansi.busezon;
import android.app.Application;
import android.content.ContentValues;
mport android.content.Intent;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.TextView;
import android.widget.Toast;
import com.example.mansi.busezon.data.dbContract;
import com.example.mansi.busezon.data.dbHelper;
import com.google.firebase.FirebaseApp;
import com.google.firebase.database.DataSnapshot;
import com.google.firebase.database.DatabaseError;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;
import com.google.firebase.database.ValueEventListener;
i
public class SELL_BUY extends AppCompatActivity {
// private dbHelper mDbHelper;
String name;
String email ;
String address ;
String phoneno ;
String password ;
//String userId;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Set the content of the activity to use the activity_main.xml layout file
setContentView(R.layout.activity_sell__buy);
check();
TextView BUY= (TextView) findViewById(R.id.buy);
BUY.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
//create intent to open the activity
Intent BUYintent= new Intent(SELL_BUY.this,HomeActivity.class);
//start the new activity
startActivity(BUYintent);
}
});
TextView SELL= (TextView) findViewById(R.id.sell);
SELL.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
//create intent to open the activity
Intent SELLintent= new Intent(SELL_BUY.this,SellHomepage.class);
//start the new activity
startActivity(SELLintent);
}
});
}
public void sendMessage(View view)
{
Intent intent = new Intent(SELL_BUY.this, profile_page.class);
startActivity(intent);
}
private void check()
{
DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
//database reference pointing to demo node
// DatabaseReference demoRef = rootRef.child("CI8hvEW0sfZ0oU1GziTpGYPJv2z2");
// String value = "User22";
// //push creates a unique id in database
// demoRef.push().setValue(value);
rootRef.addListenerForSingleValueEvent(new ValueEventListener()
{
String userId=getIntent().getStringExtra("Id");
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
for(DataSnapshot ds : dataSnapshot.getChildren())
{
if(ds.getKey().equals(userId))
{
//name1="aakritijohar";
name = ds.child("name").getValue(String.class);
email = ds.child("email").getValue(String.class);
address = ds.child("addres").getValue(String.class);
phoneno = ds.child("phoneno").getValue(String.class);
TextView textView = (TextView) findViewById(R.id.test);
textView.setText(phoneno);
password = ds.child("password").getValue(String.class);
Toast.makeText(SELL_BUY.this, email + " " + ds.getKey(), Toast.LENGTH_SHORT).show();
insertUser(name,email,address,phoneno,password);
}
}
Bundle extras=getIntent().getExtras();
if(extras!=null) {
String name = extras.getString("name");
}
}
#Override
public void onCancelled(DatabaseError databaseError) {}
});
}
private void insertUser(String nameString,String EMAILString,String addressString,String numbertString,String pass) {
// Create database helper
dbHelper mDbHelper = new dbHelper(this);
// Gets the database in write mode
SQLiteDatabase db = mDbHelper.getWritableDatabase();
ContentValues values = new ContentValues();
values.put(dbContract.userEntry.COLUMN_USER_NAME, nameString);
values.put(dbContract.userEntry.COLUMN_EMAIL, EMAILString);
values.put(dbContract.userEntry.COLUMN_number, numbertString);
values.put(dbContract.userEntry.COLUMN_address, addressString);
values.put(dbContract.userEntry.COLUMN_password, pass);
// Insert a new row for user in the database, returning the ID of that new row.
long newRowId = db.insert(dbContract.userEntry.TABLE_NAME, null, values);
// Show a toast message depending on whether or not the insertion was successful
if (newRowId == -1) {
// If the row ID is -1, then there was an error with insertion.
Toast.makeText(this, "Error with saving user", Toast.LENGTH_SHORT).show();
} else {
// Otherwise, the insertion was successful and we can display a toast with the row ID.
Toast.makeText(this, "user saved " + newRowId, Toast.LENGTH_SHORT).show();
}
}
}
database helper class
package com.example.mansi.busezon.data;
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
/**
* Database helper for Pets app. Manages database creation and version management.
*/
public class dbHelper extends SQLiteOpenHelper {
public static final String LOG_TAG = dbHelper.class.getSimpleName();
/** Name of the database file */
private static final String DATABASE_NAME = "user.db";
/**
* Database version. If you change the database schema, you must increment the database version.
*/
private static final int DATABASE_VERSION = 1;
/**
* Constructs a new instance of {#link dbHelper}.
*
* #param context of the app
*/
public dbHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
/**
* This is called when the database is created for the first time.
*/
#Override
public void onCreate(SQLiteDatabase db) {
// Create a String that contains the SQL statement to create the pets table
String SQL_CREATE_USER_TABLE = "CREATE TABLE " + dbContract.userEntry.TABLE_NAME + " ("
+ dbContract.userEntry._ID + " INTEGER PRIMARY KEY AUTOINCREMENT, "
+ dbContract.userEntry.COLUMN_USER_NAME + " TEXT NOT NULL, "
+ dbContract.userEntry.COLUMN_address + " VARCHAR, "
+ dbContract.userEntry.COLUMN_number + " VARCHAR NOT NULL, "
+ dbContract.userEntry.COLUMN_EMAIL + " VARCHAR NOT NULL, "
+ dbContract.userEntry.COLUMN_password + " VARCHAR NOT NULL );";
// Execute the SQL statement
db.execSQL(SQL_CREATE_USER_TABLE);
}
/**
* This is called when the database needs to be upgraded.
*/
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
// The database is still at version 1, so there's nothing to do be done here.
}
}
There doesn't appear to be anything wrong with the code as it is.
As such I suspect that your issue may be that you have changed the table structure since running the App.
e.g. by adding a new column and then changing the code accordingly
However, that you have then not taken into consideration that the onCreate method only gets automatically invoked when the database is created.
That is the 'onCreate' method does not run every time the App is started.
I'd suggest that deleting the App's data or uninstalling the App and then rerunning the App will resolve the issue.
If that doesn't resolve the issue then please check the log as that should contain a stack-trace for when the insert comes across the issue even though the App doesn't itself crash (you could use the insertOrThrow method instead of insert which would then result in an exception/crash).
If you then still have issues, please update the question to include the stack-trace.
I have copy this code on internet and i want to display sqlite data in a new activity when a user click on item in recycleview under textview form.
This mainActivity:
package com.herprogramacion.crunch_expenses.ui;
import android.app.ActivityOptions;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.os.Bundle;
import android.support.v4.app.LoaderManager;
import android.support.v4.content.ContextCompat;
import android.support.v4.content.CursorLoader;
import android.support.v4.content.Loader;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.DividerItemDecoration;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.Toolbar;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.TextView;
import com.herprogramacion.crunch_expenses.utils.Utilidades;
import com.herprogramacion.crunch_expenses.R;
import com.herprogramacion.crunch_expenses.provider.ContractParaGastos;
import com.herprogramacion.crunch_expenses.sync.SyncAdapter;
public class MainActivity extends AppCompatActivity
implements LoaderManager.LoaderCallbacks<Cursor> {
private RecyclerView recyclerView;
private LinearLayoutManager layoutManager;
private AdaptadorDeGastos adapter;
private TextView emptyView;
private Context context;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
setToolbar();
recyclerView = (RecyclerView) findViewById(R.id.reciclador);
DividerItemDecoration dividerItemDecoration = new DividerItemDecoration(recyclerView.getContext(), DividerItemDecoration.VERTICAL);
dividerItemDecoration.setDrawable(ContextCompat.getDrawable(getBaseContext(), R.drawable.recycle_divider));
recyclerView.addItemDecoration(dividerItemDecoration);
layoutManager = new LinearLayoutManager(this);
recyclerView.setLayoutManager(layoutManager);
adapter = new AdaptadorDeGastos(this);
recyclerView.setAdapter(adapter);
emptyView = (TextView) findViewById(R.id.recyclerview_data_empty);
getSupportLoaderManager().initLoader(0, null, this);
SyncAdapter.inicializarSyncAdapter(this);
}
private void setToolbar() {
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
}
public void onClickFab(View v) {
Intent intent = new Intent(this, InsertActivity.class);
if (Utilidades.materialDesign())
startActivity(intent,
ActivityOptions.makeSceneTransitionAnimation(this).toBundle());
else startActivity(intent);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == R.id.action_sync) {
SyncAdapter.sincronizarAhora(this, false);
return true;
}
return super.onOptionsItemSelected(item);
}
#Override
public Loader<Cursor> onCreateLoader(int id, Bundle args) {
emptyView.setText("Cargando datos...");
// Consultar todos los registros
return new CursorLoader(
this,
ContractParaGastos.CONTENT_URI,
null, null, null, null);
}
#Override
public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
adapter.swapCursor(data);
emptyView.setText("");
}
#Override
public void onLoaderReset(Loader<Cursor> loader) {
adapter.swapCursor(null);
}
}
and that is a Database:
package com.herprogramacion.crunch_expenses.provider;
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteException;
import android.database.sqlite.SQLiteOpenHelper;
/**
* Clase envoltura para el gestor de Bases de datos
*/
class DatabaseHelper extends SQLiteOpenHelper {
public DatabaseHelper(Context context, String name, SQLiteDatabase.CursorFactory factory, int version) {
super(context, name, factory, version);
}
public void onCreate(SQLiteDatabase database) {
createTable(database); // Crear la tabla "gasto"
}
/**
* Crear tabla en la base de datos
*
* #param database Instancia de la base de datos
*/
private void createTable(SQLiteDatabase database) {
String cmd = "CREATE TABLE " + ContractParaGastos.GASTO + " (" +
ContractParaGastos.Columnas._ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " +
ContractParaGastos.Columnas.MONTO + " TEXT, " +
ContractParaGastos.Columnas.ETIQUETA + " TEXT, " +
ContractParaGastos.Columnas.FECHA + " TEXT, " +
ContractParaGastos.Columnas.DESCRIPCION + " TEXT," +
ContractParaGastos.Columnas.ID_REMOTA + " TEXT UNIQUE," +
ContractParaGastos.Columnas.ESTADO + " INTEGER NOT NULL DEFAULT "+ ContractParaGastos.ESTADO_OK+"," +
ContractParaGastos.Columnas.PENDIENTE_INSERCION + " INTEGER NOT NULL DEFAULT 0)";
database.execSQL(cmd);
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
try { db.execSQL("drop table " + ContractParaGastos.GASTO); }
catch (SQLiteException e) { }
onCreate(db);
}
}
Somebody help me to diplay this data in a new view please!
ps:i'm a french speaking, excuse my poor english. But i work it.
my real problem is how to write a code who take sqlite data and save
this in new activity.
As you have a column defined as name INTEGER PRIMARY KEY AUTOINCREMENT this column will uniquely identify the row in the table. As such, it's basically a matter of ascertaining this value and passing it to the activity that is called. A convenient way of doing this is by passing the value via an Intent Extra.
Note! in all likelihood you don't need AUTOINCREMENT, name INTEGER PRIMARY KEY, will still give you a unique row identifier, but without the overheads and restrictions of using AUTOINCREMENT
An Intent Extra is created using the the Intent's put method, it takes a key to identify the data/value and the data/value itself.
Here's an example of using Intent Extras :-
Intent intent = new Intent(this,DBTableDataViewActivity.class);
intent.putExtra(DBTableDataViewActivity.INTENTKEY_DATABASENAME,mCurrentDB.getname());
intent.putExtra(DBTableDataViewActivity.INTENTKEY_DATABASEPATH,mCurrentDB.getPath());
intent.putExtra(DBTableDataViewActivity.INTENTKEY_TABLENAME,tablebame);
startActivity(intent);
The first line creates an Intent object instance, referred to as intent, that will be used to start the DBtableDataViewActivity (the other activity).
The next three lines add Extras to the Intent (Strings in this case for the Database name, it's path and the Table name). The first parameter of the putExtra method is the key, as a String, to identify the Extra. The second parameter is the value to be sent (in your case you would put a long).
The last line starts the Activity according to the Intent.
The keys, in this case are based upon :-
public static final String INTENTKEY_DATABASEPATH = "ik_dbpath";
public static final String INTENTKEY_DATABASENAME = "ik_dbname";
public static final String INTENTKEY_TABLENAME = "ik_tablename";
In the called Activity you retrieve the Intents e.g. :-
Intent callingintent = this.getIntent();
mDatabaseName = callingintent.getStringExtra(INTENTKEY_DATABASENAME);
mDatabasepath = callingintent.getStringExtra(INTENTKEY_DATABASEPATH);
mTableName = callingintent.getStringExtra(INTENTKEY_TABLENAME);
One thing to note, as you will likely be sending a long is that you have to include a default value, as a second parameter, that is used if the Extra doesn't exist.
As a unique row identifier (rowid) should not be 0 (note you can force a rowid to be 0), then using a default value of 0 may suit.
Your solution, after you have obtained the unique row identifier (for this example into a long variable named id) would be along the lines of:-
Invoking Activity
Intent intent = new Intent(this,NewActivity.class);
intent.putExtra("ROWID_INTENT_KEY",id);
startActivity(intent);
NewActivity
....
onCreate() {
....
long passed_id = this.getIntent().getLongExtra("ROWID_INTENT_KEY",0);
if (passed_id > 0) {
..... do you stuff here
} else {
.... handle no valid id passed
}
}
In the above you could then retrieve the other relevant data by querying the database. An alternative could be to pass the other data via additional Intent Extras.
Here's a more Complex example:-
The Invoking Activity
invokes the ProductsAddEditActivity, passing multiple values via Intent Extras.
public void productEdit() {
Intent intent = new Intent(this,ProductsAddEditActivity.class);
intent.putExtra(
StandardAppConstants.INTENTKEY_CALLINGACTIVITY,
THIS_ACTIVITY
);
intent.putExtra(
StandardAppConstants.INTENTKEY_CALLINGMODE,
StandardAppConstants.CM_EDIT
);
intent.putExtra(StandardAppConstants.INTENTKEY_PRODUCTID,
plcsr.getLong(
plcsr.getColumnIndex(PRODUCTID_COLUMN)
));
intent.putExtra(StandardAppConstants.INTENTKEY_PRODUCTNAME,
plcsr.getString(
plcsr.getColumnIndex(PRODUCTNAME_COLUMN
)
));
intent.putExtra(StandardAppConstants.INTENTKEY_STORAGEID,
plcsr.getLong(
plcsr.getColumnIndex(PRODUCTSTORAGEREF_COLUMN)
));
intent.putExtra(StandardAppConstants.INTENTKEY_STORAGEORDER,
plcsr.getInt(
plcsr.getColumnIndex(PRODUCTSTORAGEORDER_COLUMN)
));
intent.putExtra(menucolorcode,passedmenucolorcode);
startActivity(intent);
}
in the ProductsAddeditActivity (effecctively in the onCreate method) :-
caller = getIntent().getStringExtra(
StandardAppConstants.INTENTKEY_CALLINGACTIVITY
);
calledmode = getIntent().getIntExtra(
StandardAppConstants.INTENTKEY_CALLINGMODE,
StandardAppConstants.CM_CLEAR
);
passedstorageid = 0;
if (calledmode == StandardAppConstants.CM_EDIT) {
passedproductid = getIntent().getLongExtra(
StandardAppConstants.INTENTKEY_PRODUCTID,
0
);
passedproductname = getIntent().getStringExtra(
StandardAppConstants.INTENTKEY_PRODUCTNAME
);
inputproductname.setText(passedproductname);
passedorder = getIntent().getIntExtra(
StandardAppConstants.INTENTKEY_STORAGEORDER,0
);
inputproductorder.setText(Integer.toString(passedorder));
passedstorageid = getIntent().getLongExtra(
StandardAppConstants.INTENTKEY_STORAGEID,0
);
passedstoragname = getIntent().getStringExtra(
StandardAppConstants.INTENTKEY_STORAGENAME
);
inputproductfilter.setText("");
this.setTitle(getResources().getString(R.string.productseditlabel));
}
stcsr.moveToPosition(-1);
while (stcsr.moveToNext()) {
if (stcsr.getLong(stcsr.getColumnIndex(
STORAGEID_COLUMN
)) == passedstorageid) {
inputproductstorage_spinner.setSelection(stcsr.getPosition());
break;
}
}
I am trying to follow this tutorial (Part 3) about getting SQLite Database to work with Android application. I've made some changes to the content but the code should be the same. The android application crashes after it opens without displaying anything and this is the output from LogCat:
11-25 11:42:43.281: E/AndroidRuntime(1098): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.munroproject/com.example.munroproject.MainActivity}: android.database.sqlite.SQLiteException: near "drop": syntax error (code 1): , while compiling: CREATE TABLE munro (_id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT, area TEXT, height TEXT, grid TEXT, drop TEXT, feature TEXT, country TEXT, geographurl TEXT, latitude TEXT, longitude TEXT)
and this is the contents of the database helper:
package com.example.munroproject;
import android.content.ContentValues;
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
public class DatabaseHelper extends SQLiteOpenHelper{
public static final String DATABASE_NAME = "munro_directory";
public DatabaseHelper(Context context) {
super(context, DATABASE_NAME, null, 1);
}
public void onCreate(SQLiteDatabase db){
String sql = "CREATE TABLE munro (" +
"_id INTEGER PRIMARY KEY AUTOINCREMENT, " +
"name TEXT, " +
"area TEXT, " +
"height TEXT, " +
"grid TEXT, " +
"drop TEXT, " +
"feature TEXT, " +
"country TEXT, " +
"geographurl TEXT, " +
"latitude TEXT, " +
"longitude TEXT)";
db.execSQL(sql);
ContentValues values = new ContentValues();
String inputvalue = "Ben Chonzie,Loch Tay to Perth,931,NN773308,645,cairn/shelter,S,NN7732430857,56.453851,-3.992057");
String[] msplit = inputvalue.split(",");
int j=0;
values.put("name",msplit[j++]);
values.put("area",msplit[j++]);
values.put("height",msplit[j++]);
values.put("grid",msplit[j++]);
values.put("drop",msplit[j++]);
values.put("feature",msplit[j++]);
values.put("country",msplit[j++]);
values.put("geograph",msplit[j++]);
values.put("latitute",msplit[j++]);
values.put("longitude",msplit[j++]);
db.insert("munro", "name", values);
}
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion){
db.execSQL("DROP TABLE IF EXISTS munro");
onCreate(db);
}
}
And the mainActivity file looks like this:
package com.example.munroproject;
import android.os.Bundle;
import android.app.Activity;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.view.View;
import android.widget.EditText;
import android.widget.ListAdapter;
import android.widget.ListView;
import android.widget.SimpleCursorAdapter;
public class MainActivity extends Activity {
protected EditText searchText;
protected SQLiteDatabase db;
protected Cursor cursor;
protected ListAdapter adapter;
protected ListView munroList;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
db = (new DatabaseHelper(this)).getWritableDatabase();
searchText = (EditText) findViewById (R.id.searchText);
munroList = (ListView) findViewById (R.id.list);
}
#SuppressWarnings("deprecation")
public void search(View view) {
// || is the concatenation operation in SQLite
cursor = db.rawQuery("SELECT _id, name, height, region FROM munro WHERE name || ' ' || height LIKE ?",
new String[]{"%" + searchText.getText().toString() + "%"});
adapter = new SimpleCursorAdapter(this,R.layout.munro_list_item,cursor,new String[] {"name", "height", "region"},new int[] {R.id.name, R.id.height, R.id.region});
munroList.setAdapter(adapter);
}
Any suggestions ?
"drop" is a reserved keyword in SQLite used to drop (or delete) tables. If you really want to use it, you can, by enclosing it in double quotes. See example below
CREATE TABLE "[tablename]" ("drop" text)
In sqlite INTEGER PRIMARY KEY is Autoincrement by default no need to specify INTEGER PRIMARY KEY AUTOINCREMENT In addition sql has inbuilt command drop so change the column/attribute name