I am getting data from the server through web service and showing in recycle view.Every request I am getting 5 item from the server. I debug my code and checked that when I scroll to end of recycleview then new data is getting from the server but it's not adding in the end of recycleview. How can I solve that?
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_timeline);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
listView = (RecyclerView) findViewById(R.id.listview);
listView.setHasFixedSize(true);
layoutManager = new LinearLayoutManager(this);
listView.setLayoutManager(layoutManager);
//Adding an scroll change listener to recyclerview
listView.setOnScrollChangeListener(this);
// Progress dialog
pDialog = new ProgressDialog(this);
pDialog.setCancelable(false);
cd = new ConnectionDetector(this);
isInternetPresent = cd.isConnectingToInternet();
db = new SQLiteHandler(this);
// session manager
session = new SessionManager(this);
/*pref = getApplicationContext().getSharedPreferences("MayahudiPref", 0);
editor = pref.edit();*/
// Fetching user details from sqlite
HashMap<String, String> user = db.getUserDetails();
id = user.get("id");
token = user.get("token");
getData();
adapter = new TimeLineListAdapter(timeLineItems, this);
listView.setAdapter(adapter);
}
public void getTimeLineData(final String token, final String page) {
timeLineItems = new ArrayList<>();
String tag_string_req = "req_register";
// making fresh volley request and getting json
StringRequest strReq = new StringRequest(Request.Method.POST, AppConfig.timeline, new Response.Listener<String>() {
#Override
public void onResponse(String response) {
VolleyLog.d(TAG, "Response: " + response.toString());
if (response != null) {
try {
JSONObject jObj = new JSONObject(response);
boolean error = jObj.getBoolean("status");
String message = jObj.getString("message");
if(error){
totalPages = jObj.getInt("totalPages");
pageCount = jObj.getInt("page");
int limit = jObj.getInt("limit");
parseJsonFeed(response);
}
}catch (Exception e){
}
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
VolleyLog.d(TAG, "Error: " + error.getMessage());
}
}) {
#Override
protected Map<String, String> getParams() {
// Posting params to register url
Map<String, String> params = new HashMap<String, String>();
params.put("my_token", token);
params.put("page", page);
params.put("limit", "5");
return params;
}
};
// Adding request to request queue
AppController.getInstance().addToRequestQueue(strReq, tag_string_req);
}
private void parseJsonFeed(String response) {
try {
JSONObject jsonObj = new JSONObject(response);
JSONArray feedArray = jsonObj.getJSONArray("data");
for (int i = 0; i < feedArray.length(); i++) {
JSONObject feedObj = (JSONObject) feedArray.get(i);
TimeLineItem item = new TimeLineItem();
item.setId(feedObj.getInt("id"));
item.setName(feedObj.getString("name"));
item.setLname(feedObj.getString("lname"));
// Image might be null sometimes
String image = feedObj.isNull("image") ? null : feedObj
.getString("image");
item.setImge(image);
item.setStatus(feedObj.getString("story_text"));
item.setProfilePic(feedObj.getString("profile_pic"));
item.setTimeStamp(feedObj.getString("time_stamp"));
item.setIsLike(feedObj.getInt("is_like"));
item.setTotalLikes(feedObj.getString("total_likes"));
item.setTotalComment(feedObj.getString("total_comments"));
/*// url might be null sometimes
String feedUrl = feedObj.isNull("url") ? null : feedObj
.getString("url");
item.setUrl(feedUrl);*/
timeLineItems.add(item);
}
// notify data changes to list adapater
adapter.notifyDataSetChanged();
} catch (JSONException e) {
e.printStackTrace();
}
}
//This method will get data from the web API
private void getData() {
//Adding the method to the queue by calling the method getDataFromServer
getTimeLineData(token , String.valueOf(requestCount));
//Incrementing the request counter
requestCount++;
}
//This method would check that the recyclerview scroll has reached the bottom or not
private boolean isLastItemDisplaying(RecyclerView recyclerView) {
if (recyclerView.getAdapter().getItemCount() != 0) {
int lastVisibleItemPosition = ((LinearLayoutManager) recyclerView.getLayoutManager()).findLastCompletelyVisibleItemPosition();
if (lastVisibleItemPosition != RecyclerView.NO_POSITION && lastVisibleItemPosition == recyclerView.getAdapter().getItemCount() - 1)
return true;
}
return false;
}
#Override
public void onScrollChange(View v, int scrollX, int scrollY, int oldScrollX, int oldScrollY) {
//Ifscrolled at last then
if (isLastItemDisplaying(listView)) {
//Calling the method getdata again
getData();
}
}
I think you create a new items list each time you call getTimeLineData():
timeLineItems = new ArrayList<>();
First check if you already have a list:
if (timeLineItems == null) {
timeLineItems = new ArrayList<>();
}
RecylerView article_list;
article_list.addOnScrollListener(new RecyclerView.OnScrollListener() {
#Override
public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
super.onScrollStateChanged(recyclerView, newState);
}
#Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
visibleitemcount = linearLayoutManager.getChildCount();
total_itemcount = linearLayoutManager.getItemCount();
pastVisiblecount = linearLayoutManager.findFirstVisibleItemPosition();
Log.d(TAG, "Total : " + total_itemcount + "Visible : " + visibleitemcount + "Past : " + pastVisiblecount);
if (loading) {
if (visibleitemcount + pastVisiblecount >= total_itemcount) {
loading = false;
getHealthyLivingfromUrl(5, 0);
}
}
}
});
private void getHealthyLivingfromUrl(int limit, int offset) {
//get the data code
article_list.setAdapter(articleAdapter);
if (total_itemcount!=0 && total_itemcount > visibleitemcount) {
linearLayoutManager.setSmoothScrollbarEnabled(true);
linearLayoutManager.scrollToPosition(total_itemcount-visibleitemcount);
}
loading = true;
}
Why are you using POST method to obtain data ? Everytime you obtaining data you are creating new array, onCreate you assign to adapter an array. Then you create one, but no assign. I think you should create in adapter class, addItems(List items) method and every time you are getting data you use this method (inside this method you can notifi data has changed). That's all.
Related
i'm doing a spinner that retrieves its items from an API, i checked Postman results but there's no error there and somehow i cant even click the spinner or the spinner just doesnt drop down, here's the codes, i checked all other solutions already but not quite like this
Spinner xml:
<Spinner
android:id="#+id/select_plan_spinner"
android:layout_width="match_parent"
android:layout_height="50dp"
android:layout_marginLeft="10dp"
android:layout_weight="1"
android:background="#drawable/sos_edit_bg"
android:gravity="center"
android:spinnerMode="dropdown"
android:textColor="#color/white_new"
android:visibility="visible"></Spinner>
Spinner:
plan_spinner = (Spinner) findViewById(R.id.select_plan_spinner);
plan_spinner:
plan_spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
#Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
plan_id = PLAN_ID.get(position);
Double price = PLAN_PRICE.get(position);
planprice = price;
Log.e("planprice", "planprice>>" + planprice);
if (plan_id != 0) {
int pos = position - 1;
String view_route = feeditem.get(pos).getIMEI();
if (view_route.equals("0")) {
view_route = "No";
} else {
view_route = "yes";
}
desc.setText("Description: " +
feeditem.get(pos).getMessage() + "\n View Route History: " + view_route);
} else {
desc.setText("Please select plan");
}
}
#Override
public void onNothingSelected(AdapterView<?> parent) {
}
API:
private void Get_plan_list() {
// TODO Auto-generated method stub
pDialog = new ProgressDialog(Select_plan.this);
pDialog.setMessage("Please wait...");
pDialog.setCancelable(false);
pDialog.show();
StringRequest req = new StringRequest(Request.Method.POST, Config.YOUR_API_URL + "planlist",
new Response.Listener<String>() {
#Override
public void onResponse(String response) {
pDialog.dismiss();
// response
Log.e("Responsesearch", response);
try {
JSONObject obj = new JSONObject(response);
int success = obj.getInt("success");
if (success == 1) {
JSONArray array = obj.getJSONArray("planlist");
for (int i = 0; i < array.length(); i++) {
JSONObject jsobj = array.getJSONObject(i);
int p_id = jsobj.getInt("plan_id");
plan_name = jsobj.getString("plan_name");
planprice = jsobj.getDouble("plan_price");
timeperoide = jsobj.getString("view_route");
allow_devices = jsobj.getString("allowed_device");
description = jsobj.getString("description");
UserData detail = new UserData();
detail.setID(p_id);
detail.setName(plan_name);
detail.setEmail(allow_devices);
detail.setMessage(description);
detail.setIMEI(timeperoide);
detail.setMobile(String.valueOf(planprice));
feeditem.add(detail);
PLAN_ID.add(p_id);
PLAN_PRICE.add(planprice);
PLAN_NAME.add(plan_name + "( USD " + planprice + ")");
ArrayAdapter<String> data2 = new ArrayAdapter<String>(Select_plan.this,
R.layout.spinner_item, PLAN_NAME);
plan_spinner.setAdapter(data2);
// for auto set spinner Value
Log.e("plan_id_intent", "plan_id_intent>>" + plan_id_intent);
if (plan_id_intent == null) {
} else {
int position = Integer.parseInt(plan_id_intent);
int index = PLAN_ID.indexOf(position);
plan_spinner.setSelection(index);
}
}
} else if (success == 0) {
String msg = obj.getString("text");
Toast.makeText(getApplicationContext(), "" + msg, Toast.LENGTH_LONG).show();
} else if (success == 2) {
}
} catch (JSONException e) {
// TODO Auto-generated catch block
Log.e("Error.Response", e.toString());
e.printStackTrace();
}
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
pDialog.dismiss();
// error
Log.e("Error.Response", error.toString());
}
}
) {
#Override
protected Map<String, String> getParams() {
Map<String, String> params = new HashMap<String, String>();
return params;
}
};
// for response time increase
req.setRetryPolicy(new DefaultRetryPolicy(DefaultRetryPolicy.DEFAULT_TIMEOUT_MS * 2,
DefaultRetryPolicy.DEFAULT_MAX_RETRIES, DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));
req.setShouldCache(false);
AppController.getInstance().addToRequestQueue(req);
}
How can i display this to Recyclerview? i already got the data of the id i want to display it on Recyclerview. i want to filter the data that depends on the current user.. btw i am using navigation drawer and it is on fragment.
this is the logcat.
i want to the data of the given id to recyclerview. but the problem is it wont display. please help.. thanks in advance here is my code.
this is the AdapterApartment
public class AdapterApartment extends RecyclerView.Adapter<AdapterApartment.ViewHolderApartment> {
private Context mCtx;
private ArrayList<Apartment> apartmentList = new ArrayList <>();
public AdapterApartment(Context mCtx, ArrayList <Apartment> apartmentList) {
this.mCtx = mCtx;
this.apartmentList = apartmentList;
}
#Override
public ViewHolderApartment onCreateViewHolder(ViewGroup parent, int viewType) {
LayoutInflater inflater = LayoutInflater.from(mCtx);
View view = inflater.inflate(R.layout.layout_houses, null);
return new ViewHolderApartment(view);
}
#Override
public void onBindViewHolder(ViewHolderApartment holder, int position) {
Apartment apartment = apartmentList.get(position);
holder.category.setText(apartment.getCategory());
holder.apartmentname.setText(apartment.getApartmentname());
holder.price.setText(String.valueOf(apartment.getPrice()));
}
#Override
public int getItemCount() {
return apartmentList.size();
}
class ViewHolderApartment extends RecyclerView.ViewHolder {
TextView category, apartmentname, price;
public ViewHolderApartment(View itemView) {
super(itemView);
category = itemView.findViewById(R.id.textViewCategory);
apartmentname = itemView.findViewById(R.id.textName);
price = itemView.findViewById(R.id.textViewPrice);
}
}
}
private String url = Server.URL + "viewapartment.php";
private String url2 = Server.URL + "listapartment.php";
private ArrayList<Apartment> apartmentList = new ArrayList <>();
private AdapterApartment adapterApartment;
private RecyclerView recyclerView;
private String id;
private String username;
private int success;
TextView txt_id, txt_username;
private static final String TAG_ID = "id";
private static final String TAG_USERNAME = "username";
private static final String TAG_SUCCESS = "success";
private static final String TAG_MESSAGE = "message";
String tag_json_obj = "json_obj_req";
ProgressDialog pDialog;
public static LandlordAddApartment newInstance(String id, String username) {
LandlordAddApartment fragment = new LandlordAddApartment();
Bundle args = new Bundle();
args.putString(TAG_ID, id);
args.putString(TAG_USERNAME, username);
fragment.setArguments(args);
return fragment;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setHasOptionsMenu(true);
if (getArguments() != null) {
id = getArguments().getString(TAG_ID);
username = getArguments().getString(TAG_USERNAME);
}
}
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.landlord_add_apartment, container, false);
txt_id = (TextView) v.findViewById(R.id.add_txt_id);
txt_id.setText(id);
txt_username = (TextView)v.findViewById(R.id.add_txt_username);
txt_username.setText(username);
checkUseriD(id);
recyclerView = (RecyclerView)v.findViewById(R.id.recyclerView);
recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
adapterApartment= new AdapterApartment(getActivity(), apartmentList);
loadApartment();
recyclerView.setAdapter(adapterApartment);
FloatingActionButton fab = (FloatingActionButton) v.findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(getActivity(), AddApartment.class);
intent.putExtra(TAG_ID, id);
intent.putExtra(TAG_USERNAME, username);
startActivity(intent);
}
});
return v;
}
protected boolean isNetworkConnected() {
try {
ConnectivityManager mConnectivityManager = (ConnectivityManager) getActivity().getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo mNetworkInfo = mConnectivityManager.getActiveNetworkInfo();
return (mNetworkInfo == null) ? false : true;
}catch (NullPointerException e){
return false;
}
}
private void checkUseriD(final String id) {
pDialog = new ProgressDialog(getActivity());
pDialog.setCancelable(false);
pDialog.setMessage("searching ...");
showDialog();
StringRequest stringRequest1 = new StringRequest(Request.Method.POST, url, new Response.Listener <String>() {
#Override
public void onResponse(String response) {
Log.e(TAG, "get id Response: " + response.toString());
hideDialog();
try {
JSONObject jObj = new JSONObject(response);
JSONArray array = new JSONArray(response);
success = jObj.getInt(TAG_SUCCESS);
// Check for error node in json
if (success == 1) {
Log.e("Success", jObj.toString());
Toast.makeText(getContext(), jObj.getString(TAG_MESSAGE), Toast.LENGTH_LONG).show();
} else {
Toast.makeText(getContext(), jObj.getString(TAG_MESSAGE), Toast.LENGTH_LONG).show();
}
} catch (JSONException e) {
// JSON error
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Log.e(TAG, "Login Error: " + error.getMessage());
Toast.makeText(getContext(), error.getMessage(), Toast.LENGTH_LONG).show();
hideDialog();
}
}) {
#Override
protected Map <String, String> getParams() {
// Posting parameters to login url
Map <String, String> params = new HashMap <String, String>();
params.put("userID", id);
return params;
}
};
// Adding request to request queue
AppController.getInstance().addToRequestQueue(stringRequest1, tag_json_obj);
}
private void loadApartment() {
String url;
/*
* Creating a String Request
* The request type is GET defined by first parameter
* The URL is defined in the second parameter
* Then we have a Response Listener and a Error Listener
* In response listener we will get the JSON response as a String
*
* */
StringRequest stringRequest = new StringRequest(Request.Method.GET, url2, new Response.Listener <String>() {
#Override
public void onResponse(String response) {
try {
//converting the string to json array object
JSONObject object = new JSONObject(response);
//traversing through all the object
for (int i = 0; i < array.length(); i++) {
//getting product object from json array
JSONObject apartment = array.getJSONObject(i);
apartmentList.add(new Apartment(
apartment.getInt("userID"),
apartment.getString("Category"),
apartment.getString("apartmentName"),
apartment.getString("price_month")));
}
//creating adapter object and setting it to recyclerview
AdapterApartment adapter = new
AdapterApartment(getContext(), apartmentList);
recyclerView.setAdapter(adapter);
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
}
});
Volley.newRequestQueue(getActivity()).add(stringRequest);
}
private void showDialog() {
if (!pDialog.isShowing())
pDialog.show();
}
private void hideDialog() {
if (pDialog.isShowing())
pDialog.dismiss();
}
this is the php. i dont know if my json code format is wrong.
<?php
$server="localhost";
$user = "root";
$password= "";
$database= "albayboardinghouse";
$connect = mysql_connect($server, $user, $password) or die ("connect failed!");
mysql_select_db($database) or die ("Error!");
$userID = $_POST['userID'];
class emp{}
if (empty($userID)) {
$response = new emp();
$response->success = 0;
$response->message = "Error data";
die(json_encode($response));
} else {
$query = mysql_query("SELECT userID, Category, apartmentName, price_month FROM apartmentlocation WHERE userID = '".$userID."'");
$row = mysql_fetch_array($query);
if (!empty($row)) {
$response = new emp();
$response->success = 1;
$response->userID = $row["userID"];
$response->Category = $row['Category'];
$response->apartmentName = $row['apartmentName'];
$response->price_month = $row['price_month'];
die(json_encode($response));
}
else{
$response = new emp();
$response->success = 0;
$response->message = "Error getting Data";
die(json_encode($response));
}
}
?>
i think you need to filter the data in your recycler view. if thats the issue, there is inbuilt Filter method to filter the datas from inside recycler view adapter.
below is the code used to filter contacts using filter method...
#Override
public Filter getFilter() {
return new Filter() {
#Override
protected FilterResults performFiltering(CharSequence charSequence) {
String charString = charSequence.toString();
if (charString.isEmpty()) {
contactListFiltered = contactList;
} else {
List<Contact> filteredList = new ArrayList<>();
for (Contact row : contactList) {
// name match condition. this might differ depending on your requirement
// here we are looking for name or phone number match
if (row.getName().toLowerCase().contains(charString.toLowerCase()) || row.getPhone().contains(charSequence)) {
filteredList.add(row);
}
}
contactListFiltered = filteredList;
}
FilterResults filterResults = new FilterResults();
filterResults.values = contactListFiltered;
return filterResults;
}
#Override
protected void publishResults(CharSequence charSequence, FilterResults filterResults) {
contactListFiltered = (ArrayList<Contact>) filterResults.values;
// refresh the list with filtered data
notifyDataSetChanged();
}
};
}
just check above code and change according to your need, as i cannot correctly figure your issue.
Thank you. :)
i've added a column (named load_more) to the end of a recyclerview and each time i touch this column it should download ten more columns from a url. the first time that I touch load_more, it works properly but for the second time, program crashes.
this is the code of loading data to the recyclerview:
public class category extends AppCompatActivity {
private String url = "http://iranradiotherapy.ir/api/get_category_posts/?include=title,date&id=";
private RequestQueue requestQueue;
private ArrayList<HashMap<String, String>> data;
private RecyclerView recyclerView;
private adapter adapter;
private int page_counter;
private String page_number;
private boolean flag;
private int current;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_category);
Bundle b = getIntent().getExtras();
final String cat_id = b.getString("category_id");
url += cat_id;
Toast.makeText(category.this, url, Toast.LENGTH_SHORT).show();
data = new ArrayList<>();
flag = true;
page_counter = 1;
page_number= "&page=";
requestQueue = Volley.newRequestQueue(this);
get_data();
}
private void get_data() {
JsonObjectRequest jsonObjectRequest = new JsonObjectRequest(Request.Method.GET, url + page_number + page_counter, new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
try {
JSONArray posts = response.getJSONArray("posts");
for (int i = 0; i < posts.length(); i++) {
HashMap<String, String> hashMap = new HashMap<>();
JSONObject temp = posts.getJSONObject(i);
String post_title = temp.getString("title");
String post_id = temp.getString("id");
String post_date = temp.getString("date");
hashMap.put("post_title", post_title);
hashMap.put("post_date", post_date);
hashMap.put("post_id", post_id);
data.add(hashMap);
}
final HashMap<String, String> hashMap = new HashMap<>();
hashMap.put("load_more", "load_more");
data.add(hashMap);
recyclerView = (RecyclerView) findViewById(R.id.category_recycler_view);
adapter = new adapter(data);
RecyclerView.LayoutManager mLayoutManager = new LinearLayoutManager(getApplicationContext());
recyclerView.setLayoutManager(mLayoutManager);
recyclerView.setItemAnimator(new DefaultItemAnimator());
recyclerView.setAdapter(adapter);
flag = true;
recyclerView.addOnItemTouchListener(new RecyclerTouchListener(getApplicationContext(), new RecyclerTouchListener.OnItemClickListener() {
#Override
public void onItemClick(View view, int position) {
if (data.get(position).equals(hashMap)) {
load_more();
}
else {
Intent i = new Intent(category.this, post.class);
i.putExtra("post_id", data.get(position).get("post_id"));
category.this.startActivity(i);
}
}
}));
} catch (Exception e ) {
Toast.makeText(category.this, "error 1 : " + e.toString(), Toast.LENGTH_SHORT).show();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Toast.makeText(category.this, "error 2 : " + error.toString(), Toast.LENGTH_SHORT).show();
}
});
requestQueue.add(jsonObjectRequest);
}
private void load_more() {
if (flag){
flag = false;
Toast.makeText(this, "load more data " + current, Toast.LENGTH_SHORT).show();
page_counter++;
get_data();
data.remove(data.size() - 1 );
}
}
}
and this is the adapter :
#Override
public void onBindViewHolder(MyViewHolder holder, int position) {
if (position + 1 == data.size()) {
holder.title.setVisibility(View.INVISIBLE);
holder.date.setVisibility(View.INVISIBLE);
holder.load_more.setVisibility(View.VISIBLE);
} else {
HashMap<String, String> d = data.get(position);
holder.title.setText(d.get("post_title"));
holder.date.setText(d.get("post_date"));
holder.load_more.setVisibility(View.INVISIBLE);
}
}
Why does Log.d("Test", "" + ListOfAttractions3.size() + ""); Return 0 when Log.d("Test2", "" + ListOfAttractions3.size() + ""); returns 2 even thoughDatabseRequest(); is called first? Some how Log 2 is also printed last but I can't see why?
Code:
public class Testlist extends Activity {
List<Attractions> ListOfAttractions3 = new ArrayList<>();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_testlist);
DatabseRequest();
Log.d("Test", "" + ListOfAttractions3.size() + "");
}
/*private void reFreshDisplay(){
ListView listView2 = (ListView) findViewById(R.id.listView2);
ArrayAdapter<Attractions> adapter = new ArrayAdapter<Attractions>(this, android.R.layout.simple_list_item_1, ListOfAttractions3);
listView2.setAdapter(adapter);
adapter.notifyDataSetChanged();
}*/
private void DatabseRequest(){
Response.Listener<String> responseListener = new Response.Listener<String>() {
#Override
public void onResponse(String response) {
try {
JSONArray jsonArray = new JSONArray(response);
int i = 0;
while(i < jsonArray.length()) {
JSONObject jsonObject = jsonArray.getJSONObject(i);
boolean success;
if (jsonObject.getBoolean("success")) success = true;
else success = false;
if (success) {
String attractionname = jsonObject.getString("attractionname");
double lng = jsonObject.getDouble("longitude");
double lat = jsonObject.getDouble("latitude");
int Rating = jsonObject.getInt("rating");
Attractions attraction = new Attractions(attractionname, lng, lat, Rating);
ListOfAttractions3.add(attraction);
Log.d("Test2", "" + ListOfAttractions3.size() + "");
} else {
AlertDialog.Builder builder = new AlertDialog.Builder(Testlist.this);
builder.setMessage("Connection to server Failed")
.setNegativeButton("Retry", null)
.create()
.show();
}
i++;
}
} catch (JSONException e) {
e.printStackTrace();
}
}
};
AttractionRequest attractionRequest = new AttractionRequest(responseListener);
RequestQueue queue2 = Volley.newRequestQueue(Testlist.this);
queue2.add(attractionRequest);
}
}
I'm trying to sync a list from the handheld to the wearable. On the phone side, I have a listview and you can add items to it and on the wear side I am just displaying the same list. I'm adding items to /card/id path and adding the array size on /counter. OnDataChanged method does gets called when I add items to the list on phoneside, but when I try to read the items on wearside, it's not working. It gives nullpointer exception when I'm trying to get the connected nodes and therefor I'm not able to read the data. Here's the code and the log snapshot:
Error
04-15 12:41:38.075: E/AndroidRuntime(13791): Caused by: java.lang.NullPointerException: Attempt to invoke interface method 'android.os.Looper com.google.android.gms.common.api.GoogleApiClient.getLooper()' on a null object reference
Wear side:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mDefaultCircleRadius = getResources().getDimension(R.dimen.default_settings_circle_radius);
mSelectedCircleRadius = getResources().getDimension(R.dimen.selected_settings_circle_radius);
cards = new ArrayList<GiftCard>();
new LoadCards().execute();
final WatchViewStub stub = (WatchViewStub) findViewById(R.id.watch_view_stub);
stub.setOnLayoutInflatedListener(new WatchViewStub.OnLayoutInflatedListener() {
#Override
public void onLayoutInflated(WatchViewStub stub) {
//mTextView = (TextView) stub.findViewById(R.id.count_text);
mListView = (WearableListView) stub.findViewById(R.id.card_list_view);
}
});
mHandler = new Handler();
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addApi(Wearable.API)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.build();
}
#Override
public void onDataChanged(DataEventBuffer dataEvents) {
for (DataEvent event : dataEvents) {
if (event.getType() == DataEvent.TYPE_CHANGED) {
// DataItem changed
DataItem item = event.getDataItem();
if (item.getUri().getPath().compareTo(COUNT_PATH) == 0) {
DataMap dataMap = DataMapItem.fromDataItem(item).getDataMap();
final String counter = dataMap.getString(CardUtil.CARD_COUNT);
new LoadCards().execute();
mHandler.post(new Runnable() {
#Override
public void run() {
Toast.makeText(c,"Card count: "+ counter,Toast.LENGTH_LONG).show();
//mTextView.setText("COUNTER FROM DATACHANGE METHOD: " + counter);
}
});
}
else if(item.getUri().getPath().compareTo(CARD_PATH) == 0){
}
} else if (event.getType() == DataEvent.TYPE_DELETED) {
// DataItem deleted
}
}
}
public GiftCard loadCardData(int id){
//Uri uri = getIntent().getData().buildUpon().encodedPath("/card").appendPath(String.valueOf(id)).build();
Uri uri = getUriForDataItem("/counter");
Log.d("URI", uri.getPath());
DataApi.DataItemResult result = Wearable.DataApi.getDataItem(mGoogleApiClient,uri).await();
DataMapItem item = DataMapItem.fromDataItem(result.getDataItem());
Asset cardImageAsset = item.getDataMap().getAsset(CardUtil.CARD_IMAGE);
//Asset barcodeImageAsset = item.getDataMap().getAsset(CardUtil.BARCODE_IMAGE);
String card_type = item.getDataMap().getString(CardUtil.CARD_TYPE);
Bitmap cardImage = BitmapFactory.decodeStream(Wearable.DataApi.getFdForAsset(mGoogleApiClient, cardImageAsset).await().getInputStream());
// Bitmap barcodeImage = BitmapFactory.decodeStream(Wearable.DataApi.getFdForAsset(mGoogleApiClient,barcodeImageAsset).await().getInputStream());
GiftCard card = new GiftCard();
card.setCardImage(cardImage);
card.setCardName(card_type);
card.setCardID(id);
return card;
}
public class LoadCards extends AsyncTask<Void, Void, Boolean> {
#Override
protected void onPreExecute() {
super.onPreExecute();
}
#Override
protected Boolean doInBackground(Void... arg0) {
// Uri uri = getIntent().getData().buildUpon().encodedPath("/counter").build();
Uri uri = getUriForDataItem("/counter");
Toast.makeText(c,uri.toString(),Toast.LENGTH_LONG).show();
DataApi.DataItemResult result = Wearable.DataApi.getDataItem(mGoogleApiClient,uri).await();
DataMapItem item = DataMapItem.fromDataItem(result.getDataItem());
int card_count = Integer.parseInt(item.getDataMap().getString(CardUtil.CARD_COUNT));
// int card_count = Integer.parseInt(loadCardCounter());
if(card_count <= 0){
Toast.makeText(c,"No cards available to show!",Toast.LENGTH_LONG).show();
} else {
for (int i = 1; i <= card_count; i++) {
GiftCard c = loadCardData(i);
cards.add(c);
}
}
return null;
}
#Override
protected void onPostExecute(Boolean result) {
super.onPostExecute(result);
//update the card list
mAdapter = new CardListAdapter(c,cards);
mListView.setAdapter(mAdapter);
// mListView.setClickListener();
}
}
private Uri getUriForDataItem(String path) {
String nodeId = getNodeId();
return new Uri.Builder().scheme(PutDataRequest.WEAR_URI_SCHEME).authority(nodeId).path(path).build();
}
private String getNodeId() {
NodeApi.GetConnectedNodesResult nodesResult = Wearable.NodeApi.getConnectedNodes(mGoogleApiClient).await();
List<Node> nodes = nodesResult.getNodes();
if (nodes.size() > 0) {
return nodes.get(0).getId();
} else {
Toast.makeText(c,"NO NODES AVAILABLE",Toast.LENGTH_LONG).show();
}
return null;
}}
From the stacktrace it's pretty obvious that you are trying to use Wearable DataAPI from the thread without Looper - in doInBackground() method I believe. That is why it crashes.
Move this code directly into onDataChanged() method and it should solve the issue.