int org.json.JSONArray.length() on a null object reference - android

I'm using volley library to connect to server and I have a Transaction class and a Server class with this codes:
Trans:
public class Trans extends Server {
public Object suggest(Context context) {
return connect("xxxxxxx", Request.Method.GET);
}
}
Server:
public Object connect(String url, int method) {
final Object[] object = {null};
StringRequest postRequest;
postRequest = new StringRequest(method, url,
new Response.Listener<String>() {
#Override
public void onResponse(String response) {
object[0] = response;
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
}
}
) {
#Override
protected Map<String, String> getParams() throws AuthFailureError {
Map<String, String> params = new HashMap<String, String>();
return params;
}
#Override
public String getBodyContentType() {
return "application/x-www-form-urlencoded; charset=UTF-8";
}
};
int socketTimeout = 20000;
RetryPolicy policy = new DefaultRetryPolicy(socketTimeout,
DefaultRetryPolicy.DEFAULT_MAX_RETRIES,
DefaultRetryPolicy.DEFAULT_BACKOFF_MULT);
postRequest.setRetryPolicy(policy);
AppController.getInstance().addToRequestQueue(postRequest);
return object[0];
}
But when I'm trying to get JSONArray with this:
#Override
protected void onResume() {
ArrayList<Suggests> arrayList = new ArrayList<>();
JSONArray jsonArray = (JSONArray) trans.suggest(MainActivity.this);
for (int i = 0; i < jsonArray.length(); i++) {
try {
JSONObject item = (JSONObject) jsonArray.get(i);
Suggests suggests = new Suggests();
suggests.title = item.getString("title");
suggests.type = item.getString("type");
arrayList.add(suggests);
} catch (JSONException e) {
e.printStackTrace();
}
}
super.onResume();
}
Application force closed and I have this error in logcat:
java.lang.RuntimeException: Unable to resume activity {ir.aftabeshafa.shafadoc/ir.aftabeshafa.shafadoc.MainActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'int org.json.JSONArray.length()' on a null object reference
What's the problem and how can I fix it?

Going off the suggestions in the comments,
Step 1 Define an interface that will pass-along the result you want. The <T> is a generic type, so you can return whatever data you want. You'll see that in Step 2.
public interface AsyncResponse<T> {
void onResponse(T response);
}
Step 2 Update the Server and Trans classes to take this as a parameter
public class Server {
public void connect(String url, int method, final AsyncResponse<String> asyncResponse) {
StringRequest request = new StringRequest(method, url, new Response.Listener<String>() {
#Override
public void onResponse(String response) {
if (asyncResponse != null) {
asyncResponse.onResponse(response);
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Log.e("VolleyError", error.getMessage());
Log.e("VolleyError", new String(error.networkResponse.data));
}
}) {
#Override
protected Map<String, String> getParams() {
Map<String, String> params = new HashMap<String, String>();
return params;
}
#Override
public String getBodyContentType() {
return "application/x-www-form-urlencoded; charset=UTF-8";
}
};
int socketTimeout = 20000;
RetryPolicy policy = new DefaultRetryPolicy(socketTimeout,
DefaultRetryPolicy.DEFAULT_MAX_RETRIES,
DefaultRetryPolicy.DEFAULT_BACKOFF_MULT);
request.setRetryPolicy(policy);
AppController.getInstance().addToRequestQueue(request);
}
}
Side question: Do you really need the Context? It isn't used...
public class Trans extends Server {
public void suggest(Context context, AsyncResponse<String> asyncResponse) {
connect("xxxxxxxx", Request.Method.GET, asyncResponse);
}
}
Step 3 Use your method like so to get a result in a callback. This was tested against the url http://jsonplaceholder.typicode.com/users, which returns a JSONArray of 10 User objects.
The ArrayAdapter was added for a full example since it didn't appear the ArrayList in the question was useful for anything.
public class MainActivity extends AppCompatActivity {
private ArrayList<User> arrayList;
private Trans trans;
private ArrayAdapter<User> adapter;
private ListView listView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
trans = new Trans();
arrayList = new ArrayList<User>();
adapter = new ArrayAdapter<User>(MainActivity.this, android.R.layout.simple_list_item_1, arrayList);
listView = (ListView) findViewById(android.R.id.list);
listView.setAdapter(adapter);
}
#Override
protected void onResume() {
trans.suggest(MainActivity.this, new AsyncResponse<String>() {
#Override
public void onResponse(String response) {
arrayList.clear(); // prevent duplicate data
try {
// The URL that was tested returns a JSONArray
// Change to JSONObject, if necessary
JSONArray jsonArray = new JSONArray(response);
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject item = (JSONObject) jsonArray.get(i);
User user = new User();
user.username = item.getString("name");
user.email = item.getString("email");
arrayList.add(user);
}
} catch (JSONException e) {
e.printStackTrace();
}
// Notify since the arrayList has changed the adapter
adapter.notifyDataSetChanged();
}
});
super.onResume();
}
}

