What I had: An application that when you opened, it showed you a map with 3 buttons that said, "Restaurant", "Hospitals","Bars", and once clicked one of them they showed you this places nearby
What I have: For aesthetic questions an app that when you open, it shows you a RecyclerView with images, and when you click one of these images takes you to a map with your current position.
What I want: That when I click on one of the images of the RecyclerView for example Restaurants, it show a map with the restaurants near me, but making this request from the OnClickListener that I have in my RecyclerView's Adapter on the OnBindViewHolder() method
My Question: How do I make this request if the elements such as Latitude and Longitude are in another Activity and also within a Method called OnMapReady () in which I used to make the request with the buttons I had initially. Please I would appreciate the answers with code examples, I am still not very good at programming and there are millions of terms that I do not understand, thanks in advance
My RecyclerView and where I want to make the request
#Override
public void onBindViewHolder(#NonNull ViewHolder holder, final int position) {
holder.etiNombre.setText(listalugares.get(position).getNombre());
holder.foto.setImageResource(listalugares.get(position).getFoto());
holder.foto.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (position == 0){
Intent myIntent = new Intent(context, MapsActivity.class);
context.startActivity(myIntent);
}
}
});
}
Where I used to make my request
#Override
public void onMapReady(GoogleMap googleMap) {//esta funcion es llamada cuando el mapa esta listo para usarse(1- locacion)
mMap = googleMap;
mMap.setMapType(GoogleMap.MAP_TYPE_NORMAL);//esto es lo que que dice de que forma queremos que se vea el mapa
//Initialize Google Play Services
if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (ContextCompat.checkSelfPermission(this,
Manifest.permission.ACCESS_FINE_LOCATION)
== PackageManager.PERMISSION_GRANTED) {
buildGoogleApiClient();
mMap.setMyLocationEnabled(true);
}
}
else {
buildGoogleApiClient();
mMap.setMyLocationEnabled(true);
}
Button btnRestaurant = (Button) findViewById(R.id.btnRestaurant);
btnRestaurant.setOnClickListener(new View.OnClickListener() {
String Restaurant = "restaurant";
#Override
public void onClick(View v) {
Log.d("onClick", "Button is Clicked");
mMap.clear();
String url = getUrl(latitude, longitude, Restaurant);
Object[] DataTransfer = new Object[2];
DataTransfer[0] = mMap;
DataTransfer[1] = url;
Log.d("onClick", url);
GetNearbyPlacesData getNearbyPlacesData = new GetNearbyPlacesData();
getNearbyPlacesData.execute(DataTransfer);
Toast.makeText(MapsActivity.this,"Nearby Restaurants", Toast.LENGTH_LONG).show();
}
});
To pass data from an activity to another, you'll have to use Intent's extras field. It's a Bundle (a key/value data-structure) where you can store everything you want (with size constraints, so it's usually a good idea to pass only IDs or stuff like that, not the actual data).
What you can do here is: in your adapter's onClick method, add an extra field to the Intent, containing the information type you want to display (either restaurant, bar or hospital). Then, in your second activity (the one containing the map), in the onCreate method, read the field from the Intent. Then you can still place your Nearby Places request in the onMapReady method, using the field to determine which type you're requesting, instead of depending on a specific button click event.
Related
I would like to know how to put a Toast in each of these functions in the following lines:
Toast.makeText(OwnerAdapter.this,"Owner sucessfully deleted!",Toast.LENGTH_SHORT).show();
Toast.makeText(OwnerAdapter.this,"Owner updated successfully!",Toast.LENGTH_SHORT).show();
These functions are inside the OwnerAdapter class that serve to create a one-dimensional list of elements. But it's not working because the compiler throws an error:
Cannot resolved method 'makeText(com.example.iury.bookapp.OwnerAdapter,java.lang.String, int)
Code Here
public class Owner Adapter extends RecyclerView.Adapter<OnwerAdapter.ViewHolder> {
// Button update
holder.button_update.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
String name_owner = holder.editName_owner.getText().toString();
String email_owner = holder.editEmail_owner.getText().toString();
String telephone_owner = holder.editTelephone_owner.getText().toString();
conexao.UpdateOwner(new Owner(f_owner.getId_owner(),name_onwer,email_owner,telephone_onwer));
notifyDataSetChanged();
Toast.makeText(OwnerAdapter.this,"Owner updated successfully!",Toast.LENGTH_SHORT).show();
((Activity) context).finish();
context.startActivity(((Activity) context).getIntent());
}
});
// Button delete
holder.button_delete.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
connection.DeleteOnwer(f_owner.getId_owner());
owner.remove(position);
Toast.makeText(OwnerAdapter.this,"Owner sucessfully deleted!",Toast.LENGTH_SHORT).show();
notifyDataSetChanged();
}
});
}
You need to pass context to Toast to make it work.
If the adapter is inside an activity, you need to show a message like
Toast.makeText(getApplicationContext(),"Owner updated successfully!",Toast.LENGTH_SHORT);
If the adapter is inside a fragment, you need to show a message like
Toast.makeText(getActivity(),"Owner updated successfully!", Toast.LENGTH_SHORT).show();
If the adapter is written as a separate java file, you can do it like
Toast.makeText(v.getContext(),"Owner updated successfully!",Toast.LENGTH_SHORT).show();
or you could pass context to the adapter and pass that context to Toast
Toast.makeText(context,"Owner updated successfully!",Toast.LENGTH_SHORT).show();
I'm trying to design a page where address are stored in recycler view -> cardview.
When the user clicks the add address button from the Activity A the user is navigated to the add address page in Activity B. Here the user can input customer name, address line 1 and address line two.
And once save button is clicked in Activity B, a cardview should be created under the add address button in the Activity A.
This design is just like the amazon mobile app add address option.
Example: If a end-user has one address(one cardview will be present) and wants to add one more address(second address). Then another cardview will be created below the existing cardview with the new address.
Actual result as of now: The second address is being populated in the first cardview.
Expected result: When user enters a new address a new cardview should be created below the existing one.
Code in the Activity A
public class ProfileManageAdressFragment extends AppCompatActivity {
RecyclerView recyclerView;
ProfileManageAddressRecyclerAdapter adapter;
ArrayList<ProfileManageAddressGetterSetter> reviews;
private Button addAddress;
private String customer_name, address_one, address_two, city, state, pincode;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.fragment_profile_manage_adress);
addAddress = findViewById(R.id.addNewAddress);
addAddress.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Toast.makeText(v.getContext(), "Clicked", Toast.LENGTH_SHORT).show();
Intent intent = new Intent(ProfileManageAdressFragment.this, AddNewAddress.class);
startActivityForResult(intent, 1);
}
});
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if(requestCode == 1) {
if(resultCode == RESULT_OK) {
customer_name = data.getStringExtra("customer_name");
address_one = data.getStringExtra("address_one");
address_two = data.getStringExtra("address_two");
city = data.getStringExtra("city");
state = data.getStringExtra("state");
pincode = data.getStringExtra("pincode");
reviews = new ArrayList<>();
reviews.add(new ProfileManageAddressGetterSetter(customer_name, address_one, address_two, city, state, pincode));
recyclerView = findViewById(R.id.addressRecyclerView);
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new LinearLayoutManager(ProfileManageAdressFragment.this));
adapter = new ProfileManageAddressRecyclerAdapter(ProfileManageAdressFragment.this, reviews);
recyclerView.setAdapter(adapter);
}
}else if(resultCode == RESULT_CANCELED) {
Toast.makeText(ProfileManageAdressFragment.this, "Cancelled", Toast.LENGTH_SHORT).show();
}
}
}
Code in Activity B
public class AddNewAddress extends AppCompatActivity {
private EditText customer_name, address_one, address_two, city, state, pincode;
private Button add_address;
private String sCustomer_name, sAddress_one, sAddress_two, sCity, sState, sPincode;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_add_new_address);
customer_name = findViewById(R.id.customerName);
address_one = findViewById(R.id.addressOne);
address_two = findViewById(R.id.addressTwo);
add_address = findViewById(R.id.addAddress);
city = findViewById(R.id.city);
state = findViewById(R.id.state);
pincode = findViewById(R.id.pincode);
final ProfileFragment profileFragment = new ProfileFragment();
add_address.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//setFragment(profileFragment);
if(customer_name.getText().toString().equals("") || address_one.getText().toString().equals("") ||
address_two.getText().toString().equals("") || city.getText().toString().equals("") ||
state.getText().toString().equals("") || pincode.getText().toString().equals("")
) {
Toast.makeText(AddNewAddress.this, "Please input all fields", Toast.LENGTH_LONG).show();
}else {
sCustomer_name = customer_name.getText().toString();
sAddress_one = address_one.getText().toString();
sAddress_two = address_two.getText().toString();
sCity = city.getText().toString();
sState = state.getText().toString();
sPincode = pincode.getText().toString();
Intent intent = new Intent(AddNewAddress.this, ProfileManageAdressFragment.class);
intent.putExtra("customer_name", sCustomer_name);
intent.putExtra("address_one", sAddress_one);
intent.putExtra("address_two", sAddress_two);
intent.putExtra("city", sCity);
intent.putExtra("state", sState);
intent.putExtra("pincode", sPincode);
//startActivity(intent);
//startActivityForResult(intent, 1);
setResult(RESULT_OK, intent);
finish();
}
}
});
}
}
Kindly let me know if additional information is required. Million thanks in advance for solutions! :)
There are many things you have to handle
In ProfileManageAdressFragment
Naming Convention matter more extended AppCompatActivity and the class name is ProfileManageAdressFragment.
Button object created globally that not required, make it local obj.
same String customer_name and many more obj you're using inside onActivityResult so don't need to initialize globally make it local Obj.
In onActivityResult every time you reinitialize the recyclerView and adapter that not required. initialize recyclerView and adapter inside onCreate and when you get Data in onActivityResult add data to ArrayList and call adapter.notifyDataSetChange.
In onActivityResult using nested condition for request code and ResultCode make it on single condition Like. if (requestCode == 1 && resultCode == RESULT_OK){ code body }else {}
In AddNewAddress
All globally initialize objects not required it takes memory only. so make it locally if you're not using outside of the method.
Instead checking value like this customer_name.getText().toString().equals("") , android provide one class TextUtil and TextUtil has one method isEmpty use that method.
So, as I think, the problem is in this lines
reviews = new ArrayList<>();
reviews.add(new ProfileManageAddressGetterSetter(customer_name, address_one, address_two, city, state, pincode));
You're creating a new object of ArrayList with one item, instead of updating existing one. After that you're creating another object of adapter, instead of using existing one and refreshing it's data. So that's why you can't see another CardView populated.
Try add to your adapter next function:
void addItems(items: ArrayList<ProfileManageAddressGetterSetter>) {
this.items.addAll(items);
notifyDataSetChanged();
}
And when you receiving a result from ActivityB - insert it to your adapter with help of addItems(items: ArrayList<ProfileManageAddressGetterSetter>) function.
For better usage of adapter keep it's variable as global variable in your Activity class and call it whenever you need.
I have a basic app that populates an array and displays it in a listview. When I close the app and reopen it the listview is empty, where would you save the array? I see a lot of posts on shared preferences but it seems to be a workaround to store an array in there, also cant find any android documentation on array storage? Can anyone point me in the right direction please?
My code as requested....
public class ListView_Activity extends AppCompatActivity {
ArrayList<String>mylistarray = new ArrayList<>();
String tempdescr;
String tempname;
static final int ADD_NEW_ITEM = 1;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_list_view_);
/*add the main toolbar and make some changes to format*/
Toolbar mToolbar = findViewById(R.id.my_toolbar);
setSupportActionBar(mToolbar);
getSupportActionBar().setDisplayShowTitleEnabled(false);
mToolbar.setTitle(R.string.toolbartitle);
mToolbar.setSubtitle(R.string.toolbarsubtitle);
mToolbar.setTitleTextColor(getResources().getColor(R.color.colorWhite));
mToolbar.setSubtitleTextColor(getResources().getColor(R.color.colorAccent));
final ArrayAdapter<String> myadapter = new ArrayAdapter<String>(ListView_Activity.this, R.layout.simple_list_item_1, R.id.row_item_text_view, mylistarray);
/*create array adapter and set to listview*/
final ListView mylistview = findViewById(R.id.mylistview);
mylistview.setAdapter(myadapter);
mylistarray.add("Test");
myadapter.notifyDataSetChanged();
final FloatingActionButton additembutton = findViewById(R.id.floatingActionButton);
additembutton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent additem = new Intent(ListView_Activity.this, Create_Item_Activity.class);
startActivityForResult(additem, 1);
}
});
}
/*load options menu to toolbar*/
#Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.main_toolbar, menu);
return true;
}
/*handle options menu click events*/
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.settings:
//intent here to load settings activity//
return true;
case R.id.Feedback:
Intent Feedbackemail = new Intent(Intent.ACTION_SEND);
Feedbackemail.setType("text/email");
Feedbackemail.putExtra(Intent.EXTRA_EMAIL, new String[]{"adam.e.garnham#gmail.com"});
Feedbackemail.putExtra(Intent.EXTRA_SUBJECT, "Feedback");
Feedbackemail.putExtra(Intent.EXTRA_TEXT,"Dear..."+"");
startActivity(Intent.createChooser(Feedbackemail,"Send Feedback"));
return true;
default:
return super.onOptionsItemSelected(item);
}
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data){
if (requestCode == ADD_NEW_ITEM){
if (resultCode == Activity.RESULT_OK) {
tempdescr = data.getStringExtra("tempdescr");
tempname = data.getStringExtra("tempname");
mylistarray.add(tempdescr);
mylistarray.add(tempname);
}
if (resultCode == Activity.RESULT_CANCELED) {
Toast replacewithcode = Toast.makeText(ListView_Activity.this, "replace with code", Toast.LENGTH_SHORT);
replacewithcode.show();
}
}
}
}
There are several options you can go with to store your array.
Option 1.
Shared Preferences, its quick and pretty simple to understand. As long as your array isn't to large this would probably be the best option. Here is the link to the shared preference guide.
https://developer.android.com/training/data-storage/shared-preferences.html
With this you would probably want to use something like GSON to convert your array into a string and then store the string.
Option 2.
Store in a local mysqlite database, this is a little more complex to understand but can hold a lot of data for your array. Here is a link to the android sqlite guide.
https://developer.android.com/training/data-storage/sqlite.html
Option 3.
Use a database/server, this one would take the longest to setup but would allow the app to fetch the data. This option would require an internet connection to the database though.
I would recommend going with setting up an mysqlite database if you think that you could handle it but if your a beginner I would lean towards storing the array in shared preferences since it would be a lot less code to set up.
Sorry if this is poor etiquette but I have now re-written my entire question as the original question I asked didn't actually relate to my problem as I have just realised. I am having trouble updating the code in an activity after I return to it. The first activity contains a bunch of imageButtons which relate to levels. When the app is first run only the level one button is enabled. When that button is clicked it sends the user to a new activity where they must spell a set amount of words to unlock the next level. This is the code for my level select activity.
public class QuizLevelSelect extends AppCompatActivity {
private static int myLevel;
ImageButton level1, level2, level3, level4;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_quiz_level_select);
TextView title = (TextView) findViewById(R.id.title);
Typeface custom_font = Typeface.createFromAsset(getAssets(), "fonts/variane-script.regular.ttf");
title.setTypeface(custom_font);
level1 = (ImageButton)findViewById(R.id.level1);
level2 = (ImageButton)findViewById(R.id.level2);
level2.setEnabled(false);
level3 = (ImageButton)findViewById(R.id.level3);
level3.setEnabled(false);
level4 = (ImageButton)findViewById(R.id.level4);
level4.setEnabled(false);
level1.setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View v){
Intent i = new Intent(getApplicationContext(), Main2Activity.class);
i.putExtra("intVariableName", 1);
startActivity(i);
finish();
}
});
level2.setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View v){
Intent i = new Intent(getApplicationContext(), Main2Activity.class);
i.putExtra("intVariableName", 2);
startActivity(i);
finish();
}
});
level3.setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View v){
Intent i = new Intent(getApplicationContext(), Main2Activity.class);
i.putExtra("intVariableName", 3);
startActivity(i);
}
});
}
#Override
protected void onResume(){
super.onResume();
ParseQuery<ParseObject> query = ParseQuery.getQuery("Wordbank");
query.whereEqualTo("username", ParseUser.getCurrentUser().getUsername());
query.findInBackground(new FindCallback<ParseObject>() {
#Override
public void done(List<ParseObject> objects, ParseException e) {
for (ParseObject object : objects){
myLevel = object.getInt("level");
}
});
if (myLevel == 2){
level2.setEnabled(true);
}
}
}
When the level one button is clicked it starts a new activity where the user has to spell a set amount of words (only 1 at the moment, for testing purposes), when the user has spelled the required words it is supposed to send them back to the level select activity and unlock the level 2 button. This is the code for the second activity that checks they have spelled the words and then updates the level they are at on Parse.com before returning them to the level select activity.
if (count == 1){
ParseQuery<ParseObject> query2 = ParseQuery.getQuery("Wordbank");
query2.whereEqualTo("username", ParseUser.getCurrentUser().getUsername());
query2.findInBackground(new FindCallback<ParseObject>() {
#Override
public void done(List<ParseObject> objects, ParseException e) {
if (e == null) {
objects.get(0).put("level", ++intValue);
objects.get(0).saveInBackground();
Intent i = new Intent(getApplicationContext(), QuizLevelSelect.class);
startActivity(i);
finish();
}
}
});
}
All of this works fine except when the user returns to the level select activity, the level 2 button does not become enabled, however if I press back on my phone and then go back into the level select activity it does become enabled. I am assuming this is because when the second activity returns the user to the level select activity the onResume() method is not being run, I have also tried onStart() and onRestart() but neither worked. I know it has something to do with the life cycle of my activities but I dont understand why I have to back out of the activity and then go back into it for the onResume method to run, I thought it ran everytime regardless.
I'm trying to retrieve a information from a parse object but the strings I store them in keep equaling null.
Here is how I saved the object
// get current user
ParseObject studentClasses = new ParseObject("StudentClasses");
// register their periods into database
studentClasses.put("student_id", ParseUser.getCurrentUser());
studentClasses.put("first_period", ClassSelected_Period[PERIOD1]);
studentClasses.put("second_period", ClassSelected_Period[PERIOD2]);
studentClasses.put("third_period", ClassSelected_Period[PERIOD3]);
studentClasses.put("fourth_period", ClassSelected_Period[PERIOD4]);
studentClasses.put("fifth_period", ClassSelected_Period[PERIOD5]);
studentClasses.put("sixth_period", ClassSelected_Period[PERIOD6]);
studentClasses.put("seventh_period", ClassSelected_Period[PERIOD7]);
// save the information into database
studentClasses.saveInBackground();
It saves it perfectly fine my database. The student_id is a pointer to the user and the rest of the columns are strings.
I want to retrieve all those strings and put them in an array when I query parse for them it doesn't work
Here is my query
// check if a user is not cached
ParseUser currentUser = ParseUser.getCurrentUser();
if (currentUser == null)
{
// prompt user to Register screen
// create intent to start activity
Intent intent = new Intent(MainActivity.this, RegisterActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
// start new activity
startActivity(intent);
// stop current activity
finish();
}
// query database for user's classes
ParseQuery<ParseObject> query = ParseQuery.getQuery("StudentClasses");
query.whereEqualTo("student_id", ParseUser.getCurrentUser());
query.getFirstInBackground(new GetCallback<ParseObject>()
{
#Override
public void done (ParseObject parseObject, ParseException e)
{
if (e == null)
{
// retrieved the object
userClasses[PERIOD1] = parseObject.getString("first_period");
userClasses[PERIOD2] = parseObject.getString("second_period");
userClasses[PERIOD3] = parseObject.getString("third_period");
userClasses[PERIOD4] = parseObject.getString("fourth_period");
userClasses[PERIOD5] = parseObject.getString("fifth_period");
userClasses[PERIOD6] = parseObject.getString("sixth_period");
userClasses[PERIOD7] = parseObject.getString("seventh_period");
}
else
{
// failed lookup. Do something here
Toast.makeText(getApplicationContext(),"Exception Thrown" ,Toast.LENGTH_SHORT).show();
}
}
});
I looked at the parse docs and it looks like it should work but it doesn't save the strings
Any help or comments is appreciated thanks!
EDIT: I showed more of my code for the query part to show there is a current user
Here i am assuming that, there is data stored in your parse database.. and it works fine.. so to retrieve it try following..
ParseQuery<ParseObject> query = ParseQuery.getQuery("StudentClasses");
query.whereEqualTo("student_id", ParseUser.getCurrentUser());
query.findInBackground(new FindCallback<ParseObject>()
{
#Override
public void done (List<ParseObject> list, ParseException e)
{
if (e == null)
{
for(int i=0; i < list.size(); i++) {
userClasses[PERIOD1] = list.get(i).getString("first_period");
userClasses[PERIOD2] = list.get(i).getString("second_period");
userClasses[PERIOD3] = list.get(i).getString("third_period");
userClasses[PERIOD4] = list.get(i).getString("fourth_period");
userClasses[PERIOD5] = list.get(i).getString("fifth_period");
userClasses[PERIOD6] = list.get(i).getString("sixth_period");
userClasses[PERIOD7] = list.get(i).getString("seventh_period");
}
}
else
{
Toast.makeText(getApplicationContext(),"Exception Thrown" ,Toast.LENGTH_SHORT).show();
}
}
});
hope it helps!
Well try when getting content to use the function
parseObject.get("the_name_of_the_column")
Which actually should work and works fine for me
Here what you need to understand is in your code studentClasses.saveInBackground(); is async call and you need to query inside SaveCallback. Then you can assure that the saved data is in the database when your query runs.
You got null data because you query before the data is saved in parse.
ParseObject studentClasses = new ParseObject("StudentClasses");
// register their periods into database
studentClasses.put("student_id", ParseUser.getCurrentUser());
studentClasses.put("first_period", ClassSelected_Period[PERIOD1]);
studentClasses.put("second_period", ClassSelected_Period[PERIOD2]);
studentClasses.put("third_period", ClassSelected_Period[PERIOD3]);
studentClasses.put("fourth_period", ClassSelected_Period[PERIOD4]);
studentClasses.put("fifth_period", ClassSelected_Period[PERIOD5]);
studentClasses.put("sixth_period", ClassSelected_Period[PERIOD6]);
studentClasses.put("seventh_period", ClassSelected_Period[PERIOD7]);
// save the information into database
studentClasses.saveInBackground(new SaveCallback() {
public void done(ParseException e) {
if (e == null) {
ParseQuery<ParseObject> query = ParseQuery.getQuery("StudentClasses");
query.whereEqualTo("student_id", ParseUser.getCurrentUser());
query.getFirstInBackground(new GetCallback<ParseObject>()
{
#Override
public void done (ParseObject parseObject, ParseException e)
{
if (e == null)
{
// retrieved the object
userClasses[PERIOD1] = parseObject.getString("first_period");
userClasses[PERIOD2] = parseObject.getString("second_period");
userClasses[PERIOD3] = parseObject.getString("third_period");
userClasses[PERIOD4] = parseObject.getString("fourth_period");
userClasses[PERIOD5] = parseObject.getString("fifth_period");
userClasses[PERIOD6] = parseObject.getString("sixth_period");
userClasses[PERIOD7] = parseObject.getString("seventh_period");
}
else
{
// failed lookup. Do something here
Toast.makeText(getApplicationContext(),"Exception Thrown" ,Toast.LENGTH_SHORT).show();
}
}
});
} else {
// myObjectSaveDidNotSucceed();
}
}
});
Hope this helps
After getting some sleep then doing more research and tinkering I found the problem. The problem isn't in my code; it's in my network... well not entirely. You see my code runs ... at well run-time (As fast as my phone can process it); however, the method
query.findInBackground(new FindCallback<ParseObject>()
runs asynchronously meaning that it does not run at the speed of my other code. Which makes sense if you think about it because it has to send and wait for a response from a database. That's why when I made a toast inside it, the data was there in the string but when I tried to make a toast a few lines later, outside of the method, the data was not there. It was null.
Here's an example. I make a toast at the end of on create with this code
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// initialise and set toolbar as actionbar
toolbar = (Toolbar) findViewById(R.id.tool_bar);
setSupportActionBar(toolbar);
// initialize nav bars
initNavBars();
// initialize drawer layout
NavigationView navView = (NavigationView) findViewById(R.id.navigation_view);
// initialize nav drawer
navDrawer = (DrawerLayout) findViewById(R.id.drawer);
initNavDrawer(navDrawer);
// initialize layout manager for recycler view
RecyclerView.LayoutManager mainLayoutManager = new LinearLayoutManager(this);
// initialize data for all classes before setting adapter
initClassData(); // <---- MY PARSE QUERY IS IN THIS METHOD
// set the adapter for recycler view
RecyclerView.Adapter mainAdapter = new MainRecyclerAdapter(classrooms);
// initialize recycler view elements
RecyclerView mainRecyclerView = (RecyclerView) findViewById(R.id.main_recycler_view);
// add layout manager to recycler view
mainRecyclerView.setLayoutManager(mainLayoutManager);
// add adapter to recycler view
mainRecyclerView.setAdapter(mainAdapter);
Toast.makeText(getApplicationContext(), userClasses[PERIOD1], Toast.LENGTH_SHORT).show(); // <----- HERE IS MY TOAST
}
When I run it, the toast is empty because the string is still null, but if I run it with this code
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// initialise and set toolbar as actionbar
toolbar = (Toolbar) findViewById(R.id.tool_bar);
setSupportActionBar(toolbar);
// initialize nav bars
initNavBars();
// initialize drawer layout
NavigationView navView = (NavigationView) findViewById(R.id.navigation_view);
// initialize nav drawer
navDrawer = (DrawerLayout) findViewById(R.id.drawer);
initNavDrawer(navDrawer);
// initialize layout manager for recycler view
RecyclerView.LayoutManager mainLayoutManager = new LinearLayoutManager(this);
// initialize data for all classes before setting adapter
initClassData(); // <---- PARSE QUERY IS STILL IN THIS METHOD
// set the adapter for recycler view
RecyclerView.Adapter mainAdapter = new MainRecyclerAdapter(classrooms);
// initialize recycler view elements
RecyclerView mainRecyclerView = (RecyclerView) findViewById(R.id.main_recycler_view);
// add layout manager to recycler view
mainRecyclerView.setLayoutManager(mainLayoutManager);
// add adapter to recycler view
mainRecyclerView.setAdapter(mainAdapter);
final Handler handler = new Handler();
handler.postDelayed(new Runnable()
{
#Override
public void run()
{
// Do something after 5s = 5000ms
Toast.makeText(getApplicationContext(), userClasses[PERIOD1], Toast.LENGTH_SHORT).show();
}
}, 5000);
}
In this example I forced the toast to wait five seconds to allow
query.getFirstInBackground(new GetCallback<ParseObject>()
to finish querying the database and when I run it, the toast displays the string correctly.
So if your program relies on a parse query to get important data, you have to structure your code in a way to allow for a second or two to pass to let the parse query return.
Or you could alternatively store the data locally and then you can use the database as a backup for the data and check to make sure it is the same every time the user wants to switch it or somethings.
Thank you Ajay and Rasika I would still be trying to figure why it was not working if it weren't you.