This question already has answers here:
How can I fix 'android.os.NetworkOnMainThreadException'?
(66 answers)
Closed 5 years ago.
LocationFragment class:
public class LocationFragment extends Fragment {
FragmentNameFactory nameFactory = new FragmentNameFactory();
List<LocationData> locationData;
LocationRecyclerAdapter locationRecyclerAdapter = new LocationRecyclerAdapter(locationData);
public LocationFragment(){
//Fragment needs a constructor, can be empty
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState){
((MainActivity) getActivity()).setFragmentName(nameFactory.getNameNL(6));
final View view = inflater.inflate(R.layout.flocationrecylce, container, false);
new JSONAsyncTask(new JSONCallBack(){
//This method updates the UI
#Override
public void success(JSONParser jsonParser) {
final JSONParser json = jsonParser;
//This part makes sure it is able to multi thread.
//In case this method is missing the application will crash upon refreshing this fragment
locationData = json.storeJSONData();
RecyclerView recyclerView = (RecyclerView) view.findViewById(R.id.locationRecyclerView);
recyclerView.setHasFixedSize(true);
recyclerView.setAdapter(locationRecyclerAdapter);
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(getActivity());
recyclerView.setLayoutManager(linearLayoutManager);
}
//In case of failure the method sprints the log to the debugging console
#Override
public void failed() {
System.out.print("Failure");
}
//Sends the task to the doInBackground method inside RSSReaderAsync, which execute the code inside RSSReader
}).execute("");
return view;
}
#Override
public void onViewCreated(View view, Bundle savedInstance){
super.onViewCreated(view, savedInstance);
}
#Override
public void onActivityCreated(Bundle savedInstance){
super.onActivityCreated(savedInstance);
}
}
JSONParser class:
public class JSONParser {
String url;
String requestMethod;
List<LocationData> locations;
public JSONParser(String url, String requestMethod){
this.url = url;
this.requestMethod = requestMethod;
locations = storeJSONData();
}
private String read(BufferedReader bufferedReader) throws IOException {
//Creates new StringBuilder to avoid escaping chars
StringBuilder stringBuilder = new StringBuilder();
//Creates new variable
String currentLine;
//Gets the currentLine
while((currentLine = bufferedReader.readLine()) !=null ){
//Adds the currentLine to the stringBuild if the currentLine is not null
stringBuilder.append(currentLine);
}
//Returns the StringBuilder is String format
return stringBuilder.toString();
}
public JSONObject sendRequest() throws IOException, JSONException {
//Get the URL from the constructor
URL url = new URL(this.url);
//Opens the connection
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
//Sets the requestMethod
connection.setRequestMethod(this.requestMethod);
//Sets the requestProperties
connection.setRequestProperty("Content-type", "application/JSON");
//Tries to read the through the BufferedReader
try {
//Creates new BufferedReader & InputStreamReader which get the input of the connection
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
//Stores the output of the connection in a string
String jsonText = read(bufferedReader);
//Creates a new JSON object from the above String
JSONObject json = new JSONObject(jsonText);
//Returns the JSON Object
return json;
} finally {
//Disconnects from the URL
connection.disconnect();
}
}
public List<LocationData> storeJSONData(){
//Creates temporary List
List<LocationData> tempList = new ArrayList<>();
try{
//Sends request
JSONObject json = sendRequest();
//For loop to parse all the data from the request
for(Integer i =0; i < json.getJSONArray("response").length(); i++){
tempList.add(new LocationData(json.getJSONArray("response").getJSONObject(i).getString("name"),
json.getJSONArray("response").getJSONObject(i).getString("zipcode"),
json.getJSONArray("response").getJSONObject(i).getString("street"),
json.getJSONArray("response").getJSONObject(i).getString("streetnumber"),
json.getJSONArray("response").getJSONObject(i).getDouble("longitude"),
json.getJSONArray("response").getJSONObject(i).getDouble("latitude"),
json.getJSONArray("response").getJSONObject(i).getString("city")));
}
}
catch (IOException e){
System.out.print(e);
}
catch (JSONException e){
System.out.print(e);
}
//Returns the list
return tempList;
}
}
JSONCallBack interface:
public interface JSONCallBack {
void success(JSONParser jsonParser);
void failed();
}
JSONAsyncTask class:
public class JSONAsyncTask extends AsyncTask<String, Integer, Integer> {
private JSONCallBack jsonCallBack;
public JSONAsyncTask(JSONCallBack jsonCallBack) {
this.jsonCallBack = jsonCallBack;
}
#Override
protected Integer doInBackground(String... params) {
JSONParser parser = new JSONParser("http://grwn.ddns.net:1337/locations", "POST");
jsonCallBack.success(parser);
return null;
}
}
I'm trying to create a Async task inside a Fragment. The way I did this works for my RSS reader but somehow it doesn't work for my JSONParser. I tried almost each answer of this topic How to fix android.os.NetworkOnMainThreadException?
No of those options fix my issue:
android.os.NetworkOnMainThreadException
at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1303)
at java.net.SocketInputStream.read(SocketInputStream.java:150)
at java.net.SocketInputStream.read(SocketInputStream.java:120)
at com.android.okhttp.okio.Okio$2.read(Okio.java:136)
at com.android.okhttp.okio.AsyncTimeout$2.read(AsyncTimeout.java:211)
at com.android.okhttp.okio.RealBufferedSource.exhausted(RealBufferedSource.java:60)
at com.android.okhttp.internal.http.HttpConnection.isReadable(HttpConnection.java:155)
at com.android.okhttp.Connection.isReadable(Connection.java:417)
at com.android.okhttp.OkHttpClient$1.isReadable(OkHttpClient.java:93)
at com.android.okhttp.internal.http.HttpEngine.createNextConnection(HttpEngine.java:339)
at com.android.okhttp.internal.http.HttpEngine.connect(HttpEngine.java:329)
at com.android.okhttp.internal.http.HttpEngine.sendRequest(HttpEngine.java:247)
at com.android.okhttp.internal.huc.HttpURLConnectionImpl.execute(HttpURLConnectionImpl.java:457)
at com.android.okhttp.internal.huc.HttpURLConnectionImpl.getResponse(HttpURLConnectionImpl.java:405)
at com.android.okhttp.internal.huc.HttpURLConnectionImpl.getInputStream(HttpURLConnectionImpl.java:243)
at com.example.sande.androidhro.JSONParser.sendRequest(JSONParser.java:69)
at com.example.sande.androidhro.JSONParser.storeJSONData(JSONParser.java:92)
at com.example.sande.androidhro.LocationFragment$1$1.run(LocationFragment.java:46)
at android.os.Handler.handleCallback(Handler.java:751)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:153)
at android.app.ActivityThread.main(ActivityThread.java:6236)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:891)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:781)
I know this has something to do with the Async task but I don't know what I'm doing wrong
The sendRequest() function must happen in the background (aka doinbackground in the asynctask)
All because you need to make network calls on back thread,
Having said that you can use Volley or Retrofit Libraries instead for easier network calls
Volley - https://developer.android.com/training/volley/index.html
Retrofit - http://square.github.io/retrofit/
EDIT :
this is your onsuccess:
#Override
public void success(JSONParser jsonParser) {
final JSONParser json = jsonParser;
**locationData = json.storeJSONData();**
RecyclerView recyclerView = (RecyclerView)
view.findViewById(R.id.locationRecyclerView);
recyclerView.setHasFixedSize(true);
recyclerView.setAdapter(locationRecyclerAdapter);
LinearLayoutManager linearLayoutManager = new
LinearLayoutManager(getActivity());
recyclerView.setLayoutManager(linearLayoutManager);
You are now on mainthread(that's why you can change views and do findviewbyid and so on ... )
Than you try
locationData = json.storeJSONData();
Which calls sendrequest again , this time on mainthread , like Slevin tried to imply , this will fix the current crash .
Related
So I was trying to retrieve all the posts from the REST API I made to be outputted to a textview in my Posts activity. I can successfully retrieve the JSON Objects and store them in their corresponding ArrayLists. However, whenever I call my ListPosts function from my Posts activity within the AsyncTask's onPostExecute, its saying that my postsSect textview is null.
I am thinking that for some reason the R.id is not getting contacted, even though I declared it in onCreate of my Posts. Because of this I'm getting this error message in my logcat:
01-14 21:43:57.022 16588-16588/com.example.android.androidcraftsappprototype E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.android.androidcraftsappprototype, PID: 16588
java.lang.NullPointerException: Attempt to invoke virtual method 'android.view.Window$Callback android.view.Window.getCallback()' on a null object reference
at android.support.v7.app.AppCompatDelegateImpl.<init>(AppCompatDelegateImpl.java:249)
at android.support.v7.app.AppCompatDelegate.create(AppCompatDelegate.java:182)
at android.support.v7.app.AppCompatActivity.getDelegate(AppCompatActivity.java:520)
at android.support.v7.app.AppCompatActivity.findViewById(AppCompatActivity.java:191)
at com.example.android.androidcraftsappprototype.WSAdapter$SendPostsRequest.onPostExecute(WSAdapter.java:186)
at com.example.android.androidcraftsappprototype.WSAdapter$SendPostsRequest.onPostExecute(WSAdapter.java:104)
at android.os.AsyncTask.finish(AsyncTask.java:695)
at android.os.AsyncTask.-wrap1(Unknown Source:0)
at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:712)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6494)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:807)
Posts.java
public class Posts extends AppCompatActivity {
TextView postsSect;
Button postsDoneBtn;
WSAdapter.SendPostsRequest PostsHelper;
StringBuilder postsBuffer = new StringBuilder();
#Override
protected void onResume(){
super.onResume();
PostsDetails postDetailsHelper = new PostsDetails();
//postDetailsHelper.ListPosts();
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_posts);
postsDoneBtn = (Button) findViewById(R.id.PostsDoneButton);
postsSect = (TextView) findViewById(R.id.PostsSection);
PostsDetails postDetailsHelper = new PostsDetails();
postDetailsHelper.callPostDetails("http://192.168.0.18:8000/api/");
//postDetailsHelper.ListPosts();
postsDoneBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
startActivity(new Intent(Posts.this, MainActivity.class));
}
});
}
public class PostsDetails {
//String post_title, post_content;
ArrayList<Integer> post_id = new ArrayList<Integer>();
ArrayList<String> post_title = new ArrayList<String>();
ArrayList<String> post_content = new ArrayList<String>();
boolean isPDCalled;
// sets if Post details are called
// checks if postsDetails functions are called for AsyncTask
boolean getIsPDCalled(){
return isPDCalled;
}
// calls the execute for AsyncTask
private void callPostDetails(String theurl){
PostsHelper = new WSAdapter().new SendPostsRequest();
// executes AsyncTask
PostsHelper.execute(theurl);
}
// sets values for the posts arrays
public void setPost(int p_id, String p_title, String p_content) {
this.post_id.add(p_id);
this.post_title.add(p_title);
this.post_content.add(p_content);
}
public ArrayList<Integer> getPostID() {
return this.post_id;
}
public ArrayList<String> getPostTitle() {
return this.post_title;
}
public ArrayList<String> getPostContent() {
return this.post_content;
}
// Lists the posts from the database
public void ListPosts() {
/////////// add functionality if a post was deleted and was clicked
int lastFrJSONArray = getPostID().size() - 1;
postsSect = (TextView) findViewById(R.id.PostsSection);
// outputs the id of the very first post, something to put to the textview
postsSect.setText("id: " + getPostID().get(0) + "\n");
for (int i = lastFrJSONArray; i >= 0; i--)
{
// appending the titles and contents of the current post
postsSect.append("title: " + getPostTitle().get(i) + "\n");
postsSect.append("content: " + getPostContent().get(i) + "\n");
// if this is the last post, then don't need to append id for the next post.
if (i != 0) {
postsSect.append("id: " + getPostID().get(i) + "\n");
}
}
}
}
}
WSAdapter.java
public class WSAdapter {
/*#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}*/
public class SendPostsRequest extends AsyncTask<String, String, String> {
TextView postsSect;
// Add a pre-execute thing
HttpURLConnection urlConnection;
private WeakReference<Activity> mPostReference;
/*public SendPostsRequest(Activity activity){
mPostReference = new WeakReference<Activity>(activity);
}*/
#Override
protected String doInBackground(String... params) {
StringBuilder result = new StringBuilder();
try {
urlConnection = (HttpURLConnection) new URL(params[0]).openConnection();
urlConnection.setRequestMethod("GET");
urlConnection.connect();
InputStream in = new BufferedInputStream(urlConnection.getInputStream());
BufferedReader reader = new BufferedReader(new InputStreamReader(in));
String line;
while ((line = reader.readLine()) != null) {
result.append(line);
}
}catch( Exception e) {
e.printStackTrace();
}
/*finally {
urlConnection.disconnect();
}*/
return result.toString();
}
#Override
protected void onPostExecute(String result) {
// expecting a response code fro my server upon receiving the POST data
Log.e("TAG", result);
Posts.PostsDetails postsHelper = new Posts().new PostsDetails();
// For posts
try {
JSONArray pJObjArray = new JSONArray(result);
// algorithm for parsing the JSONArray from the Django REST API
for (int i = 0; i < pJObjArray.length(); i++) {
// puts the current iterated JSON object from the array to another temporary object
JSONObject pJObj_data = pJObjArray.getJSONObject(i);
// inputs necesarry elements to the ListPosts function
postsHelper.setPost(pJObj_data.getInt("id"), pJObj_data.getString("post_title"), pJObj_data.getString("post_content"));
}
} catch (JSONException e) {
//Toast.makeText(JSonActivity.this, e.toString(), Toast.LENGTH_LONG).show();
Log.d("Json","Exception = "+e.toString());
}
postsHelper.ListPosts();
}
}
}
First of all restructure your code. And for setting text make those fields static which you want to use and then set their values in the onPostExecute of AsyncTask or else you can return the jsonstring as it is to your activity and then parse it there and set values for better readability.
Is there a way to overwrite the "week_kg" variable with the async task in the oncreateview method?
The async task overwrites the variable, but the View is already created and doesn't contain the new value.
It's a Rest Communications with a Node.js Server and a Mysql database.
public class Feedback extends Fragment {
private RecyclerView mRecylcerView;
private RecyclerView.Adapter mAdapter;
private RecyclerView.LayoutManager mLayoutManager;
public String username = "ilovenature";
public double week_kg;
String resturl = "http://192.168.178.199:3000/"; //ip
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_feedback, container, false);
new HttpGet().execute(resturl + "user/" + username);
ArrayList < Feedback_inhalt > feedback_inhalt = new ArrayList<>();
feedback_inhalt.add(new Feedback_inhalt(R.mipmap.ic_plastic_color, "Verwertungskosten", "kg eingespart", week_kg));
mRecylcerView = view.findViewById(R.id.feedback_view);
mRecylcerView.setHasFixedSize(true);
mLayoutManager = new LinearLayoutManager(this.getActivity());
mAdapter = new FeedbackAdapter(feedback_inhalt);
mRecylcerView.setLayoutManager(mLayoutManager);
mRecylcerView.setAdapter(mAdapter);
return view;
}
public class HttpGet extends AsyncTask<String, Void, String> {
#Override
protected String doInBackground(String...strURLs) {
URL url;
String output;
HttpURLConnection conn;
try {
url = new URL(strURLs[0]);
conn = (HttpURLConnection) url.openConnection();
BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream()));
StringBuilder sb = new StringBuilder();
while ((output = br.readLine()) != null) {
sb.append(output);
}
return sb.toString();
} catch (IOException e) {
return "Unable to retrieve web page. URL may be invalid.";
}
}
#Override
protected void onPostExecute(String result) {
try {
JSONArray jsonArray = new JSONArray(result);
JSONObject jsonObject = jsonArray.getJSONObject(0);
week_kg = jsonObject.getDouble("wochenkilogramm");
} catch (JSONException e) {
e.printStackTrace();
}
}
}
}
The onCreateView() method is only called once when the view is created.
However, you can refresh your RecyclerView once your AsyncTask has finished executing. To achieve this, add the newly fetched data to your ArrayList feedback_halt and then call notifyDataSetChanged() on your adapter.
When you call notifyDataSetChanged(), the views will be refreshed based on the data in your ArrayList.
So, inside onPostExecute() after you have set the value of week_kg:
feedback_inhalt.add(new Feedback_inhalt(R.mipmap.ic_plastic_color, "Verwertungskosten", "kg eingespart", week_kg));
mAdapter.notifyDatSetChanged()
Finally, the notifyDataSetChanged() method should only be called from a UI thread but the onPostExecute() method runs on the UI thread by design so you are good to go :-)
Im new to android development have very basic knowledge of this whatever i have achieved till now is achieved using this website or youtube videos i'm stuck in AsyncTask (Earlier i was using .get() on Create View and it was working fine but UI Was blocked until task is finished. To Avoid UI Blocking i was advice to remove .get() function from OnCreateView() function now after removing this im not being able to get any data from AsyncTask). I did that but now i'm not being able to create view i did lots of research but unable to get this strength
Here is my Codes Please Help how to create view from this
OnCreateView() :-
public View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) {
View GView = inflater.inflate(R.layout.fragment_dashboard, container, false);
progressBarHolder = (FrameLayout) GView.findViewById(R.id.progressBarHolder);
GridView gridView = (GridView) GView.findViewById(R.id.gridView);
//Toast.makeText(getActivity(),Json_String,Toast.LENGTH_LONG).show();
String finalResult = null;
try{
finalResult = String.valueOf(new JSONTask().execute("https://www.example.in/android_api/dashboard_data",JsonData()));
Toast.makeText(getActivity(),Json_String,Toast.LENGTH_LONG).show();
JSONObject parentObject = null;
parentObject = new JSONObject(finalResult);
if(((String) parentObject.names().get(0)).matches("error")){
JSONObject jObj = parentObject.getJSONObject("error");
errorThrow(jObj.getString("Description"));
} else if(((String) parentObject.names().get(0)).matches("success")){
JSONObject jObj = parentObject.getJSONObject("success");
JSONArray arrajson = jObj.getJSONArray("data");
String arrayCount = Integer.toString(arrajson.length());
String[] type = new String[arrajson.length()];
Integer[] count = new Integer[arrajson.length()];
for (int i=0; i<arrajson.length();i++){
JSONObject jsonObject = arrajson.getJSONObject(i);
type[i] = jsonObject.getString("type");
count[i] = jsonObject.getInt("count");
}
CustomAdpter customAdpter = new CustomAdpter(DashboardFragment.this,type,count);
gridView.setAdapter(customAdpter);
return GView;
}
} catch (JSONException e) {
e.printStackTrace();
}
return GView;
}
Base Adapter Code :-
class CustomAdpter extends BaseAdapter {
String[] type;
Integer[] count;
public CustomAdpter(DashboardFragment dashboardFragment, String[] type, Integer[] count){
this.count = count;
this.type = type;
}
#Override
public int getCount() {
return type.length;
}
#Override
public Object getItem(int i) {
return null;
}
#Override
public long getItemId(int i) {
return 0;
}
#Override
public View getView(int i, View view, ViewGroup viewGroup) {
view = getLayoutInflater().inflate(R.layout.grid_single_itme,null);
TextView textView = (TextView) view.findViewById(R.id.TextView1);
TextView textView1 = (TextView) view.findViewById(R.id.textView2);
textView.setText(String.valueOf(count[i]));
textView1.setText(type[i]);
view.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Toast.makeText(getActivity(),"Booking Item Clicked",Toast.LENGTH_LONG).show();
}
});
return view;
}
}
AsyncTask Code :-
public class JSONTask extends AsyncTask<String,String,String> {
private ProgressDialog mProgressDialog;
int progress;
public JSONTask(){
mProgressDialog = new ProgressDialog(getContext());
mProgressDialog.setMax(100);
mProgressDialog.setProgress(0);
}
#Override
protected void onPreExecute(){
mProgressDialog = ProgressDialog.show(getContext(),"Loading","Loading Data...",true,false);
super.onPreExecute();
}
#Override
protected String doInBackground(String... params) {
HttpURLConnection connection = null;
BufferedReader reader = null;
final String finalJson = params[1];
String json = finalJson;
try{
URL url = new URL(params[0]);
connection = (HttpURLConnection) url.openConnection();
connection.setConnectTimeout(5000);
connection.setRequestProperty("Content-Type", "application/json; charset=UTF-8");
connection.setRequestProperty("A-APK-API", "******");
connection.setRequestProperty("Authorization", "Basic **:**");
connection.setDoOutput(true);
connection.setDoInput(true);
connection.setRequestMethod("POST");
connection.connect();
OutputStream stream = connection.getOutputStream();
OutputStreamWriter streams = new OutputStreamWriter(stream, "UTF-8");
stream.write(json.getBytes("UTF-8"));
stream.close();
reader = new BufferedReader(new InputStreamReader(connection.getInputStream(),"UTF-8"));
StringBuffer buffer = new StringBuffer();
String line = "";
while((line = reader.readLine()) != null){
buffer.append(line);
}
return buffer.toString();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if(connection != null){
connection.disconnect();
}
try {
if(reader != null) {
reader.close();
}
} catch (IOException e){
e.printStackTrace();
}
}
return null;
}
protected void onPostExecute(String result){
super.onPostExecute(result);
Json_String = result;
Toast.makeText(getContext(),result,Toast.LENGTH_LONG).show();
mProgressDialog.dismiss();
}
}
Please help me here
You cannot get a result from asynctask when you dont use .get().
So change that statement. Start only the asynctask.
Then put all the code after that line in onPostExecute() of the AsyncTask.
Thats all.
you should change way you are creating the Adapter and attaching
you should do this
1.At first get the data in List,ArrayList etc. via AsyncTask, doInBackGround method
then on the onPostExecute method retrieve the data and create Adapter and attach it to your View
While you are getting data you can show some ProgressDialog.
If your AsyncTask is in other separate class then use interface to get the data from your AsyncTask class
look at this https://stackoverflow.com/a/47373959/8197737
This question already has answers here:
NetworkOnMainThreadException [duplicate]
(5 answers)
Closed 5 years ago.
Im just a beginner learning Json parsing and stream from the net,
well I dont get errors in this app but it doesnt display anything.
I dont know what the problem and cant see any problem in the log.
here is the code:
InputStream is;
String line;
TextView textView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textView = (TextView) findViewById(R.id.text);
try {
URL url = new URL("https://earthquake.usgs.gov/fdsnws/event/1/query?format=geojson&minlatitude=4&maxlatitude=5");
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
is = new BufferedInputStream(connection.getInputStream());
if(connection.getInputStream()==null)
{
textView.setText("input stream empty");
}
BufferedReader reader = new BufferedReader(new InputStreamReader(is));
StringBuilder builder = new StringBuilder();
while((line=reader.readLine())!=null){
builder.append(line);
}
if(builder.toString().equals(""))
{
textView.setText("no work builder empty");
}
line=builder.toString();
JSONObject object = new JSONObject(line);
JSONArray fea = object.getJSONArray("features");
JSONObject QUAKE = fea.getJSONObject(0);
JSONObject pro = QUAKE.getJSONObject("properties");
int mag = pro.getInt("mag");
textView.setText(mag+"");
} catch (Exception e) {
e.printStackTrace();
}
}
Thanks!
A exception is thrown when an application attempts to perform a networking operation on its main thread. Hence the network call wouldn't take place in your case as you are making a network call on main thread and it would directly throw a NetworkOnMainThreadException instead of making a network call. Run your code in AsyncTask
well doing any network operation on main thread is crime in Android. You will be punished with network_operation_on_main_thread exception. You need take help from AsyncTask.
please try below code
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textView = (TextView) findViewById(R.id.text);
new LongOperation().execute("");
}
private class LongOperation extends AsyncTask<String, Void, String> {
String data = "input stream empty";
#Override
protected String doInBackground(String... params) {
try {
URL url = new URL("https://earthquake.usgs.gov/fdsnws/event/1/query?format=geojson&minlatitude=4&maxlatitude=5");
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
is = new BufferedInputStream(connection.getInputStream());
BufferedReader reader = new BufferedReader(new InputStreamReader(is));
StringBuilder builder = new StringBuilder();
while((line=reader.readLine())!=null){
builder.append(line);
}
if(builder.toString().equals(""))
{
data = "no work builder empty";
}
line=builder.toString();
JSONObject object = new JSONObject(line);
JSONArray fea = object.getJSONArray("features");
JSONObject QUAKE = fea.getJSONObject(0);
JSONObject pro = QUAKE.getJSONObject("properties");
int mag = pro.getInt("mag");
data = mag+"";
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(String result) {
textView.setText(data);
}
#Override
protected void onPreExecute() {
}
#Override
protected void onProgressUpdate(Void... values) {
}
}
I am new to Android Studio and have a simple android view i am working on. A button click makes a call to the foursquare API and get backresults for starbucks around my location that I parse and am trying to set to the adapter for the listbox on the same view. If i put a breakpoint in the OnPostExecute() I see the mFoursquare adapter that I set for the listview has two json string results in the mFoursquareAdapter , I even call the
mFoursquareAdapter.notifyDataSetChanged();
in it but the view does not get refreshed with the results. I have posted the code below. Can anyone please point out what I am doing wrong or need to change since I already have the results and need to get this done...Your help and feedback very much appreciated! thanks
public class FoursquareInfoFragment extends android.app.Fragment {
private ArrayAdapter<String> mFoursquareAdapter;
public FoursquareInfoFragment() {
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setHasOptionsMenu(true);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
// Dummy data for the ListView. Here's the sample weekly forecast
String[] data = {
"Sample Foursquare Data",
};
List<String> foursquareList = new ArrayList<String>(Arrays.asList(data));
mFoursquareAdapter = new ArrayAdapter<String>(
getActivity(), // the current context ie the activity
R.layout.fragment_my, // the name of the layout Id
R.id.textViewFoursquare, // the Id of the TextView to populate
foursquareList);
View rootView = inflater.inflate(R.layout.fragment_my, container, false);
//View resultsView = inflater.inflate(R.layout.results, container, false);
View resultsView = inflater.inflate(R.layout.fragment_my, container, false);
ListView listView = (ListView) resultsView.findViewById(R.id.listview_FoursquareInfo);
listView.setAdapter(mFoursquareAdapter);
Button btnGetFoursquareData = (Button) rootView.findViewById(R.id.btnFoursquare);
btnGetFoursquareData.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
FetchFoursquareDataTask fetch = new FetchFoursquareDataTask();
fetch.execute("Starbucks");
}
});
return rootView;
}
public class FetchFoursquareDataTask extends AsyncTask<String, Void, String[]> {
private final String LOG_TAG = FetchFoursquareDataTask.class.getSimpleName();
#Override
protected void onPostExecute(String[] result) {
if (result != null) {
mFoursquareAdapter.clear();
for (String ItemStr : result) {
mFoursquareAdapter.add(ItemStr);
}
mFoursquareAdapter.notifyDataSetChanged();
}
}
#Override
protected String[] doInBackground(String... params) {
// If there's no venue category, theres nothing to look up. Verify the size of the params.
if (params.length == 0) {
return null;
}
// These two need to be declared outside the try/catch
// so that they can be closed in the finally block.
HttpURLConnection urlConnection = null;
BufferedReader reader = null;
// Will contain the raw JSON response as a string.
String foursquareJsonStr = null;
try {
// Build Foursquare URI with Parameters
final String FOURSQUARE_BASE_URL =
"https://api.foursquare.com/v2/venues/search";
final String client_id = "client_id";
final String client_secret = "client_secret";
final String v = "20130815";
final String near = "Dunwoody, Ga";
final String query = "Starbucks";
final String limit = "2";
Uri builtUri = Uri.parse(FOURSQUARE_BASE_URL).buildUpon()
.appendQueryParameter("client_id", client_id)
.appendQueryParameter("client_secret", client_secret)
.appendQueryParameter("v", v)
.appendQueryParameter("near", near)
.appendQueryParameter("query", query)
.appendQueryParameter("limit", limit)
.build();
URL url = new URL(builtUri.toString());
// Create the request to Foursquare, and open the connection
urlConnection = (HttpURLConnection) url.openConnection();
urlConnection.setRequestMethod("GET");
urlConnection.connect();
// Read the input stream into a String
InputStream inputStream = urlConnection.getInputStream();
StringBuffer buffer = new StringBuffer();
if (inputStream == null) {
// Nothing to do.
return null;
}
reader = new BufferedReader(new InputStreamReader(inputStream));
String line;
while ((line = reader.readLine()) != null) {
buffer.append(line + "\n");
}
if (buffer.length() == 0) {
// Stream was empty. No point in parsing.
foursquareJsonStr = null;
return null;
}
foursquareJsonStr = buffer.toString();
Log.v(LOG_TAG, "Foursquare JSON String: " + foursquareJsonStr);
} catch (IOException e) {
Log.e(LOG_TAG, "Error ", e);
// If the code didn't successfully get the fpursquare data, there's no point in attempting
// to parse it.
return null;
} finally {
if (urlConnection != null) {
urlConnection.disconnect();
}
if (reader != null) {
try {
reader.close();
} catch (final IOException e) {
Log.e("PlaceholderFragment", "Error closing stream", e);
}
}
}
String[] list = new String[]{"", ""};
try {
JSONObject foursquareJson = new JSONObject(foursquareJsonStr);
JSONObject responseObject = (JSONObject) foursquareJson.get("response");
JSONArray foursquareArray = responseObject.getJSONArray("venues");
list = new String[foursquareArray.length()];
for (int i = 0; i < foursquareArray.length(); i++) {
list[i] = foursquareArray.get(i).toString();
}
return list;
} catch (JSONException e) {
Log.e(LOG_TAG, e.getMessage(), e);
e.printStackTrace();
} finally {
Log.e(LOG_TAG, "ba");
return list;
}
}
}
}
This
mFoursquareAdapter.add(ItemStr);
Should be
foursquareList.add(ItemStr)
And you'll need to declare foursquareList properly (as a field).
You should also declare your Adapter as a field variable as well, just in case you need to reference it later