I am new to Firebase and I am trying to make an Android app where users can track workouts by creating activities and the activities are then stored in a database (Firebase). However, when I try to add each activity object to the database, only some of the fields are inserted. Please see relevant code below
Activity class
public class Activity {
private String workout, user, exercise, duration, weight, reps, date, activity_workout_user;
Activity(String workout, String user, String exercise, String duration, String weight, String reps, String date) {
this.workout = workout;
this.user = user;
this.exercise = exercise;
this.duration = duration;
this.weight = weight;
this.reps = reps;
this.date = date;
this.activity_workout_user = exercise + "_" + workout + "_" + user;
}
//getters and setters
}
AddActivity class
public class AddActivity extends AppCompatActivity {
FirebaseDatabase database;
DatabaseReference ref;
String user, workoutName, timeCreated;
Spinner AAexerciseSP;
EditText AArepsET, AAdurationET, AAweightET;
TextView AAworkoutNameTV, AAerrorsTV, AAinfoTV;
Button AAaddActivityBTN, AAsaveWorkoutBTN;
static ArrayList<Activity> activities;
int totalActivities = 0;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_add);
database = FirebaseDatabase.getInstance();
ref = database.getReference();
SQLquery = "";
activities = new ArrayList<>();
Intent intent = getIntent();
user = intent.getStringExtra("username");
workoutName = intent.getStringExtra("workout_name");
timeCreated = DateTime.TimeDate();
AAworkoutNameTV = findViewById(R.id.AAworkoutNameTV);
AAerrorsTV = findViewById(R.id.AAerrorsTV);
AAinfoTV = findViewById(R.id.AAinfoTV);
AAexerciseSP = findViewById(R.id.AAexerciseSP);
AAaddActivityBTN = findViewById(R.id.AAaddActivityBTN);
AAsaveWorkoutBTN = findViewById(R.id.AAsaveWorkoutBTN);
AArepsET = findViewById(R.id.AArepsET);
AAdurationET = findViewById(R.id.AAdurationET);
AAweightET = findViewById(R.id.AAweightET);
AAworkoutNameTV.setText(String.format("Workout name: %s", workoutName));
// Create an ArrayAdapter using the string array and a default spinner layout
ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(this,
R.array.exercise_list, android.R.layout.simple_spinner_item);
// Specify the layout to use when the list of choices appears
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
// Apply the adapter to the spinner
AAexerciseSP.setAdapter(adapter);
AAexerciseSP.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
#Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
String item = (String) parent.getSelectedItem();
String[] array = getResources().getStringArray(R.array.cardio_exercises);
List<String> exercises = Arrays.asList(array);
}
#Override
public void onNothingSelected(AdapterView<?> parent) {
}
});
}
public String selectedExercise(){
return (String) AAexerciseSP.getSelectedItem();
}
public void addActivity(View view){
String activityExercise = selectedExercise();
String activityUser = user;
String activityWorkout = workoutName;
String activityDuration = AAdurationET.getText().toString();
String activityReps = AArepsET.getText().toString();
String activityWeight = AAweightET.getText().toString();
String activityDate = DateTime.TimeDate();
Activity activity = new Activity(activityWorkout, activityUser, activityExercise,
activityDuration, activityWeight, activityReps, timeCreated);
activities.add(activity);
totalActivities += 1;
}
public void saveWorkout(View view){
for (Activity activity:activities){
String key = database.getReference("activities").push().getKey();
assert key != null;
ref.child("activities").child(key).setValue(activity);
}
Workout workout = new Workout(workoutName,user,timeCreated,"");
String key = database.getReference("workouts").push().getKey();
assert key != null;
ref.child("workouts").child(key).setValue(workout);
startActivity(new Intent(this, HomePage.class));
}
}
The insertion of each activity object into the database happens in the "saveWorkout" method, but instead of inserting all the fields from the class, only the "activity_workout_user" and "user" fields are inserted. Please see below for the snippet from the database.
Any help getting all the fields to be inserted would be greatly appreciated.
Thanks in advance,
Cheers
I would like to comment, but I am very new to stackoverflow, so I cant comment yet.
I just recently started to use Firebase myself and i didnt learn to use it 100% properly.
But I read, that when it comes to adding custom objects to the database, the objects should have an additional constructor without parameters and there should be getters and setters for every variable.
Related
I have a MainAtivity which has some EditText and 2 button. Save button will save user input to ListView and List button to show ListView (which I display in second activity).
Is there anyway to collect data from multiple inputs then pass it to other activity. And after get that data how to combine it to a List item.
Please show me some code and explain cause I'm a beginner.
I have read some post and they suggest use startActivityForResult, intent, bundles but I still don't understand.
This is my Main class:
public class MainActivity extends AppCompatActivity {
String str, gender, vaccine, date;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button okay = (Button) findViewById(R.id.btnOk);
Button list = (Button) findViewById(R.id.btnList);
EditText name = (EditText) findViewById(R.id.inputName);
EditText address = (EditText) findViewById(R.id.inputAdd);
EditText phone = (EditText) findViewById(R.id.inputPhone);
RadioGroup radioGroup = (RadioGroup) findViewById(R.id.radioGroup);
RadioButton female = (RadioButton) findViewById(R.id.inputFemale);
RadioButton male = (RadioButton) findViewById(R.id.inputMale);
CheckBox first = (CheckBox)findViewById(R.id.inputFirst);
CheckBox second = (CheckBox)findViewById(R.id.inputSecond);
CheckBox third = (CheckBox)findViewById(R.id.inputThird);
EditText datefirst = (EditText) findViewById(R.id.dateFirst);
EditText datesecond = (EditText) findViewById(R.id.dateSecond);
EditText datethird = (EditText) findViewById(R.id.dateThird);
TextView result = (TextView)findViewById(R.id.textResult);
okay.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if(female.isChecked()) gender = female.getText().toString();
if(male.isChecked()) gender = male.getText().toString();
if(first.isChecked()) {
vaccine = first.getText().toString();
date = datefirst.getText().toString();
}
if(second.isChecked()) {
vaccine = second.getText().toString();
date = datesecond.getText().toString();
}
if(third.isChecked()) {
vaccine = third.getText().toString();
date = datethird.getText().toString();
}
str = name.getText().toString() + "\n" + address.getText().toString() + "\n" + phone.getText().toString() + "\n" +
gender + "\n" + vaccine + "\n" + date;
result.setText(str);
Toast.makeText(getApplicationContext(),result.getText().toString(),Toast.LENGTH_SHORT).show();
Intent intent = new Intent(MainActivity.this, PersonView.class);
intent.putExtra("NAME",name.getText().toString());
startActivity(intent);
}
});
list.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent intent = new Intent(MainActivity.this, PersonView.class);
startActivity(intent);
}
});
}
}
This is my ListView class:
public class PersonView extends AppCompatActivity {
ArrayList<Person> listPerson;
PersonListViewAdapter personListViewAdapter;
ListView listViewPerson;
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_list);
Intent intent = getIntent();
String message = intent.getStringExtra("NAME");
Button back = (Button) findViewById(R.id.btnBack);
back.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent intent = new Intent(PersonView.this, MainActivity.class);
//startActivityForResult(intent,2);
}
});
listPerson = new ArrayList<>();
listPerson.add(new Person("Lieu Mai","25 Mac Dinh Chi", "0786867073", "female","3 injection", "24/07/2000"));
personListViewAdapter = new PersonListViewAdapter(listPerson);
listViewPerson = findViewById(R.id.listPerson);
listViewPerson.setAdapter(personListViewAdapter);
}
class Person {
String name, address, phone, gender, vaccine, date;
public Person( String name, String address, String phone, String gender, String vaccine, String date) {
this.name = name;
this.address = address;
this.phone = phone;
this.gender = gender;
this.vaccine = vaccine;
this.date = date;
}
}
class PersonListViewAdapter extends BaseAdapter {
final ArrayList<Person> listPerson;
PersonListViewAdapter(ArrayList<Person> listPerson) {
this.listPerson = listPerson;
}
#Override
public int getCount() {
return listPerson.size();
}
#Override
public Object getItem(int position) {
return listPerson.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View viewPerson;
if (convertView == null) {
viewPerson = View.inflate(parent.getContext(), R.layout.person_view, null);
} else viewPerson = convertView;
Person person = (Person) getItem(position);
((TextView) viewPerson.findViewById(R.id.txtName)).setText(String.format("Name: %s", person.name));
((TextView) viewPerson.findViewById(R.id.txtAddress)).setText(String.format("Address : %s", person.address));
((TextView) viewPerson.findViewById(R.id.txtPhone)).setText(String.format("Phone number: %s", person.phone));
((TextView) viewPerson.findViewById(R.id.txtGender)).setText(String.format("Gender: %s", person.gender));
((TextView) viewPerson.findViewById(R.id.txtVaccine)).setText(String.format("Vaccine: %s", person.vaccine));
((TextView) viewPerson.findViewById(R.id.txtDate)).setText(String.format("Date: %s", person.date));
return viewPerson;
}
}
}
You should look into the Singleton pattern. It is very simple as there is no external DB. What it essentially is a class that manages the data and lets other classes and activities use the data while not allowing duplication.
You have a model Person
public class Person {
private String name;
public String address;
...
constructors and getters and setters
Create a class PersonsSingelton something like this.
public class PersonManagerSingleton {
private PersonManagerSingleton() {
loadPersonsDataSet();
}
private static PersonManagerSingleton instance = null;
public static PersonManagerSingleton getInstance() {
// if there is a instance already created use that instance of create new instance
// instance created in MainActivity and you try to create a new instance in Details
// should not happen as that will cause data duplication.
if (instance == null) {
instance = new PersonManagerSingleton();
}
return instance;
}
private ArrayList<Person> personList = new ArrayList<Person>();
private void loadPersonsDataSet() {
this.personList.add(new Person(...));
this.personList.add(new Person(...));
this.personList.add(new Person(...));
this.personList.add(new Person(...));
}
public ArrayList<Person> getpersonList() {
return personList;
}
public Person getPersonByID(int PersonNumber) {
for (int i = 0; i < this.personList.size(); i++) {
Person curPerson = this.personList.get(i);
if (curPerson.getNumber() == PersonNumber) {
return curPerson;
}
}
return null;
}
// methods for adding a new person used in Activity with the form.
// other methods ...
}
This would be like a state in React. of the State Manager.
Your person adapter constructor has to accept an ArrayList<Person> listPerson. So modify the activity passing the data to pass only the position of the ListView clicked. You need to modify your Adapter for that.
Use the Singleton created to access the data.
PersonManagerSingleton personSingelton = PersonManagerSingleton.getInstance();
ArrayList<Person> listPerson = personSingelton.getPersonList();
PersonAdapter Person = new PersonAdapter(listPerson);
So now only things left is to modify the Persons adapter to pass position using Intent and nothing else. and then you can use the instance of Singleton in other files to access the data using the listPerson.get(position) and using getters and setters.
Link to a project like this.
https://github.com/smitgabani/anroid_apps_using_java/tree/main/pokemon_app
I am new to app development and so far my app is working as intended but only when I launch it on my device from Android Studio. For example, I have once instance variable that I give a value of 1 in the onCreate() method. When I launch the app from android studio on to my device, it works fine and the variable has a value of 1. However, when I launch it from my device without using android studio, the variable is given a value of 0. I have also found that I will get a bunch of NullPointerExceptions on variables that I know should have a value, and once again it works when launched from Android Studio, but not when launched from the device.
Here is MainActivity
public class MainActivity extends AppCompatActivity
{
private ArrayList<String> arrayList;
private ArrayList<ListItem> itemList;
private ArrayAdapter<String> adapter;
private EditText txtInput;
private int payRoll;
private String value;
private Intent mainToPayroll;
private int hours;
private int earnings;
private ArrayList<Integer> rollList;
private ArrayList<Integer> hourList;
private ArrayList<Integer> wageList;
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
rollList = new ArrayList<>(0);
hourList = new ArrayList<>(0);
wageList = new ArrayList<>(0);
payRoll = 1;
Bundle bun = getIntent().getExtras();
if(bun != null)
{
rollList = bun.getIntegerArrayList("rolls");
hourList = bun.getIntegerArrayList("hours");
wageList = bun.getIntegerArrayList("wages");
payRoll = bun.getInt("roll");
}
ListView listView = (ListView) findViewById(R.id.listv);
String[] items = {};
arrayList = new ArrayList<>(Arrays.asList(items));
itemList = new ArrayList<>(0);
adapter = new ArrayAdapter<String>(this, R.layout.list_item, R.id.txtitem, arrayList);
listView.setAdapter(adapter);
Button btAdd = (Button) findViewById(R.id.btadd);
mainToPayroll = new Intent(this, PayrollActivity.class);
if(rollList != null)
{
for (int i = 0; i < rollList.size(); i++) {
ListItem newItem = new ListItem(rollList.get(i), hourList.get(i), wageList.get(i));
arrayList.add(newItem.toString());
itemList.add(newItem);
adapter.notifyDataSetChanged();
}
rollList.clear();
hourList.clear();
wageList.clear();
}
btAdd.setOnClickListener(new View.OnClickListener()
{
public void onClick(View v)
{
ListItem newItem = new ListItem(payRoll, 0, 0);
arrayList.add(newItem.toString());
itemList.add(newItem);
adapter.notifyDataSetChanged();
payRoll++;
}
});
listView.setOnItemClickListener(new AdapterView.OnItemClickListener()
{
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id)
{
value = (String)adapter.getItem(position);
ListItem item = itemList.get(position);
Bundle info = new Bundle();
info.putString("val", value);
info.putInt("hours", item.getHours());
info.putInt("wage", item.getWages());
info.putInt("pos", position);
if(itemList.size() > 0)
{
for (ListItem items : itemList)
{
rollList.add(items.getPayroll());
hourList.add(items.getHours());
wageList.add(items.getWages());
}
}
info.putIntegerArrayList("rolls", rollList);
info.putIntegerArrayList("hours", hourList);
info.putIntegerArrayList("wages", wageList);
info.putInt("roll", payRoll);
info.putBoolean("rest", restore);
mainToPayroll.putExtras(info);
startActivity(mainToPayroll);
}
});
}
This Activity is started whenever an item on the listview is clicked
public class PayrollActivity extends AppCompatActivity
{
private static TextView text;
private String payrollNumber;
private int payrollHrs;
private int payrollWages;
private int position;
private Intent payrollToMain;
private Button returnButton;
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_payroll);
final Bundle info = getIntent().getExtras();
System.out.print(getIntent().getType());
payrollNumber = info.getString("val");
payrollHrs = info.getInt("hours");
payrollWages = info.getInt("wage");
position = info.getInt("pos");
payrollToMain = new Intent(this, MainActivity.class);
returnButton = (Button) findViewById(R.id.btnRtrn);
returnButton.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View v)
{
Bundle thing = new Bundle();
thing.putIntegerArrayList("rolls", info.getIntegerArrayList("rolls"));
thing.putIntegerArrayList("hours", info.getIntegerArrayList("hours"));
thing.putIntegerArrayList("wages", info.getIntegerArrayList("wages"));
thing.putInt("roll", info.getInt("roll"));
thing.putBoolean("rest", info.getBoolean("rest"));
payrollToMain.putExtras(thing);
startActivity(payrollToMain);
}
});
text = (TextView) findViewById(R.id.title);
text.setText(payrollNumber);
}
public static void setLabelText(String val)
{
text.setText(val);
}
This is a class I created for the items that go on the listview
public class ListItem
{
private int payroll;
private int hrs;
private int wages;
public ListItem(int roll, int hours, int wag)
{
payroll = roll;
hrs = hours;
wages = wag;
}
public int getPayroll()
{
return payroll;
}
public int getHours()
{
return hrs;
}
public int getWages()
{
return wages;
}
public void setPayroll(int roll)
{
payroll = roll;
}
public void setHrs(int hours)
{
hrs = hours;
}
public void setWages(int wage)
{
wages = wage;
}
public String toString()
{
return "Payroll " + payroll + "\n" + hrs + " hours\n$" + wages;
}
I think your problem is this piece of code in your MainActivity:
Bundle bun = getIntent().getExtras();
if(bun != null)
{
rollList = bun.getIntegerArrayList("rolls");
hourList = bun.getIntegerArrayList("hours");
wageList = bun.getIntegerArrayList("wages");
payRoll = bun.getInt("roll");
}
The getIntent().getExtras() may return a non-null Bundle object but the bundle may not have the keys you are trying to access, in which case all your instance variables will be set to null or zero for int.
You can get around this by simply checking if a particular key exists in the bundle and only setting your variable if it does.
bun.containsKey()
Or you can initialize your variables if they are null after loading them from the bundle.
Try uninstalling the app completely from the device and then try again. This solves the issue at times.
I am not sure why, I have explored both .setValue() and .updateChildren() methods, but for whatever reason when I read data from firebase it is returning null. Here is how I write to Firebase:
Model Poll Class:
#IgnoreExtraProperties
public class Poll {
private String question;
private String image_URL;
public Poll() {
}
public Poll(String Question, String Image_URL) {
this.question = Question;
this.image_URL = Image_URL;
}
public String getQuestion() {
return question;
}
public void setQuestion(String question) {
this.question = question;
}
public String getImage_URL() {
return image_URL;
}
public void setImage_URL(String image_URL) {
this.image_URL = image_URL;
}
#Exclude
public Map<String, Object> toMap(){
HashMap<String, Object> result = new HashMap<>();
result.put("question", question);
result.put("image_URL", image_URL);
return result;
}
}
*I am following the documentation here with my .toMap() method and use of .updateChildren()
Here is where I create my Firebase references and write to the database:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_create);
mStorage = FirebaseStorage.getInstance();
mStorageRef = mStorage.getReferenceFromUrl("gs://firebase-fan-polls.appspot.com");
mBaseRef = FirebaseDatabase.getInstance().getReference();
mPollsRef = mBaseRef.child("Polls");
mAddImageButton = (FloatingActionButton) findViewById(R.id.add_image_button);
mAddAnswersButton = (ImageView) findViewById(R.id.add_answers_button);
mImagePreview = (ImageView) findViewById(R.id.preview_image);
mCreatePollQuestion = (EditText) findViewById(R.id.create_poll_question_editText);
mCreatePollAnswerCounter = (TextView) findViewById(R.id.create_poll_answer_counter_TextView);
mEditTextAnswerLayout = (ViewGroup) findViewById(R.id.create_poll_questions_answer_layout);
mSubmitPollCreation = (FloatingActionButton) findViewById(R.id.submit_poll_FAB);
mNumberOfPollAnswersCreatedByUser = 2;
mAnswerChoices = new ArrayList<>();
mCreatePollAnswerCounter.setText(String.valueOf(mNumberOfPollAnswersCreatedByUser));
for (int i = 0; i < mNumberOfPollAnswersCreatedByUser; i++) {
createAnswerChoice(i + 1);
}
mAddAnswersButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
mNumberOfPollAnswersCreatedByUser++;
if (mNumberOfPollAnswersCreatedByUser > 5) {
Toast.makeText(getApplicationContext(), R.string.max_create_answers, Toast.LENGTH_SHORT).show();
return;
}
createAnswerChoice(mNumberOfPollAnswersCreatedByUser);
mCreatePollAnswerCounter.setText(String.valueOf(mNumberOfPollAnswersCreatedByUser));
}
});
mSubmitPollCreation.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//TODO: Need to check if poll requirements are added, i.e. Question, Answer, ......
//check if image has been loaded first
if (resultImageURL == null) {
Toast.makeText(getApplicationContext(), getResources().getString(R.string.no_image_selected), Toast.LENGTH_LONG).show();
return;
}
Poll poll = new Poll(mCreatePollQuestion.getText().toString(), resultImageURL);
Map <String, Object> pollMap = poll.toMap();
String key = mBaseRef.child("Polls").push().getKey();
Map<String, Object> childUpdates = new HashMap<String, Object>();
childUpdates.put("/Polls/" + key, pollMap);
mBaseRef.updateChildren(childUpdates);
if (mNumberOfPollAnswersCreatedByUser > 5) {
Toast.makeText(getApplicationContext(), getResources().getText(R.string.poll_answers_greater_than_five), Toast.LENGTH_LONG).show();
mNumberOfPollAnswersCreatedByUser = 5;
}
Intent toHomeActivity = new Intent(CreateActivity.this, HomeActivity.class);
toHomeActivity.putExtra("viewpager_position", 2);
startActivity(toHomeActivity);
}
});
Everything is writing to Firebase correctly, as I can see it in the database in my console. I try and read it from this activity:
public class PollFragment extends Fragment {
#Bind(R.id.comment_label_counter)
TextView mCommentCounter;
#Bind(R.id.comments_label_icon)
ImageView mCommentsLabelIcon;
private DatabaseReference mBaseRef;
private DatabaseReference mPollsRef;
private DatabaseReference mSelectedPollRef;
private RadioGroup mPollQuestionRadioGroup;
private RadioGroup.LayoutParams mParams;
//static
private TextView mCommentsLabel;
private TextView mTotalVoteCounter;
private TextView mSelectedVote;
private TextView mYourVotelabel;
private ViewPager mViewPager;
private int mPagerCurrentPosition;
private static final String VOTE_COUNT_LABEL = "Vote_Count";
private static final String QUESTION_LABEL = "question";
private static final String ANSWERS_LABEL = "Answers";
private static final String POLL_LABEL = "Poll";
private static final String IMAGE_URL = "image_URL";
//all date items; dynamic
private DateFormat mDateFormat;
private Date mDate;
private String mCurrentDateString;
private TextView mPollQuestion;
private ArrayList<RadioButton> mPollAnswerArrayList;
private HorizontalBarChart mPollResults;
ArrayList<BarEntry> pollResultChartValues;
private BarDataSet data;
private ArrayList<IBarDataSet> dataSets;
private ValueEventListener valueEventListener;
private String pollID;
private int mPollIndex;
private ProgressBar mProgressBar;
private OnFragmentInteractionListener mListener;
public PollFragment() {
// Required empty public constructor
}
/**
* Use this factory method to create a new instance of
* this fragment using the provided parameters.
*
* #return A new instance of fragment PollFragment.
*/
// TODO: Rename and change types and number of parameters
// TODO: Decide where to add comments button;
public static PollFragment newInstance(String pollIndex) {
PollFragment fragment = new PollFragment();
Bundle args = new Bundle();
args.putString("POLL_ID", pollIndex);
fragment.setArguments(args);
return fragment;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//TODO: check navigation to see if there are different ID's being generated from trending, following, and new fragments
Bundle args = getArguments();
String pollID = args.getString("POLL_ID");
Log.v("TAG", "THE PASSED ID Is " + pollID);
mBaseRef = FirebaseDatabase.getInstance().getReference();
mPollsRef = mBaseRef.child(POLL_LABEL);
mSelectedPollRef = mPollsRef.child(pollID);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// TODO: Add Fragment Code to check if savedInstanceState == null; add at Activity Level?
// Inflate the layout for this fragment
final ViewGroup rootView = (ViewGroup) inflater.inflate(R.layout.fragment_poll, container, false);
ButterKnife.bind(this, rootView);
getActivity().setTitle(R.string.todays_polls_title);
//Initialize Poll Results Bar Chart and set to Invisible
mPollResults = (HorizontalBarChart) rootView.findViewById(R.id.poll_results_chart);
mPollResults.setBackgroundColor(getResources().getColor(R.color.white));
mPollResults.setNoDataTextDescription(getResources().getString(R.string.no_results_description));
mPollResults.setVisibility(View.INVISIBLE);
mTotalVoteCounter = (TextView) rootView.findViewById(R.id.total_vote_counter);
mCommentCounter = (TextView) rootView.findViewById(R.id.comment_label_counter);
mCommentCounter = (TextView) rootView.findViewById(R.id.comment_label_counter);
mProgressBar = (ProgressBar) rootView.findViewById(R.id.progress_bar_white);
mPollQuestion = (TextView) rootView.findViewById(R.id.poll_question);
mPollQuestion.setTextSize(TypedValue.COMPLEX_UNIT_PX, getResources().getDimension(R.dimen.poll_question_text_size));
mPollQuestionRadioGroup = (RadioGroup) rootView.findViewById(R.id.poll_question_group);
mSelectedPollRef.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
Log.v("TAG", dataSnapshot.getKey());
//add question
String pollQuestion = (String) dataSnapshot.child(QUESTION_LABEL).getValue();
Log.v("TAG", "THE POLL QUESTION IS " + pollQuestion);
mPollQuestion.setText(pollQuestion);
mPollQuestion.setTypeface(null, Typeface.BOLD);
//add image
String pollImageURL = (String) dataSnapshot.child(IMAGE_URL).getValue();
Log.v("TAG", "THE POLL IMAGE URL IS" + pollImageURL);
Picasso.with(getActivity())
.load(pollImageURL)
.fit()
.placeholder(R.drawable.loading_spinner_white)
.into((ImageView) rootView.findViewById(R.id.poll_image));
Finally, here is my Firebase Database:
Careless mistake:
private static final String POLL_LABEL = "Poll";
Should be:
private static final String POLL_LABEL = "Polls";
The first choice was not the correct Firebase referencing thus causing the error.
Hi just to state i am a beginner android developer and my code may be a bit messy i also appreciate any help anyone can give me, i have implemented parcelable using this tutorial http://www.javacodegeeks.com/2014/01/android-tutorial-two-methods-of-passing-object-by-intent-serializableparcelable.html
i have Two activities activity A and activity B, the first displays a list of custom objects (properties) and the Property class implements parcelable
Activity A has a custom list and I want to add objects dynamically. In this activity I have a button that opens activity B where i input the information required to created a property object which i want to send back to activity A to be added to the list.
Before I implemented parcelable i was able to create the object with no issue but it was stuck in activity B and needs to be added to the list in activity A after implementing parcelable when i first try to open activity A i get an error that crashes my app i think it's because i've added Property mProperty = getIntent().getParcelableExtra(AddProperty.PAR_KEY); in the onCreate method in activity A which looks for an intent before ones been created in Activity B
public class Property implements Parcelable {
// have quit alot of fields so took them out to save space
public Property()
{
}
public Property(String postCode, String address, String county,int noRoom, int askPrice,
String eName,String agentName,String agentNumber, String time) {
this.postCode = postCode;
this.addressFirsLine = address;
this.county = county;
setNumberOfRoom(noRoom);
//numberOfRoom = 2;
setAskingPrice(askPrice);
//askingPrice = 0;
//setCurrentOffer(currentOff);
currentOffer = 0;
//setAgreedPrice(agreedPrice);
agreedPrice = 0;
// setRefurbCost(refurb);
//refurbCost = 2555;
setEstateAgent(eName,agentNumber ,agentName);
// estateAgent = null;
condition = false;
setTime(time);
}
public static final Creator<Property> CREATOR = new Creator<Property>() {
#Override
public Property createFromParcel(Parcel source) {
Property mProperty = new Property();
mProperty.postCode = source.readString() ;
mProperty.addressFirsLine = source.readString();
mProperty.county =source.readString() ;
mProperty.numberOfRoom = source.readInt();
mProperty.askingPrice = source.readInt();
mProperty.agentName = source.readString();
mProperty.agentNumber = source.readString();
mProperty.eName = source.readString();
return mProperty;
}
#Override
public Property[] newArray(int size) {
return new Property[size];
}
};
#Override
public int describeContents() {
return 0;
}
#Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(postCode);
dest.writeString(addressFirsLine);
dest.writeString(county);
dest.writeInt(numberOfRoom);
dest.writeInt(askingPrice);
dest.writeString(agentName);
dest.writeString(agentNumber);
dest.writeString(eName);
dest.writeString(time);
}
}
the propery class also has full getters and setters.
the createViewing method is on activity B and is whats used to create the object and send the object back
public void CreateViewing(View view) {
String strPostCode,strAddressFirsLine,strCounty,strEstateAgent,strAgentName,strAgentPhone,strTime ;
int roomNO ;
int askingPrice2 ;
try{
strPostCode = postCode.getText().toString();
strAddressFirsLine=addressFirsLine.getText().toString();
strCounty = county.getText().toString();
roomNO = Integer.parseInt(roomNumber.getText().toString());
askingPrice2 = Integer.parseInt(askingPrice.getText().toString());
strEstateAgent=estateAgent.getText().toString();
strAgentName=agentName.getText().toString() ;
strAgentPhone=agentPhone.getText().toString() ;
strTime =time.getText().toString() ;
Property mProperty = new Property(strPostCode, strAddressFirsLine,
strCounty ,roomNO,askingPrice2,strEstateAgent ,strAgentName,strAgentPhone,
strTime ) ;
String r = mProperty.toString() ;
Intent mIntent = new Intent(this,ViewingSchedule.class);
Bundle mBundle = new Bundle();
mBundle.putParcelable(PAR_KEY,mProperty);
mIntent.putExtras(mBundle);
startActivity(mIntent);
Toast.makeText(AddProperty.this, r, Toast.LENGTH_SHORT).show();
} catch (Exception e) {
e.printStackTrace();
}
this is the onCreate Method for activity A
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_viewing_schedule);
Toolbar toolbar = (Toolbar) findViewById(R.id.app_bar);
setSupportActionBar(toolbar);
getSupportActionBar().setHomeButtonEnabled(true);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
Property mProperty = getIntent().getParcelableExtra(AddProperty.PAR_KEY);
Toast.makeText(ViewingSchedule.this,mProperty.toString(),Toast.LENGTH_SHORT).show();
Property[] propertyList = {new Property("SG1 1LS", "24 CrossGates", "Hertfordshire",2, 200000,"Connels","becky","078123456","9:00")};
//propertyList = mProperty ;
ListView listView1 = (ListView) findViewById(R.id.listView);
ArrayAdapter adapter = new myAdapter2(this,propertyList);
listView1.setAdapter(adapter);
listView1.setOnItemClickListener((new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
String itemSelected = "You selected " +
String.valueOf(parent.getItemAtPosition(position));
Toast.makeText(ViewingSchedule.this, itemSelected, Toast.LENGTH_SHORT).show();
}
}));
I have a SQLite Database of Web site data (ftp address, username, password, port, homedir, url etc). I can add records to the table but can't seem to update them.
I created a SiteManager Activity that loads each row and creates a WebSite object from each row. The WebSite's properties are loaded into EditTexts. The person can edit the properties and than the Update button SHOULD update the table row but it doesn't. Logcat doesn't give any errors so I'm completely at a loss, not sure where to start.
public class SiteManager extends Activity {
private DBAdapter myDb;
private EditText siteManFTPAddress;
private EditText siteManFTPUsername;
private EditText siteManFTPPassword;
private EditText siteManFTPPort;
private EditText siteManURL;
private EditText siteManHome;
private ImageView favIcon;
public ListView site_list;
private Button openBtn;
private Button siteManUpdateBtn;
private int _rowId;
private String _name;
private String _remoteHomeDir;
private int _isLive;
private String _address;
private String _username;
private String _password;
private int _port;
private String _url;
private boolean _status = false;
private String siteFolder;
private List<WebSite> model = new ArrayList<WebSite>();
private ArrayAdapter<WebSite> adapter;
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
setContentView(R.layout.site_manager);
site_list = (ListView) findViewById(R.id.siteList);
adapter = new SiteAdapter(this, R.id.ftpsitename, R.layout.siterow,
model);
site_list.setAdapter(adapter);
addListeners();
openDb();
displayRecords();
}
public void addListeners() {
siteManFTPAddress = (EditText) findViewById(R.id.siteManFTPAdd);
siteManFTPUsername = (EditText) findViewById(R.id.siteManFTPUser);
siteManFTPPassword = (EditText) findViewById(R.id.siteManFTPPass);
siteManFTPPort = (EditText) findViewById(R.id.siteManFTPPort);
siteManURL = (EditText) findViewById(R.id.siteManURL);
siteManHome = (EditText) findViewById(R.id.siteManHome);
site_list.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, final View view,
int position, long id) {
File rootDir = new File(Environment
.getExternalStorageDirectory() + "/My Webs");
final WebSite item = (WebSite) parent
.getItemAtPosition(position);
_name = item.getName();
siteFolder = rootDir.toString() + "/" + _name;
_remoteHomeDir = item.getHomeDir();
_isLive = item.isLive();
String tmpaddress = item.getAddress();
_address = tmpaddress;
siteManFTPAddress.setText(_address);
String tmpuser = item.getUsername();
_username = tmpuser;
siteManFTPUsername.setText(_username);
String tmppass = item.getPassword();
_password = tmppass;
siteManFTPPassword.setText(_password);
int tmpport = item.getPort();
_port = tmpport;
String portString = Integer.toString(tmpport);
siteManFTPPort.setText(portString);
String tmpURL = item.getUrl();
_url = tmpURL;
siteManURL.setText(_url);
String tmpHome = item.getHomeDir();
_remoteHomeDir = tmpHome;
siteManURL.setText(_remoteHomeDir);
}
});
openBtn = (Button) findViewById(R.id.openSiteBtn);
openBtn.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
Intent returnResult = new Intent();
returnResult.putExtra("siteopen", "siteopen");
returnResult.putExtra("sitename", _name);
returnResult.putExtra("sitehome", siteFolder);
returnResult.putExtra("sitelive", _isLive);
returnResult.putExtra("siteremotehome", _remoteHomeDir);
returnResult.putExtra("siteaddress", _address);
returnResult.putExtra("siteusername", _username);
returnResult.putExtra("sitepassword", _password);
returnResult.putExtra("siteport", _port);
returnResult.putExtra("url", _url);
setResult(2, returnResult);
finish();
}
});
siteManUpdateBtn = (Button)findViewById(R.id.siteManFTPUpdate);
siteManUpdateBtn.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
_address = siteManFTPAddress.getText().toString();
_username = siteManFTPUsername.getText().toString();
_password = siteManFTPPassword.getText().toString();
String port = siteManFTPPort.getText().toString();
_port = Integer.parseInt(port);
Toast.makeText(SiteManager.this, "Update", Toast.LENGTH_LONG).show();
myDb.updateRow(_rowId, _name, _name, _isLive, _address, _username, _password, _port, _url);
model.clear();
adapter.notifyDataSetChanged();
displayRecords();
}
});
}
private void openDb() {
myDb = new DBAdapter(this);
myDb.open();
}
#Override
protected void onDestroy() {
// TODO Auto-generated method stub
super.onDestroy();
closeDb();
}
private void closeDb() {
myDb.close();
}
public void displayRecords() {
Cursor cursor = myDb.getAllRows();
displayRecordSet(cursor);
}
protected void displayRecordSet(Cursor c) {
if (c.moveToFirst()) {
do {
int rowId = c.getInt(c.getColumnIndex(DBAdapter.KEY_ROWID));
_rowId = c.getInt(rowId);
int keyNameIndex = c.getColumnIndex(DBAdapter.KEY_NAME);
_name = c.getString(keyNameIndex);
int keyHomeIndex = c.getColumnIndex(DBAdapter.KEY_HOME);
_remoteHomeDir = c.getString(keyHomeIndex);
int keyLiveIndex = c.getColumnIndex(DBAdapter.KEY_LIVE);
_isLive = c.getInt(keyLiveIndex);
int keyAddressIndex = c.getColumnIndex(DBAdapter.KEY_ADDRESS);
_address = c.getString(keyAddressIndex);
int keyUsernameIndex = c.getColumnIndex(DBAdapter.KEY_USERNAME);
_username = c.getString(keyUsernameIndex);
int keyPassIndex = c.getColumnIndex(DBAdapter.KEY_PASSWORD);
_password = c.getString(keyPassIndex);
int keyPortIndex = c.getColumnIndex(DBAdapter.KEY_PORT);
_port = c.getInt(keyPortIndex);
int keyUrlIndex = c.getColumnIndexOrThrow(DBAdapter.KEY_URL);
_url = c.getString(keyUrlIndex);
WebSite sitesFromDB = new WebSite(_rowId, _name, _remoteHomeDir,
_isLive, _address, _username, _password, _port, _url);
model.add(sitesFromDB);
adapter.notifyDataSetChanged();
if(adapter.isEmpty()){
}
} while (c.moveToNext());
}
c.close();
}
#Override
protected void onResume() {
// TODO Auto-generated method stub
super.onResume();
adapter.notifyDataSetChanged();
}
class SiteAdapter extends ArrayAdapter<WebSite> {
private final List<WebSite> objects;
private final Context context;
public SiteAdapter(Context context, int resource,
int textViewResourceId, List<WebSite> objects) {
super(context, R.id.sitename, R.layout.siterow, objects);
this.context = context;
this.objects = objects;
}
/** #return The number of items in the */
public int getCount() {
return objects.size();
}
public boolean areAllItemsSelectable() {
return false;
}
/** Use the array index as a unique id. */
public long getItemId(int position) {
return position;
}
public View getView(int position, View convertView, ViewGroup parent) {
LayoutInflater inflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View rowView = inflater.inflate(R.layout.siterow, parent, false);
TextView textView = (TextView) rowView.findViewById(R.id.sitename);
textView.setText(objects.get(position).getName());
return (rowView);
}
}
DBAdapter.java
public boolean updateRow(long rowId, String name, String homedir,
int islive, String address, String username, String password,
int port, String url) {
String where = KEY_ROWID + "=" + rowId;
/*
* CHANGE 4:
*/
// TODO: Update data in the row with new fields.
// TODO: Also change the function's arguments to be what you need!
// Create row's data:
ContentValues newValues = new ContentValues();
newValues.put(KEY_NAME, name);
newValues.put(KEY_HOME, homedir);
newValues.put(KEY_LIVE, islive);
newValues.put(KEY_ADDRESS, address);
newValues.put(KEY_USERNAME, username);
newValues.put(KEY_PASSWORD, password);
newValues.put(KEY_PORT, port);
newValues.put(KEY_URL, url);
// newValues.put(KEY_PASSIVE, passive);
// Insert it into the database.
return db.update(DATABASE_TABLE, newValues, where, null) != 0;
}
The value _rowId is only ever set inside the displayRecordSet method where you iterate through the results from the database and set the _rowId:
int rowId = c.getInt(c.getColumnIndex(DBAdapter.KEY_ROWID));
_rowId = c.getInt(rowId);
This piece of code seems rather random to me. First you get the columnIndex for the rowId, next you get the index for this specific row and then you get the value of the column with index rowId and then set the _rowId field from this value.
I couldn't tell if the SQLite Database would be so nasty as to just return 0 if there isn't any value in the specified column, but that could definately be the problem.
So every time you get the _rowId set, it might just be set to 0 and when you try to update a row where rowId = 0 nothing happens, as no index in the database can be 0.
See the official documentation about getInt(columnIndex).
To diagnose issues like this, I usually add debug logs into the app. You can see these in your logcat. Log.d("tag", "there is something happening here: " + value);