I have written app for weather using open weather API.... but when i install the app in my phone and click on the button to determine weather it crashes... I use Android M in my phone
public class DownloadTask extends AsyncTask<String,Void,String>{
#Override
protected String doInBackground(String... urls) {
String result = "";
URL url;
HttpURLConnection httpURLConnection = null;
try {
url = new URL(urls[0]);
httpURLConnection = (HttpURLConnection) url.openConnection();
InputStream in = httpURLConnection.getInputStream();
InputStreamReader reader = new InputStreamReader(in);
int data = reader.read();
while(data != -1){
char current = (char) data;
result += current;
data = reader.read();
}
return result;
}
//combined the exceptions MalformedURL and IOException to a common to display a toast msg
catch (Exception e) {
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
try {
String msg = "";
JSONObject jsonObject = new JSONObject(result);
String weatherInfo = jsonObject.getString("weather");
JSONArray arr = new JSONArray(weatherInfo);
for(int i = 0;i<arr.length();i++){
JSONObject jsonPart = arr.getJSONObject(i);
String main = "";
String desc = "";
main = jsonPart.getString("main");
desc = jsonPart.getString("description");
icon = jsonPart.getString("icon");
if (main != "" && desc != "") {
msg += main + "\r\n" + desc;
}
}
if(msg != ""){
weatherReport.setText(msg);
}
else{
Toast.makeText(MainActivity.this,
"Location not able to determine",Toast.LENGTH_LONG).show();
}
} catch (JSONException e) {
Toast.makeText(MainActivity.this,
"Location not able to determine",Toast.LENGTH_LONG).show();
e.printStackTrace();
}
}
}
The error shown is that arr.length() is applied on a null array....
i don't get what the error is . is it about permissions ... if so how should i implement permissions in Marshmallow... this is the code that is inside onCreate(), if its about permissions pls tell how to implement..
try {
//to hide the keyboard after pressing the button
InputMethodManager manager =
(InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
manager.hideSoftInputFromInputMethod(weatherInput.getWindowToken(),0);
DownloadTask downloadTask = new DownloadTask();
//used to encode the entered input for url.. for example San Fransisco appears in url
//as San%20Fransisco ... and to enable that we use the encoder...
String encodedCity = URLEncoder.encode(city,"UTF-8");
downloadTask.execute("http://api.openweathermap.org/data/2.5/weather?q=" + encodedCity);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
Logcat ..
02-25 22:56:54.009 1413-1413/com.example.hemantj.weather E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.hemantj.weather, PID: 1413
java.lang.NullPointerException: Attempt to invoke virtual method 'int java.lang.String.length()' on a null object reference
at org.json.JSONTokener.nextCleanInternal(JSONTokener.java:116)
at org.json.JSONTokener.nextValue(JSONTokener.java:94)
at org.json.JSONObject.<init>(JSONObject.java:156)
at org.json.JSONObject.<init>(JSONObject.java:173)
at com.example.hemantj.weather.MainActivity$DownloadTask.onPostExecute(MainActivity.java:133)
at com.example.hemantj.weather.MainActivity$DownloadTask.onPostExecute(MainActivity.java:92)
at android.os.AsyncTask.finish(AsyncTask.java:651)
at android.os.AsyncTask.access$500(AsyncTask.java:180)
at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:668)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5451)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
try {
Log.d(TAG, "onPostExecute: this inner of post" + getcontent_for_validate);
jsonobj = new JSONObject(getcontent_for_validate);
System.out.println("this is get content" + jsonobj.toString());
JSONArray array = jsonobj.getJSONArray("Staff_Details");
for (int i = 0; i < array.length(); i++) {
Clint_id = editText_user_name.getText().toString();
Api_key = array.getJSONObject(i).getString("api_key");
COMPANY_LOGO = array.getJSONObject(i).getString("company_logo");
Password = editText_password.getText().toString();
}
} catch (JSONException e) {
e.printStackTrace();
}
internet permission only
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
error is in your onPostExecute()
new JSONArray(weatherInfo); //is returning null
so arr is null
what is value of weatherInfo?
Related
I used glide for displaying image from url.When i used the debugger the url contains the image.But the problem is when ever the app run it closes.Is there any thing to do in code of imageview?Please help me to recover this problem.Forgive me if i asked blunder.Thanks in advance.My code is provided below.
public class ProductImages extends AsyncTask<Void , Void, Void> {
int status;StringBuilder sb;
String strJson, postData;
JSONArray jsonArray;
String msg;
boolean pass=false;
ArrayList<String> imgurls=new ArrayList<>();
#Override
protected void onPreExecute() {
super.onPreExecute();
}
#Override
protected Void doInBackground(Void... arg0) {
String url =getResources().getString(R.string.url) + "WebServices/WebService.asmx/ProductImages";
HttpURLConnection c = null;
try {
postData = "{\"productID\":\"" + productID + "\",\"TID\":\"" + constants.TID + "\"}";
String response=db.GetResponses(url,postData);
if(!response.equals("")){
strJson=response;
}
else {
URL u = new URL(url);
c = (HttpURLConnection) u.openConnection();
c.setRequestMethod("POST");
c.setRequestProperty("Content-type", "application/json; charset=utf-16");
c.setRequestProperty("Content-length", Integer.toString(postData.length()));
c.setDoInput(true);
c.setDoOutput(true);
c.setUseCaches(false);
c.setConnectTimeout(10000);
c.setReadTimeout(10000);
DataOutputStream wr = new DataOutputStream(c.getOutputStream());
wr.writeBytes(postData);
wr.flush();
wr.close();
status = c.getResponseCode();
switch (status) {
case 200:
case 201: BufferedReader br = new BufferedReader(new InputStreamReader(c.getInputStream()));
sb = new StringBuilder();
String line;
while ((line = br.readLine()) != null) {
sb.append(line).append("\n");
}
br.close();
int a=sb.indexOf("[");
int b=sb.lastIndexOf("]");
strJson=sb.substring(a, b + 1);
// strJson=cryptography.Decrypt(strJson);
strJson="{\"JSON\":" + strJson.replace("\\\"","\"").replace("\\\\","\\") + "}";
}
}
} catch (Exception ex) {
Logger.getLogger(getClass().getName()).log(Level.SEVERE, null, ex);
msg=ex.getMessage();
} finally {
if (c != null) {
try {
c.disconnect();
} catch (Exception ex) {
Logger.getLogger(getClass().getName()).log(Level.SEVERE, null, ex);
msg=ex.getMessage();
}
}
}
if(strJson!=null)
{try {
JSONObject jsonRootObject = new JSONObject(strJson);
jsonArray = jsonRootObject.optJSONArray("JSON");
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject jsonObject = jsonArray.getJSONObject(i);
msg=jsonObject.optString("Message");
pass=jsonObject.optBoolean("Flag",true);
imgurls.add(getResources().getString(R.string.url) + jsonObject.optString("Image").substring((jsonObject.optString("Image")).indexOf("Media")));
if(jsonObject.optBoolean("IsMain")){
productImage=getResources().getString(R.string.url) + jsonObject.optString("Image").substring((jsonObject.optString("Image")).indexOf("Media"));
}
}
if(pass){
if(c!=null)
db.ResponsesSaving(url,postData,strJson,"null");
}
} catch (Exception ex) {
msg=ex.getMessage();
}}
return null;
}
#Override
protected void onPostExecute(Void result) {
super.onPostExecute(result);
if(!pass) {
new AlertDialog.Builder(EnquiryItem.this).setIcon(android.R.drawable.ic_dialog_alert)//.setTitle("")
.setMessage(msg)
.setPositiveButton(R.string.ok_button, new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
}
}).setCancelable(false).show();
}
else {
for (int i=0;i<imgurls.size();i++) {
final int fi=i;
ImageView imageView = (ImageView) findViewById(R.id.image);
Glide.with(EnquiryItem.this).load(imgurls).into(imageView);
}
}
}
**My image view**
<ImageView
android:id="#+id/image"
android:layout_width="170dp"
android:layout_height="170dp"
android:layout_above="#+id/textView22"
android:layout_alignLeft="#+id/textView22"
android:layout_alignStart="#+id/textView22"
android:layout_gravity="center"
android:layout_marginBottom="16dp"
android:background="#drawable/back"
Logcat
java.lang.IllegalArgumentException: Unknown type class java.util.ArrayList. You must provide a Model of a type for which there is a registered ModelLoader, if you are using a custom model, you must first call Glide#register with a ModelLoaderFactory for your custom model class
at com.bumptech.glide.RequestManager.loadGeneric(RequestManager.java:629)
at com.bumptech.glide.RequestManager.load(RequestManager.java:598)
at com.tech.test.testapp.EnquiryItem$ProductImages.onPostExecute(EnquiryItem.java:524)
at com.tech.test.testapp.EnquiryItem$ProductImages.onPostExecute(EnquiryItem.java:412)
at android.os.AsyncTask.finish(AsyncTask.java:651)
at android.os.AsyncTask.-wrap1(AsyncTask.java)
at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:668)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5417)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
Glide need not have declare GlideModule in AndroidMinifest.xml. You just need to following steps:
YourGlideModule extends AppGlideModule, you can override function applyOptions in the YourGlideModule class.
You should make project in android studio -> build -> make project, it will generate the GlideApp class.
Use the GlideApp such as
GlideApp.with(this)
.load(imagegUrl)
.into(imageview)
I'm searching an api from an android app and I would like to display a Toast/error message to the user when the search returns no results from the api.
When the api returns no results the following is displayed to the logs:
{boards: null}
This is where I would like to display a message/toast.
I have tried:
if (name.equals ("null");
also many other 'solutions' that i've found, but none seem to work.
please see code below:
public class apitestsearch extends AppCompatActivity {
EditText boardName;
TextView resultView;
public void findBoard (View view){
// Log.i("board", boardName.getText().toString());
InputMethodManager mgr = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
mgr.hideSoftInputFromWindow(boardName.getWindowToken(), 0);
DownloadTask task = new DownloadTask();
task.execute("https://www.api.com/airquality/api/json.php?boardID="+ boardName.getText().toString());
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_apitestsearch);
boardName = (EditText)findViewById(R.id.boardName);
resultView = (TextView) findViewById(R.id.resultView);
}
public class DownloadTask extends AsyncTask<String, Void, String>{
#Override
protected String doInBackground(String... urls) {
String result = "";
URL url;
HttpURLConnection urlConnection = null;
try {
url = new URL(urls[0]);
urlConnection = (HttpURLConnection) url.openConnection();
InputStream in = urlConnection.getInputStream();
InputStreamReader reader = new InputStreamReader(in);
int data = reader.read();
while (data != -1)
{
char current = (char) data;
result += current;
data = reader.read();
}
return result;
} catch (Exception e) {
Toast.makeText(getApplicationContext(), "No results found", Toast.LENGTH_SHORT);
}
return null;
}
#Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
try {
String message = " ";
JSONObject jsonObject = new JSONObject(result);
String board = jsonObject.getString("boards");
// Log.i("boardID", board);
JSONArray arr = new JSONArray(board);
for(int i = 0; i < 1; i++)
{
JSONObject jsonPart = arr.getJSONObject(i);
String name = "";
name = jsonPart.getString("boardID");
if(name != ""){
message += name + "\r\n";
}
}
if (message != "") {
resultView.setText(message);
}
} catch (JSONException e) {
Toast.makeText(getApplicationContext(), "No results found", Toast.LENGTH_SHORT);
}
// Log.i("Content", result);
}
}
}
You can try this.
if(jsonObject.isNull("boards")){
// null handling goes here..
}else{
String board = jsonObject.getString("boards");
}
and if you want to use board as globally then
String board;
if(jsonObject.isNull("boards")){
// null handling goes here..
}else{
board = jsonObject.getString("boards");
}
and more short
String board;
if(!jsonObject.isNull("boards")){
board = jsonObject.getString("boards");
}
String board = "Not available";
//null check
if(!jsonObject.isNull("boards")){
board = jsonObject.getString("boards");
}else{
// your toast
Toast.makeText(context, "Board " + board, Toast.LENGTH_SHORT).show();
}
I keep on getting a null pointer exception error. I looked through my code and I am not sure why I am getting this error. I populates when i complile the program
The error reads like this
Null pointer Exception: Attempt to invoke virtual method int java.lang.String.length() on a null object reference. Thanks in advance.
EditText enterCity;
TextView weatherView;
public void onClick (View view) {
downloadAPIInfo task = new downloadAPIInfo();
String APIKEY = "b4fabae83c89c469d7a458a230b7a267";
String website = "http://api.openweathermap.org/data/2.5/weather?q=";
String url = website + enterCity.getText().toString() + APIKEY;
task.execute(url);
Log.i("User Entry", enterCity.getText().toString());
}
public class downloadAPIInfo extends AsyncTask<String, Void, String> {
URL url;
HttpURLConnection httpURLConnection = null;
String result = "";
#Override
protected String doInBackground(String... urls) {
try {
url = new URL(urls[0]);
httpURLConnection = (HttpURLConnection) url.openConnection();
InputStream input = httpURLConnection.getInputStream();
InputStreamReader reader = new InputStreamReader(input);
int data = reader.read();
while(data != -1) {
char one = (char) data;
result += one;
data = reader.read();
}
return result;
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
//Onpostexecute interacts with the UI
#Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
try {
String message = "";
JSONObject object = new JSONObject(result);
String weatherInfo = object.getString("weather");
Log.i("Weather content", weatherInfo);
JSONArray array = new JSONArray(weatherInfo);
for(int i = 0; i < array.length(); i++ ) {
JSONObject jsonPart = array.getJSONObject(i);
Log.i("main", jsonPart.getString("main"));
String main = "";
String description = "";
main = jsonPart.getString("main");
description = jsonPart.getString("description");
if(main != "" && description != "") {
message+= main + ":" + description + "\r\n";
}
}
if(message != "") {
weatherView.setText(message);
}
} catch (JSONException e) {
e.printStackTrace();
}
//Log.i("WebsiteContent", result);
}
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
enterCity = (EditText) findViewById(R.id.cityeditText);
weatherView = (TextView) findViewById(R.id.weathertextView);
}
}
The JSONArray named 'array' is null in your onPostExecute mehtod.
Most probably your weatherInfo string is null.
I suggest you post the full stacktrace for a better explanation.
So I have the following code in my current activity class:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_chores);
bChore = (Button) findViewById(R.id.addChore);
bChore.setOnClickListener(this);
Bundle extras = getIntent().getExtras();
final String user = extras.getString("username");
fillInBackground();
}
#Override
public void onClick(View v) {
Bundle extras = getIntent().getExtras();
final String user = extras.getString("username");
switch (v.getId()) {
case R.id.addChore:
name = (EditText) findViewById(R.id.choreName);
value = (EditText) findViewById(R.id.points);
String choreTitle = name.getText().toString();
int pointValue = Integer.parseInt(value.getText().toString());
try {
if (choreTitle.length() <= 0)
Toast.makeText(Chores.this, "Please enter a chore", Toast.LENGTH_SHORT).show();
else {
if (pointValue == 0)
Toast.makeText(Chores.this, "Please enter a valid number", Toast.LENGTH_SHORT).show();
else {
Chore chore = new Chore(choreTitle, pointValue, user);
uploadChore(chore);
break;
}
}
} catch (NumberFormatException e) {
Toast.makeText(Chores.this, "Please enter a valid point value", Toast.LENGTH_SHORT).show();
}
}
}
private void fillInBackground() {
new AsyncTask<Void, Void, Wrapper>() {
Bundle extras = getIntent().getExtras();
final String user = extras.getString("username");
#Override
protected Wrapper doInBackground(Void... params) {
String requestURL = SERVER_ADDRESS + "FetchChoreData.php";
ListView choreList = (ListView) findViewById(R.id.choreList);
ArrayList<String> chores = new ArrayList<>();
Wrapper wrapper = new Wrapper();
String headings = "Chore" + "\t" + "Child" + "\t" + "Points";
chores.add(headings);
URL url;
try {
//Opens the connection to the PHP files
//Sets the conditions of the connection
url = new URL(requestURL);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setReadTimeout(CONNECTION_TIMEOUT);
conn.setConnectTimeout(CONNECTION_TIMEOUT);
conn.setRequestMethod("POST");
conn.setDoInput(true);
conn.setDoOutput(true);
//Opens an output stream to send the data to be verified
// and then closes the all output streams and flushes the output writer
OutputStream os = conn.getOutputStream();
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(os, "UTF-8"));
Uri.Builder builder = new Uri.Builder()
.appendQueryParameter("username", user);
String query = builder.build().getEncodedQuery();
writer.write(query);
writer.flush();
writer.close();
os.close();
//saves the response code to ensure connection was succesful
int code = conn.getResponseCode();
Log.d("code", Integer.toString(code));
//Opens an input stream to retrieve verified data back from the server
//Starts a String Builder to read the data off the input
//Closes the BufferedReader once it has finished building the string
InputStream responseStream = new BufferedInputStream(conn.getInputStream());
BufferedReader responseStreamReader = new BufferedReader(new InputStreamReader(responseStream));
String line;
StringBuilder stringBuilder = new StringBuilder();
while ((line = responseStreamReader.readLine()) != null)
stringBuilder.append(line + "/n");
responseStreamReader.close();
String response = stringBuilder.toString();
Log.d("response", response);
JSONObject jsonResponse = new JSONObject(response);
//Creates a JSON object from the string
JSONArray choresArray = jsonResponse.getJSONArray("chore");
for (int i = 0; i < choresArray.length(); i++) {
JSONObject chore = choresArray.getJSONObject(i);
String current_chore = chore.optString("chore_name");
String name = chore.optString("child_username");
String points = chore.optString("point_value");
String currentChore = "";
if (name == null)
currentChore = current_chore + "\t" + "Not Claimed" + "\t" + points;
else
currentChore = current_chore + "\t" + name + "\t" + points;
chores.add(currentChore);
Log.d("Output", currentChore);
}
wrapper.myArrayAdapter = new ArrayAdapter<>(Chores.this, android.R.layout.simple_list_item_1, chores);
wrapper.list = choreList;
} catch (Exception e) {
e.printStackTrace();
}
return wrapper;
}
protected void onPostExecute(Wrapper wrapper) {
//After the previous method executes we end the process dialog
//and we return the user call back and return the verified user
wrapper.list.setAdapter(wrapper.myArrayAdapter);
}
}.execute();
}
private void uploadChore(Chore chore) {
Bundle extras = getIntent().getExtras();
final String user = extras.getString("username");
//Implements the ServerRequest class to register the user details
ServerRequests serverRequests = new ServerRequests(this);
//Checks that the details are valid and what account type it is setting up
serverRequests.storeChoreData(chore,new GetUserCallBack() {
//What is done when the user has successfully registered
#Override
public void complete(User returnedUser) {
Intent chores = new Intent(Chores.this, Chores.class);
chores.putExtra("username", user);
startActivity(chores);
}
});
}
}
The wrapper class looks as follows:
public class Wrapper {
public ListView list;
public ArrayAdapter<String> myArrayAdapter;
}
However when I run the application it stops and I get the following fatal exception:
W/System.err: org.json.JSONException: Value <!DOCTYPE of type java.lang.String cannot be converted to JSONObject
03-14 11:54:17.493 18935-19311/com.jack.pointcollector W/System.err: at org.json.JSON.typeMismatch(JSON.java:111)
03-14 11:54:17.493 18935-19311/com.jack.pointcollector W/System.err: at org.json.JSONObject.<init>(JSONObject.java:160)
03-14 11:54:17.493 18935-19311/com.jack.pointcollector W/System.err: at org.json.JSONObject.<init>(JSONObject.java:173)
03-14 11:54:17.494 18935-19311/com.jack.pointcollector W/System.err: at com.jack.pointcollector.Chores$1.doInBackground(Chores.java:149)
03-14 11:54:17.494 18935-19311/com.jack.pointcollector W/System.err: at com.jack.pointcollector.Chores$1.doInBackground(Chores.java:89)
03-14 11:54:17.494 18935-19311/com.jack.pointcollector W/System.err: at android.os.AsyncTask$2.call(AsyncTask.java:295)
03-14 11:54:17.494 18935-19311/com.jack.pointcollector W/System.err: at java.util.concurrent.FutureTask.run(FutureTask.java:237)
03-14 11:54:17.494 18935-19311/com.jack.pointcollector W/System.err: at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:234)
03-14 11:54:17.494 18935-19311/com.jack.pointcollector W/System.err: at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113)
03-14 11:54:17.494 18935-19311/com.jack.pointcollector W/System.err: at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588)
03-14 11:54:17.494 18935-19311/com.jack.pointcollector W/System.err: at java.lang.Thread.run(Thread.java:818)
03-14 11:54:17.581 18935-18935/com.jack.pointcollector D/AndroidRuntime: Shutting down VM
03-14 11:54:17.581 18935-18935/com.jack.pointcollector E/AndroidRuntime: FATAL EXCEPTION: main Process: com.jack.pointcollector, PID: 18935
java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.ListView.setAdapter(android.widget.ListAdapter)' on a null object reference
at com.jack.pointcollector.Chores$1.onPostExecute(Chores.java:183)
at com.jack.pointcollector.Chores$1.onPostExecute(Chores.java:89)
at android.os.AsyncTask.finish(AsyncTask.java:651)
at android.os.AsyncTask.-wrap1(AsyncTask.java)
at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:668)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5417)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
Could someone please tell me where I'm going wrong as I am only new to this.
the problem is only that your create the Object Wrapper in doInBackgroud() method........and you try to access then in onPostExecute() method.......
new AsyncTask<Void, Void, Wrapper>() {
#Override
protected Wrapper doInBackground(Void... params) {
ListView choreList = (ListView) findViewById(R.id.choreList);
ArrayList<String> chores = new ArrayList<>();
// change this make them Global.....
Wrapper wrapper = new Wrapper();
wrapper.myArrayAdapter = new ArrayAdapter<>(Chores.this, android.R.layout.simple_list_item_1, chores);
wrapper.list = choreList;
} catch (Exception e) {
e.printStackTrace();
}
return wrapper;
}
protected void onPostExecute(Wrapper wrapper) {
//After the previous method executes we end the process dialog
//and we return the user call back and return the verified user
wrapper.list.setAdapter(wrapper.myArrayAdapter);
}
}.execute();
}
You should move
ListView choreList = (ListView) findViewById(R.id.choreList);
ArrayList<String> chores = new ArrayList<>();
outside your do in background and have them as a globar variable.
Once you are done fetching data you can set your adapter in onPost execute. Your listview is never initialised and hence the null pointer exception.
String response = stringBuilder.toString();
JSONObject jsonResponse = new JSONObject(response);
check response
it should be like:
{
"chore": [{
"chore_name": "name",
"child_username": "username",
"point_value": "value"
}, {
"chore_name": "name",
"child_username": "username",
"point_value": "value"
}]
}
Reason:
Problem is not with setting adapter but with the JSON parsing. As per your error log
W/System.err: org.json.JSONException: Value <!DOCTYPE of type java.lang.String cannot be converted to JSONObject
you are getting as string which can not be converted to a JSONObject. When this error occurs the is being catch in the catch block and by that time
wrapper.myArrayAdapter = new ArrayAdapter<>(Chores.this, android.R.layout.simple_list_item_1, chores);
wrapper.list = choreList;
is not called. This is causing onPostExecute to receive a null object of listview and finally a NPE is being thrown.
Solution:
You should check the JSON you are getting form server and correct them.
Following are the mistakes I found in your code and I also tried to fix the same.
You should initialize all your views and adapter in onCreate().
In uploadChore()'s complete(), don't start the same activity for passing the data to some other method rather pass it as an argument.
The ListView and its Adapter should be initialized at the beginning. Later on, add the data into the list and call adapter's notifyDataSetChanged()
ArrayList<String> chores;
Wrapper wrapper;
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_chores);
bChore = (Button) findViewById(R.id.addChore);
name = (EditText) findViewById(R.id.choreName);
value = (EditText) findViewById(R.id.points);
wrapper = new Wrapper();
ListView choreList = (ListView) findViewById(R.id.choreList);
chores = new ArrayList<>();
wrapper.myArrayAdapter = new ArrayAdapter<>(Chores.this, android.R.layout.simple_list_item_1, chores);
wrapper.list = choreList;
wrapper.list.setAdapter(wrapper.myArrayAdapter);
bChore.setOnClickListener(this);
}
#Override
public void onClick(View v)
{
Bundle extras = getIntent().getExtras();
final String user = extras.getString("username");
switch (v.getId())
{
case R.id.addChore:
String choreTitle = name.getText().toString();
int pointValue = Integer.parseInt(value.getText().toString());
try
{
if (choreTitle.length() <= 0)
Toast.makeText(Chores.this, "Please enter a chore", Toast.LENGTH_SHORT).show();
else
{
if (pointValue == 0)
Toast.makeText(Chores.this, "Please enter a valid number", Toast.LENGTH_SHORT).show();
else
{
Chore chore = new Chore(choreTitle, pointValue, user);
uploadChore(chore);
break;
}
}
}
catch (NumberFormatException e)
{
Toast.makeText(Chores.this, "Please enter a valid point value", Toast.LENGTH_SHORT).show();
}
}
}
private void fillInBackground(String user)
{
new AsyncTask<Void, String, Wrapper>()
{
#Override
protected Wrapper doInBackground(Void... params)
{
String requestURL = SERVER_ADDRESS + "FetchChoreData.php";
String headings = "Chore" + "\t" + "Child" + "\t" + "Points";
publishProgress(headings);
URL url;
try
{
//Opens the connection to the PHP files
//Sets the conditions of the connection
url = new URL(requestURL);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setReadTimeout(CONNECTION_TIMEOUT);
conn.setConnectTimeout(CONNECTION_TIMEOUT);
conn.setRequestMethod("POST");
conn.setDoInput(true);
conn.setDoOutput(true);
//Opens an output stream to send the data to be verified
// and then closes the all output streams and flushes the output writer
OutputStream os = conn.getOutputStream();
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(os, "UTF-8"));
Uri.Builder builder = new Uri.Builder()
.appendQueryParameter("username", user);
String query = builder.build().getEncodedQuery();
writer.write(query);
writer.flush();
writer.close();
os.close();
//saves the response code to ensure connection was succesful
int code = conn.getResponseCode();
Log.d("code", Integer.toString(code));
//Opens an input stream to retrieve verified data back from the server
//Starts a String Builder to read the data off the input
//Closes the BufferedReader once it has finished building the string
InputStream responseStream = new BufferedInputStream(conn.getInputStream());
BufferedReader responseStreamReader = new BufferedReader(new InputStreamReader(responseStream));
String line;
StringBuilder stringBuilder = new StringBuilder();
while ((line = responseStreamReader.readLine()) != null)
stringBuilder.append(line + "/n");
responseStreamReader.close();
String response = stringBuilder.toString();
Log.d("response", response);
JSONObject jsonResponse = new JSONObject(response);
//Creates a JSON object from the string
JSONArray choresArray = jsonResponse.getJSONArray("chore");
for (int i = 0; i < choresArray.length(); i++)
{
JSONObject chore = choresArray.getJSONObject(i);
String current_chore = chore.optString("chore_name");
String name = chore.optString("child_username");
String points = chore.optString("point_value");
String currentChore = "";
if (name == null)
currentChore = current_chore + "\t" + "Not Claimed" + "\t" + points;
else
currentChore = current_chore + "\t" + name + "\t" + points;
publishProgress(currentChore);
Log.d("Output", currentChore);
}
}
catch (Exception e)
{
e.printStackTrace();
}
return wrapper;
}
#Override
protected void onProgressUpdate(String... values)
{
super.onProgressUpdate(values);
wrapper.list.add(values[0]);
}
protected void onPostExecute(Wrapper wrapper)
{
//After the previous method executes we end the process dialog
//and we return the user call back and return the verified user
wrapper.myArrayAdapter.notifyDataSetChanged();
}
}.execute();
}
private void uploadChore(Chore chore)
{
Bundle extras = getIntent().getExtras();
final String user = extras.getString("username");
//Implements the ServerRequest class to register the user details
ServerRequests serverRequests = new ServerRequests(this);
//Checks that the details are valid and what account type it is setting up
serverRequests.storeChoreData(chore, new GetUserCallBack()
{
//What is done when the user has successfully registered
#Override
public void complete(User returnedUser)
{
// Simple add data into the list. Don't start same activity again and again.
fillInBackground(user);
}
});
}
I am parsing data from URL , Its Getting below mentioned Error.
Raw Data is Showing Perfectly from Server.Not able to Split the Data Using Json Parsing.
Please help me solve this error
EDIT : 1
Json Response from URL
[
{
"ID": 4,
"Name": "Vinoth",
"Contact": "1111111111",
"Msg": "1"
},
{
"ID": 5,
"Name": "Mani",
"Contact": "22222222",
"Msg": "1"
},
{
"ID": 6,
"Name": "Manoj",
"Contact": "33333333333",
"Msg": "1"
}
]
Error :
org.json.JSONException: Value [{"ID":1,"Name":"Lalita","Contact":"9997162499","Msg":"1"},{"ID":2,"Name":"kumar","Contact":"123456789","Msg":"1"}] of type java.lang.String cannot be converted to JSONArray
12-11 18:23:27.249 30195-30195/com.knowledgeflex.restapidemo W/System.err: at org.json.JSON.typeMismatch(JSON.java:111)
12-11 18:23:27.249 30195-30195/com.knowledgeflex.restapidemo W/System.err: at org.json.JSONArray.<init>(JSONArray.java:96)
12-11 18:23:27.249 30195-30195/com.knowledgeflex.restapidemo W/System.err: at org.json.JSONArray.<init>(JSONArray.java:108)
12-11 18:23:27.249 30195-30195/com.knowledgeflex.restapidemo W/System.err: at com.knowledgeflex.restapidemo.MainActivity$LoadService.onPostExecute(MainActivity.java:135)
12-11 18:23:27.249 30195-30195/com.knowledgeflex.restapidemo W/System.err: at com.knowledgeflex.restapidemo.MainActivity$LoadService.onPostExecute(MainActivity.java:58)
12-11 18:23:27.249 30195-30195/com.knowledgeflex.restapidemo W/System.err: at android.os.AsyncTask.finish(AsyncTask.java:632)
12-11 18:23:27.249 30195-30195/com.knowledgeflex.restapidemo W/System.err: at android.os.AsyncTask.access$600(AsyncTask.java:177)
12-11 18:23:27.249 30195-30195/com.knowledgeflex.restapidemo W/System.err: at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:645)
12-11 18:23:27.249 30195-30195/com.knowledgeflex.restapidemo W/System.err: at android.os.Handler.dispatchMessage(Handler.java:102)
12-11 18:23:27.249 30195-30195/com.knowledgeflex.restapidemo W/System.err: at android.os.Looper.loop(Looper.java:136)
12-11 18:23:27.249 30195-30195/com.knowledgeflex.restapidemo W/System.err: at android.app.ActivityThread.main(ActivityThread.java:5584)
12-11 18:23:27.249 30195-30195/com.knowledgeflex.restapidemo W/System.err: at java.lang.reflect.Method.invokeNative(Native Method)
12-11 18:23:27.249 30195-30195/com.knowledgeflex.restapidemo W/System.err: at java.lang.reflect.Method.invoke(Method.java:515)
12-11 18:23:27.249 30195-30195/com.knowledgeflex.restapidemo W/System.err: at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1268)
12-11 18:23:27.259 30195-30195/com.knowledgeflex.restapidemo W/System.err: at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1084)
12-11 18:23:27.259 30195-30195/com.knowledgeflex.restapidemo W/System.err: at dalvik.system.NativeStart.main(Native Method)
MainActivity.java
public class MainActivity extends Activity {
TextView name1,email,status,face;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final Button GetServerData = (Button) findViewById(R.id.button1);
name1 = (TextView)findViewById(R.id.sname);
email = (TextView)findViewById(R.id.email);
status = (TextView)findViewById(R.id.status);
face = (TextView)findViewById(R.id.fb);
GetServerData.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
// Server Request URL
String serverURL = "http://webapp/api/values";
// Create Object and call AsyncTask execute Method
new LoadService().execute(serverURL);
}
});
}
// Class with extends AsyncTask class
private class LoadService extends AsyncTask<String, Void, Void> {
private final HttpClient Client = new DefaultHttpClient();
private String Content;
private String Error = null;
private final String TAG = null;
String name = null;
private ProgressDialog Dialog = new ProgressDialog(MainActivity.this);
TextView uiUpdate = (TextView) findViewById(R.id.textView2);
protected void onPreExecute() {
// NOTE: You can call UI Element here.
// UI Element
uiUpdate.setText("");
Dialog.setMessage("Loading service..");
Dialog.show();
}
// Call after onPreExecute method
protected Void doInBackground(String... urls) {
try {
// NOTE: Don't call UI Element here.
HttpGet httpget = new HttpGet(urls[0]);
ResponseHandler<String> responseHandler = new BasicResponseHandler();
Content = Client.execute(httpget, responseHandler);
} catch (ClientProtocolException e) {
Error = e.getMessage();
cancel(true);
} catch (IOException e) {
Error = e.getMessage();
cancel(true);
}
return null;
}
protected void onPostExecute(Void unused) {
// Close progress dialog
Dialog.dismiss();
Log.e(TAG, "------------------------------------- Output: " + Content);
try {
JSONArray jArr=new JSONArray(Content);
for(int i=0;i<jArr.length();i++) {
JSONObject json=jArr.getJSONObject(i);
name1.setText(json.getString("Name"));
email.setText(json.getString("ID"));
status.setText(json.getString("Contact"));
face.setText(json.getString("Msg"));
}
} catch (JSONException e) {
e.printStackTrace();
Log.i("EXCEPTION ","");
}
uiUpdate.setText("Raw Output : " + Content);
}
}
}
As per your response is JSONArray and gson library is better to use while json data parsing so use below class to any type of data like that
import com.google.gson.Gson;
import com.google.gson.JsonArray;
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.List;
public class ApiData {
#SerializedName("data")
#Expose
private JsonArray Data;
public <T> List<T> getData(Class<T> c) {
Type type = new ListParams(c);
return new Gson().fromJson(Data, type);
}
private class ListParams implements ParameterizedType {
private Type type;
private ListParams(Type type) {
this.type = type;
}
#Override
public Type[] getActualTypeArguments() {
return new Type[]{type};
}
#Override
public Type getRawType() {
return ArrayList.class;
}
#Override
public Type getOwnerType() {
return null;
}
#Override
public boolean equals(Object o) {
return super.equals(o);
}
}
}
Create model class like :
public class Model{
String ID;
String Name;
String Contact;
String msg;
}
Now parse your data like:
ApiData apiData = new Gson().fromJson(Content, ApiData.class);
Lis<Model> models = apiData.getData(Model.class);
try {
Object jsonObject = new JSONTokener(Content).nextValue();
JSONArray jArr=new JSONArray(jsonObject );
for(int i=0;i<jArr.length();i++) {
JSONObject json=jArr.getJSONObject(i);
name1.setText(json.getString("Name"));
email.setText(json.getString("ID"));
status.setText(json.getString("Contact"));
face.setText(json.getString("Msg"));
}
} catch (JSONException e) {
e.printStackTrace();
Log.i("EXCEPTION ","");
}
Directly you cannot apply string to array, you should convert string to jsonobject ,then you can do object to array.
Hope you understand
As i have added escaping to your json here only for storing it temporary :
Please check below parsing code and it is working for me :
String response = "[\r\n {\r\n \"ID\": 4,\r\n \"Name\": \"Vinoth\",\r\n \"Contact\": \"1111111111\",\r\n \"Msg\": \"1\"\r\n },\r\n {\r\n \"ID\": 5,\r\n \"Name\": \"Mani\",\r\n \"Contact\": \"22222222\",\r\n \"Msg\": \"1\"\r\n },\r\n {\r\n \"ID\": 6,\r\n \"Name\": \"Manoj\",\r\n \"Contact\": \"33333333333\",\r\n \"Msg\": \"1\"\r\n }\r\n]";
try {
JSONArray jsonArray = new JSONArray(response); // replace response with your response string
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject jsonObject = jsonArray.getJSONObject(i);
Log.e("ID", jsonObject.getInt("ID") + "");
Log.e("Name", jsonObject.getString("Name"));
Log.e("Contact", jsonObject.getString("Contact"));
Log.e("Msg", jsonObject.getString("Msg"));
}
} catch (JSONException e) {
e.printStackTrace();
}
Logs I have printed :
12-17 15:42:54.459 9064-9064/com.example.testapplication E/ID: 4 12-17
15:42:54.459 9064-9064/com.example.testapplication E/Name: Vinoth
12-17 15:42:54.459 9064-9064/com.example.testapplication E/Contact:
1111111111 12-17 15:42:54.459 9064-9064/com.example.testapplication
E/Msg: 1 12-17 15:42:54.459 9064-9064/com.example.testapplication
E/ID: 5 12-17 15:42:54.459 9064-9064/com.example.testapplication
E/Name: Mani 12-17 15:42:54.459 9064-9064/com.example.testapplication
E/Contact: 22222222 12-17 15:42:54.459
9064-9064/com.example.testapplication E/Msg: 1 12-17 15:42:54.459
9064-9064/com.example.testapplication E/ID: 6 12-17 15:42:54.459
9064-9064/com.example.testapplication E/Name: Manoj 12-17 15:42:54.459
9064-9064/com.example.testapplication E/Contact: 33333333333 12-17
15:42:54.459 9064-9064/com.example.testapplication E/Msg: 1
Thanks ..!
The documentation of public JSONArray (String json) says it throws a
JSONException if the parse fails or doesn't yield a JSONArray.
Maybe he can't handle your response which is quite funny because a simple online json parser can: http://json.parser.online.fr/
As the user "Jelle van Es" mentioned in a previous comment, I would try Gson to do the work. (I would have commented under his comment but I have to few reputation xD)
You are using getString on "ID" when you should be using getInt. I tested the JSON string you provided in your question. The following code works:
String json =
"[{\"ID\":4,\"Name\":\"Vinoth\",\"Contact\":\"1111111111\",\"Msg\":\"1\"},{\"ID\":5,\"Name\":\"Mani\",\"Contact\":\"22222222\",\"Msg\":\"1\"},{\"ID\":6,\"Name\":\"Manoj\",\"Contact\":\"33333333333\",\"Msg\":\"1\"}]";
try {
JSONArray jsonArray = new JSONArray(json);
for (int i = 0, len = jsonArray.length(); i < len; i++) {
JSONObject jsonObject = jsonArray.getJSONObject(i);
int id = jsonObject.getInt("ID");
String name = jsonObject.getString("Name");
String contact = jsonObject.getString("Contact");
String msg = jsonObject.getString("Msg");
System.out.println("id=" + id + ", name='" + name + "\', contact='" + contact + "\', msg='" + msg);
}
} catch (JSONException e) {
e.printStackTrace();
}
Output from running the above code:
id=4, name='Vinoth', contact='1111111111', msg='1
id=5, name='Mani', contact='22222222', msg='1
id=6, name='Manoj', contact='33333333333', msg='1
If you are still getting an error, post the stacktrace.
Check this linkJSONArray
You should not directly use the response you get after hitting web service.First convert it to string as given in the link and also use getInt() when you are parsing your id
You can Parse your JSON like below.
try {
JSONArray _jArray = new JSONArray("YOUR_RESPONSE");
if (_jArray.length()>0){
for (int i = 0 ; i < _jArray.length();i++){
JSONObject _jSObject = _jArray.getJSONObject(i);
int ID = _jSObject.getInt("ID");
String Name = _jSObject.getString("Name");
String Contact = _jSObject.getString("Contact");
String Msg = _jSObject.getString("Msg");
System.out.println("Id : " + ID);
System.out.println("Name : " + Name);
System.out.println("Contact : " + Contact);
System.out.println("Msg : " + Msg);
}
}
} catch (Exception e) {
e.printStackTrace();
}
Best way and very fast parsing of JSON is GSON liabrary
dependacy for android studio compile 'com.google.code.gson:gson:2.3.1' OR you can download jar.
Make DTO names of all strings exactly same json of resonse.
Class ClassDTO{
String ID;
String Name;
String Contact;
String Msg;
take gettters & setters
}
Just include this lines in your code.
JSONArray array=new JSONArray(Content);
if (array.length() > 0) {
Gson gson = new Gson();
int i = 0;
while (i < array.length()) {
list.add(gson.fromJson(array.getJSONObject(i).toString(), ClassDTO.class));
i++;
}
} else {
Toast.makeText(JobCardActivity.this, "No response from server", Toast.LENGTH_LONG).show();
}
for json url hit and parsing of the data i have use this way
First i have created a class for Async request
public class AsyncRequestForActivities extends
AsyncTask<String, Integer, String> {
OnAsyncRequestComplete caller;
Context context;
String method = "POST";
List<NameValuePair> parameters = null;
ProgressDialog pDialog = null;
String Progress_msg;
// Three Constructors
public AsyncRequestForActivities(Context a, String m, String Msg,
List<NameValuePair> p) {
caller = (OnAsyncRequestComplete) a;
context = a;
method = m;
parameters = p;
Progress_msg = Msg;
}
public AsyncRequestForActivities(Context a, String m) {
caller = (OnAsyncRequestComplete) a;
context = a;
method = m;
}
public AsyncRequestForActivities(Context a) {
caller = (OnAsyncRequestComplete) a;
context = a;
}
// Interface to be implemented by calling activity
public interface OnAsyncRequestComplete {
public void asyncResponse(String response);
}
public String doInBackground(String... urls) {
// get url pointing to entry point of API
String address = urls[0].toString();
if (method == "POST") {
return post(address);
}
if (method == "GET") {
return get(address);
}
return null;
}
public void onPreExecute() {
pDialog = new ProgressDialog(context);
pDialog.setMessage(Progress_msg); // typically you will
pDialog.setCancelable(false); // define such
// strings in a remote file.
pDialog.show();
}
public void onProgressUpdate(Integer... progress) {
// you can implement some progressBar and update it in this record
// setProgressPercent(progress[0]);
}
public void onPostExecute(String response) {
if (pDialog != null && pDialog.isShowing()) {
pDialog.dismiss();
}
caller.asyncResponse(response);
}
protected void onCancelled(String response) {
if (pDialog != null && pDialog.isShowing()) {
pDialog.dismiss();
}
caller.asyncResponse(response);
}
#SuppressWarnings("deprecation")
private String get(String address) {
try {
if (parameters != null) {
String query = "";
String EQ = "=";
String AMP = "&";
for (NameValuePair param : parameters) {
query += param.getName() + EQ
+ URLEncoder.encode(param.getValue()) + AMP;
}
if (query != "") {
address += "?" + query;
}
}
HttpClient client = new DefaultHttpClient();
HttpGet get = new HttpGet(address);
HttpResponse response = client.execute(get);
return stringifyResponse(response);
} catch (ClientProtocolException e) {
// TODO Auto-generated catch block
} catch (IOException e) {
// TODO Auto-generated catch block
}
return null;
}
private String post(String address) {
try {
HttpClient client = new DefaultHttpClient();
HttpPost post = new HttpPost(address);
if (parameters != null) {
post.setEntity(new UrlEncodedFormEntity(parameters));
}
HttpResponse response = client.execute(post);
return stringifyResponse(response);
} catch (ClientProtocolException e) {
// TODO Auto-generated catch block
} catch (IOException e) {
// TODO Auto-generated catch block
}
return null;
}
private String stringifyResponse(HttpResponse response) {
BufferedReader in;
try {
in = new BufferedReader(new InputStreamReader(response.getEntity()
.getContent()));
StringBuffer sb = new StringBuffer("");
String line = "";
while ((line = in.readLine()) != null) {
sb.append(line);
}
in.close();
return sb.toString();
} catch (IllegalStateException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
}
now when you want to get Data you have to implement the interface in your activity
public class SomeClass extends Activity implements OnAsyncRequestComplete{
// your activity code here
// some where in class in any function you want
AsyncRequestForActivities req=new AsyncRequestForActivities(SomeClass.this, MethodType, YourMessage,
Perameters_in_List<NameValuePareType>);
req.execute(YourURL);
}//end of that function
#Override
public void asyncResponse(String response) {
try {
if (!(response == null)) {
JSONArray jArray = new JSONArray("response");
if (jArray.length()>0){
for (int i = 0 ; i < jArray.length();i++){
JSONObject jSObject = jArray.getJSONObject(i);
int ID = _jSObject.getInt("ID");
String Name = _jSObject.getString("Name");
String Contact = jSObject.getString("Contact");
String Msg = jSObject.getString("Msg");
System.out.println("Id : " + ID);
System.out.println("Name : " + Name);
System.out.println("Contact : " + Contact);
System.out.println("Msg : " + Msg);
}
}
} catch (JSONException e) {
e.printStackTrace();
}
}
}