This is what I essentially want to do, but can't. I want the value of urlData and size to be updated from the inner class functions. The app is crashing by giving a Null Pointer Exception at the line where I try to access these variables from the CreateTextView() function.
package edu.ahduni.seas.gyapak;
import android.os.AsyncTask;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.ArrayList;
import org.json.JSONException;
import org.json.JSONArray;
import org.json.JSONObject;
import android.util.Log;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.TextView;
public class MainActivity extends AppCompatActivity {
public ArrayList<Data> urlData; //Culprit 1
public int size; //no. of dirs + files, Culprit 2
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
public void parseJSON() throws JSONException {
ParseActivity parse = new ParseActivity();
String url = "RDovQWNhZGVtaWMvU2FuamF5IENoYXVkaGFyeQ==";
parse.execute(url);
CreateTextView();
Log.e("RETURNING JSON","RETURNING");
}
public void CreateTextView() {
TextView text = (TextView) findViewById(R.id.text);
text.setText(Integer.toString(size));
Button myButton = new Button(this);
if(urlData==null) //workaround for crash
return;
myButton.setText(urlData.get(0).getName());
LinearLayout ll = (LinearLayout)findViewById(R.id.textlayout);
LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT,
LinearLayout.LayoutParams.WRAP_CONTENT);
ll.addView(myButton, lp);
}
class ParseActivity extends AsyncTask<String, Void, ArrayList<Data>> {
InputStream is = null;
JSONArray jObj = null;
String json = "";
#Override
public void onPostExecute(ArrayList<Data> data) {
size = data.size(); //here!
}
#Override
protected ArrayList<Data> doInBackground(String... params) {
final String BASE_URL = "http://111.93.66.162/json/main.php?f=" + params[0];
HttpURLConnection urlConnection;
// Making HTTP request
try {
Log.e("OPENING: ", "URL");
URL url = new URL(BASE_URL);
urlConnection = (HttpURLConnection) url.openConnection();
urlConnection.setRequestMethod("GET");
urlConnection.connect();
is = urlConnection.getInputStream();
StringBuffer buffer = new StringBuffer();
if (is == null) {
// Nothing to do.
return null;
}
BufferedReader in = new BufferedReader(new InputStreamReader(is));
String line;
while ((line = in.readLine()) != null) {
buffer.append(line + "\n");
Log.e("JSON: ", line);
}
if (buffer.length() == 0) {
// Stream was empty. No point in parsing.
return null;
}
is.close();
json = buffer.toString();
} catch (Exception e) {
e.printStackTrace();
}
try {
return getData(json);
} catch (JSONException e) {
e.printStackTrace();
}
return null;
}
public ArrayList<Data> getData(String jsonString) throws JSONException {
// try parse the string to a JSON object
final String EXT = "ext";
final String PATH = "path";
final String NAME = "name";
try {
jObj = new JSONArray(jsonString);
} catch (JSONException e) {
e.printStackTrace();
}
urlData = new ArrayList<Data>();
for (int i=0;i<jObj.length();i++) {
JSONObject obj = jObj.getJSONObject(i);
String ext = obj.getString(EXT);
String path = obj.getString(PATH);
String name = obj.getString(NAME);
urlData.add(new Data(ext,path,name)); //and here!
}
return urlData;
}
}
}
The inner class is not static, so it needs an instance of the enclosing class to be instantiated. Like so:
public class abcd {
static int x;
public static void main(String[] args) {
abcd o = new abcd(); // Create instance of abcd called 'o'
abcd.efgh o2 = o.new efgh(); // Use instance 'o' to create an instance of efgh
System.out.println(x); // 0
o2.ok();
System.out.println(x); // 5
}
class efgh {
public void ok() {
x = 5;
}
}
}
Related
I am trying to make an English Dictionary using the Oxford API. I made this according to docs and resources found on the web. But I got this issue "org.json.JSONException: No value for senses" and I don't why. Wherever I looked I couldn't find reason of this issue. I'll give you my MainActivity and request class. Can anyone help me?
MainActiviy:
package com.alitalhacoban.english_dictionary;
import android.os.Bundle;
import android.view.View;
import android.widget.EditText;
import android.widget.TextView;
import androidx.appcompat.app.AppCompatActivity;
public class MainActivity extends AppCompatActivity {
TextView textView;
EditText editText;
private String url;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textView = findViewById(R.id.textView);
editText = findViewById(R.id.editText);
url = dictionaryEntries();
}
public void find(View view){
MyDictionaryRequest myDictionaryRequest = new MyDictionaryRequest(this);
myDictionaryRequest.execute(url);
}
private String dictionaryEntries() {
final String language = "en-gb";
final String word = "Ace";
final String fields = "pronunciations";
final String strictMatch = "false";
final String word_id = word.toLowerCase();
return "https://od-api.oxforddictionaries.com:443/api/v2/entries/" + language + "/" + word_id + "?" + "fields=" + fields + "&strictMatch=" + strictMatch;
}
}
Request class:
import android.content.Context;
import android.os.AsyncTask;
import android.util.Log;
import android.widget.Toast;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.URL;
import javax.net.ssl.HttpsURLConnection;
public class MyDictionaryRequest extends AsyncTask<String, Integer, String> {
Context context;
MyDictionaryRequest(Context context) {
this.context = context;
}
final String app_id = "127ae33f";
final String app_key = "e42c0fccfe30223fb9ec02e12ae8c8a9";
#Override
protected String doInBackground(String... params) {
try {
URL url = new URL(params[0]);
HttpsURLConnection urlConnection = (HttpsURLConnection) url.openConnection();
urlConnection.setRequestProperty("Accept", "application/json");
urlConnection.setRequestProperty("app_id", app_id);
urlConnection.setRequestProperty("app_key", app_key);
BufferedReader reader = new BufferedReader(new InputStreamReader(urlConnection.getInputStream()));
StringBuilder stringBuilder = new StringBuilder();
String line;
while ((line = reader.readLine()) != null) {
stringBuilder.append(line).append("\n");
}
return stringBuilder.toString();
} catch (Exception e) {
e.printStackTrace();
return e.toString();
}
}
#Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
String def = "";
try {
JSONObject js = new JSONObject(result);
JSONArray results = js.getJSONArray("results");
for (int i = 0; i < results.length(); i++) {
JSONObject lentries = results.getJSONObject(i);
JSONArray la = lentries.getJSONArray("lexicalEntries");
for (int j = 0; j < la.length(); j++) {
JSONObject entries = la.getJSONObject(j);
JSONArray e = entries.getJSONArray("entries");
for (int k = 0; k < e.length(); k++) {
JSONObject senses = e.getJSONObject(k);
JSONArray s = senses.getJSONArray("senses");
JSONObject d = e.getJSONObject(0);
JSONArray de = d.getJSONArray("definitions");
def = de.getString(0);
}
}
}
Log.e("def", def);
} catch (JSONException e) {
e.printStackTrace();
}
}
}
try to validate the "senses" with senses.has("senses") before use it and then parse it with optjsonarray or optjsonobject for this type and check this key or check at backend side from where what value getting in json response.
//[(START)File:ThirdActivity.java] -->
package com.example.caleb.splash_screen;
import android.os.AsyncTask;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.widget.TextView;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.io.IOException;
import java.io.OutputStream;
public class ThirdActivity extends AppCompatActivity {
//public String text = "https://jsonparsingdemo-cec5b.firebaseapp.com/jsonData/moviesDemoItem.txt";
public TextView text;
private void writeStream(OutputStream out){
String output = "Hello world";
// out.write(output.getBytes());
//out.flush();
}
/*private String readStream(InputStream is) {
try {`enter code here`
ByteArrayOutputStream bo = new ByteArrayOutputStream();
int i = is.read();
while(i != -1) {
bo.write(i);
i = is.read();
}
return bo.toString();
} catch (IOException e) {
return "";
}
}*/
//[(START) readStream -->
private String readStream(InputStream in) throws IOException {
BufferedReader bin = new BufferedReader(new InputStreamReader(in));
//temporary
try {
StringBuilder sb = new StringBuilder();
String inputLine;
while ((inputLine = bin.readLine()) != null) {
sb.append(inputLine);
}
return sb.toString();
} finally {
}
}
//[(END) readStream -->
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_third2);
text = (TextView)findViewById(R.id.textView);
new JSONTask().execute("https://jsonparsingdemo-cec5b.firebaseapp.com/jsonData/moviesDemoItem.txt");
}
}
//[(END)File:ThirdActivity] -->
//[(START)File:JSONTask] -->
package com.example.caleb.splash_screen;
import android.app.Activity;
import android.content.Context;
import android.os.AsyncTask;
import android.support.v4.widget.TextViewCompat;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.widget.TextView;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
/**
* Created by Caleb on 12/17/2017.
*/
public class JSONTask extends AsyncTask<String,String,String> {
//final TextView txt = (TextView)findViewById(R.id.textView);
private Context context;
public JSONTask(Activity ThirdActivity) {
context = ThirdActivity;
}
#Override
protected String doInBackground(String... params) {
BufferedReader reader = null;
HttpURLConnection urlConnection = null;
//{(START)] Working Connection:ALERT! Error within code will cause crash -->
try {
URL url = new URL(params[0]);
Log.w("testing", "test");
urlConnection = (HttpURLConnection) url.openConnection();
urlConnection.setRequestMethod("GET");
urlConnection.setDoOutput(false);
urlConnection.connect();
//urlConnection.setChunkedStreamingMode(0);
//OutputStream out = new BufferedOutputStream(urlConnection.getOutputStream());
//writeStream(out);
/*int a = urlConnection.getResponseCode();
String b = String.valueOf(a);
Log.e(b, "yesssssssssssssssss");*/
InputStream in = urlConnection.getInputStream();
//InputStream in = new BufferedInputStream(urlConnection.getInputStream());
reader = new BufferedReader(new InputStreamReader(in));
StringBuffer buffer = new StringBuffer();
String line = "";
while ((line = reader.readLine()) != null) {
buffer.append(line);
}
/*String data = readStream(in);
/*final TextView textView = (TextView) findViewById(R.id.textView);
textView.setText("hello");
*/
return buffer.toString();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
throw new RuntimeException(e);
} finally {
if (urlConnection != null) {
urlConnection.disconnect();
}
try {
if (reader != null) {
reader.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
//{(END)] Working Connection -->
return null;
}
#Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
TextView text = (TextView) ((AppCompatActivity) context).findViewById(R.id.textView);
text.setText(result);
}
}
//[(END)File:JSONTask] -->
/Desired Effect/
Blockquote
I would like to pull data from the json file that the url points to and change the TextView within the UI called textView. I don't understand how to access the findviewbyid within the AsyncTask. I've looked all throughout the internet and couldn't find anything :( Any suggestions are greatly appreciated!!
try weak reference to get textview in asynctask
//call async task
new JSONTask(yourTextView).execute();
//in your async task
private final WeakReference<TextView> textViewReference;
public JSONTask (TextView textView){
textViewReference = new WeakReference<TextView>( textView);
}
#Override
protected void onPostExecute() {
TextView textView = textViewReference.get();
//set values to text view
}
I'm using OkHttp to do the same task in my apps
HTTP/2 support allows all requests to the same host to share a socket.
Connection pooling reduces request latency (if HTTP/2 isn’t available).
Transparent GZIP shrinks download sizes.
Response caching avoids the network completely for repeat requests.
Add this dependency
implementation 'com.squareup.okhttp3:okhttp:3.9.1'
Then create/code a new Class named OkHttpHandler
class OkHttpHandler extends AsyncTask<String, String, String> {
OkHttpClient client = new OkHttpClient();
private volatile String data;
public String getResult() {
return data;
}
#Override
protected String doInBackground(String... params) {
try {
Request.Builder builder = new Request.Builder();
builder.url(params[0]);
Request request = builder.build();
Response response = client.newCall(request).execute();
return response.body().string();
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(String s) {
super.onPostExecute(s);
data = s;
}
}
}
and use it like this way
String str = new OkHttpHandler().execute("http://www.<TEST>.com/json").get();
I also suggest to check whether Wi-fi-Connected/Bluetooth-Connected or PhoneData-Enabled is false if true/else, Proceed to your code
I have a news app. My app takes so much time to fetch data from server and display it on the listView.But i have seen that apps like flipboard,facebook and Game News which has more data to fetch than mine does it faster.I think my app loads the entire data and displays the entire list together.Is there a way to display the list such that it loads the items in listView one by one?I do the fetching using a AsyncTaskLoader in the background.Also how to display a large list of news like 100 in a list .
MainActivity:
package com.example.android.gametalks;
import android.app.LoaderManager;
import android.content.Intent;
import android.content.Loader;
import android.net.Uri;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ListView;
import java.util.ArrayList;
import java.util.List;
public class MainActivity extends AppCompatActivity implements LoaderManager.LoaderCallbacks<List<GameNews>> {
//IGN url
final String ign_url = "https://newsapi.org/v1/articles?source=ign&sortBy=top&apiKey=679f6fb918d34343b18590ca70f7fcde";
final String google_url = " https://newsapi.org/v1/articles?source=google-news&sortBy=top&apiKey=679f6fb918d34343b18590ca70f7fcde";
final String engadget_url = "https://newsapi.org/v1/articles?source=engadget&sortBy=top&apiKey=679f6fb918d34343b18590ca70f7fcde";
GameAdapter adapter ;
private View progressBar;
final private int game_loader = 0;
ArrayList<String> urls = new ArrayList<>();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
urls.add(ign_url);
urls.add(google_url);
urls.add(engadget_url);
//Getting listView
ListView gameListView = (ListView) findViewById(R.id.listView);
//progress bar finding
progressBar = findViewById(R.id.progress_bar);
ArrayList<GameNews> gameList = new ArrayList<>();
//Making a new arrayAdapter
adapter = new GameAdapter(this,gameList);
//Connecting ArrayAdapter to ListView
gameListView.setAdapter(adapter);
getLoaderManager().initLoader(game_loader, null, this);
//ListView item click listner
gameListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
GameNews currentEarthquake = adapter.getItem(i);
String url = currentEarthquake.getUrl();
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setData(Uri.parse(url));
startActivity(intent);
}
});
}
#Override
public Loader<List<GameNews>> onCreateLoader(int i, Bundle bundle) {
return new GameLoader(this,urls);
}
#Override
public void onLoadFinished(Loader<List<GameNews>> loader, List<GameNews> games) {
progressBar.setVisibility(View.INVISIBLE);
adapter.clear();
if(games == null)
{
return;
}
adapter.addAll(games);
}
#Override
public void onLoaderReset(Loader<List<GameNews>> loader) {
adapter.clear();
}
}
GameLoader:
package com.example.android.gametalks;
import android.content.AsyncTaskLoader;
import android.content.Context;
import java.util.ArrayList;
import java.util.List;
/**
* Created by apple on 9/8/17.
*/
public class GameLoader extends AsyncTaskLoader<List<GameNews>> {
private ArrayList<String> Urls = new ArrayList<>();
public GameLoader(Context context, ArrayList<String> Url) {
super(context);
Urls = Url;
}
#Override
protected void onStartLoading()
{
forceLoad();
}
#Override
public List<GameNews> loadInBackground() {
if(Urls == null)
{
return null;
}
// Perform the HTTP request for earthquake data and process the response.
List<GameNews> games = QueryUtils.FetchEarthquakeData(Urls);
return games;
}
}
QueryUtils(Here the network fetching takes place):
package com.example.android.gametalks;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.util.Log;
import android.widget.ListView;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.nio.charset.Charset;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
/**
* Helper methods related to requesting and receiving earthquake data from USGS.
*/
public final class QueryUtils {
private static final String LOG_TAG = QueryUtils.class.getSimpleName();
/**
* Create a private constructor because no one should ever create a {#link QueryUtils} object.
* This class is only meant to hold static variables and methods, which can be accessed
* directly from the class name QueryUtils (and an object instance of QueryUtils is not needed).
*/
private QueryUtils() {
}
public static List<GameNews> FetchEarthquakeData(ArrayList<String> Url) {
List<GameNews> games ;
List<GameNews> Total = new ArrayList<>();
URL url;
Log.d(LOG_TAG,Url.get(0));
for(int i = 0 ; i < Url.size(); i++) {
url = createUrl(Url.get(i));
try {
//Make http request
String jsonResponse = makeHttpRequest(url);
games = extractFeatureFromJson(jsonResponse);
Total.addAll(games);
} catch (IOException e) {
Log.e("IOException", "" + e);
}
}
return Total;
}
private static URL createUrl(String stringUrl) {
URL url = null;
try {
url = new URL(stringUrl);
} catch (MalformedURLException e) {
Log.e(LOG_TAG, "Error with creating URL ", e);
}
return url;
}
private static String makeHttpRequest(URL url) throws IOException {
String jsonResponse = "";
InputStream inputStream = null;
HttpURLConnection urlConnection = null;
try {
urlConnection = (HttpURLConnection) url.openConnection();
if (urlConnection.getResponseCode() == 200) {
inputStream = urlConnection.getInputStream();
jsonResponse = readInputStream(inputStream);
} else {
Log.e(LOG_TAG, "" + urlConnection.getResponseCode());
return null;
}
} catch (IOException e) {
Log.d(LOG_TAG, "" + e);
} finally {
if (urlConnection != null) {
urlConnection.disconnect();
}
if (inputStream != null) {
// function must handle java.io.IOException here
inputStream.close();
}
}
return jsonResponse;
}
private static String readInputStream(InputStream inputStream) throws IOException {
StringBuilder output = new StringBuilder();
if (inputStream != null) {
InputStreamReader inputStreamReader = new InputStreamReader(inputStream, Charset.forName("UTF-8"));
BufferedReader reader = new BufferedReader(inputStreamReader);
String line = reader.readLine();
while (line != null) {
output.append(line);
line = reader.readLine();
}
}
return output.toString();
}
private static ArrayList<GameNews> extractFeatureFromJson(String jsonResponse) {
ArrayList<GameNews> games = new ArrayList<>();
try {
JSONObject jsonObject = new JSONObject(jsonResponse);
JSONArray articles = jsonObject.getJSONArray("articles");
for (int i = 0; i < articles.length(); i++) {
JSONObject currentGame = articles.getJSONObject(i);
// Extract the value for the key called "mag"
String title = currentGame.getString("title");
// Extract the value for the key called "place"
String description = currentGame.getString("description");
// Extract the value for the key called "url"
String url = currentGame.getString("url");
//Extract value from key called urlToImage
String urlToImage = "nn";
urlToImage = currentGame.getString("urlToImage");
URL urlOfImage = null;
Bitmap bmp = null;
try {
urlOfImage = new URL(urlToImage);
} catch (MalformedURLException e) {
e.printStackTrace();
}
try {
bmp = BitmapFactory.decodeStream(urlOfImage.openConnection().getInputStream());
} catch (IOException e) {
e.printStackTrace();
}
// Create a new {#link Earthquake} object with the magnitude, location, time,
// and url from the JSON response.
GameNews game = new GameNews(title, description,bmp,url);
// Add the new {#link Earthquake} to the list of earthquakes.
games.add(game);
}
} catch (JSONException e) {
Log.d(LOG_TAG, "" + e);
}
return games;
}
}
Thanks in advance.
I am new to Android so I am sorry if this is a mundane question. I am working on one of the exercises in a tutorial and I have a simple list which is supposed to display the data I got from a website. My listview is empty despite my adapter being populated correctly. I tried printing the adapter objects and it is working fine. Please help. Thanks in advance.
MainAcitvity.java
import android.os.AsyncTask;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.TextView;
import java.net.URL;
import java.util.ArrayList;
import java.util.concurrent.ExecutionException;
public class MainActivity extends AppCompatActivity {
private static String USGS_URL = "https://earthquake.usgs.gov/fdsnws/event/1/query?format=geojson&starttime=2014-01-01&endtime=2014-12-01&minmagnitude=7";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
DownloadTask task = new DownloadTask();
ArrayList<String> place = new ArrayList<>();
try {
place = task.execute(USGS_URL).get();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
ArrayAdapter<String> placesAdapter = new ArrayAdapter<String>(getApplicationContext(),android.R.layout.simple_list_item_1,place);
ListView listView = (ListView)findViewById(R.id.listView);
listView.setAdapter(placesAdapter);
}
private class DownloadTask extends AsyncTask<String, Void, ArrayList<String>>
{
#Override
protected ArrayList<String> doInBackground(String... strings) {
ArrayList<String > place = QueryUtils.fetchData(strings[0]);
}return place;
}
}
}
QueryUtils.java
import android.util.Log;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import javax.net.ssl.HttpsURLConnection;
public final class QueryUtils {
private QueryUtils() {
}
protected static ArrayList<String> fetchData(String rawStream) {
URL newUrl = null;
try {
newUrl = createUrl(rawStream);
Log.i("QueryUtils.java", newUrl.toString());
} catch (MalformedURLException e) {
e.printStackTrace();
}
ArrayList<String> values = QueryUtils.makeHttpRequest(newUrl);
}return values;
}
private static URL createUrl(String rawStream) throws MalformedURLException {
URL url = new URL(rawStream);
return url;
}
public static ArrayList<String> makeHttpRequest(URL newUrl) {
HttpsURLConnection url = null;
InputStream in = null;
ArrayList<String> values = new ArrayList<>();
try {
url = (HttpsURLConnection) newUrl.openConnection();
in = url.getInputStream();
String data = fetchJsonData(in);
values = fetchOutput(data);
} }catch (IOException e) {
e.printStackTrace();
}
finally {
if(url !=null)
url.disconnect();
}
return values;
}
private static ArrayList<String> fetchOutput(String data) {
String place = null;
ArrayList<String> values = new ArrayList<>();
try {
JSONObject baseJsonObject = new JSONObject(data);
JSONArray featuresAray =baseJsonObject.getJSONArray("features");
for(int i=0;i<featuresAray.length();i++) {
JSONObject firstArray = featuresAray.getJSONObject(i);
JSONObject properties = firstArray.getJSONObject("properties");
place = properties.getString("place");
values.add(place);
}
} catch (JSONException e) {
e.printStackTrace();
}
return values;
}
private static String fetchJsonData(InputStream in) throws IOException {
StringBuilder output = new StringBuilder();
InputStreamReader inReader = new InputStreamReader(in);
BufferedReader reader = new BufferedReader(inReader);
String line = reader.readLine();
while (line != null) {
output.append(line);
line = reader.readLine();
}
return output.toString();
}
}
So the solution was really really stupid. I cant believe I wasted so much time over this. Apparently the text was white and that's why my listView seemed empty :(:(
I have a button that gets month and year from spinners then calls an Async task, which read json data. That part works fine But if I try and change the month and year then click the button again it does nothing. I have to press back to reload the page to click the button again to get different results.
Here is my code. Can any of you smart folks please help me.
package com.app.simplictyPortal;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import com.app.simplicityPortal.adapter.InvoiceAdapter;
import android.app.Fragment;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ListView;
import android.widget.Spinner;
public class InvoiceFragment extends Fragment {
public InvoiceFragment(){}
Button load;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_invoice, container, false);
ArrayList<String> years = new ArrayList<String>();
int thisYear = Calendar.getInstance().get(Calendar.YEAR);
int currentMonth = Calendar.getInstance().get(Calendar.MONTH);
for (int i = 2013; i <= thisYear; i++)
{
years.add(Integer.toString(i));
}
//String tmonth = Integer.toString(currentMonth);
String tyear = Integer.toString(thisYear);
final Spinner year = (Spinner)rootView.findViewById(R.id.spinner1);
final Spinner month = (Spinner)rootView.findViewById(R.id.spinner2);
ArrayAdapter<String> adapter = new ArrayAdapter<String>(getActivity(),
android.R.layout.simple_spinner_item, years);
// Specify the layout to use when the list of choices appears
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
// Apply the adapter to the spinner
year.setAdapter(adapter);
year.setSelection(adapter.getPosition(tyear));
ArrayAdapter<CharSequence> adapter2 = ArrayAdapter.createFromResource(getActivity(),
R.array.month, android.R.layout.simple_spinner_item);
// Specify the layout to use when the list of choices appears
adapter2.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
// Apply the adapter to the spinner
month.setAdapter(adapter2);
month.setSelection(currentMonth);
load=(Button)rootView.findViewById(R.id.button1);
load.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
String y = (String) year.getSelectedItem();
int im = month.getSelectedItemPosition();
String m = Integer.toString(im +1);
final GlobalClass globalVariable = (GlobalClass) getActivity().getApplicationContext();
final String Compid = globalVariable.getCompid();
new InvoiceAsyncTask().execute("http://dev-sql1:8080/api/invoice/getall/"+Compid+"?m="+m+"&y="+y);
}
});
return rootView;
}
public void invoice(JSONArray jArray) {
ListView lv = (ListView) getView().findViewById(R.id.listView1);
List<ListViewItem> items = new ArrayList<InvoiceFragment.ListViewItem>();
try {
for (int i = 0; i <jArray.length(); i++) {
final JSONObject json_data = jArray.getJSONObject(i);
items.add(new ListViewItem()
{{
Vendor= json_data.optString("CarrierName");
Bill = "$ " + json_data.optString("BillAmount");
Serviceacct = json_data.optString("ServiceAccountNumber");
Date = json_data.optString("ReceivedDate");
}});
}
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
InvoiceAdapter adapter = new InvoiceAdapter(getActivity(), items);
lv.setAdapter(adapter);
// TODO Auto-generated method stub
}
public class ListViewItem
{
public String Vendor;
public String Bill;
public String Serviceacct;
public String Date;
} public static String GET(String url){
InputStream inputStream = null;
String result = "";
try {
// create HttpClient
HttpClient httpclient = new DefaultHttpClient();
// make GET request to the given URL
HttpResponse httpResponse = httpclient.execute(new HttpGet(url));
// receive response as inputStream
inputStream = httpResponse.getEntity().getContent();
// convert inputstream to string
if(inputStream != null)
result = convertInputStreamToString(inputStream);
else
result = "Did not work!";
} catch (Exception e) {
Log.d("InputStream", e.getLocalizedMessage());
}
return result;
}
private static String convertInputStreamToString(InputStream inputStream) throws IOException{
BufferedReader bufferedReader = new BufferedReader( new InputStreamReader(inputStream));
String line = "";
String result = "";
while((line = bufferedReader.readLine()) != null)
result += line;
inputStream.close();
return result;
}
public class InvoiceAsyncTask extends AsyncTask<String, Void, String> {
#Override
protected String doInBackground(String... urls) {
return GET(urls[0]);
}
// onPostExecute displays the results of the AsyncTask.
#Override
protected void onPostExecute(String result) {
try {
JSONArray jArray = new JSONArray(result);
invoice(jArray);
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
How do you process results of your InvoiceAsyncTask? Do you implement a callback from your AsyncTask's onPostExecute() to the activity?
Maybe the sample below will help you.
First, implement AsyncTask class with callback interface:
public class ServerRequestAsyncTask extends AsyncTask<String, Void, ServerResponseDetails> {
public ServerRequestAsyncTask(Fragment fragment, ServerRequestDetails request) {
mFragment = fragment;
mRequest = request;
}
public interface OnServerRequestAsyncTaskCompletedListener {
void onServerRequestAsyncTaskCompleted(ServerResponseDetails response);
}
public void cancel() {
if (mHttpGet != null && !mHttpGet.isAborted()) mHttpGet.abort();
cancel(true);
}
And also add onPostExecute():
#Override
protected void onPostExecute(ServerResponseDetails response) {
if (mFragment != null) mFragment.onServerRequestAsyncTaskCompleted(response);
}
I call AsyncTask from Fragment, but you can use it with Activity instead.
Then, in your Activity you implement interface:
#Override
public void onServerRequestAsyncTaskCompleted(ServerResponseDetails response) {
// do what you need here, then 'finish' task by setting mServerRequest to null
mServerRequest = null;
}
And to execute AsyncTask:
protected ServerRequestAsyncTask mServerRequest = null;
public boolean isServerRequestRunning() {
return (mServerRequest != null);
}
public void cancelServerRequest() {
mServerRequest.cancel();
}
public void sendServerRequest(Fragment fragment, ServerRequestDetails request) {
if (Application.isNetworkAvailable()) {
if (!isServerRequestRunning()) {
mServerRequest = new ServerRequestAsyncTask(fragment, request);
mServerRequest.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR,
{params});
}
}
}
mServerRequest variable holds reference to currently executed task. You can call mServerRequest.cancel() if need to abort.
Thanks Everyone But I have figured it out. I needed to cancel the Async task in the post execute method.
#Override
protected void onPostExecute(String result) {
try {
JSONArray jArray = new JSONArray(result);
invoice(jArray);
cancel(true);
isCancelled();
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}