I am trying to populate a listview with data from a database but it won't allow me to assign a string variable.
i have read some other articles on this but i cannot for the life of me figure out why my variable is shown as " 'this' is not available " When i use the debugger.
public class InventoryActivity extends AppCompatActivity
{
private RecyclerView varRecyclerView;
private RecyclerView.Adapter varAdapter;
private RecyclerView.LayoutManager varLayoutManager;
private static String URL_FindInventory = "MyPHPFile";
//IM TRYING TO SET THESE TWO VARIABLES
public String itemOneName, itemOneEffect;
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_inventory);
String characterID = getIntent().getStringExtra("characterID");
ArrayList<LayoutItem> inventoryList = new ArrayList<>();
FindInventory(characterID);
inventoryList.add(new LayoutItem(R.drawable.ic_add_circle, itemOneName, itemOneEffect));
inventoryList.add(new LayoutItem(R.drawable.ic_add_circle, "Item Two Name", "Item Two's Effect"));
varRecyclerView = findViewById(R.id.recyclerView);
varRecyclerView.setHasFixedSize(true);
varLayoutManager = new LinearLayoutManager(this);
varAdapter = new LayoutAdapter(inventoryList);
varRecyclerView.setLayoutManager(varLayoutManager);
varRecyclerView.setAdapter(varAdapter);
}
private void FindInventory(final String characterID)
{
StringRequest stringRequest = new StringRequest(Request.Method.POST, URL_FindInventory,
new Response.Listener<String>()
{
#Override
public void onResponse(String response)
{
try
{
JSONObject jsonObject = new JSONObject(response);
String result = jsonObject.getString("result");
if (result != null)
{
JSONArray jsonArray = jsonObject.getJSONArray("result");
for(int i = 0; i < jsonArray.length(); i++)
{
JSONObject object = jsonArray.getJSONObject(i);
//IM TRYING TO USE THESE TWO VARIABLES TO SET THE PUBLIC ONES.
String itemName = object.getString("Name").trim(); // this has a value of "Cap of Thinking"
String itemEffect = object.getString("Effect").trim(); // this has a value of "Helps the user to think +2 Intelligence"
itemOneName = itemName; // THIS IS SHOWN AS "ItemOneName = 'this' is not available "
itemOneEffect = itemEffect; // THIS IS SHOWN AS "ItemOneEffect = 'this' is not available "
}
}
else if ((result.equals("error")))
{
Toast.makeText(InventoryActivity.this, "Cannot find Inventory", Toast.LENGTH_LONG).show();
}
} catch (JSONException e)
{
e.printStackTrace();
Toast.makeText(InventoryActivity.this, "Exception Error " + e.toString(), Toast.LENGTH_LONG).show();
}
}
},
new Response.ErrorListener()
{
#Override
public void onErrorResponse(VolleyError error) {
Toast.makeText(InventoryActivity.this, "Error " + error.toString(), Toast.LENGTH_LONG).show();
}
}) {
#Override
protected Map<String, String> getParams() throws AuthFailureError {
Map<String, String> params = new HashMap<>();
params.put("characterid", characterID);
return params;
}
};
RequestQueue requestQueue = Volley.newRequestQueue(this);
requestQueue.add(stringRequest);
}
When I'm trying to set the value of the 2 public strings they are being set as null, I can't for the life of me figure out why it won't allow me to set there value to the variables I read from the JSON object.
They are null because your web request happens after you added the items to the lists.
Make inventoryList a field and remove the two string fields you're trying to set
Move the two inventoryList.add methods into the onResponse, then you need to notify the RecyclerView adapter that new data needs to be displayed
The reason they are null is because when the compiler executes below two lines(let's call it line 1 and line 2):
FindInventory(characterID);//line 1
inventoryList.add(new LayoutItem(R.drawable.ic_add_circle, itemOneName, itemOneEffect));//line 2
-At line 1, the method gets executed asynchronously(means that it will not block the execution of line 2, line 2 will be executed either after or before line 1). This causes the variables itemOneName and itemOneEffect to be null, since line 2 was executed before line 1, remember line 1 and line 2 are being executed in parallel or same time.
To fix this:
-You have to do below:
inventoryList.add(new LayoutItem(R.drawable.ic_add_circle, itemOneName, itemOneEffect));
inventoryList.add(new LayoutItem(R.drawable.ic_add_circle, "Item Two Name", "Item Two's Effect"));
...and other dependencies
After you invoke these lines within onResponse():
String itemName = object.getString("Name").trim(); // this has a value of "Cap of Thinking"
String itemEffect = object.getString("Effect").trim();
Related
I'm fetching some of the locations from the server and need to point them as markers in the google map, so what i did was i created a model of the locations and used the volley library to fetch the details from the server and saved them in a variable and post it in the map. But I'm getting an error as java.lang.NumberFormatException: multiple points.
So need some assistance.
This is my model
public class LocationModel
private String pdLatitude;
private String pdLongitude;
public LocationModel(String pdLatitude, String pdLongitude){
this.pdLatitude = pdLatitude;
this.pdLongitude = pdLongitude; }
public String getPdLatitude() {
return pdLatitude;
}
public String getPdLongitude() {
return pdLongitude;
}
This is my Activity where i'm retreiving the information from the server
private void findRoute(){
StringRequest request = new StringRequest(Request.Method.GET,
Constant.Route_URL + "/" + driverschoolname + "/" + driverid,
new Response.Listener<String>() {
#Override
public void onResponse(String response) {
String pdlatitude = "";
String pdlongitude = "";
try{
JSONObject jsonObject = new JSONObject(response);
JSONArray array = jsonObject.getJSONArray("res");
for (int i=0; i<array.length(); i++){
JSONObject object = array.getJSONObject(i);
StudentsPickDropModel pickDropModel = new StudentsPickDropModel(
object.getString("pdloc_latitude"),
object.getString("pdloc_longitude")
);
pdlatitude += pickDropModel.getPdLatitude();
pdlongitude += pickDropModel.getPdLongitude();
Toast.makeText(StudentsPickDropActivity.this, pickDropModel.getPdName(), Toast.LENGTH_SHORT).show();
Intent intent = new Intent(Activity.this, GetRoute.class);
intent.putExtra("pd_latitude", pdlatitude);
intent.putExtra("pd_longitude", pdlongitude);
startActivity(intent);
}
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Toast.makeText(Activity.this, error.getMessage(), Toast.LENGTH_SHORT).show();
}
});
RequestQueue queue = Volley.newRequestQueue(this);
queue.add(request);
}
And this is how i'm posting my coordiantes in Google maps
Bundle bundle = getIntent().getExtras();
schoollat = bundle.getString("school_lat");
schoollng = bundle.getString("school_lng");
pdlat = bundle.getString("pd_latitude");
pdlng = bundle.getString("pd_longitude");
mFusedLocationClient = LocationServices.getFusedLocationProviderClient(this);
mFusedLocationClient.getLastLocation().addOnCompleteListener(new OnCompleteListener<Location>() {
#Override
public void onComplete(#NonNull Task<Location> task) {
Location location = task.getResult();
if (location == null){
requestNewLocationData();
} else {
currentLat = location.getLatitude();
currentLng = location.getLongitude();
System.out.println("Current Latitude: "+location.getLatitude());
System.out.println("Current Longitude: "+location.getLongitude());
}
}
});
Double clat = currentLat;
System.out.println("Current Latitude : "+clat);
Double schoollatitude = new Double(schoollat);
Double schoollongitude = new Double(schoollng);
System.out.println("School latitude : "+schoollatitude + ", School Longitude : "+schoollongitude);
Double pdlatitude = new Double(pdlat);
Double pdlongitude = new Double(pdlng);
getDirections = findViewById(R.id.getdirection);
getDirections.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
new FetchURL(GetRoute.this).execute(getUrl(placeOne.getPosition(), placeTwo.getPosition(), "driving"), "driving");
}
});
MapFragment mapFragment = (MapFragment) getFragmentManager().findFragmentById(R.id.map_fragment);
mapFragment.getMapAsync(this);
places = new MarkerOptions().position(new LatLng(pdlatitude, pdlongitude)).title("Office");
And this is my JSON
"res": [
{
"pdloc_latitude": "12.3111356",
"pdloc_longitude": "76.6075989",
},
{
"pdloc_latitude": "88.568645787",
"pdloc_longitude": "75.54544454887",
}
Use Double.parseDouble() for better efficiency
The core method is parseDouble() which is specially designed to parse
a String containing floating point value into the Double object. Rest
of the methods e.g. valueOf() and constructor uses parseDouble()
internally.
and be sure that the pdlat value you are passing is a valid double number and not just plain characters
This( Double.parseDouble()) method will throw NullPointerException if the string you are passing is null and NumberFormatException if String is not containing a valid double value e.g. containing alphabetic characters.
Just debug Double pdlatitude = new Double(pdlat); line to be sure.
Your PDlat have 2 points. That is invalid for Double since Double have 1 point.
Your value:
12.311135688.568645787
What it should has 1 point like this:
12.311135688568645787
PS. You can catch an exception If the value parsing is fail, and what to do is up to what exception occurs.
This question already has answers here:
Reversing an Array in Java [duplicate]
(15 answers)
Closed 4 years ago.
I have source code of an app which displays the list of values as uploaded in the backend server, but the problem is it displays values in opposite order (Things uploaded older is listed first) I want it to be sorted just opposite (By Date).
public class SelectQuizActivity extends AppCompatActivity {
private static final String TAG = SelectQuizActivity.class.getSimpleName();
private int categoryId;
private String catName;
private String catImage;
private ImageView categoryImage;
private TextView categoryName;
private RecyclerView quizRecyclerView;
#Override
protected void onCreate(Bundle savedInstanceState) {
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_select_quiz);
categoryId = getIntent().getExtras().getInt(Constants.CATEGORY);
catName = getIntent().getExtras().getString(Constants.CATEGORY_NAME);
catImage = getIntent().getExtras().getString(Constants.CATEGORY_IMAGE);
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
if(getSupportActionBar() != null){
getSupportActionBar().setElevation(0);
}
setTitle("");
categoryImage = (ImageView)findViewById(R.id.quiz_category_image);
categoryName = (TextView)findViewById(R.id.quiz_category_name);
quizRecyclerView = (RecyclerView)findViewById(R.id.quiz_category);
quizRecyclerView.setLayoutManager(new GridLayoutManager(SelectQuizActivity.this, 3));
quizRecyclerView.setHasFixedSize(true);
if(Helper.isNetworkAvailable(this)){
allSubcategoryInCategory(catName);
}else{
DisplayMessage.displayErrorMessage(this, "No network available");
}
}
private void allSubcategoryInCategory(String name){
Map params = getParams(name);
GsonRequest<SingleQuizObject[]> serverRequest = new GsonRequest<SingleQuizObject[]>(
Request.Method.POST,
Constants.PATH_TO_QUIZ_SUBCATEGORIES,
SingleQuizObject[].class,
params,
createRequestSuccessListener(),
createRequestErrorListener());
((CustomApplication)getApplication()).getNetworkCall().callToRemoteServer(serverRequest);
}
private Map getParams(String name){
Map<String, String> params = new HashMap<String,String>();
params.put(Constants.NAME, name);
return params;
}
private Response.Listener<SingleQuizObject[]> createRequestSuccessListener() {
return new Response.Listener<SingleQuizObject[]>() {
#Override
public void onResponse(SingleQuizObject[] response) {
try {
if(response != null){
categoryName.setText(catName + " subcategories");
String serverImagePath = Constants.PUBLIC_FOLDER + catImage;
RequestOptions requestOptions = new RequestOptions();
requestOptions.diskCacheStrategy(DiskCacheStrategy.ALL);
Glide.with(SelectQuizActivity.this).load(serverImagePath).apply(requestOptions.fitCenter().override(80, 80)).into(categoryImage);
ArrayList<SingleQuizObject> list = arrayToListObject(response);
Collections.reverse(list);
CategoryAdapter mAdapter = new CategoryAdapter(SelectQuizActivity.this, arrayToListObject(list));
quizRecyclerView.setAdapter(mAdapter);
} else{
displayErrorMessage(SelectQuizActivity.this, "No subcategory found ");
}
} catch (Exception e) {
e.printStackTrace();
}
}
};
}
private Response.ErrorListener createRequestErrorListener() {
return new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
error.printStackTrace();
}
};
}
private List<SingleQuizObject> arrayToListObject(SingleQuizObject[] response){
List<SingleQuizObject> allCategories = new ArrayList<>();
Collections.addAll(allCategories, response);
return allCategories;
}
}
Above code take input from category adapter and displays it as recycler view
Reverse list by Java Collection class
Collections.reverse(arrayToListObject(response));
or reverse RecyclerView items.
LinearLayoutManager lm = new LinearLayoutManager(YourActivity.this);
lm.setReverseLayout(true);
lm.setStackFromEnd(true);
Edit Example
As you are not doing right thing, here is the way
ArrayList<SingleQuizObject> list = arrayToListObject(response);
Collections.reverse(list);
CategoryAdapter mAdapter = new CategoryAdapter(SelectQuizActivity.this, list);
Reason
You reversed another copy of list, and you inserted another list. So first hold list, reverse it, and insert same list in adapter.
First call this
Collections.reverse(arrayToListObject(response));
then
CategoryAdapter mAdapter = new CategoryAdapter(SelectQuizActivity.this, arrayToListObject(response));
quizRecyclerView.setAdapter(mAdapter);
java.util.Collections.reverse(arrayToListObject(response))
<?php
// DEVOLVE TODAS AS PESSOAS COM TODA A INFO
$app->get('/api/pessoas', function () {
require_once('db/dbconnect.php');
$myArray = array();
foreach($db->pessoa()
->order("id")
as $row){
array_push($myArray, array('nome' => $row["nome"], 'idade' =>
$row["idade"]));
$result = ['status' => true, 'data' => $myArray];
}
if(isset($result)){
echo json_encode($result, JSON_UNESCAPED_UNICODE);
}else{
echo "Não existem resultados";
}
});
this is the web service I am using and it's giving me the correct answer of every person in the db with all attributes
{"status":true,"data":[{"nome":"Paulo","idade":"23"},{"nome":"Manuela","idade":"23"},{"nome":"Paulo2","idade":"25"},{"nome":"Maranhao Faria","idade":"888"}]}
Now, I want to receive it in Java and fill a list with it:
public class ListInfo extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_list_info);
String url = "paulomaranhao.000webhostapp.com/myslim/api/pessoas";
JsonObjectRequest jsObjRequest = new JsonObjectRequest
(Request.Method.GET, url, null, new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
try{
JSONArray array = response.getJSONArray("data");
List<JSONObject> items = new ArrayList<>();
for(int i = 0; i < array.length(); i++){
items.add(array.getJSONObject(i));
}
ArrayAdapter<JSONObject> adapter = new ArrayAdapter<>(ListInfo.this, android.R.layout.simple_list_item_1, items);
((ListView) findViewById(R.id.list)).setAdapter(adapter);
}catch(JSONException e){}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Toast.makeText(ListInfo.this, getResources().getString(R.string.errorShowing), Toast.LENGTH_SHORT). show();
return;
}
});
// Access the RequestQueue through your singleton class.
MySingleton.getInstance(this).addToRequestQueue(jsObjRequest);
}
When I debug it does not even enter the onResponse.
After that I want to fill the list, if possible customized, or just with the name of the person.
Thank you so much!!!
Solved my problem! I was adding it to the queue, MySingleton, but it was not initialized in the begining. It was just missing this RequestQueue declaration :
private RequestQueue queue;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_rest_post);
queue = MySingleton.getInstance(this.getApplicationContext()).
getRequestQueue();
}
The internet permission is added and working as the other points because I already have two different activities working properly, one that inserts a person on the db and one that gets the info of a person by id, and all of that works. Also the URL in the browser is correct
In my app, I have successfully implemented passing JSON Objects via Intent to a new activity by doing find "findviewByid."
Now this is a restaurant finder app, and each restaurant has several menu photos. I was looking all over stackoverflow to find sth like it but couldn't implement.
This is a part of my JSON file:
[
{
login_id: "6",
name: "Urban Spice",
location: "banani",
latitude: "23.790327",
longitude: "90.409007",
address: "House- 119, Road-11, Block-E, Banani",
rating: "4.00",
costfortwopeople: "0",
openingclosingtime: "",
type: "restaurant,ice cream parlour",
perks: "kids zone,home delivery,catering",
cuisine: "indian,indonesian",
phone: "01777899901,2,3,9862672",
image: - [
"http://www.petuuk.com/restaurant_images/img_2146.jpg",
"http://www.petuuk.com/restaurant_images/img_2147.jpg"
],
menu: - [
"http://www.petuuk.com/restaurant_images/.jpg",
"http://www.petuuk.com/restaurant_images/.jpg",
"http://www.petuuk.com/restaurant_images/.jpg",
"http://www.petuuk.com/restaurant_images/.jpg",
"http://www.petuuk.com/restaurant_images/.jpg",
"http://www.petuuk.com/restaurant_images/.jpg",
"http://www.petuuk.com/restaurant_images/.jpg",
"http://www.petuuk.com/restaurant_images/.jpg"
]
},
{
login_id: "7",
name: "The Sky Room Dining",
location: "banani",
latitude: "23.793972",
longitude: "90.403190",
address: "ABC House, 12th Floor, 8 Kemal Ataturk Avenue, Banani",
rating: "4.00",
costfortwopeople: "0",
openingclosingtime: "",
type: "restaurant",
perks: "rooftop view,catering",
cuisine: "thai,indian",
phone: "01675019211,9822017",
image: - [
"http://www.petuuk.com/restaurant_images/img_2204.jpg",
"http://www.petuuk.com/restaurant_images/img_2205.jpg",
"http://www.petuuk.com/restaurant_images/img_2206.jpg"
], etc..................................................................
I'm having a hard time retrieving the JSON array "menu" and "image" from the JSON output as above. I was able to retrieve the other JSON Objects such as login_id, name, location etc.
The main objective I am trying to achieve here is, load all the data in the Listview, where a user can search a restaurant, then when the user clicks on the specific restaurant, all the loaded data should gets into the "Intent.putExtra" for getting viewed in a full restaurant profile view in a new activity.
These are parts of my "SeachAll" activity where I need help. This is the for loop for retrieving data from the JSON file. I need help here retrieving data from "image" and "menu" and then putting it into my hashmap.
protected String doInBackground(String... arg) {
//building parameters
List<NameValuePair> params = new ArrayList<NameValuePair>();
//Getting JSON from URL
String json = jsonParser.makeHttpRequest(URL_RESTAURANT_LIST, "GET", params);
//Log Cat Response Check
Log.d("Areas JSON: ", "> " + json);
try {
restaurants = new JSONArray(json);
if (restaurants != null) {
//loop through all restaurants
for (int i = 0; i < restaurants.length(); i++) {
JSONObject c = restaurants.getJSONObject(i);
//Storing each json object in the variable.
String id = c.getString(TAG_ID);
String name = c.getString(TAG_NAME);
String location = c.getString(TAG_LOCATION);
String rating = c.getString(TAG_RATING);` HashMap<String, String> map = new HashMap<String, String>();
//adding each child node to Hashmap key
map.put(TAG_ID, id);
map.put(TAG_NAME, name);
map.put(TAG_LOCATION, location);
map.put(TAG_RATING, rating);
//adding HashList to ArrayList
restaurant_list.add(map);
}
}
} catch (JSONException e) {
e.printStackTrace();
}`
This is my onItemClick. Need help in putting the arrays, I dont know if it is alright to pass json array just like json objects i did below.
ListView lv = getListView();
lv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Intent intent = new Intent(getApplicationContext(), RestaurantProfile.class);
String loginId = ((TextView) view.
findViewById(R.id.login_id)).
getText().toString();
String res_name = ((TextView) view.
findViewById(R.id.restaurant_name)).
getText().toString();
intent.putExtra(TAG_ID, loginId);
intent.putExtra(TAG_NAME, res_name);
startActivity(intent);
}
});
So In brief I need help with two things,
1. Retrieve JSON array "image" and "menu" URLS from the JSON file and put it inside the Hashmap.
2. Put this data to my Intent for being passed to a new activity.
This my full code for "SearchAll" activity.
public class SearchAll extends ListActivity {
ConnectionDetector cd;
AlertDialogManager alert = new AlertDialogManager();
//Progress Dialog
private ProgressDialog pDialog;
//make json parser Object
JSONParser jsonParser = new JSONParser();
ArrayList<HashMap<String, String>> restaurant_list;
//Restaurant Json array
JSONArray restaurants = null;
private static final String URL_RESTAURANT_LIST
= "http://www.petuuk.com/android/allRestaurantList2.php";
//all JSON Node Names
private static final String TAG_ID = "login_id";
private static final String TAG_NAME = "name";
private static final String TAG_LOCATION = "location";
private static final String TAG_LAT = "lattitude";
private static final String TAG_LONG = "longitude";
private static final String TAG_ADDRESS = "address";
private static final String TAG_COST_2 = "costfortwopeople";
private static final String TAG_TYPE = "type";
private static final String TAG_PERKS = "perks";
private static final String TAG_CUISINE = "cuisne";
private static final String TAG_PHONE = "phone";
private static final String TAG_RATING = "rating";
private static final String TAG_IMAGE = "image";
private static final String TAG_MENU = "menu";
private static final String TAG_TIMING = "openingclosingtime";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_search_all);
cd = new ConnectionDetector(getApplicationContext());
//Check for Internet Connection
if (!cd.isConnectingToInternet()) {
//Internet connection not present
alert.showAlertDialog(SearchAll.this, "Internet Connection Error",
"Please Check Your Internet Connection", false);
//stop executing code by return
return;
}
restaurant_list = new ArrayList<HashMap<String, String>>();
//get ListView
ListView lv = getListView();
lv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Intent intent = new Intent(getApplicationContext(), RestaurantProfile.class);
String loginId = ((TextView) view.
findViewById(R.id.login_id)).
getText().toString();
String res_name = ((TextView) view.
findViewById(R.id.restaurant_name)).
getText().toString();
intent.putExtra(TAG_ID, loginId);
intent.putExtra(TAG_NAME, res_name);
startActivity(intent);
}
});
lv.setOnScrollListener(new EndlessScrollListener() {
#Override
public void onLoadMore(int page, int totalItemsCount) {
}
});
new LoadRestaurants().execute();
}
class LoadRestaurants extends AsyncTask<String, String, String> {
//Show Progress Dialog
#Override
protected void onPreExecute() {
super.onPreExecute();
pDialog = new ProgressDialog(SearchAll.this);
pDialog.setMessage("Loading All Restaurants...");
pDialog.setIndeterminate(false);
pDialog.setCancelable(false);
pDialog.show();
}
protected String doInBackground(String... arg) {
//building parameters
List<NameValuePair> params = new ArrayList<NameValuePair>();
//Getting JSON from URL
String json = jsonParser.makeHttpRequest(URL_RESTAURANT_LIST, "GET", params);
//Log Cat Response Check
Log.d("Areas JSON: ", "> " + json);
try {
restaurants = new JSONArray(json);
if (restaurants != null) {
//loop through all restaurants
for (int i = 0; i < restaurants.length(); i++) {
JSONObject c = restaurants.getJSONObject(i);
//Storing each json object in the variable.
String id = c.getString(TAG_ID);
String name = c.getString(TAG_NAME);
String location = c.getString(TAG_LOCATION);
String rating = c.getString(TAG_RATING);
String address = c.getString(TAG_ADDRESS);
String latitude = c.getString(TAG_LAT);
String longitude = c.getString(TAG_LONG);
String costfor2 = c.getString(TAG_COST_2);
String timing = c.getString(TAG_TIMING);
String type = c.getString(TAG_TYPE);
String perks = c.getString(TAG_PERKS);
String cuisine = c.getString(TAG_CUISINE);
String phone = c.getString(TAG_PHONE);
JSONArray menuArray = c.getJSONArray("menu");
JSONArray imagesArray = c.getJSONArray("image");
//Creating New Hashmap
HashMap<String, String> map = new HashMap<String, String>();
//adding each child node to Hashmap key
map.put(TAG_ID, id);
map.put(TAG_NAME, name);
map.put(TAG_LOCATION, location);
map.put(TAG_RATING, rating);
for(int m=0;m<menuArray.length();++m){
map.put("MENU_" + m,menuArray.getString(m));
}//menu for loop
map.put("TOTAL_MENU", menuArray.length());
// map.put(TAG_MENU, String.valueOf(menu));
//adding HashList to ArrayList
restaurant_list.add(map);
}
}
} catch (JSONException e) {
e.printStackTrace();
}
return null;
}
protected void onPostExecute(String file_url) {
//dismiss the dialog
pDialog.dismiss();
//Updating UI from the Background Thread
runOnUiThread(new Runnable() {
#Override
public void run() {
ListAdapter adapter = new SimpleAdapter(
SearchAll.this, restaurant_list,
R.layout.listview_restaurants, new String[]{
TAG_ID, TAG_NAME, TAG_LOCATION, TAG_RATING}, new int[]{
R.id.login_id, R.id.restaurant_name, R.id.location, R.id.rating});
setListAdapter(adapter);
}
});
}
}
}
In short, you don't pass all of your data from one Activity to another. You should just pass a restaurant ID to a new Activity, and it uses that ID to pull data of the restaurant.
You should consider your restaurant list as (part of) Model in an MVC architecture. It should be separated from your Activities (which are Controller). Model is your data expert, it keeps your data in memory, files or a database, and it lives beyound the life-cycle of any particular Activity. You don't pass the Model from one Activity to another. After an Activity is created, it grabs the Model (if the Model is a Singleton) or the Model is injected into that Activity (Dependency Injection, my prefer framework is Dagger). The Activity then can ask for any particular data from the Model and render its View. It can also observe for any further changes within the Model and update its view accordlingly.
not sure of this is exactly what you need, but you might get some ideas out of this
first, to get the image and menu array, from the restaurant, you need this
inside the for loop, where you get the json object (c)
JSONObject c = restaurants.getJSONObject(i);
JsonArray menuArray = c.getJsonArray("menu");
JsonArray imagesArray = c.getJsonArray("image");
and you can loop among menuArray and imagesArray items using a for loop
imagesArray.getString(index);
now, as you have declared your map as < String, String > you can't assign a multiple values (images or menu items) in one string,
so either you find another way to structure your data,
or create another 2 maps, menuPam, imageMap that will have restaurant ID as key, and String as value for menu and image entries.
inside the for loop that read restaurant objects:
for (int i = 0; i < restaurants.length(); i++) {
:
:
map.put(TAG_ID, id);
map.put(TAG_NAME, name);
:
:
JsonArray menuArray = c.getJsonArray("menu");
for(int m=0;m<menuArray.length();++m){
menuMap.add(id,menuArray.getString(m));
}//menu for loop
//another for loop for imageArray...
}//end of restaurants loop
but then you have to add the menuMap and imageMap to an array list, called menus, images...
why don't you create an object to hold all info about restaurant
class restaurant{
private String name="", id =""....
//setters and getters ...
String menuItems[] = null;
String imageItems[] = null;
//setters getters for the arrays.
}
}
EDIT:
this sol does not need a new maps, just add images and menu to same map
using dynamic key name
for(int m=0;m<menuArray.length();++m){
map.add("MENU_" + m,menuArray.getString(m));
}//menu for loop
map.add("TOTAL_MENU", Integer.toString(menuArray.length()));
you can use above code, to add menu items to the map
and same thing to images, "IMAGE_"+m
and TOTAL_IMAGES
now at target activity, read all IMAGE_n and MENU_n in a loop
from 0 to TOTAL_IMAGES, and TOTAL_MENU
When I run my app, onPostExecute doesn't seem to be called. It is not populated the UI like it should be. Also, on DoInBackground, any log messages past the for loop:
for (int i = 0; i < businesses.length(); i++) { }
excluding the log messages in that particular for loop are not shown. So for example, the log message in the 2nd for loop for(int j = 0; j < businessNames.size(); j++) { } are not shown for some reason. Is this a timing issue or am I missing something?
But just to sum up, the UI in my onPostExecute is not being hit (as I know of).
Here is my code
public class CoffeeResultActivity extends Activity{
ExpandableListAdapter listAdapter;
ExpandableListView expListView;
List<String> businessNames = new ArrayList<String>();
List<String> businessInfo = new ArrayList<String>();
HashMap<String, List<String>> listDataChild = new HashMap<String, List<String>>();
private int lastExpandedPosition = -1;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
expListView = (ExpandableListView) findViewById(R.id.lvExp);
//Calling AsyncTask
new RetreiveSearchResults().execute("coffee");
// Listview Group click listener
expListView.setOnGroupClickListener(new OnGroupClickListener() {
#Override
public boolean onGroupClick(ExpandableListView parent, View v,
int groupPosition, long id) {
return false;
}
});
expListView.setOnGroupExpandListener(new OnGroupExpandListener() {
#Override
public void onGroupExpand(int groupPosition) {
if (lastExpandedPosition != -1 && groupPosition != lastExpandedPosition) {
expListView.collapseGroup(lastExpandedPosition);
}
lastExpandedPosition = groupPosition;
}
});
// Listview Group collasped listener
expListView.setOnGroupCollapseListener(new OnGroupCollapseListener() {
#Override
public void onGroupCollapse(int groupPosition) {
Toast.makeText(getApplicationContext(),
businessNames.get(groupPosition) + " Collapsed",
Toast.LENGTH_SHORT).show();
}
});
// Listview on child click listener
expListView.setOnChildClickListener(new OnChildClickListener() {
#Override
public boolean onChildClick(ExpandableListView parent, View v,
int groupPosition, int childPosition, long id) {
// TODO Auto-generated method stub
Toast.makeText(
getApplicationContext(),
businessNames.get(groupPosition)
+ " : "
+ listDataChild.get(
businessNames.get(groupPosition)).get(
childPosition), Toast.LENGTH_SHORT)
.show();
return false;
}
});
}
class RetreiveSearchResults extends AsyncTask<String, Void, Void> {
#Override
protected Void doInBackground(String... terms) {
// Some example values to pass into the Yelp search service.
String category = "coffee";
// Execute a signed call to the Yelp service.
OAuthService service = new ServiceBuilder().provider(YelpApi2.class).apiKey("key").apiSecret("key").build();
Token accessToken = new Token("key", "key");
OAuthRequest request = new OAuthRequest(Verb.GET, "http://api.yelp.com/v2/search");
request.addQuerystringParameter("location", "Waterfront, Boston, MA");
request.addQuerystringParameter("category", category);
service.signRequest(accessToken, request);
Response response = request.send();
String rawData = response.getBody();
try {
JSONObject json = new JSONObject(rawData);
JSONArray businesses;
businesses = json.getJSONArray("businesses");
for (int i = 0; i < businesses.length(); i++) {
JSONObject business = businesses.getJSONObject(i);
//Log.d("FOO FOO", "FOO FOO FOO" + business.toString());
businessNames.add(business.get("name").toString());
//The following log message gets displayed
Log.d("FOO FOO", "FOO FOO " + businessNames.get(i));
businessInfo.add(business.get("rating").toString());
//The following log message gets displayed
Log.d("FOO FOO", "FOO FOO " + businessInfo.get(i));
}
//The following log message gets displayed
Log.d("FOO FOO", "SIZE" + businessNames.size());
for(int j = 0; j < businessNames.size(); j++) {
//The following log message DOES NOT GET DISPLAYED. But it does run through this for loop in debugger.
Log.d("FOO FOO", "FOO FOO ##### Get Here?);
//In Debugger, listDataChild does get populated.
listDataChild.put(businessNames.get(j), businessInfo);
}
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
protected void onPostExecute() {
//Does not enter onPostExecute in Debugger nor on a Regular run.
//Log message does NOT get printed
Log.d("FOO FOO", "FOO FOO Get in POST?");
listAdapter = new ExpandableListAdapter(CoffeeResultActivity.this, businessNames, listDataChild);
listAdapter.notifyDataSetChanged();
// setting list adapter
expListView.setAdapter(listAdapter);
}
}
}
The signature of onPostExecute is wrong. It should be like
protected void onPostExecute(Void result) {
}
Your onPostExecute does not match the AsyncTasks signature.
Try adding a Void parameter to the method like so:
protected void onPostExecute(Void result){}
You seem to have forgot to add your #Override tag to your onPostExecute