I'm working my way through "Sam's Tech Yourself Android Application Development in 24 Hours" and at some point my Nickname and Email settings stopped saving correctly. It now doesn't save the Nickname at all and saves the Email to both. What have I done to cause this, and how can I fix it?
I think that these are the relevant areas of the code, but if you need more please ask.
As far as I can tell, this is still code from the book, and it used to work. Maybe a typo somewhere?
public class QuizActivity extends Activity {
public static final String GAME_PREFERENCES = "GamePrefs";
public static final String GAME_PREFERENCES_NICKNAME = null; //String
public static final String GAME_PREFERENCES_EMAIL = null; //String
#Override
protected void onPause() {
super.onPause();
EditText nicknameText = (EditText) findViewById(R.id.EditText_Nickname);
EditText emailText = (EditText) findViewById(R.id.EditText_Email);
String strNickname = nicknameText.getText().toString();
String strEmail = emailText.getText().toString();
// TODO: fix password and email saving and displaying improperly
Editor editor = mGameSettings.edit();
editor.putString(GAME_PREFERENCES_NICKNAME, strNickname);
editor.putString(GAME_PREFERENCES_EMAIL, strEmail);
editor.commit();
Toast.makeText(QuizSettingsActivity.this, R.string.settings_saved,
Toast.LENGTH_SHORT).show();
}
public void initNicknameEntry() {
EditText nicknameText = (EditText) findViewById(R.id.EditText_Nickname);
if (mGameSettings.contains(GAME_PREFERENCES_NICKNAME)) {
nicknameText.setText(mGameSettings.getString(
GAME_PREFERENCES_NICKNAME, ""));
}
}
public void initEmailEntry() {
EditText emailText = (EditText) findViewById(R.id.EditText_Email);
if (mGameSettings.contains(GAME_PREFERENCES_EMAIL)) {
emailText.setText(mGameSettings.getString(GAME_PREFERENCES_EMAIL,
""));
}
}
You must initialize these to distinct values:
public static final String GAME_PREFERENCES_NICKNAME = "Nickname"; //String
public static final String GAME_PREFERENCES_EMAIL = "Email"; //String
Otherwise SharedPreferences cannot distinguish between the two keys and will always return the first key found.
Related
I'm using Firebase Realtime Database to store data for a project. I'm using Android Studio and Java to create a mobile app. In this particular activity, a new user is filling out a form to sign up for the service. Once they input their info and hit the submit button, the on click handles that info and inserts it into the Database.
Here is the relevant code for that class:
public class CreateUserActivity extends AppCompatActivity {
private DatabaseReference mDatabaseReference;
private List<String> mInterestList;
private EditText mUsername;
private EditText mPassword;
private EditText mEmail;
private EditText mLocation;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_create_user);
mDatabaseReference = FirebaseDatabase.getInstance().getReference();
mInterestList = new ArrayList<>();
mUsername = findViewById(R.id.text_username);
mPassword = findViewById(R.id.text_password);
mEmail = findViewById(R.id.text_email);
mLocation = findViewById(R.id.text_location);
}
public void onCheckboxClicked(View view) {
CheckBox checkbox = (CheckBox) view;
boolean isChecked = checkbox.isChecked();
String interest = checkbox.getText().toString();
if(isChecked) {
mInterestList.add(interest);
}else {
mInterestList.remove(interest);
}
}
public void onSaveUser(View view) {
String username = mUsername.getText().toString();
String password = mPassword.getText().toString();
String email = mEmail.getText().toString();
String location = mLocation.getText().toString();
if(TextUtils.isEmpty(username) ||
TextUtils.isEmpty(password) ||
TextUtils.isEmpty(email) ||
TextUtils.isEmpty(location) ||
mInterestList.size() == 0) {
displayToast("Please enter values for all fields");
}else {
List<String> interests = mInterestList;
User user = new User(username, password, email, location, interests, null);
mDatabaseReference.child("users").child(username).setValue(user, new DatabaseReference.CompletionListener() {
#Override
public void onComplete(#Nullable DatabaseError databaseError, #NonNull DatabaseReference databaseReference) {
if(databaseError != null) {
Log.e(GetTogetherApp.LOG_TAG, databaseError.getMessage());
}else{
displayToast("User created!");
}
}
});
}
}
As I've run through breakpoints the error seems to fire on this line:
mDatabaseReference.child("users").child(username).setValue()
Specifically once I try and enter into the setValue() method. The other two child() calls work to find the path as intended. I have the database reference set as a member variable, so I'm not sure why it seems to lose it at that point.
Here's a look at my database structure
Firebase Database Structure Pic
Error in Android Studio:
The error message in your screenshot is in the variable inspector in the Android Studio debugger. It means that where the error occurs, there is no variable mDatabaseReference so the debugger can't show its value. This is not the actual cause of the crash, merely the debugger telling you that it can't show you something you asked for.
You can find the actual cause of the problem by inspecting the InvocationTargetException e.
I want to store the data from both the RadioButtons as well as the EditText values in the User attribute registeredData, but I don't know how to access my function in a way that allows me to grab all the data, as well as displaying a color change from the RadioButtons. Also how do I check if the input data is already in use (like email)?
I have tried splitting them into two different functions, but I can't get the data back from them into my User attribute registeredData. This is my first try at coding an app so any help is appreciated.
public class Registration extends AppCompatActivity {
private EditText displayname, email, password, confirmpassword;
private Button bsubmit;
private RadioGroup rgroup;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_registration);
displayname = findViewById(R.id.displayname);
email = findViewById(R.id.useremail);
password = findViewById(R.id.password);
confirmpassword = findViewById(R.id.confirmpassword);
bsubmit = findViewById(R.id.bsubmit);
rgroup = findViewById(R.id.rgroupteams);
bsubmit.setOnClickListener(onRegister);
}
private View.OnClickListener onRegister = new View.OnClickListener() {
#Override
public void onClick(View v) {
final User registeredData;
registeredData = new User();
switch (v.getId()) {
case R.id.bsubmit:
String useremail = email.getText().toString();
String userdisplayname = displayname.getText().toString();
String userpassword = password.getText().toString();
registeredData.email = useremail;
registeredData.displayname = userdisplayname;
registeredData.password = userpassword;
case R.id.rgroupteams:
RadioGroup group = findViewById(R.id.rgroupteams);
group.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(RadioGroup group, int idOfSelected) {
switch (idOfSelected) {
case R.id.rbtnmantis:
bsubmit.setBackgroundColor(Color.parseColor("#FF0000"));
bsubmit.setTextColor(Color.parseColor("#000000"));
registeredData.team = "Mantis";
break;
case R.id.rbtlightbringers:
bsubmit.setBackgroundColor(Color.parseColor("#F4DC00"));
bsubmit.setTextColor(Color.parseColor("#000000"));
registeredData.team = "LightBringers";
break;
case R.id.rbtncryptographers:
bsubmit.setBackgroundColor(Color.parseColor("#1C00AA"));
bsubmit.setTextColor(Color.parseColor("#FFFFFF"));
registeredData.team = "Cryptographers";
break;
default:
registeredData.team = "";
}
}
});
}
}
};
}
Right now the color change only turns on after I've have clicked the submit button because I don't know how to better set my setOnClickListener(), I haven't made use of any variables in the registeredData outside of this either, are they set up to be able to be accessed for some data (like displayname) to be displayed?
You need to move onCheckedChangeListener outside of onClickListener. Also, move registeredData outside onClickListener. Make sure that registeredData is "globally" accessible. Then on button click and checked listener you can set data from input fields and from checkboxes to the object.
Second, with TextUtils.isEmpty(email.getText().toString()) you can get boolean if email is empty or not. This you can use for other input fields, just send text to the isEmpty method
Disclaimer: I am a newbie to Android development :)
How can I pass the string values collected from this first class to the class below? I attempted this but only got null values.
Here's my main activity.
public class Register extends AppCompatActivity {
protected SnapToSellDataSource mDataSource;
public String sFullname;
public String sEmail;
public String sMobileNumber;
public String sPassword;
EditText full_name, email, mobile_number, pwd, copwd;
Button registerButton;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_register);
mDataSource = new SnapToSellDataSource(Register.this);
full_name = (EditText) findViewById(R.id.editText);
email = (EditText) findViewById(R.id.editText2);
mobile_number = (EditText) findViewById(R.id.editText3);
pwd = (EditText) findViewById(R.id.editText4);
copwd = (EditText) findViewById(R.id.editText5);
registerButton = (Button) findViewById(R.id.button);
registerButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Register register = new Register();
String editPassword = pwd.getText().toString();
String editConfirmPassword = copwd.getText().toString();
if(editPassword.equals(editConfirmPassword)) {
//This isn't overwriting the null class variables I
//instantiated so that I can pass them to the class below
sFullname = full_name.getText().toString();
sEmail = email.getText().toString();
sMobileNumber = mobile_number.getText().toString();
sPassword = pwd.getText().toString();
mDataSource.insertUser(register);
}
}
});
}
}
Here's the class that should receive the string values:
public class SnapToSellDataSource {
private SQLiteDatabase mDatabase;
private SnapToSellHelper mHelper;
private Context mContext;
public SnapToSellDataSource(Context context){
mContext = context;
mHelper = new SnapToSellHelper(mContext);
}
public void insertUser(Register register){
ContentValues values = new ContentValues();
values.put(SnapToSellHelper.COL_NAME, register.sFullname);
values.put(SnapToSellHelper.COL_EMAIL, register.sEmail);
values.put(SnapToSellHelper.COL_NUMBER, register.sMobileNumber);
values.put(SnapToSellHelper.COL_PASSWORD, register.sPassword);
mDatabase.insert(SnapToSellHelper.TBL_USERS, null, values);
}
}
I attempted to getText, getString from the second class but my app crashed maybe since the widgets were not yet assigned ids at the class level. Passing actual string values encased in quoation marks ("") works so it means the DatabaseHelper is properly set up.
I also tried declaring class variables and assigning the widget values to them but kept getting the "Cannot resolve symbol" error.
How you get a read from the local variables and pass them to the class variables that can then be set as public and read by another class; in this case, the second class?
You can not simply create instances of an activity in Android. Activities are not classes that you just do a “new” on and call their constructor. An instance of an Activity is created when the app starts or when an Intent starts an activity.
So doing this: Register register = new Register(); is not good! You can find good arguments here
Instead you can pass those values as parameters to the insertUser(params...) method or create a new User class and instantiate it with those string values and pass it to insertUser(user) method.
Method call:
mDataSource.insertUser(sFullname, sEmail, sMobileNumber, sPassword);
Method definition:
public void insertUser(String sFullname, String sEmail, String sMobileNumber, String sPassword) {
ContentValues values = new ContentValues();
values.put(SnapToSellHelper.COL_NAME, sFullname);
values.put(SnapToSellHelper.COL_EMAIL, sEmail);
values.put(SnapToSellHelper.COL_NUMBER, sMobileNumber);
values.put(SnapToSellHelper.COL_PASSWORD, sPassword);
mDatabase.insert(SnapToSellHelper.TBL_USERS, null, values);
}
Anyone, Please help, how to remove this warning in Eclipse..
I completely newbie in android developing and I want to know how to get remove this warning, indicated in this photo. It said "The value of the field LoginActivity.KEY_ERROR_MSG and KEY_ERROR is not used". Anyone?
Here's the code:
// JSON Response node names
private static String KEY_SUCCESS = "success";
private static String KEY_ERROR = "error";
private static String KEY_ERROR_MSG = "error_msg";
private static String KEY_UID = "uid";
private static String KEY_NAME = "name";
private static String KEY_EMAIL = "email";
private static String KEY_CREATED_AT = "created_at";
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.login);
// Importing all assets like buttons, text fields
inputEmail = (EditText) findViewById(R.id.loginEmail);
inputPassword = (EditText) findViewById(R.id.loginPassword);
btnLogin = (Button) findViewById(R.id.btnLogin);
btnLinkToRegister = (Button) findViewById(R.id.btnLinkToRegisterScreen);
loginErrorMsg = (TextView) findViewById(R.id.login_error);
// Login button Click Event
btnLogin.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
String email = inputEmail.getText().toString();
String password = inputPassword.getText().toString();
UserFunctions userFunction = new UserFunctions();
Log.d("Button", "Login");
JSONObject json = userFunction.loginUser(email, password);
// check for login response
try {
if (json.getString(KEY_SUCCESS) != null) {
loginErrorMsg.setText("");
String res = json.getString(KEY_SUCCESS);
if(Integer.parseInt(res) == 1){
// user successfully logged in
// Store user details in SQLite Database
DatabaseHandler db = new DatabaseHandler(getApplicationContext());
JSONObject json_user = json.getJSONObject("user");
// Clear all previous data in database
userFunction.logoutUser(getApplicationContext());
db.addUser(json_user.getString(KEY_NAME), json_user.getString(KEY_EMAIL), json.getString(KEY_UID), json_user.getString(KEY_CREATED_AT));
// Launch Dashboard Screen
Intent dashboard = new Intent(getApplicationContext(), DashboardActivity.class);
// Close all views before launching Dashboard
dashboard.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(dashboard);
// Close Login Screen
finish();
}else{
// Error in login
loginErrorMsg.setText("Incorrect username/password");
}
}
} catch (JSONException e) {
e.printStackTrace();
}
}
});
// Link to Register Screen
btnLinkToRegister.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
Intent i = new Intent(getApplicationContext(),
RegisterActivity.class);
startActivity(i);
finish();
}
});
}
}
I won't buy an Apple, if I'm not hungry :)
That means you are declared a filed and not using it anywhere. I just remove that, if I'm not using it anymore. Or at least comment it, for future uses.
put #SuppressWarnings("unused") before the variable where you are getting warning .
This warning message occurs when you declare variables which are not used within their respective scope.
This is not an error but it would be better if you remove unused variables.
Should you want to remove this warning message but would like to retain the declaration, place the following tag right on top of the variable with the warning (in case of class scope declaration) or on top of the method (method scope declaration) where it was declared:
#SuppressWarnings("unused")
I am spinning my wheels trying to create and Save a Customer Object to SQLite in Android,
Here is my Customer Class
public class Customer {
private int id;
private String Name;
private String EmailAddress;
private String Phone;
private Double InitialValue;
private Double BalanceOnCard = 0.00;
private String CardUID;
private Date EnrollmentDate = new Date();
private Date LastTransactionDate = new Date();
public Customer(){}
In my Activity I create private variables like so
public class EnrollmentActivity extends MenuOnlyActivity {
private CustomerSQLiteHelper db;
private final String TAG = "Customer_Add";
Button submitButton;
Button cancelButton;
private EditText customerNameEditText;
private EditText customerEmailEditText;
private EditText customerPhoneEditText;
private EditText valueToAddEditText;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.fragment_enrollment);
submitButton = (Button) findViewById(R.id.buttonEnrollment);
cancelButton = (Button) findViewById(R.id.CancelEnrollment);
customerNameEditText = (EditText) findViewById(R.id.editTextCustomerName);
customerEmailEditText = (EditText) findViewById(R.id.editTextCustomerEmailAddress);
customerPhoneEditText = (EditText) findViewById(R.id.editTextBusinessPhoneNumber);
valueToAddEditText = (EditText) findViewById(R.id.editTextValueToAdd);
And here is the SubmitButton listener and it is within this code block that it fails, Its not getting to the point of calling the DatabaseHelper to save the Customer object, it fails somewhere right after creating a blank Customer object and starting to set the instance variables.
Log.i(TAG, "Entering Submit Button event");
submitButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if (customerNameEditText.getText().length() == 0) {
Toast.makeText(EnrollmentActivity.this, "Enter Customer's name", Toast.LENGTH_SHORT).show();
customerNameEditText.requestFocus();
return;
}
Log.i(TAG, "Create new customer");
//Create new customer object
Customer enteredCustomer = new Customer();
Log.i(TAG, "Created blank customer object");
Log.i(TAG, "populate the new customer object");
//Populate the values of the new object with the values entered in the screen
enteredCustomer.setId(1);
enteredCustomer.setName(customerNameEditText.getText().toString());
enteredCustomer.setEmailAddress(customerEmailEditText.getText().toString());
enteredCustomer.setPhone(customerPhoneEditText.getText().toString());
String enteredValueSting = valueToAddEditText.getText().toString();
double storedValue = Double.parseDouble(enteredValueSting); //convert String to Double
enteredCustomer.setInitialValue(storedValue);
enteredCustomer.setCardUID("ABC123");
Log.i(TAG, "Creating DB Instance");
db = new CustomerSQLiteHelper(EnrollmentActivity.this);
Log.i(TAG, "Created Database instance");
if (db.create(enteredCustomer) != -1) {
Toast.makeText(EnrollmentActivity.this,"Add Customer Successful",Toast.LENGTH_SHORT).show();
customerNameEditText.getText().clear();
customerEmailEditText.getText().clear();
customerPhoneEditText.getText().clear();
valueToAddEditText.getText().clear();
} else {
Toast.makeText(EnrollmentActivity.this, "Add Customer failed", Toast.LENGTH_SHORT).show();
}
}
});
The error message is all over the place, It consistently gives a toast "Unfortunately PROJECT_NAME has stopped" The current console error is "n established connection was aborted by the software in your host machine
java.io.IOException: An established connection was aborted by the software in your host machine" I have restarted Eclipse and Emulator a couple of times. Any help/suggestion will be greatly appreciated.
After more hair pulling I did two things to isolate and resolve the issue, first I created a a default constructor and initialized the parameters to sensible defaults, null for strings and 0 for Ints, then I renamed all my XML IDs to match the Java variables I created in the Activity. Now I am able to create instance of my Customer objects and persist to database.