i try to connect to firebase to get display_name and also profile_photo
for my post like instagram
like this one
example image
but when i run my app it says that i have nullPointerException on my variable
mUserAccountSettings cause my app won't run onDataChanged() or onDataCancelled()
function.
i already tried to get data from mUserAccountSettings for Profile class and actually it work perfectly but in ViewFragment class it won't work
it says :
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.jesslyn.foodylife, PID: 5655
java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String
com.example.jesslyn.foodylife.FoodyLife.models.UserAccountSettings.getProfile_photo()'
on a null object reference
at com.example.jesslyn.foodylife.FoodyLife.Utils.ViewPostFragment.setupWidgets(ViewPostFragment.java:156)
at com.example.jesslyn.foodylife.FoodyLife.Utils.ViewPostFragment.onCreateView(ViewPostFragment.java:117)
at android.support.v4.app.Fragment.performCreateView(Fragment.java:2192)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1299)
at android.support.v4.app.FragmentManagerImpl.moveFragmentToExpectedState(FragmentManager.java:1528)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1595)
at android.support.v4.app.BackStackRecord.executeOps(BackStackRecord.java:758)
at android.support.v4.app.FragmentManagerImpl.executeOps(FragmentManager.java:2363)
at android.support.v4.app.FragmentManagerImpl.executeOpsTogether(FragmentManager.java:2149)
at android.support.v4.app.FragmentManagerImpl.optimizeAndExecuteOps(FragmentManager.java:2103)
at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:2013)
at android.support.v4.app.FragmentManagerImpl$1.run(FragmentManager.java:710)
at android.os.Handler.handleCallback(Handler.java:742)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:5544)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:739)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:629)
E/MQSEventManagerDelegate: failed to get MQSService.
and this is my code in ViewFragment class:
package com.example.jesslyn.foodylife.FoodyLife.Utils;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.text.LoginFilter;
import android.util.EventLogTags;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.ImageView;
import android.widget.RatingBar;
import android.widget.TextView;
import com.example.jesslyn.foodylife.FoodyLife.Utils.BottomNavigationViewHelper;
import com.example.jesslyn.foodylife.FoodyLife.Utils.FirebaseMethods;
import com.example.jesslyn.foodylife.FoodyLife.Utils.GridImageAdapter;
import com.example.jesslyn.foodylife.FoodyLife.Utils.SquareImageView;
import com.example.jesslyn.foodylife.FoodyLife.Utils.UniversalImageLoader;
import com.example.jesslyn.foodylife.FoodyLife.models.Photo;
import com.example.jesslyn.foodylife.FoodyLife.models.UserAccountSettings;
import com.example.jesslyn.foodylife.R;
import com.google.android.gms.tasks.OnCompleteListener;
import com.google.android.gms.tasks.Task;
import com.google.firebase.auth.FirebaseAuth;
import com.google.firebase.auth.FirebaseUser;
import com.google.firebase.auth.GetTokenResult;
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.Query;
import com.google.firebase.database.ValueEventListener;
import com.ittianyu.bottomnavigationviewex.BottomNavigationViewEx;
import junit.framework.Test;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.Locale;
import java.util.TimeZone;
import java.util.concurrent.Executor;
/**
* Created by Jesslyn on 12/4/2017.
*/
public class ViewPostFragment extends Fragment {
private static final String TAG = "ViewPostFragment";
private SquareImageView mPostImage;
private BottomNavigationViewEx bottomNavigationViewEx;
private TextView mBackLabel, mCaption, mUsername, mTimeStamp;
private ImageView mBackArrow, mEllipses, mProfileImage;
private RatingBar mStars;
private String photoUrl;
private Photo mPhoto;
private int mActivityNumber = 0;
private String photoUsername = "";
private String profilePhotoUrl = "";
private UserAccountSettings mUserAccountSettings;
// firebase
private FirebaseAuth mAuth;
private FirebaseAuth.AuthStateListener mAuthListener;
private FirebaseDatabase mFirebaseDatabase;
private DatabaseReference myRef;
private FirebaseMethods mFirebaseMethods;
private String userID;
public ViewPostFragment() {
super();
setArguments(new Bundle());
}
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_view_post, container, false);
mPostImage = (SquareImageView) view.findViewById(R.id.post_image);
bottomNavigationViewEx = (BottomNavigationViewEx) view.findViewById(R.id.bottomNavViewBar);
mBackArrow = (ImageView) view.findViewById(R.id.backArrow);
mBackLabel = (TextView) view.findViewById(R.id.tvBackLabel);
mCaption = (TextView) view.findViewById(R.id.image_caption);
mUsername = (TextView) view.findViewById(R.id.username);
mTimeStamp = (TextView) view.findViewById(R.id.image_time_posted);
mEllipses = (ImageView) view.findViewById(R.id.iv_ellipses);
mStars = (RatingBar) view.findViewById(R.id.ratingBar);
mStars.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
RatingBar bar = (RatingBar) v;
Log.d(TAG,"VALUE IS : "+bar.getRating()+" **************************************************");
}
});
mStars.setRating(0);
mProfileImage = (ImageView) view.findViewById(R.id.profile_photo);
try {
mPhoto = getPhotoFromBundle();
UniversalImageLoader.setImage(mPhoto.getImage_path(), mPostImage, null, "");
} catch (NullPointerException e) {
Log.e(TAG, "onCreateView NullPointerException : " + e.getMessage());
}
setupBottomNavigationView();
setupFirebaseAuth();
getPhotoDetails();
setupWidgets();
return view;
}
private void getPhotoDetails(){
Log.d(TAG, "getPhotoDetails: retrieving photo details.");
DatabaseReference reference = FirebaseDatabase.getInstance().getReference();
Query query = reference
.child(getString(R.string.dbname_user_account_settings))
.orderByChild(getString(R.string.field_user_id))
.equalTo(mPhoto.getUser_id());
query.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
Log.d(TAG, "onDataChange: ");
for ( DataSnapshot singleSnapshot : dataSnapshot.getChildren()){
Log.d(TAG, "onDataChange: " +singleSnapshot.getValue().toString());
mUserAccountSettings = singleSnapshot.getValue(UserAccountSettings.class);
Log.d(TAG, "onDataChange: "+mUserAccountSettings.getUsername());
}
setupWidgets();
}
#Override
public void onCancelled(DatabaseError databaseError) {
Log.d(TAG, "onCancelled: query cancelled.");
}
});
}
private void setupWidgets(){
String timestampDiff = getTimeStampDifference();
if(!timestampDiff.equals("0")){
mTimeStamp.setText(timestampDiff + " DAYS AGO");
}else{
mTimeStamp.setText("TODAY");
}
UniversalImageLoader.setImage(mUserAccountSettings.getProfile_photo(), mProfileImage, null, "");
mUsername.setText(mUserAccountSettings.getUsername());
}
//get how many days ago of post
private String getTimeStampDifference() {
Log.d(TAG, "getTimeStampDifference : getting time difference");
String difference = "";
Calendar c = Calendar.getInstance();
SimpleDateFormat sdf = new SimpleDateFormat("dd-MM-yyyy'T'HH:mm:ss'Z'", Locale.ENGLISH);
sdf.setTimeZone(TimeZone.getTimeZone("Asia/Jakarta"));
Date timestamp;
Date today = c.getTime();
sdf.format(today);
final String photoTimestamp = mPhoto.getDate_created();
try {
timestamp = sdf.parse(photoTimestamp);
difference = String.valueOf(Math.round(((today.getTime() - timestamp.getTime()) / 1000 / 60 / 60 / 24)));
} catch (ParseException e) {
Log.e(TAG, "PARSE EXCEPTION : " + e.getMessage());
difference = "0";
}
return difference;
}
private int getActivityFromBundle() {
Log.d(TAG, "getActivityFromBundle arguments : " + getArguments());
Bundle bundle = this.getArguments();
if (bundle != null) {
return bundle.getInt(getString(R.string.activity_number));
} else {
return 0;
}
}
private Photo getPhotoFromBundle() {
Log.d(TAG, "getPhotoFromBundle arguments : " + getArguments());
Bundle bundle = this.getArguments();
if (bundle != null) {
return bundle.getParcelable(getString(R.string.photo));
} else {
return null;
}
}
/**
* BottomNavigationView setup
*/
private void setupBottomNavigationView() {
Log.d(TAG, "setupBottomNavigationView: setting up BottomNavigationView");
BottomNavigationViewHelper.setupBottomNavigationView(bottomNavigationViewEx);
BottomNavigationViewHelper.enableNavigation(getActivity(), getActivity(), bottomNavigationViewEx);
Menu menu = bottomNavigationViewEx.getMenu();
MenuItem menuItem = menu.getItem(mActivityNumber);
menuItem.setChecked(true);
}
/**
* ----------------------------------Firebase stuffs-----------------------------------------
*/
//setup the firebase auth obj
private void setupFirebaseAuth() {
Log.d(TAG, "setupFirebaseAuth : setting up firebase auth");
mAuth = FirebaseAuth.getInstance();
mFirebaseDatabase = FirebaseDatabase.getInstance();
myRef = mFirebaseDatabase.getReference();
mAuthListener = new FirebaseAuth.AuthStateListener() {
#Override
public void onAuthStateChanged(#NonNull FirebaseAuth firebaseAuth) {
FirebaseUser user = firebaseAuth.getCurrentUser();
if (user != null) {
//user is signed in
Log.d(TAG, "user is signed in" + user.getUid());
} else {
//user is signed out
Log.d(TAG, "onAuthStateChanged : signed out");
}
}
};
}
#Override
public void onStart() {
super.onStart();
mAuth.addAuthStateListener(mAuthListener);
}
#Override
public void onStop() {
super.onStop();
if (mAuthListener != null) {
mAuth.removeAuthStateListener(mAuthListener);
}
}
}
It is because the variable mUserAccountSettings is initialized in onDataChange() method which is a callback and is executed async. Before this it initialized your main thread is trying to access that in setupWidgets()
A possible fix would be to move the below code from setupWidgets() to onDataChange().
UniversalImageLoader.setImage(mUserAccountSettings.getProfile_photo(), mProfileImage, null, "");
NOTE: this is not intend to show you any best practice. This solution is just to show that all UI updates which depends on value from server, should happen ones you get the response from server.
Related
So im doing a project where i have to get Values from specific places from Google Firebase database and put them into textViews in android studio and ive been trying to get 1 value from 1 place to get an idea how everything works before i try to go any further, so here is what ive been trying to do:
Database structure:
{
"Flower" : 100,
"Flowers" : {
"Flower1" : 123,
"Flower2" : 1233,
"Flower3" : 830,
"Flower4" : 95,
"Flower5" : 1,
"Flower6" : 20,
"Flower7" : 330,
"Flower8" : 50
}
}
so with this code im about to show you below my android emulator keeps crashing, but when i change:
String value = dataSnapshot.getValue().toString();
to:
String value = dataSnapshot.getValue(String.class);
It opens up but doesnt show any values from databases in the textview im trying to get them to but also returns a null when i try to show it with line:
Log.d(TAG, "Value is : "value)
Its possible that im only blind to my own code since ive been trying to make this work for a long period of time today but What i have to fix in my code to get value from database into my textView?
Thank you already for possible help.
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
import androidx.annotation.NonNull;
import com.google.android.gms.tasks.OnCompleteListener;
import com.google.android.gms.tasks.OnFailureListener;
import com.google.android.gms.tasks.Task;
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;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import okhttp3.OkHttpClient;
import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.Request;
import okhttp3.Response;
public class MainActivity extends AppCompatActivity {
FirebaseDatabase firebaseDatabase;
DatabaseReference databaseReference;
private static final String TAG = "MainActivity";
TextView textView1, textView2, textView3, textView4, textView5;
TextView textViewDate1, textViewDate2, textViewDate3, textViewDate4, textViewDate5, textViewDatabase;
ArrayList<String> listDate = new ArrayList<String>();
ArrayList<String> listTemp = new ArrayList<String>();
final String url = "";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
databaseReference = FirebaseDatabase.getInstance().getReference().child("Flower");
setTextViewIds();
connectToFmiAndShowResult();
getData();
}
private void getData() {
databaseReference.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
long value = dataSnapshot.getValue(Long.class);
textViewDatabase.setText("" + value);
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
// Getting Post failed, log a message
Toast.makeText(MainActivity.this, "Fail to get data.", Toast.LENGTH_SHORT).show();
}
});
}
private void connectToFmiAndShowResult()
{
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
.url(url)
.build();
client.newCall(request).enqueue(new Callback()
{
#Override
public void onFailure(Call call, IOException e)
{
e.printStackTrace();
}
#Override
public void onResponse(Call call, Response response) throws IOException {
if (response.isSuccessful())
{
String myResponse = response.body().string();
String [] tokensTemp = myResponse.split("<BsWfs:ParameterValue>");
String [] tokensDate = myResponse.split("<BsWfs:Time>");
for (int i=1; i<tokensDate.length; i++)
{
listDate.add(tokensDate[i].substring(0, Math.min(tokensTemp[i].length(), 10)));
listTemp.add(tokensTemp[i].substring(0, Math.min(tokensTemp[i].length(), 5)).replace("<","").replace("/",""));
}
String d1 = listDate.get(0);
String d2 = listDate.get(1);
String d3 = listDate.get(2);
String d4 = listDate.get(3);
String dLast = listDate.get(listDate.size()-1);
String t1 = listTemp.get(0);
String t2 = listTemp.get(1);
String t3 = listTemp.get(2);
String t4 = listTemp.get(3);
String tLast = listTemp.get(listTemp.size()-1);
MainActivity.this.runOnUiThread(new Runnable() {
#Override
public void run()
{
textViewDate1.setText(d1 + ":");
textViewDate2.setText(d2 + ":");
textViewDate3.setText(d3 + ":");
textViewDate4.setText(d4 + ":");
textViewDate5.setText(dLast + ":");
textView1.setText(t1 + "°C");
textView2.setText(t2 + "°C");
textView3.setText(t3 + "°C");
textView4.setText(t4 + "°C");
textView5.setText(tLast + "°C");
}
});
}
}
});
}
private void setTextViewIds()
{
textView1 = findViewById(R.id.textViewTemp1);
textView2 = findViewById(R.id.textViewTemp2);
textView3 = findViewById(R.id.textViewTemp3);
textView4 = findViewById(R.id.textViewTemp4);
textView5 = findViewById(R.id.textViewTemp5);
textViewDate1 = findViewById(R.id.textViewDate1);
textViewDate2 = findViewById(R.id.textViewDate2);
textViewDate3 = findViewById(R.id.textViewDate3);
textViewDate4 = findViewById(R.id.textViewDate4);
textViewDate5 = findViewById(R.id.textViewDate5);
textViewDatabase = findViewById(R.id.textViewDatabase);
}
}
To solve this, please change the following line of code:
String value = dataSnapshot.getValue().toString();
To:
long value = dataSnapshot.getValue(Long.class);
And this line:
textViewDatabase.setText(value);
To:
textViewDatabase.setText("" + value);
This is needed because your "Flower" property holds in your database a number and not a String. The result in the logcat will be:
100
Edit:
Seeing your new database schema, to print 100, please use the following lines of code:
DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
DatabaseReference flowerRef = rootRef.child("Flower");
flowerRef.get().addOnCompleteListener(new OnCompleteListener<DataSnapshot>() {
#Override
public void onComplete(#NonNull Task<DataSnapshot> task) {
if (task.isSuccessful()) {
long value = task.getResult().getValue(Long.class);
Log.d(TAG, "value: " + value);
} else {
Log.d(TAG, task.getException().getMessage()); //Don't ignore potential errors!
}
}
});
The result in the logcat will be:
value: 100
This question already has answers here:
What is a NullPointerException, and how do I fix it?
(12 answers)
Closed 2 years ago.
package com.example.agriflex.ui.fooddetail;
import android.content.DialogInterface;
import android.icu.util.IslamicCalendar;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.CompoundButton;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.RadioButton;
import android.widget.RadioGroup;
import android.widget.RatingBar;
import android.widget.TextView;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;
import androidx.fragment.app.Fragment;
import androidx.lifecycle.Observer;
import androidx.lifecycle.ViewModelProviders;
import androidx.recyclerview.widget.RecyclerView;
import com.andremion.counterfab.CounterFab;
import com.bumptech.glide.Glide;
import com.cepheuen.elegantnumberbutton.view.ElegantNumberButton;
import com.example.agriflex.Common.Common;
import com.example.agriflex.Model.CommentModel;
import com.example.agriflex.Model.FoodModel;
import com.example.agriflex.Model.SizeModel;
import com.example.agriflex.R;
import com.example.agriflex.ui.comments.CommentFragment;
import com.google.android.gms.tasks.OnCompleteListener;
import com.google.android.gms.tasks.Task;
import com.google.android.material.floatingactionbutton.FloatingActionButton;
import com.google.firebase.database.DataSnapshot;
import com.google.firebase.database.DatabaseError;
import com.google.firebase.database.FirebaseDatabase;
import com.google.firebase.database.ServerValue;
import com.google.firebase.database.ValueEventListener;
import java.util.HashMap;
import java.util.Map;
import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick;
import butterknife.Unbinder;
import dmax.dialog.SpotsDialog;
public class FoodDetailFragment extends Fragment {
private FoodDetailViewModel foodDetailViewModel;
private Unbinder unbinder;
private android.app.AlertDialog waitingDialog;
#BindView(R.id.img_food)
ImageView img_food;
#BindView(R.id.btnCart)
CounterFab btnCart;
#BindView(R.id.btn_rating)
FloatingActionButton btn_rating;
#BindView(R.id.food_name)
TextView food_name;
#BindView(R.id.food_description)
TextView food_description;
#BindView(R.id.food_price)
TextView food_price;
#BindView(R.id.number_button)
ElegantNumberButton numberButton;
#BindView(R.id.ratingBar)
RatingBar ratingBar;
#BindView(R.id.btnShowComment)
Button btnShowComment;
#BindView(R.id.rdi_group_size)
RadioGroup rdi_group_size;
#OnClick(R.id.btn_rating)
void onRatingButtonClick() {
showDialogRating();
}
#OnClick(R.id.btnShowComment)
void onShowCommentButtonClick() {
CommentFragment commentFragment = CommentFragment.getInstance();
commentFragment.show(getActivity().getSupportFragmentManager(), "CommentFragment");
}
private void showDialogRating() {
androidx.appcompat.app.AlertDialog.Builder builder = new androidx.appcompat.app.AlertDialog.Builder(getContext());
builder.setTitle("Rating Food");
builder.setMessage("Please fill Information");
View itemView = LayoutInflater.from(getContext()).inflate(R.layout.layout_rating, null);
RatingBar ratingBar = (RatingBar) itemView.findViewById(R.id.rating_bar);
EditText edt_comment = (EditText) itemView.findViewById(R.id.edt_comment);
builder.setView(itemView);
builder.setNegativeButton("CANCEL", (dialogInterface, i) -> {
dialogInterface.dismiss();
});
builder.setPositiveButton("OK", (dialogInterface, i) -> {
CommentModel commentModel = new CommentModel();
commentModel.setName(Common.currentUser.getName());
commentModel.setUid(Common.currentUser.getUid());
commentModel.setComment(edt_comment.getText().toString());
commentModel.setRatingValue(ratingBar.getRating());
Map<String, Object> serverTimeStamp = new HashMap<>();
serverTimeStamp.put("timeStamp", ServerValue.TIMESTAMP);
commentModel.setCommentTimeStamp(serverTimeStamp);
foodDetailViewModel.setCommentModel(commentModel);
});
AlertDialog dialog = builder.create();
dialog.show();
}
public View onCreateView(#NonNull LayoutInflater inflater,
ViewGroup container, Bundle savedInstanceState) {
foodDetailViewModel =
ViewModelProviders.of(this).get(FoodDetailViewModel.class);
View root = inflater.inflate(R.layout.fragment_food_detail, container, false);
unbinder = ButterKnife.bind(this, root);
initViews();
foodDetailViewModel.getMutableLiveDataFood().observe(this, foodModel -> {
displayInfo(foodModel);
});
foodDetailViewModel.getMutableLiveDataComment().observe(this, commentModel -> {
submitRatingToFirebase(commentModel);
});
return root;
}
private void initViews() {
waitingDialog = new SpotsDialog.Builder().setCancelable(false).setContext(getContext()).build();
}
private void submitRatingToFirebase(CommentModel commentModel) {
waitingDialog.show();
//First , we will submit to Comments ref
FirebaseDatabase.getInstance()
.getReference(Common.COMMENT_REF)
.child(Common.selectedFood.getId())
.push()
.setValue(commentModel)
.addOnCompleteListener(task -> {
if (task.isSuccessful()) {
//After submit to CommentRef , we will update value aveger in food
addRatingToFood(commentModel.getRatingValue());
}
waitingDialog.dismiss();
});
}
private void addRatingToFood(float ratingValue) {
FirebaseDatabase.getInstance()
.getReference(Common.CATEGORY_REF)
.child(Common.CategorySelected.getMenu_id()) // Select Category
.child("foods") // select array list 'foods' of this category
.child(Common.selectedFood.getKey()) // Because food item is array list so key is index of arraylist
.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
if (dataSnapshot.exists()) {
FoodModel foodModel = dataSnapshot.getValue(FoodModel.class);
foodModel.setKey(Common.selectedFood.getKey()); //Don't forget set it
//Apply rating
if (foodModel.getRatingValue() == null)
foodModel.setRatingValue(0d); // d = D lower case
if (foodModel.getRatingCount() == null)
foodModel.setRatingCount(0l); // l = L lower case, not 1 (number 1)
double sumRating = foodModel.getRatingValue() + ratingValue;
long ratingCount = foodModel.getRatingCount() + 1;
double result = sumRating / ratingCount;
Map<String, Object> updateData = new HashMap<>();
updateData.put("ratingValue", result);
updateData.put("ratingCount", ratingCount);
//update data in variable
foodModel.setRatingValue(result);
foodModel.setRatingCount(ratingCount);
dataSnapshot.getRef()
.updateChildren(updateData)
.addOnCompleteListener(task -> {
waitingDialog.dismiss();
if (task.isSuccessful()) {
Toast.makeText(getContext(), "Thank you !", Toast.LENGTH_SHORT).show();
Common.selectedFood = foodModel;
foodDetailViewModel.setFoodModel(foodModel); // Call refresh
}
});
} else
waitingDialog.dismiss();
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
waitingDialog.dismiss();
Toast.makeText(getContext(), "" + databaseError.getMessage(), Toast.LENGTH_SHORT).show();
}
});
}
private void displayInfo(FoodModel foodModel) {
Glide.with(getContext()).load(foodModel.getImage()).into(img_food);
food_name.setText(new StringBuilder(foodModel.getName()));
food_description.setText(new StringBuilder(foodModel.getDescription()));
food_price.setText(new StringBuilder(foodModel.getPrice().toString()));
if (foodModel.getRatingValue() != null)
ratingBar.setRating(foodModel.getRatingValue().floatValue());
((AppCompatActivity)getActivity())
.getSupportActionBar()
.setTitle(Common.selectedFood.getName());
//Size
for (SizeModel sizeModel: Common.selectedFood.getSizeModel())
{
RadioButton radioButton = new RadioButton(getContext());
radioButton.setOnCheckedChangeListener((buttonView, isChecked) -> {
if (isChecked)
Common.selectedFood.setUserSelectedSize(sizeModel);
calculateTotalPrice(); //Update Price
});
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(0,
LinearLayout.LayoutParams.MATCH_PARENT,
1.0f);
radioButton.setLayoutParams(params);
radioButton.setText(sizeModel.getName());
radioButton.setTag(sizeModel.getPrice());
rdi_group_size.addView(radioButton);
}
if (rdi_group_size.getChildCount() > 0) {
RadioButton radioButton = (RadioButton) rdi_group_size.getChildAt(0);
radioButton.setChecked(true); //Default First Select
}
calculateTotalPrice();
}
private void calculateTotalPrice () {
double totalPrice = Double.parseDouble(Common.selectedFood.getPrice().toString()), displayPrice = 0.0;
//Size
totalPrice += Double.parseDouble(Common.selectedFood.getUserSelectedSize().getPrice().toString());
displayPrice = totalPrice * (Integer.parseInt(numberButton.getNumber()));
displayPrice = Math.round(displayPrice * 100.0 / 100.0);
food_price.setText(new StringBuilder("").append(Common.formatPrice(displayPrice)).toString());
}
}
----------
## Heading ##
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.agriflex, PID: 5673
java.lang.NullPointerException: Attempt to invoke interface method 'java.util.Iterator java.util.List.iterator()' on a null object reference
at com.example.agriflex.ui.fooddetail.FoodDetailFragment.displayInfo(FoodDetailFragment.java:236)
at com.example.agriflex.ui.fooddetail.FoodDetailFragment.lambda$onCreateView$2$FoodDetailFragment(FoodDetailFragment.java:135)
at com.example.agriflex.ui.fooddetail.-$$Lambda$FoodDetailFragment$qUbisKr6hIzCwm4MXSIKgBZ3EXA.onChanged(Unknown Source:4)
at androidx.lifecycle.LiveData.considerNotify(LiveData.java:113)
at androidx.lifecycle.LiveData.dispatchingValue(LiveData.java:126)
at androidx.lifecycle.LiveData$ObserverWrapper.activeStateChanged(LiveData.java:424)
at androidx.lifecycle.LiveData$LifecycleBoundObserver.onStateChanged(LiveData.java:376)
at androidx.lifecycle.LifecycleRegistry$ObserverWithState.dispatchEvent(LifecycleRegistry.java:361)
at androidx.lifecycle.LifecycleRegistry.forwardPass(LifecycleRegistry.java:300)
at androidx.lifecycle.LifecycleRegistry.sync(LifecycleRegistry.java:339)
at androidx.lifecycle.LifecycleRegistry.moveToState(LifecycleRegistry.java:145)
at androidx.lifecycle.LifecycleRegistry.handleLifecycleEvent(LifecycleRegistry.java:131)
at androidx.fragment.app.Fragment.performStart(Fragment.java:2637)
at androidx.fragment.app.FragmentManagerImpl.moveToState(FragmentManagerImpl.java:915)
at androidx.fragment.app.FragmentManagerImpl.addAddedFragments(FragmentManagerImpl.java:2100)
at androidx.fragment.app.FragmentManagerImpl.executeOpsTogether(FragmentManagerImpl.java:1874)
at androidx.fragment.app.FragmentManagerImpl.removeRedundantOperationsAndExecute(FragmentManagerImpl.java:1830)
at androidx.fragment.app.FragmentManagerImpl.execPendingActions(FragmentManagerImpl.java:1727)
at androidx.fragment.app.FragmentManagerImpl$2.run(FragmentManagerImpl.java:150)
at android.os.Handler.handleCallback(Handler.java:790)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6494)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:807)
I/zygote: Do full code cache collection, code=495KB, data=334KB
After code cache collection, code=484KB, data=293KB
Replace your displayInfo method with
private void displayInfo(FoodModel foodModel) {
Glide.with(getContext()).load(foodModel.getImage()).into(img_food);
food_name.setText(new StringBuilder(foodModel.getName()));
food_description.setText(new StringBuilder(foodModel.getDescription()));
food_price.setText(new StringBuilder(foodModel.getPrice().toString()));
if (foodModel.getRatingValue() != null)
ratingBar.setRating(foodModel.getRatingValue().floatValue());
((AppCompatActivity)getActivity())
.getSupportActionBar()
.setTitle(Common.selectedFood.getName());
//Size
//Add NULL check for your object and your code wont throw the exception
if(null!=Common.selectedFood && null!=Common.selectedFood.getSizeModel()) {
for (SizeModel sizeModel : Common.selectedFood.getSizeModel()) {
RadioButton radioButton = new RadioButton(getContext());
radioButton.setOnCheckedChangeListener((buttonView, isChecked) -> {
if (isChecked)
Common.selectedFood.setUserSelectedSize(sizeModel);
calculateTotalPrice(); //Update Price
});
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(0,
LinearLayout.LayoutParams.MATCH_PARENT,
1.0f);
radioButton.setLayoutParams(params);
radioButton.setText(sizeModel.getName());
radioButton.setTag(sizeModel.getPrice());
rdi_group_size.addView(radioButton);
}
}
if (rdi_group_size.getChildCount() > 0) {
RadioButton radioButton = (RadioButton) rdi_group_size.getChildAt(0);
radioButton.setChecked(true); //Default First Select
}
calculateTotalPrice();
}
I have just added null checks before the list iteration.
It seems that your "foodModel" is null:
foodDetailViewModel.getMutableLiveDataFood().observe(this, foodModel -> {
displayInfo(foodModel);
});
Before displaying info you need to check if is not null :
foodDetailViewModel.getMutableLiveDataFood().observe(this, foodModel -> {
if( foodModel != null )
displayInfo(foodModel);
});
Otherwhise you need to check your "getMutableLiveDataFood()" method returns null data
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 3 years ago.
Improve this question
My logcat here
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.barberbooking, PID: 13610
java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String com.example.barberbooking.Model.Salon.getSalonId()'
on a null object reference
at com.example.barberbooking.Fragments.BookingStep4Fragment.lambda$null$0$BookingStep4Fragment(BookingStep4Fragment.java:260)
at com.example.barberbooking.Fragments.-$$Lambda$BookingStep4Fragment$4Ef790x-NNkmXHs_bv2YFCA2Nyk.onSuccess(Unknown
Source:4)
at com.google.android.gms.tasks.zzn.run(Unknown Source:4)
at android.os.Handler.handleCallback(Handler.java:790)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6494)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:807)
My Bookingstep4fragment
package com.example.barberbooking.Fragments;
import android.app.AlertDialog;
import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.provider.CalendarContract;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import com.example.barberbooking.Common.Common;
import com.example.barberbooking.Database.CartDataSource;
import com.example.barberbooking.Database.CartDatabase;
import com.example.barberbooking.Database.CartItem;
import com.example.barberbooking.Database.LocalCartDataSource;
import com.example.barberbooking.Model.BookingInformation;
import com.example.barberbooking.Model.EventBus.ConfirmBookingEvent;
import com.example.barberbooking.Model.FCMResponse;
import com.example.barberbooking.Model.FCMsendData;
import com.example.barberbooking.Model.MyNotification;
import com.example.barberbooking.Model.MyToken;
import com.example.barberbooking.R;
import com.example.barberbooking.Retrofit.IFCMApi;
import com.example.barberbooking.Retrofit.RetrofitClient;
import com.google.android.gms.tasks.OnCompleteListener;
import com.google.android.gms.tasks.OnFailureListener;
import com.google.android.gms.tasks.OnSuccessListener;
import com.google.android.gms.tasks.Task;
import com.google.firebase.Timestamp;
import com.google.firebase.firestore.CollectionReference;
import com.google.firebase.firestore.DocumentReference;
import com.google.firebase.firestore.DocumentSnapshot;
import com.google.firebase.firestore.FieldValue;
import com.google.firebase.firestore.FirebaseFirestore;
import com.google.firebase.firestore.QuerySnapshot;
import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.TimeZone;
import java.util.UUID;
import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick;
import butterknife.Unbinder;
import dmax.dialog.SpotsDialog;
import io.paperdb.Paper;
import io.reactivex.SingleObserver;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.CompositeDisposable;
import io.reactivex.disposables.Disposable;
import io.reactivex.functions.Consumer;
import io.reactivex.schedulers.Schedulers;
#SuppressWarnings("ALL")
public class BookingStep4Fragment extends Fragment {
CartDataSource cartDataSource;
CompositeDisposable compositeDisposable = new CompositeDisposable();
SimpleDateFormat simpleDateFormat;
Unbinder unbinder;
IFCMApi ifcmApi;
AlertDialog dialog;
#BindView(R.id.txt_booking_barber_text)
TextView txt_booking_barber_text;
#BindView(R.id.txt_booking_time_text)
TextView txt_booking_time_text;
#BindView(R.id.txt_salon_address)
TextView txt_salon_address;
#BindView(R.id.txt_salon_open_hours)
TextView txt_salon_open_hours;
#BindView(R.id.txt_salon_phone)
TextView txt_salon_phone;
#BindView(R.id.txt_salon_website)
TextView txt_salon_website;
#BindView(R.id.txt_salon_name)
TextView txt_salon_name;
#OnClick(R.id.btn_confirm)
void confirmBooking() {
dialog.show();
//DatabaseUtils.getAllCart(CartDatabase.getInstance(getContext()),
//this);
compositeDisposable.add(cartDataSource.getAllItemFromCart(Common.currentUser.getPhoneNumber())
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Consumer<List<CartItem>>() {
#Override
public void accept(List<CartItem> cartItems) throws Exception {
String startTime = Common.convertTimeSlotToString(Common.currentTimeSlot);
String[] convertTime = startTime.split("-");
String[] startTimeConvert = convertTime[0].split(":");
int startHourInt = Integer.parseInt(startTimeConvert[0].trim());
int startMinInt = Integer.parseInt(startTimeConvert[1].trim()); // We get 00
Calendar bookingDateWithourHouse = Calendar.getInstance();
bookingDateWithourHouse.setTimeInMillis(Common.currentDate.getTimeInMillis());
bookingDateWithourHouse.set(Calendar.HOUR_OF_DAY, startHourInt);
bookingDateWithourHouse.set(Calendar.MINUTE, startMinInt);
//Create timestamp object and apply to BookingInformation
Timestamp timestamp = new Timestamp(bookingDateWithourHouse.getTime());
final BookingInformation bookingInformation = new BookingInformation();
bookingInformation.setCityBook(Common.city);
bookingInformation.setTimestamp(timestamp);
bookingInformation.setDone(false);
bookingInformation.setBarberId(Common.currentBarber.getBarberId());
bookingInformation.setBarberName(Common.currentBarber.getName());
bookingInformation.setCustomerName(Common.currentUser.getName());
bookingInformation.setCustomerPhone(Common.currentUser.getPhoneNumber());
bookingInformation.setSalonId(Common.currentSalon.getSalonId());
bookingInformation.setSalonAddress(Common.currentSalon.getAddress());
bookingInformation.setSalonName(Common.currentSalon.getName());
bookingInformation.setTime(new StringBuilder(Common.convertTimeSlotToString(Common.currentTimeSlot))
.append(" at ")
.append(simpleDateFormat.format(bookingDateWithourHouse.getTime())).toString());
bookingInformation.setSlot(Long.valueOf(Common.currentTimeSlot));
bookingInformation.setCartItemList(cartItems);
DocumentReference bookingDate = FirebaseFirestore.getInstance()
.collection("AllSalon")
.document(Common.city)
.collection("Branch")
.document(Common.currentSalon.getSalonId())
.collection("Barber")
.document(Common.currentBarber.getBarberId())
.collection(Common.simpleDateFormat.format(Common.currentDate.getTime()))
.document(String.valueOf(Common.currentTimeSlot));
bookingDate.set(bookingInformation)
.addOnSuccessListener((aVoid) -> {
resetStaticData();
getActivity().finish(); activity
Toast.makeText(getContext(), "Success", Toast.LENGTH_SHORT).show();
//DatabaseUtils.clearCart(CartDatabase.getInstance(getContext()));
cartDataSource.clearCart(Common.currentUser.getPhoneNumber())
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new SingleObserver<Integer>() {
#Override
public void onSubscribe(Disposable d) {
}
#Override
public void onSuccess(Integer integer) {
addToUserBooking(bookingInformation);
}
#Override
public void onError(Throwable e) {
Toast.makeText(getContext(), "" + e.getMessage(), Toast.LENGTH_SHORT).show();
}
});
}).addOnFailureListener(e -> {
Toast.makeText(getContext(), "" + e.getMessage(), Toast.LENGTH_SHORT).show();
});
}
}, new Consumer<Throwable>() {
#Override
public void accept(Throwable throwable) throws Exception {
Toast.makeText(getContext(), "" + throwable.getMessage(), Toast.LENGTH_SHORT).show();
}
}));
}
private void addToUserBooking(BookingInformation bookingInformation) {
final CollectionReference userBooking = FirebaseFirestore.getInstance()
.collection("User")
.document(Common.currentUser.getPhoneNumber())
.collection("Booking");
Calendar calendar = Calendar.getInstance();
calendar.add(Calendar.DATE, 0);
calendar.set(Calendar.HOUR_OF_DAY, 0);
calendar.set(Calendar.MINUTE, 0);
Timestamp toDayTimeStamp = new Timestamp(calendar.getTime());
userBooking
.whereGreaterThanOrEqualTo("timestamp", toDayTimeStamp)
.whereEqualTo("done", false)
.limit(1)
.get()
.addOnCompleteListener(task -> {
if (task.getResult().isEmpty()) {
userBooking.document()
.set(bookingInformation)
.addOnSuccessListener(aVoid -> {
MyNotification myNotification = new MyNotification();
myNotification.setUid(UUID.randomUUID().toString());
myNotification.setTitle("New Booking");
myNotification.setContent("You have a new appoiment for customer hair care with " + Common.currentUser.getName());
myNotification.setRead(false); // We will only filter notification with 'read' is false on barber staff app
myNotification.setServerTimestamp(FieldValue.serverTimestamp());
FirebaseFirestore.getInstance()
.collection("AllSalon")
.document(Common.city)
.collection("Branch")
.document(Common.currentSalon.getSalonId())
.collection("Barber")
.document(Common.currentBarber.getBarberId())
.collection("Notifications")
.document(myNotification.getUid())
.set(myNotification)
.addOnSuccessListener(new OnSuccessListener<Void>() {
#Override
public void onSuccess(Void aVoid) {
dialog.dismiss();
//First , get Token base on Barber id
FirebaseFirestore.getInstance()
.collection("Tokens")
.whereEqualTo("userPhone", Common.currentBarber.getUsername())
.limit(1)
.get()
.addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {
#Override
public void onComplete(#NonNull Task<QuerySnapshot> task) {
if (task.isSuccessful() && task.getResult().size() > 0) {
MyToken myToken = new MyToken();
for (DocumentSnapshot tokenSnapShot : task.getResult())
myToken = tokenSnapShot.toObject(MyToken.class);
FCMsendData sendRequest = new FCMsendData();
Map<String, String> dataSend = new HashMap<>();
dataSend.put(Common.TITLE_KEY, "New Booking");
dataSend.put(Common.CONTENT_KEY, "You have new booking from user "+ Common.currentUser.getName());
sendRequest.setTo(myToken.getToken());
sendRequest.setData(dataSend);
compositeDisposable.add(ifcmApi.sendNotification(sendRequest)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Consumer<FCMResponse>() {
#Override
public void accept(FCMResponse fcmResponse) throws Exception {
dialog.dismiss();
addToCalendar(Common.currentDate,
Common.convertTimeSlotToString(Common.currentTimeSlot));
resetStaticData();
getActivity().finish(); //Close Activity
Toast.makeText(getContext(), "Success", Toast.LENGTH_SHORT).show();
}
}, new Consumer<Throwable>() {
#Override
public void accept(Throwable throwable) throws Exception {
Log.d("NOTIFICATION_ERROR", throwable.getMessage());
addToCalendar(Common.currentDate,
Common.convertTimeSlotToString(Common.currentTimeSlot));
resetStaticData();
getActivity().finish(); //Close Activity
Toast.makeText(getContext(), "Success", Toast.LENGTH_SHORT).show();
}
}));
}
}
});
}
});
})
.addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
if (dialog.isShowing())
dialog.dismiss();
Toast.makeText(getContext(), e.getMessage(), Toast.LENGTH_SHORT).show();
}
});
} else {
if (dialog.isShowing())
dialog.dismiss();
resetStaticData();
getActivity().finish(); // Close activity
Toast.makeText(getContext(), "Success", Toast.LENGTH_SHORT).show();
}
});
}
private void addToCalendar(Calendar bookingDate, String startDate) {
String startTime = Common.convertTimeSlotToString(Common.currentTimeSlot);
String[] convertTime = startTime.split("-"); //Split ex : 9:00-10:00
//Get start time : get 9:00
String[] startTimeConvert = convertTime[0].split(":");
int startHourInt = Integer.parseInt(startTimeConvert[0].trim()); int startMinInt = Integer.parseInt(startTimeConvert[1].trim());
String[] endTimeConvert = convertTime[1].split(":");
int endHourInt = Integer.parseInt(endTimeConvert[0].trim());
int endMinInt = Integer.parseInt(endTimeConvert[1].trim());
Calendar startEvent = Calendar.getInstance();
startEvent.setTimeInMillis(bookingDate.getTimeInMillis());
startEvent.set(Calendar.HOUR_OF_DAY, startHourInt);
startEvent.set(Calendar.MINUTE, startMinInt);
Calendar endEvent = Calendar.getInstance();
endEvent.setTimeInMillis(bookingDate.getTimeInMillis());
endEvent.set(Calendar.HOUR_OF_DAY, endHourInt); hour
endEvent.set(Calendar.MINUTE, endMinInt);
SimpleDateFormat calendarDateFormat = new SimpleDateFormat("dd-MM-yyyy HH:mm");
String startEventTime = calendarDateFormat.format(startEvent.getTime());
String endEventTime = calendarDateFormat.format(endEvent.getTime());
addToDeviceCalendar(startEventTime, endEventTime, "Haircut Booking",
new StringBuilder("Haircut from ")
.append(startTime)
.append(" with ")
.append(Common.currentBarber.getName())
.append(" at ")
.append(Common.currentSalon.getName()).toString(),
new StringBuilder("Address: ").append(Common.currentSalon.getAddress()).toString());
}
private void addToDeviceCalendar(String startEventTime, String endEventTime, String title, String description, String location) {
SimpleDateFormat calendarDateFormat = new SimpleDateFormat("dd-MM-yyyy HH:mm");
try {
Date start = calendarDateFormat.parse(startEventTime);
Date end = calendarDateFormat.parse(endEventTime);
ContentValues event = new ContentValues();
event.put(CalendarContract.Events.CALENDAR_ID, getCalendar(getContext()));
event.put(CalendarContract.Events.TITLE, title);
event.put(CalendarContract.Events.DESCRIPTION, description);
event.put(CalendarContract.Events.EVENT_LOCATION, location);
event.put(CalendarContract.Events.DTSTART, start.getTime());
event.put(CalendarContract.Events.DTEND, end.getTime());
event.put(CalendarContract.Events.ALL_DAY, 0);
event.put(CalendarContract.Events.HAS_ALARM, 1);
String timeZone = TimeZone.getDefault().getID();
event.put(CalendarContract.Events.EVENT_TIMEZONE, timeZone);
Uri calendars;
if (Build.VERSION.SDK_INT >= 22)
calendars = Uri.parse("content://com.android.calendar/events");
else
calendars = Uri.parse("content://calendar/events");
Uri uri_save = getActivity().getContentResolver().insert(calendars, event);
Paper.init(getActivity());
Paper.book().write(Common.EVENT_URI_CACHE, uri_save.toString());
} catch (ParseException e) {
e.printStackTrace();
}
}
private String getCalendar(Context context) {
String gmailIdCalendar = "";
String projection[] = {"_id", "calendar_displayName"};
Uri calendars = Uri.parse("content://com.android.calendar/calendars");
ContentResolver contentResolver = context.getContentResolver();
Cursor managedCursor = contentResolver.query(calendars, projection, null, null, null);
if (managedCursor.moveToFirst()) {
String calName;
int nameCol = managedCursor.getColumnIndex(projection[1]);
int idCol = managedCursor.getColumnIndex(projection[0]);
do {
calName = managedCursor.getString(nameCol);
if (calName.contains("#gmail.com")) {
gmailIdCalendar = managedCursor.getString(idCol);
break; // Exit as soon as have io
}
} while (managedCursor.moveToNext());
managedCursor.close();
}
return gmailIdCalendar;
}
private void resetStaticData() {
Common.step = 0;
Common.currentTimeSlot = -1;
Common.currentSalon = null;
Common.currentBarber = null;
Common.currentDate.add(Calendar.DATE, 0);//Current date
}
#Override
public void onStart() {
super.onStart();
EventBus.getDefault().register(this);
}
#Override
public void onStop() {
EventBus.getDefault().unregister(this);
super.onStop();
}
#Subscribe(sticky = true, threadMode = ThreadMode.MAIN)
public void setDataBooking(ConfirmBookingEvent event) {
if (event.isConfirm()) {
setData();
}
}
private void setData() {
txt_booking_barber_text.setText(Common.currentBarber.getName());
txt_booking_time_text.setText(new StringBuilder(Common.convertTimeSlotToString(Common.currentTimeSlot))
.append(" at ")
.append(simpleDateFormat.format(Common.currentDate.getTime())));
txt_salon_address.setText(Common.currentSalon.getAddress());
txt_salon_website.setText(Common.currentSalon.getWebsite());
txt_salon_name.setText(Common.currentSalon.getName());
txt_salon_open_hours.setText(Common.currentSalon.getOpenHours());
}
static BookingStep4Fragment instance;
public static BookingStep4Fragment getInstance() {
if(instance == null) ;
instance = new BookingStep4Fragment();
return instance;
}
#Override
public void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ifcmApi = RetrofitClient.getInstance().create(IFCMApi.class);
//Apply format for date display on Confirm
simpleDateFormat = new SimpleDateFormat("dd/MM/yyyy");
dialog = new SpotsDialog.Builder().setContext(getContext()).setCancelable(false)
.build();
}
#Override
public void onDestroy() {
compositeDisposable.clear();
super.onDestroy();
{ if (dialog != null) { dialog.dismiss(); dialog = null; }}
}
#Nullable
#Override
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
super.onCreateView(inflater, container, savedInstanceState);
View itemView = inflater.inflate(R.layout.fragment_bookingstep_four, container, false);
unbinder = ButterKnife.bind(this, itemView);
cartDataSource = new LocalCartDataSource(CartDatabase.getInstance(getContext()).cartDAO());
return itemView;
}
}
Check those lines
bookingInformation.setSalonId(Common.currentSalon.getSalonId());
.document(Common.currentSalon.getSalonId())
The error is clear
Attempt to invoke virtual method 'java.lang.String com.example.barberbooking.Model.Salon.getSalonId()' on a null object
You are sending salonId null
I have these codes which work perfectly to search the data form my array list,but , its shows only one result of all the results that we got, I want the text view to view all the results that filtered to contain user input ( if there is a better widget to do this instead of text view it is fine for me).
//searchActivity.class //
package com.example.boc.PhoneNumbers;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.RecyclerView;
import android.content.Context;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;
import com.example.boc.R;
import com.example.boc.main.phone_nombers_Activity;
import com.example.boc.models.Note;
import com.google.android.gms.tasks.OnCompleteListener;
import com.google.android.gms.tasks.OnFailureListener;
import com.google.android.gms.tasks.OnSuccessListener;
import com.google.android.gms.tasks.Task;
import com.google.firebase.firestore.CollectionReference;
import com.google.firebase.firestore.DocumentReference;
import com.google.firebase.firestore.DocumentSnapshot;
import com.google.firebase.firestore.FirebaseFirestore;
import com.google.firebase.firestore.Query;
import com.google.firebase.firestore.QueryDocumentSnapshot;
import com.google.firebase.firestore.QuerySnapshot;
import org.w3c.dom.Text;
import java.util.ArrayList;
import java.util.Map;
public class searchActivity extends phone_nombers_Activity {
private DocumentSnapshot documentSnapshot;
public TextView resultsTxt , userinput ;
public FirebaseFirestore db = FirebaseFirestore.getInstance();
public Note note ;
public LinearLayout layout ;
private ArrayList<Note> mNotes = new ArrayList<>();
private DocumentReference noteRef = db.collection("notes").document();
private CollectionReference notesCollectionRef = db.collection("notes");
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate( savedInstanceState );
setContentView( R.layout.activity_search );
final EditText userinput = findViewById( R.id.userInputtxt );
final Button findbutton = findViewById( R.id.findBtn );
Button openresultBtn = findViewById( R.id.openresult );
final TextView previewResultTextview = findViewById( R.id.resultsTxt );
FirebaseFirestore db = FirebaseFirestore.getInstance();
CollectionReference notesCollectionRef = db
.collection("notes");
Query notesQuery = null;
if(documentSnapshot != null){
notesQuery = notesCollectionRef;
}
else{
notesQuery = notesCollectionRef
.orderBy("timestamp", Query.Direction.ASCENDING);
}
notesQuery.get().addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {
#Override
public void onComplete(#NonNull Task<QuerySnapshot> task) {
if(task.isSuccessful()){
String data = "";
for(final QueryDocumentSnapshot document: task.getResult()){
Note note = document.toObject(Note.class);
String title = note.getTitle();
String content = note.getContent();
data += "Title:" + title + "\nDescrition:" + content + "\n\n";
mNotes.add(note);
if( userinput !=null ) {
findbutton.setOnClickListener( new View.OnClickListener() {
#Override
public void onClick(View v) {
final String userinputString = userinput.getText().toString();
Note match = null;
String matcheddata ="";
for (Note note : mNotes) {
if (note.getTitle().contains(userinputString)) {
match = note;
String matchedtitle = match.getTitle();
String matchedcontent = match.getContent();
matcheddata += "Title:" + matchedtitle + "\nDescrition:" + matchedcontent + "\n\n";
break;
}
}
if (match != null) {
// Found a match
previewResultTextview.setText(matcheddata);
}
else {
previewResultTextview.setText( "no match found" );
}
}
} );
}
else {
userinput.setError( "اسم الملف مطلوب" );
}
}
}
}
});
}
#Override
public void onStart () {
final TextView previewResultTextview = findViewById( R.id.resultsTxt );
super.onStart();
notesCollectionRef.get().addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {
#Override
public void onComplete(#NonNull Task<QuerySnapshot> task) {
if(task.isSuccessful()){
String data = "";
for(final QueryDocumentSnapshot document: task.getResult()){
Note note = document.toObject(Note.class);
String title = note.getTitle();
String content = note.getContent();
data += "Title:" + title + "\nDescrition:" + content + "\n\n";
mNotes.add(note);
previewResultTextview.setText( data );
}
}}});
}}
I've made an apache thrift server and I have a service which contains several functions.
I'm trying to figure out what is the best way to make calls to the remote server from my android application.
My problem is that I can't make calls from the MainActivity thread (the main thread) - and I need to use most of the remote functions in my main activity methods.
I tried to make a static class with a static member called "Server" equals to the server object, and I set it in another thread and then I tried to call it in the main thread (the main activity class) - but I had errors because of jumping from one thread to another..
To be more specified I want something like that:
public class MainActivity extends Activity {
private service.Client myService;
#Override
protected void onCreate(Bundle savedInstanceState) {
..
... Some stuff that define myService (In a new thread ofcourse) ...
}
...
private void MyFunc1() {
myService.Method1();
}
private void MyFunc2() {
myService.Method2();
}
private void MyFunc3() {
myService.Method3();
}
}
I've got a library for talking to REST APIs. Feel free to slice, dice, and re-use: https://github.com/nedwidek/Android-Rest-API
The code is BSD or GPL.
Here's how I use what I have (I've trimmed MainActivity a bit, hopefully not too much):
package com.hatterassoftware.voterguide.api;
import java.util.HashMap;
public class GoogleCivicApi {
protected final String baseUrl = "https://www.googleapis.com/civicinfo/us_v1/";
protected String apiKey = "AIzaSyBZIP5uY_fMF35SVVrytpKgHtppBbj8J0I";
public static final String DATE_FORMAT = "yyyy-MM-dd";
protected static HashMap<String, String> headers;
static {
headers = new HashMap<String, String>();
headers.put("Content-Type", "application/json");
}
public String createUrl(String uri, HashMap<String, String> params) {
String url = baseUrl + uri + "?key=" + apiKey;
if (params != null) {
for (String hashKey: params.keySet()) {
url += hashKey + "=" + params.get(hashKey) + "&";
}
url = url.substring(0, url.length());
}
return url;
}
}
package com.hatterassoftware.voterguide.api;
import android.util.Log;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import com.hatterassoftware.restapi.GetTask;
import com.hatterassoftware.restapi.HttpReturn;
import com.hatterassoftware.restapi.RestCallback;
import com.hatterassoftware.voterguide.api.callbacks.ElectionCallback;
import com.hatterassoftware.voterguide.api.models.Election;
public class ElectionsQuery extends GoogleCivicApi implements RestCallback {
GetTask getTask;
ElectionCallback callback;
final String TAG = "ElectionQuery";
public ElectionsQuery(ElectionCallback callback) {
String url = this.createUrl("elections", null);
this.callback = callback;
Log.d(TAG, "Creating and executing task for: " + url);
getTask = new GetTask(url, this, null, null, null);
getTask.execute();
}
#Override
public void onPostSuccess() {
Log.d(TAG, "onPostSuccess entered");
}
#Override
public void onTaskComplete(HttpReturn httpReturn) {
Log.d(TAG, "onTaskComplete entered");
Log.d(TAG, "httpReturn.status = " + httpReturn.status);
if (httpReturn.content != null) Log.d(TAG, httpReturn.content);
if (httpReturn.restException != null) Log.d(TAG, "Exception in httpReturn", httpReturn.restException);
JsonParser parser = new JsonParser();
JsonElement electionArrayJson = ((JsonObject)parser.parse(httpReturn.content)).get("elections");
Log.d(TAG, electionArrayJson.toString());
Gson gson = new GsonBuilder().setDateFormat(GoogleCivicApi.DATE_FORMAT).create();
Election[] elections = gson.fromJson(electionArrayJson.toString(), Election[].class);
callback.retrievedElection(elections);
}
}
package com.hatterassoftware.voterguide;
import java.util.Calendar;
import java.util.List;
import com.actionbarsherlock.app.SherlockFragmentActivity;
import com.hatterassoftware.voterguide.api.ElectionsQuery;
import com.hatterassoftware.voterguide.api.VoterInfoQuery;
import com.hatterassoftware.voterguide.api.callbacks.ElectionCallback;
import com.hatterassoftware.voterguide.api.callbacks.VoterInfoCallback;
import com.hatterassoftware.voterguide.api.models.Election;
import com.hatterassoftware.voterguide.api.models.VoterInfo;
import android.location.Address;
import android.location.Geocoder;
import android.location.Location;
import android.location.LocationManager;
import android.os.Bundle;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.res.Resources;
import android.text.Editable;
import android.text.Html;
import android.text.TextWatcher;
import android.text.method.LinkMovementMethod;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.ProgressBar;
import android.widget.Spinner;
import android.widget.TextView;
import android.widget.Toast;
public class MainActivity extends SherlockFragmentActivity implements ElectionCallback, VoterInfoCallback {
private ProgressBar mProgressBar;
public Button submit;
public Spinner state;
public Spinner election;
public EditText address;
public EditText city;
public EditText zip;
private int count=0;
private Object lock = new Object();
private static final String TAG = "MainActivity";
public static final String VOTER_INFO = "com.hatterassoftware.voterguide.VOTER_INFO";
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mProgressBar = (ProgressBar) findViewById(R.id.home_progressBar);
Resources res = getResources();
SharedPreferences mPrefs = getApplicationSharedPreferences();
ImageButton gpsButton = (ImageButton) findViewById(R.id.locate);
try {
LocationManager manager = (LocationManager) getSystemService( Context.LOCATION_SERVICE );
if (!manager.isProviderEnabled(Context.LOCATION_SERVICE)) {
gpsButton.setClickable(false);
}
} catch(Exception e) {
Log.d(TAG, e.getMessage(), e);
gpsButton.setClickable(false);
gpsButton.setEnabled(false);
}
submit = (Button) findViewById(R.id.submit);
submit.setClickable(false);
submit.setEnabled(false);
state = (Spinner) findViewById(R.id.state);
election = (Spinner) findViewById(R.id.election);
address = (EditText) findViewById(R.id.streetAdress);
city = (EditText) findViewById(R.id.city);
zip = (EditText) findViewById(R.id.zip);
submit.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
doSubmit();
}
});
gpsButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
doLocate();
}
});
// Let's check for network connectivity before we get down to business.
if (Utils.isNetworkAvailable(this, true)) {
// Show the disclaimer on first run.
if(mPrefs.getBoolean("firstRun", true)) {
AlertDialog alert = new AlertDialog.Builder(this).create();
alert.setCancelable(false);
alert.setTitle(res.getString(R.string.welcome));
LayoutInflater inflater = (LayoutInflater) this.getSystemService(LAYOUT_INFLATER_SERVICE);
View layout = inflater.inflate(R.layout.custom_dialog, null);
TextView alertContents = (TextView) layout.findViewById(R.id.custom_dialog_text);
alertContents.setMovementMethod(LinkMovementMethod.getInstance());
alertContents.setText(Html.fromHtml(res.getString(R.string.welcome_dialog_text)));
alert.setView(alertContents);
alert.setButton(AlertDialog.BUTTON_POSITIVE, "OK", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
SharedPreferences mPrefs = getApplicationSharedPreferences();
SharedPreferences.Editor editor = mPrefs.edit();
editor.putBoolean("firstRun", false);
editor.commit();
dialog.dismiss();
retrieveElections();
}
});
alert.show();
} else {
retrieveElections();
}
}
}
#Override
public void onResume() {
super.onResume();
// Let's check for network connectivity before we get down to business.
Utils.isNetworkAvailable(this, true);
LocationManager manager = (LocationManager) getSystemService( Context.LOCATION_SERVICE );
if (!(manager.isProviderEnabled(LocationManager.GPS_PROVIDER)
|| manager.isProviderEnabled(LocationManager.NETWORK_PROVIDER))) {
Toast.makeText(this, "GPS is not available", 2).show();
ImageButton gpsButton = (ImageButton) findViewById(R.id.locate);
gpsButton.setClickable(false);
}
}
public SharedPreferences getApplicationSharedPreferences() {
Context mContext = this.getApplicationContext();
return mContext.getSharedPreferences("com.hatterassoftware.voterguide", MODE_PRIVATE);
}
private void showSpinner() {
synchronized(lock) {
count++;
mProgressBar.setVisibility(View.VISIBLE);
}
}
private void hideSpinner() {
synchronized(lock) {
count--;
if(count < 0) { // Somehow we're trying to hide it more times than we've shown it.
count=0;
}
if (count == 0) {
mProgressBar.setVisibility(View.INVISIBLE);
}
}
}
public void retrieveElections() {
Log.d(TAG, "Retrieving the elections");
showSpinner();
ElectionsQuery query = new ElectionsQuery(this);
}
#Override
public void retrievedElection(Election... elections) {
Log.d(TAG, "Retrieved the elections");
hideSpinner();
for (int i=0; i<elections.length; i++) {
Log.d(TAG, elections[i].toString());
}
ArrayAdapter arrayAdapter = new ArrayAdapter(this, android.R.layout.simple_spinner_item, elections);
arrayAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
Spinner spinner = (Spinner) this.findViewById(R.id.election);
spinner.setAdapter(arrayAdapter);
}
}