Im trying to populate my listView with data from my database. i have tbl_table with only tableID and tableCapacity. i tried running my phpcodes to postman, and in the printing in the log too, and it seems that there is no problem, so i figured that it must be because of the way i convert the Json encode. i keep on getting this error. thanks in advance.. im running my codes in android 4.1.2 API 16.
FATAL EXCEPTION: main
com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_ARRAY but was STRING at line 1 column 1
at com.google.gson.Gson.fromJson(Gson.java:815)
at com.google.gson.Gson.fromJson(Gson.java:768)
at com.google.gson.Gson.fromJson(Gson.java:717)
at com.kosalgeek.android.json.JsonConverter.toArrayList(JsonConverter.java:42)
at markjon.nobleza.qaldi.Table.onResponse(Table.java:51)
at markjon.nobleza.qaldi.Table.onResponse(Table.java:20)
Here is my Codes:
Table.class
public class Table extends AppCompatActivity implements Response.Listener<String> {
final String TAG = this.getClass().getSimpleName();
ListView tableLV;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_table);
String URL = "http://192.168.1.10/myDB/table.php";
StringRequest stringRequest = new StringRequest(Request.Method.GET, URL, this, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Toast.makeText(getApplicationContext(), "Error retrieving data", Toast.LENGTH_SHORT).show();
}
});
MySingleton.getInstance(getApplicationContext()).addToRequestQueue(stringRequest);
tableLV = (ListView)findViewById(R.id.tableList);
}
#Override
public void onResponse(String response) {
Log.d(TAG, response);
ArrayList<myTable> tableList = new JsonConverter<myTable>().toArrayList(response, myTable.class);
BindDictionary<myTable> dict = new BindDictionary<>();
dict.addStringField(R.id.tableNum, new StringExtractor<myTable>() {
#Override
public String getStringValue(myTable item, int position) {
return "" + item.tableID;
}
});
dict.addStringField(R.id.tableCap, new StringExtractor<myTable>() {
#Override
public String getStringValue(myTable item, int position) {
return "" + item.tableCapacity;
}
});
FunDapter<myTable> adapter = new FunDapter<>(getApplicationContext(), tableList, R.layout.table_layout, dict);
tableLV.setAdapter(adapter);
}
}
myTable.class
public class myTable {
#SerializedName("tableID")
public int tableID;
#SerializedName("tableCapacity")
public int tableCapacity;
}
The error point on these two lines:
public class Table extends AppCompatActivity implements Response.Listener<String>
ArrayList<myTable> tableList = new JsonConverter<myTable>().toArrayList(response, myTable.class);
The response variable should be a proper json string, but it has not the right format. According to the error message and as it is expected to be a json array, this json string should start with array symbol, i.e. [ and ends with ].
I suggest that you use a break point on this line and evaluate the value of response variable. You can use online json formatters/validators to find out what is wrong in this json string. Then you should change the logic of the method that creates this json.
Related
i am new to Android,here is class Question bank returns list of json obj received from an api
ArrayAsyncResponse in interface containing only one method process complete ,i readed that http request is asynchronous but unable to relate
Question is model class
case 1) when there is no ArrayAsyncResponse interface exist and i return the list to main activity and print it it shows empty list but when i make call to callback.processComplete() and then return list followed by printing ,it shows data
case2 )if i pass null in this function callback.processComplete() then again returned list is empty
so what basically Interface is helping us
public class QuestionBank {
ArrayList questionArrayList = new ArrayList<>();
private String url = "https://raw.githubusercontent.com/curiousily/simple-quiz/master/script/statements-data.json";
public List<Question> getQuestions(final AnswerListAsyncResponse callBack) {
JsonArrayRequest jsonArrayRequest = new JsonArrayRequest(
Request.Method.GET,
url,
(JSONArray) null,
new Response.Listener<JSONArray>() {
#Override
public void onResponse(JSONArray response) {
for (int i = 0; i < response.length(); i++) {
try {
Question question = new Question();
question.setAnswer(response.getJSONArray(i).get(0).toString());
question.setAnswerTrue(response.getJSONArray(i).getBoolean(1));
//Add question objects to list
questionArrayList.add(question);
//Log.d("Hello", "onResponse: " + question.getAnswer());
// Log.d("JSON", "onResponse: " + response.getJSONArray(i).get(0));
//Log.d("JSON2", "onResponse: " + response.getJSONArray(i).getBoolean(1));
} catch (JSONException e) {
e.printStackTrace();
}
}
if (null != callBack) callBack.processFinished(questionArrayList);
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
}
});
AppController.getInstance().addToRequestQueue(jsonArrayRequest);
return questionArrayList;
}
public class MainActivity extends AppCompatActivity {
private QuestionBank questionBank;
List<Question> questionList;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
questionBank=new QuestionBank();
questionList=questionBank.getQuestions(new AnswerListAsyncResponse() {
#Override
public void processFinished(ArrayList<Question> questionsArrayList) {//this function triggers when response is received from api
Log.d("inside", "processFinished: "+questionsArrayList);
}
});
Log.d("sync response", "questionLIst: "+questionList);
}
}
Sorry I can't write this in comment, but I think I can help you.
I don't understand well your question. but I think you need to get a Listener of the async in your class activity.
You can do that with EventBus, like this : https://github.com/greenrobot/EventBus
I want to get string from arraylist inside oncreateview fragment but i cant figure itout since no position index has been pass. get(position) return error.
String price = arrayList.get(position).getPrice();
i need to get string price and settext for price.this is my main concern.
this values should return from arraylist.
this is response JSON array from volley using mysingleton.
Single Product Response: [{"price":"75","date":"2017-07-13 03:25:31","pk_i_id":"4"}]
this main activty fragment
public class MainActivityFragment extends Fragment {
private TextView product,price,date,title;
private String product_id;
ArrayList<ProductItem> arrayList = new ArrayList<>();
Context context;
public MainActivityFragment() {
// Required empty public constructor
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.fragment_main_activity, container, false);
product = (TextView) view.findViewById(R.id.tv1);
title = (TextView) view.findViewById(R.id.tvTitle);
price = (TextView) view.findViewById(R.id.tvPrice);
date = (TextView) view.findViewById(R.id.tvDate);
if (getArguments() != null) {
Log.i(TAG, "getArgument is not null");
product_id = getArguments().getString("product_id");
ProductBackgroundTask productBackgroundTask = new ProductBackgroundTask(this.getActivity(), product_id);
arrayList = productBackgroundTask.getList();
String price = arrayList.get(position).getPrice();
// Log.d(TAG, "price: " + price);
product.setText(product_id);
// price.setText(price);
}else {
Log.i(TAG, "getArgument is null");
}
return view;
}
}
this is task to get arraylist using volley
public class ProductBackgroundTask {
private Context context;
ArrayList<ProductItem> arrayList = new ArrayList<>();
String json_url = "phpfile.php";
private String product_id;
public ProductBackgroundTask(Context context, String product_id) {
this.context = context;
this.product_id = product_id;
}
public ArrayList<ProductItem> getList(){
StringRequest stringRequest = new StringRequest(Request.Method.POST, json_url,
new Response.Listener<String>() {
#Override
public void onResponse(String response) {
Log.d(TAG, "Single Product Response: " + response);
try {
JSONArray jsonarr = new JSONArray(response);
for (int i = 0; i < jsonarr.length(); i++) {
JSONObject jsonobj = jsonarr.getJSONObject(i);
ProductItem productItem = new ProductItem(jsonobj.getString("price"), jsonobj.getString("date"), jsonobj.getInt("pk_i_id"));
arrayList.add(productItem);
}
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
}
}){
#Override
protected Map<String, String> getParams() throws AuthFailureError {
Map<String,String> params = new HashMap<>();
params.put("product_id", product_id);
return params;
}
};
MySingleton.getInstance(context).addToRequestQueue(stringRequest);
return arrayList;
}
}
and this is class of array list
public class ProductItem {
private String Price,Date;
private int ProductId;
public ProductItem(String Price, String Date, int ProductId){
this.setPrice(Price);
this.setDate(Date);
this.setProductId(ProductId);
}
public int getProductId() {
return ProductId;
}
public void setProductId(int productId) {
ProductId = productId;
}
public String getPrice() {
return Price;
}
public void setPrice(String price) {
Price = price;
}
public String getDate() {
return Date;
}
public void setDate(String date) {
Date = date;
}
Clearly in your oncreate you haven’t initialized the product item and you cannot parse the complete list.You can try two to solve this
1.Pass specific item number instead of position i.e
say if you want to show 4th item then position=3
2.Or write a loop like this to parse entire arrayList like this
for(ProductItem productItem:arrayList){
String price = productItem.getPrice();
// Log.d(TAG, "price: " + price);
product.setText(product_id);
price.setText(price);
}
Mistake you're doing is that in the MainActivityFragment your trying to assign the value to the arrayList even before the data is added to the arrayList in the ProductBackgroundTask-getList. That's the reason you are getting the list null all the time. Try to use interfaces.
1.Make your MainActivityFragment implement the interface.
2.Set the value to the interface method once you get the data from the server.
3.Get the data in the MainActivityFragment inside interface method and do all the operation you're doing inside the onCreateView method.
Now your arraylist will have the data whatever you received from the server.
Below is the link for the example on interfaces if you haven't used them before. He is doing exactly as your requirement.
https://www.justinmccandless.com/post/setting-up-a-callback-function-in-android/
Allow me. The arrayList that you return from getList isn't populated at the time you call String price = arrayList.get(position).getPrice();. The server call using volley takes some time to process and that's when the onResponse gets called. This happens AFTER you've returned the arrayList which is in fact empty.
The sequence of events is as follows.
• Call to arrayList = productBackgroundTask.getList(); which returns an empty ArrayList.
• String price = arrayList.get(position).getPrice();
Now after a while..
• onResponse inside getList() gets called.
Do you now see why it's empty?
Simple Solution: • Define a simple interface ProductListener alongside ProductBackgroundTask. (With only a single abstract method onProducts).
• Instantiate it inside the Fragment's onCreateView using an anonymous class and pass it to the constructor of ProductListener to save it for later use. Do whatever you want to do with the products inside the onProducts method. (Since that will be called with the actual data)
• Call its onProducts method with the data that's parsed and fetched inside the onResponse method.
ProductBackgroundTask code:
public class ProductBackgroundTask {
private Context context;
// I removed the instance ArrayList since that can be made
// local.
// Here, we add a reference to our callback interface as we can use it later.
private ProductListener listener;
String json_url = "http://192.168.43.55/android/v1/productList.php";
private String product_id;
// Instantiate this class using an additional listener argument
// which would be a concrete implementation of our interface.
public ProductBackgroundTask(Context context, String product_id, ProductListener listener) {
this.context = context;
this.product_id = product_id;
this.listener = listener;
}
// getList should not return anything,
// so I keep the return as void.
public void getList() {
StringRequest stringRequest = new StringRequest(Request.Method.POST, json_url,
new Response.Listener<String>() {
#Override
public void onResponse(String response) {
ArrayList<ProductItem> arrayList = new ArrayList<>();
Log.d(TAG, "Single Product Response: " + response);
try {
JSONArray jsonarr = new JSONArray(response);
for (int i = 0; i < jsonarr.length(); i++) {
JSONObject jsonobj = jsonarr.getJSONObject(i);
ProductItem productItem = new ProductItem(jsonobj.getString("price"), jsonobj.getString("date"), jsonobj.getInt("pk_i_id"));
arrayList.add(productItem);
}
// Notice this line here, this is what
// calls the callback with the products.
listener.onProducts(arrayList);
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
}
}){
#Override
protected Map<String, String> getParams() throws AuthFailureError {
Map<String,String> params = new HashMap<>();
params.put("product_id", product_id);
return params;
}
};
MySingleton.getInstance(context).addToRequestQueue(stringRequest);
}
}
// Callback interface, we would need a concrete implementation
// of this and pass that to the constructor of ProductBackgroundTask.
interface ProductListener {
void onProducts(ArrayList<ProductItem> products);
}
The code inside onCreateView:
ProductBackgroundTask productBackgroundTask = new ProductBackgroundTask(this.getActivity(), product_id, new ProductListener() {
// This method will be called with the needed products.
// Give an anonymous class implementation of our interface
// right here since we won't be using it anymore.
public void onProducts(ArrayList<ProductItem> products) {
// Get the price you want.
String str = arrayList.get(0).getPrice();
// Use str wherever necessary. Use the UI thread here if you need
// to change any visible elements on the screen.
}
});
// Simply call this method to get the ball rolling.
productBackgroundTask.getList();
This is a concrete implementation of the this answer and you won't be changing much code.
I am using retrofit library.I have created a class in which i am getting the value of particular id from other class, and i want to fetch particular list of that id but in the onResponse() method am getting an error. i checked in the postman in json format the list is fetching......but not here!
public class Main2Activity extends AppCompatActivity implements Callback<MailChimpEmailResponse> {
public String idReceived;
List<MailChimpEmailResponseSecond> emailList = new ArrayList<>();
private RecyclerView recyclerViewSecond;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main2);
Call<MailChimpEmailResponse> call = MailChimpAPIClient.getClient().fetchMembers(idReceived,"efb918ee88a3a8a77-us15" );
call.enqueue(this);
}
#Override
public void onResponse(Call<MailChimpEmailResponse> call, Response<MailChimpEmailResponse> response) {
Log.d("ashu", "null response");
Intent intent = getIntent();
idReceived = intent.getStringExtra("id_value");
Log.d("ashu", "id received is: " + idReceived);
MailChimpEmailResponse listResponse = response.body();
for (MailChimpEmailResponseSecond list : listResponse.emailLists) {
Log.d("ashu", list.getEmailListName());
this.emailList = listResponse.emailLists;
}
recyclerViewSecond = (RecyclerView) findViewById(R.id.my_recycler_view_second);
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this);
recyclerViewSecond.setLayoutManager(linearLayoutManager);
EmailAdapter adapter = new EmailAdapter(this.emailList);
recyclerViewSecond.setAdapter(adapter);
adapter.notifyDataSetChanged();
}
#Override
public void onFailure(Call<MailChimpEmailResponse> call, Throwable t) {
}
}
my api class:
public interface MailChimpApi {
#GET("lists")
public Call<MailChimpListResponse> fetchLists(#Query("apikey") String apikey, #Query("offset") int offset, #Query("count") int count);
#GET("lists/{list_id}/members")
public Call<MailChimpEmailResponse> fetchMembers(#Path("list_id") String listId,#Query("apikey") String apikey);
}
my json:
{
"members": [
{
"id": "04d80020e78edd86a79eda",
"email_address": "ashuingh.02046547#gmail.com",
"unique_email_id": "784c772918",
"email_type": "html",
"status": "subscribed",
"merge_fields": {
"FNAME": "Ashsdjssh",
"LNAME": "kudjskjar"
},
I believe the following line should be in onCreate method instead of onResponse,
idReceived = intent.getStringExtra("id_value");
This Android app is using Android Studio. The function is to scan and display data from the beacon/eddystone. The app already functions and after the scanning stops, the data saves to the local file. I need to transfer the data to the server. How can i insert the volley coding to the mainacitivity.java. I tried to put under the stopscanning button, but it shows error. Im really beginners to learn about android studio.
Here is the coding:
private void stopScanning(Button scanButton) {
try {
beaconManager.stopRangingBeaconsInRegion(region);
} catch (RemoteException e) {
// TODO - OK, what now then?
}
String scanData = logString.toString();
if (scanData.length() > 0)
{
public class MainActivity extends AppCompatActivity {
//The values of these variables will be fetched by the file(Where you will store data)
private String PREFERENCE_SCANINTERVAL = "scanInterval";
private String PREFERENCE_TIMESTAMP = "timestamp";
private String PREFERENCE_POWER = "power";
private String PREFERENCE_PROXIMITY = "proximity";
private String PREFERENCE_RSSI = "rssi";
private String PREFERENCE_MAJORMINOR = "majorMinor";
private String PREFERENCE_UUID = "uuid";
private String PREFERENCE_INDEX = "index";
private String PREFERENCE_LOCATION = "location";
private String PREFERENCE_REALTIME = "realTimeLog";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
String url = "http://beaconscanner.byethost33.com/beaconscanner.php";//This is the url of your server where you will be sending the data to.
//StringRequest is a class in the Volley Library.
//The constructor of this class has four parameters.
// 1 parameter is Request.Method.POST =this specifies the method type, That is post.
//2 parameter is the url you will be sending the request to.That is the server
//3 parameter is the response listener , It will listen for any response from your server . you will be able to fetch the response from the server using this.
//4 parameter is the error listener, it will listen for any error's during the connection or etc.
StringRequest request = new StringRequest(Request.Method.POST, url, new Response.Listener<String>() {
#Override
public void onResponse(String response) {
//Here you will be able to fetch the response coming from the server.
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
}
})
//This is the method we override.
{
//This is method is used to send the data to the server for post methods. This method returns all the data you want to send to server. This is how you send data using Volley.
#Override
protected Map<String, String> getParams() throws AuthFailureError {
Map<String,String> params = new HashMap<String, String>();
params.put("scanInterval",PREFERENCE_SCANINTERVAL);
params.put("timestamp",PREFERENCE_SCANINTERVAL);
params.put("power",PREFERENCE_POWER);
params.put("proximity",PREFERENCE_PROXIMITY);
params.put("rssi",PREFERENCE_RSSI);
params.put("majorMinor",PREFERENCE_MAJORMINOR);
params.put("uuid",PREFERENCE_UUID);
params.put("index",PREFERENCE_INDEX);
params.put("location",PREFERENCE_LOCATION);
params.put("realTimelog",PREFERENCE_REALTIME);
return params;
}
};//The constructor ends here.
Volley.newRequestQueue(this).add(request);// This is the main potion of this code. if you dont add this you will not be able to send the request to your server. this helps you to send it.
}
}
// Write file
fileHelper.createFile(scanData);
// Display file created message.
Toast.makeText(getBaseContext(),
"File saved to:" + getFilesDir().getAbsolutePath(),
Toast.LENGTH_SHORT).show();
scanButton.setText(MODE_STOPPED);
} else {
// We didn't get any data, so there's no point writing an empty file.
Toast.makeText(getBaseContext(),
"No data captured during scan, output file will not be created.",
Toast.LENGTH_SHORT).show();
scanButton.setText(MODE_STOPPED);
}
}
Please add your stacktrace. Also I guess that you want to send the data using the body not the params :). In that case, call the request using the following signature:
new JsonObjectRequest(Request.Method.POST, url, new JSONObject(bodyData), new Response.Listener<JSONObject>() { }
public void sendMyData(HashMap map) {
String url = "http://"....";
StringRequest request = new StringRequest(Request.Method.POST, url, new Response.Listener<String>() {
#Override
public void onResponse(String response) {
progressBar.setVisibility(View.INVISIBLE);
try {// to receive server response, in this example it's jsonArray
JSONArray jsonArray = new JSONArray(response);
//code
}
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
System.out.println(error);
}
}) {
#Override
public String getBodyContentType() { // if your server uses java restfull webservice , you have to override this content type
return "application/json";
}
#Override
protected Map<String, String> getParams() throws AuthFailureError {// parameters which should server receive
Map<String, String> parameters =map;
return parameters;
}
};
requestQueue.add(request);
}
In my application, I want to bind Json response to a target class using Volley library, But am not able to do that.
My Code:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
registerComponentDownload(GalleryParser.class, Const.api.URL_GALLERY);
}//on create
private void makeJsonObjectRequest(final Class<? extends BaseModel> className, String urlJsonArry) {
JsonObjectRequest jsonObjectRequest=new JsonObjectRequest(Request.Method.GET,urlJsonArry,null, new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
//start gallery activity
}
} , new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
}
});
AppController.getInstance().addToRequestQueue(jsonObjectRequest);
}
private void registerComponentDownload(Class<? extends BaseModel> aClass, String url) {
makeJsonObjectRequest(aClass,Const.buildUrl(url));
}
}
Is it possible to get response in class? Or am trying in wrong direction.
Please suggest me.
Thank you.
I think you can refer to this using volley with gson library to make a Gson request
https://developer.android.com/training/volley/request-custom.html
Add Gson Library in you lib folder .
this is class formate
public class TestData {
public int success;
public String message;
public TestDatail data;
public class TestDatail
{
public int is_friend;
public int is_following;
}
}
Gson gs=new Gson();
return gs.fromJson(your Volley Library Response,TestData.class);
Method 1:Using Bundle object-->
In my case i'm passing an array from Activity A to Activity B something like this:
public void onResponse(JSONObject response)
{
ArrayList<Images> imagesArrayList = new ArrayList<Images>();
try{
if(response.has("images"))
{
JSONArray imagesList = response.getJSONArray("images");
Intent i = newIntent(ActivityA.this,ActivityB.class);
i.putExtra("jsonArray",imagesList.toString());
startActivity(i);
}
}catch(JSONException e){}
}
And in Activity B's onCreate method check for the that passed bundle something like this:
Intent i = getIntent();
if (i.hasExtra("jsonArray"))
{
String jsonArray = i.getStringExtra("jsonArray");
try {
JSONArray array = new JSONArray(jsonArray);
// do whatever you need with this array
} catch (JSONException e) {
e.printStackTrace();
}
}
Method 2: Using pojo/getters & setter
Create a pojo
Extract the required data once you receive the response using volley.
set it using setters of pojo.
start gallery activity.
get the data using getters of pojo.