Related

Cannot connect to the API using Volley

I am trying to get a JSON request from an API using volley but it didn't seem to work. I did try another dummy API and it works but not for this one. The one I am currently using has headers with key and value. Also, on checking the API on postman, I saw that the JSON format begins with '[' so I am not sure what to put for the JSONObject. Also, I am not sure if I added the header right. I am very new to android and would definitely appreciate it if someone could help me out.
public class MainActivity extends AppCompatActivity {
private RecyclerView mRecyclerView;
private ExampleAdapter mExampleAdapter;
private ArrayList<ExampleItem> mExampleList;
private RequestQueue mRequestQueue;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mRecyclerView = findViewById(R.id.recycler_view);
mRecyclerView.setHasFixedSize(true);
mRecyclerView.setLayoutManager(new LinearLayoutManager(this));
mExampleList = new ArrayList<>();
mRequestQueue = Volley.newRequestQueue(this);
parseJSON();
}
private void parseJSON() {
String url = "http://apidev.travelhouse.world/api/v1/packages";
JsonArrayRequest request = new JsonArrayRequest(url, new Response.Listener<JSONArray>() {
#Override
public void onResponse(JSONArray response) {
try {
for (int i = 0; i < response.length(); i++) {
JSONObject hit = response.getJSONObject(i);
String creatorName = hit.getString("holiday_name");
String imageUrl = hit.getString("primary_image");
String likeCount = hit.getString("package_price");
mExampleList.add(new ExampleItem(imageUrl, creatorName, likeCount));
}
mExampleAdapter = new ExampleAdapter(MainActivity.this, mExampleList);
mRecyclerView.setAdapter(mExampleAdapter);
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
error.printStackTrace();
Toast.makeText(MainActivity.this, "Failed to connect", Toast.LENGTH_LONG).show();
}
}) {
/** Passing some request headers* */
#Override
public Map getHeaders() throws AuthFailureError {
HashMap headers = new HashMap();
headers.put("Content-Type", "application/json");
headers.put("X-API-KEY", "CODEX#123");
return headers;
}
};
mRequestQueue.add(request);
}
Replace your JsonObjectRequest with:
JsonArrayRequest request = new JsonArrayRequest(url, new Response.Listener<JSONArray>() {
#Override
public void onResponse(JSONArray jsonArray) {
for (int i = 0; i < jsonArray.length(); i++) {....}
}
}

i want send json file to my server from android what should i do in doInBackground method?

my backend is laravel and i want to send json file to a specific rout
i already create my json plz help
public class MainActivity extends AppCompatActivity {
EditText usernameview;
EditText passwordview;
private static final String TAG = "MainActivity";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
usernameview = (EditText)findViewById(R.id.username) ;
passwordview = (EditText)findViewById(R.id.password) ;
Button login = (Button) findViewById(R.id.loginid);
}
public void senddatatoserver(View v) {
String username= usernameview.getText().toString();
String password = passwordview.getText().toString();
JSONObject login = new JSONObject();
try {
login.put("username",username);
login.put("password",password);
} catch (JSONException e) {
e.printStackTrace();
}
if (login.length() > 0) {
new SendDataToServer().execute(String.valueOf(login));
}
}
here is my class to send data i just wanna know what i should write in doinbackground methode
class SendDataToServer extends AsyncTask<String,String,String> {
#Override
protected String doInBackground(String... params) {
}
#Override
protected void onPostExecute(String s) {
}
}
you can use volley to send request
StringRequest stringRequest = new StringRequest(Request.Method.POST, YOUR_URL,
new Response.Listener<String>() {
#Override
public void onResponse(String response) {
for (int i = 0; i < response.length(); i++) {
JSONObject json; // convert String to JSONObject
try {
json = new JSONObject(response);
JSONArray jsonArray = json.getJSONArray("data");
lyric_string = jsonArray.getJSONObject(0).getString("song_lyric");
artist_string = jsonArray.getJSONObject(0).getString("song_artist");
//album_string = jsonArray.getJSONObject(0).getString("song_album");
} catch (JSONException e) {
e.printStackTrace();
}
}
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
//error message
dismissDialog();
lyric.setText("Sorry No Lyric Found");
lyric.setVisibility(View.VISIBLE);
}
}) {
#Override
protected Map<String, String> getParams() {
Map<String, String> params = new HashMap<>();
params.put("song_name", "A song Name");
return params;
}
};
RequestQueue requestQueue = Volley.newRequestQueue(this);
requestQueue.add(stringRequest);

requestQueue volley doenst work (sending multiple requests)

I want to upload multiple images (using base64 encode).
I send these images using a for :
for(int i =1; i<6; i++){
bmp = ((BitmapDrawable)imgs[i].getDrawable()).getBitmap();
String image = getEncoded64ImageStringFromBitmap(bmp);
SendImage(image);
}
But it just send one or two requests of 5 requests! also no error occurs here. I have a requestQueue that I initialized at onCreate method.
And this is my volley request :
private void SendImage( final String image) {
String URL = APPURL;
final StringRequest stringRequest = new StringRequest(Request.Method.POST, URL,
new Response.Listener<String>() {
#Override
public void onResponse(String response) {
try {
JSONObject jsonObject = new JSONObject(response);
} 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 Hashtable<String, String>();
params.put("image", image);
return params;
}
};
{
requestQueue.add(stringRequest);
Toast.makeText(AddProduct.this,"added "+requestQueue.getSequenceNumber(),Toast.LENGTH_SHORT).show();
}}
You have to do this through the recursion method
like
just you have to call one time
multiFileUpload(uploadedFileCount);
then it will process all file in recursion model.
private int totalFileCount = 6;
private int uploadedFileCount = 1;
private String URL = APPURL;
private multiFileUpload(int _uploadedFileCount)
{
final StringRequest stringRequest = new StringRequest(Request.Method.POST, URL,
new Response.Listener<String>() {
#Override
public void onResponse(String response) {
try {
JSONObject jsonObject = new JSONObject(response);
if((uploadedFileCount<6)
{
uploadedFileCount++;
multiFileUpload(uploadedFileCount);
}
} catch (JSONException e) {
e.printStackTrace();
}
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
}
}) {
#Override
protected Map<String, String> getParams() throws AuthFailureError {
Bitmap bmp = ((BitmapDrawable)imgs[_uploadedFileCount].getDrawable()).getBitmap();
String image = getEncoded64ImageStringFromBitmap(bmp);
Map<String, String> params = new Hashtable<String, String>();
params.put("image", image);
return params;
}
};
{
requestQueue.add(stringRequest);
Toast.makeText(AddProduct.this,"added "+requestQueue.getSequenceNumber(),Toast.LENGTH_SHORT).show();
}
}
My problem was at the backend part. The images come at the same time and I used time() function to name them so just one or two file saved in the server.

getting error org.json.JSONException: Value <pre of type java.lang.String cannot be converted to JSONObject

I want to access my Android apps through Web-Service.
but getting error in my android app ,
i am using volley & POST method for login.. `public class Main extends AppCompatActivity implements View.OnClickListener
{
public static final String LOGIN_URL = "http://10.54.103.8:4067/evivaservices/Webservices/login";
public static final String KEY_USERNAME="username";
public static final String KEY_PASSWORD="password";
private EditText editTextUsername;
private EditText editTextPassword;
private Button buttonLogin;
private String username;
private String password;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.login_layout);
editTextUsername = (EditText) findViewById(R.id.username1);
editTextPassword = (EditText) findViewById(R.id.password1);
buttonLogin = (Button) findViewById(R.id.login_button);
buttonLogin.setOnClickListener(this);
}
private void userLogin() {
username = editTextUsername.getText().toString().trim();
password = editTextPassword.getText().toString().trim();
StringRequest stringRequest = new StringRequest(Request.Method.POST, LOGIN_URL,
new Response.Listener<String>() {
#Override
public void onResponse(String response) {
try
{
JSONObject jsonObject = new JSONObject(response);
Next();
}
catch(JSONException e)
{
e.printStackTrace();
}
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Toast.makeText(getApplicationContext(),error.toString(), Toast.LENGTH_LONG ).show();
}
}){
#Override
protected Map<String, String> getParams() throws AuthFailureError {
Map<String,String> map = new HashMap<String,String>();
map.put(KEY_USERNAME,username);
map.put(KEY_PASSWORD,password);
return map;
}
};
RequestQueue requestQueue = Volley.newRequestQueue(this);
requestQueue.add(stringRequest);
}
private void Next(){
Intent intent = new Intent(this, HomeScreen.class);
intent.putExtra(KEY_USERNAME, username);
startActivity(intent);
}
#Override
public void onClick(View v)
{
userLogin();
}
}
`
JSON DATA
{
"id": 31,
"username": "andrew.cope#services.co.in",
"user_image": "http:\/\/103.54.103.8:4067\/evivaservices\/img\/profile_31.png",
"err-code": 0
}
`
Please change your StringRequest to JsonRequest as below:
JsonRequest jsonRequest = new JsonRequest(Request.Method.POST, LOGIN_URL, new Response.Listener<>() {
#Override
public void onResponse(Object response) {
try {
Next();
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Toast.makeText(getApplicationContext(), error.toString(), Toast.LENGTH_LONG).show();
}
}) {
#Override
protected Map<String, String> getParams() throws AuthFailureError {
Map<String, String> map = new HashMap<String, String>();
map.put(KEY_USERNAME, username);
map.put(KEY_PASSWORD, password);
return map;
}
#Override
protected Response parseNetworkResponse(NetworkResponse response) {
return null;
}
#Override
public int compareTo(Object another) {
return 0;
}
};
Thank You.
Hello dear you made a mistake while you parsing the response
JSONArray jsonArray=jsonObject.getJSONArray("err-code")
remove above the line and then parse again.
In you JSON DATA, I not find array, so you shouldn't use JsonArray, you can delete this line in your code :JSONArray jsonArray=jsonObject.getJSONArray("err-code").

Parsing JSONArray within JSONObject with volley in android

i have situation here
have some json code in the server side ... here's a part of json
{
"status":"ok",
"count":10,
"count_total":88,
"pages":9,
"posts":
[{
"id":1530,
"type":"post",
"slug":"slug",
""url":"url",
"status":"publish",
"title":"title",
"title_plain":"sth",
"content":"some content",
"modified":"2016-05-22 20:21:47",
"categories":[{"blah":"blah"}]
}]
}
i want "content" under the "posts" array and volley wouldn't let me use jsonarray inside jsonobject .
here's a part of my codes :
JsonObjectRequest obreq = new JsonObjectRequest(Request.Method.GET, url, new
Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
try {
JSONObject obj = response.getJSONObject("posts");
}
JSONcatch (JSONException e) {
e.printStackTrace();
}
}
},null);
sorry for the snippet i couldn't insert my code ...
Tnx
Is that a typo or something but your JSON is invalid you are having two double quotes here ""url":"url". Just remove one.
Just do this :
JsonObjectRequest obreq = new JsonObjectRequest(Request.Method.GET, url, new
Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
try {
JSONArray obj = response.getJSONArray("posts");
for (int i = 0; i < obj.length(); i++) {
JSONObject jsonObject = obj.getJSONObject(i);
int id = jsonObject.getInt("id");
String type = jsonObject.getString("type");
// retrieve the values like this so on..
}
}
catch (JSONException e) {
e.printStackTrace();
}
}
},null);
First create Models:
public class CategoryModel
{
public String blah;
}
public class PostModel
{
public int id;
public String type;
public String slug;
public String url;
public String status;
public String title;
public String title_plain;
public String content;
public String modified;
public List<CategoryModel> categories;
}
public class PostsModel
{
public String status;
public int count;
public int count_total;
public int pages;
public List<PostModel> posts;
}
then use gson;
in gradle:
compile 'com.google.code.gson:gson:2.4'
then in code get your object:
JSONObject json;
Gson gson = new Gson();
try {
json = new JSONObject(yourJsonString)
PostsModel result = gson.fromJson(json, PostsModel.class);
return result; // this is your deserialized response object
}catch(Exception e){
}
Volley:
in app class:
private VolleyServiceSingleton mVolleySingleton;
private RequestQueue mVolleyApiClient;
on create:
mVolleySingleton = VolleyServiceSingleton.getInstance();
mVolleyApiClient = mVolleySingleton.gerRequestQueue();
String request:
class VolleyStringRequest extends StringRequest
{
private Map<String, String> mParams;
public VolleyStringRequest(int method, String url, Response.Listener<String> listener, Response.ErrorListener errorListener, Map<String, String> requestParams) {
super(method, url, listener, errorListener);
mParams = requestParams;
afterRequestErrorRunnable = null;
Log.e("Request",url);
}
#Override
protected VolleyError parseNetworkError(VolleyError volleyError) {
if(volleyError.networkResponse != null && volleyError.networkResponse.data != null){
try {
Log.e("errorResponse", new String( volleyError.networkResponse.data, "utf-8" ));
}catch(Exception e){
}
}
return super.parseNetworkError(volleyError);
}
#Override
public RetryPolicy getRetryPolicy() {
DefaultRetryPolicy retryPolicy = new DefaultRetryPolicy(
TIMEOUT_IN_MILLISECONDS,
DefaultRetryPolicy.DEFAULT_MAX_RETRIES,
DefaultRetryPolicy.DEFAULT_BACKOFF_MULT);
return retryPolicy;
}
#Override
public Map getHeaders() throws AuthFailureError {
Map headers = new HashMap();
headers.put("Accept-Charset","utf-8");
//headers.put("Accept", RITEAID_HTTP_CONTENT_TYPE);
return headers;
}
#Override
public Map<String, String> getParams() {
return mParams;
}
}
and request (this must be customized):
HashMap<String, String> paramMap = new HashMap<String, String>();
paramMap.put("sign_in_username_email", Utils.nullToStringOrString(username));
paramMap.put("sign_in_password", password != null ? Utils.passwordConvert(password) : "");
paramMap.put("key", Constants.API_KEY);
mResponseHandler = getResponseHandler(requestUrl, positiveResponseFunc, inClass);
VolleyStringRequest request = new VolleyStringRequest(Request.Method.POST, getFinalUrl(requestUrl, null), getResponseHandler(requestUrl, positiveResponseFunc, inClass), createErrorListener(context, progress), paramMap);
request.setRetryPolicy(mRetryPolicy);
request.setTag(REQUEST_TAG);
mVolleyApiClient.add(request);

Categories

Resources