I am downloading JSON Content from server in the MainActivity and passing the JSON from MainActivity to ListActivity, the problem here is I have added a sleep time of 10s in the backend server i.e. Php from where the data is fetched. Since, the response will the delayed I would expect that screen opens and waits until the response comes and move to next screen.
But what is happening is the screen goes white/black completely untill the response is recieved and ListActivity is loaded, the problem here is the MainActivity is never visible. Below is code for the same:
MainActivity
JSONData jsonData = new JSONData();
String jsonList = jsonData.fetchList();
Intent intent = new Intent(getApplicationContext(),ListActivity.class);
intent.putExtra("jsonList",jsonList);
startActivity(intent);
finish();
JSON Data class
public String fetchList() {
try {
String list = new DownloadJSONData().execute(listURL).get().toString();
return list;
} catch (Exception e) {
return "";
}
}
private class DownloadJSONData extends AsyncTask<String, String, String> {
protected void onPreExecute() {
super.onPreExecute();
}
protected String doInBackground(String... params) {
HttpURLConnection connection = null;
BufferedReader reader = null;
try {
URL url = new URL(params[0]);
connection = (HttpURLConnection) url.openConnection();
connection.connect();
InputStream stream = connection.getInputStream();
reader = new BufferedReader(new InputStreamReader(stream));
StringBuffer buffer = new StringBuffer();
String line;
while ((line = reader.readLine()) != null) {
buffer.append(line + "\n");
}
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 "";
}
#Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
}
}
you are using get() method which accquires the main thread or ui thread untill the async task is completed
you should avoid using get() and also can use progress dialog in onPreExecute for displaying progression on network call to user
Related
I'm trying to build an Android application where I show on a Map different bicycle stations with markers all around the city. I'm using the public API offered by the city goverment. (http://www.zaragoza.es/docs-api_sede/#!/Equipamientos_y_movilidad%3A_Estaciones_Bizi/get_servicio_urbanismo_infraestructuras_estacion_bicicleta).
My problem is that I don't know how to recieve this JSON into my application. I've tried different ways but I'm always getting an exception with InputStream saying that there is no file.
I'm using this URL for testing: (https://www.zaragoza.es/sede/servicio/urbanismo-infraestructuras/equipamiento/aparcamiento-bicicleta?rf=html&srsname=wgs84&rows=2&distance=5000) With this URL you get just 2 stations. If you try it on google, you can see the JSON I'm trying to recieve, which is something like this:
{"totalCount":1122,"start":0,"rows":2,"result":[{"id":293,"title":"CALLE SOBRARBE, 46","tipo":"Abierto","plazas":6,"anclajes":3,"lastUpdated":"2018-12-24T00:00:00Z","geometry":{"type":"Point","coordinates":[-0.873314510445586,41.66099094543581]},"icon":"//www.zaragoza.es/contenidos/iconos/aparcabici.png"},{"id":294,"title":"AVENIDA SAN JUAN DE LA PEÑA, 1","tipo":"Abierto","plazas":10,"anclajes":5,"lastUpdated":"2018-12-24T00:00:00Z","geometry":{"type":"Point","coordinates":[-0.8732431572812822,41.66172067640118]},"icon":"//www.zaragoza.es/contenidos/iconos/aparcabici.png"}]}
This is the fragment where I'm trying to recieve the JSON.
public class fMap extends Fragment implements OnMapReadyCallback {
String page= "https://www.zaragoza.es/sede/servicio/urbanismo-infraestructuras/equipamiento/aparcamiento-bicicleta?rf=html&srsname=wgs84&rows=2&distance=5000";
public fMap() {
// Required empty public constructor
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View v = inflater.inflate(R.layout.fragment_f_map, container, false);
new JsonTask().execute("page");
return v;
}
private class JsonTask extends AsyncTask<String, String, String> {
protected void onPreExecute() {
super.onPreExecute();
pd = new ProgressDialog(getContext());
pd.setMessage("Please wait");
pd.setCancelable(false);
pd.show();
}
protected String doInBackground(String... params) {
HttpURLConnection connection = null;
BufferedReader reader = null;
try {
URL url = new URL(params[0]);
connection = (HttpURLConnection) url.openConnection();
connection.connect();
InputStream stream = connection.getInputStream();
reader = new BufferedReader(new InputStreamReader(stream));
StringBuffer buffer = new StringBuffer();
String line = "";
while ((line = reader.readLine()) != null) {
buffer.append(line+"\n");
Log.d("Response: ", "> " + line); //here u ll get whole response...... :-)
}
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;
}
}
}
My goal is getting this JSON so I can get the stations and show them on the Google Map.
I have a problem with parsing a tag inside a Json object.
My json code is structured like that:
{"giocatori":[{"nome":"Giovanni","cognome":"Muchacha","numero":"1","ruolo":"F-G"},
{"nome":"Giorgio","cognome":"Rossi","numero":"2","ruolo":"AG"},
{"nome":"Andrea","cognome":"Suagoloso","numero":"3","ruolo":"P"},
{"nome":"Salvatore","cognome":"Aranzulla","numero":"4","ruolo":"G"},
{"nome":"Giulio","cognome":"Muchacha","numero":"5","ruolo":"F"}]}
I got the code that let me get the Json file from here: Get JSON Data from URL Using Android? and I'm trying to parse a tag (for example the "nome" tag) into a Json object.
This is the code I got:
public class MainActivity extends AppCompatActivity {
Button btnHit;
TextView txtJson;
ProgressDialog pd;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btnHit = (Button) findViewById(R.id.btnHit);
txtJson = (TextView) findViewById(R.id.tvJsonItem);
btnHit.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
new JsonTask().execute("https://api.myjson.com/bins/177dpo");
}
});
}
private class JsonTask extends AsyncTask<String, String, String> {
protected void onPreExecute() {
super.onPreExecute();
pd = new ProgressDialog(MainActivity.this);
pd.setMessage("Please wait");
pd.setCancelable(false);
pd.show();
}
protected String doInBackground(String... params) {
HttpURLConnection connection = null;
BufferedReader reader = null;
try {
URL url = new URL(params[0]);
connection = (HttpURLConnection) url.openConnection();
connection.connect();
InputStream stream = connection.getInputStream();
reader = new BufferedReader(new InputStreamReader(stream));
StringBuffer buffer = new StringBuffer();
String line = "";
while ((line = reader.readLine()) != null) {
buffer.append(line+"\n");
Log.d("Response: ", "> " + 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;
}
#Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
if (pd.isShowing()){
pd.dismiss();
}
txtJson.setText(result);
}
}
}
I've never worked with this type of file so I'll really appreciate your help!
You can use something like this:
try {
String servResponse = response.toString();
JSONObject parentObj = new JSONObject(servResponse);
JSONArray parentArray = parentObj.getJSONArray("giocatori");
if (parentArray.length() == 0) {
//if it's empty, do something (or not)
} else {
//Here, finalObj will have your jsonObject
JSONObject finalObj = parentArray.getJSONObject(0);
//if you decide to store some value of the object, you can do like this (i've created a nomeGiocatori for example)
nomeGiocatori = finalObj.getString("nome");
}
} catch (Exception e) {
Log.d("Exception: ", "UnknownException");
}
I use this kind of code all the time, works like a charm.
I want to receive and send data with a web server but the code does not work
What do I do for this code to work?
Note this code inside onCreate
try {
URL url = new URL("http://myweb.com/");
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
InputStream Stream = connection.getInputStream();
InputStreamReader reader = new InputStreamReader(Stream);
BufferedReader b = new BufferedReader(reader);
StringBuilder s = new StringBuilder();
String str ="";
while ((str = b.readLine())!=null) {
s.append(str);
}
String data = s.toString();
TextView myText = (TextView) findViewById(R.id.Text);
myText.setText(data);
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
Make sure that you do network-related tasks on a separate thread in Android. Also, check that you have the INTERNET permission set.
If you want to then update the UI from another thread, you have to use
runOnUiThread (new Runnable () {
public void run() {
//update ui in here
}
}
All your code runs in Main thread which should be always used for setting up the UI and to listen for UI events such as on click listeners.
Network calls are not allowed on this thread as they might take long time. Use AsyncTask API of android which is designed for running code in separate thread.
Create a class like one below for all GET request tasks.
public class DownloadTask extends AsyncTask<String, Void, Integer> {
private String TAG = "InDownloadTask";
private DownloadCallback callback;
private String data;
public DownloadTask(DownloadCallback cb){
callback = cb;
}
#Override
protected Integer doInBackground(String... params) {
Integer result = 0;
HttpURLConnection urlConnection;
try {
URL url = new URL(params[0]);
urlConnection = (HttpURLConnection) url.openConnection();
int statusCode = urlConnection.getResponseCode();
if (statusCode == 200) {
BufferedReader r = new BufferedReader(new InputStreamReader(urlConnection.getInputStream()));
StringBuilder response = new StringBuilder();
String line;
while ((line = r.readLine()) != null) {
response.append(line);
}
data = response.toString();
result = 1;
} else {
result = 0;
}
} catch (Exception e) {
Log.d(TAG, e.getLocalizedMessage());
}
return result;
}
#Override
protected void onPostExecute(Integer integer) {
super.onPostExecute(integer);
callback.onFinishDownload(data, integer);
}
}
Create a callback interface that we use for the above class.
public interface DownloadCallback {
public void onFinishDownload(String data, Integer result);
}
Now from your activity onCreate
String url = "http://myweb.com/";
new DownloadTask(new DownloadCallback() {
public void onFinishDownload(String data, Integer result) {
if(result == 1)
myText.setText(data);
else
myText.setText("Error");
}
}).execute(url);
If you have many network related operations, use a Network library such as Volley which will take care of this.
This question already has answers here:
How do I parse JSON in Android? [duplicate]
(3 answers)
Closed 6 years ago.
I am attempting to make an app in android studio that gets live currency rates, so I decided to use a JSON to do this. I am currently able to print out the entire JSON as a string, however I would like to be able to set the TextView to the USD conversion rate, however it doesn't work. The TextView does not change. Any help would be greatly appreciated.
public class Converter extends AppCompatActivity {
TextView txtJson;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_converter);
txtJson = (TextView) findViewById(R.id.tvJsonItem);
new JsonTask().execute("https://openexchangerates.org/api/latest.json?app_id=870447ebb4d94379972250a3bdaed73f");
}
private class JsonTask extends AsyncTask<String, String, String> {
protected String doInBackground(String... params) {
HttpURLConnection connection = null;
BufferedReader reader = null;
try {
URL url = new URL(params[0]);
connection = (HttpURLConnection) url.openConnection();
connection.connect();
InputStream stream = connection.getInputStream();
reader = new BufferedReader(new InputStreamReader(stream));
StringBuffer buffer = new StringBuffer();
String line = "";
while ((line = reader.readLine()) != null) {
buffer.append(line + "\n");
Log.d("Response: ", "> " + 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;
}
#Override
public void onPostExecute(String result) {
super.onPostExecute(result);
try {
JSONObject jObject = new JSONObject(result);
int USD = jObject.getInt("USD");
String strUSD = Integer.toString(USD);
txtJson.setText(strUSD);
} catch (JSONException e) {
e.printStackTrace();
}
}
}}
You need to get the "rates" object before you can access the "USD" value
Also, it's not an integer. It's a double
getJSONObject("rates").getDouble("USD")
I'm really bad at googling things I want so I decided to ask here. My question is is it possible to show a progress bar while fetching the data from the database? I'm using the typical code when fetching data(Pass value to php and the php will do the query and pass it again to android)
Edit(I have tried adding proggressdialog but the problem now is the loaded data will appear first before the progress dialog here's my AsyncTask code)
public class getClass extends AsyncTask<String, Void, String> {
public getClass()
{
pDialog = new ProgressDialog(getActivity());
}
URLConnection connection = null;
String command;
Context context;
String ip = new returnIP().getIpAddresss();
String link = "http://" + ip + "/android/getClass.php";//ip address/localhost
public URLConnection getConnection(String link) {
URL url = null;
try//retrieves link from string
{
url = new URL(link);
} catch (MalformedURLException e) {
e.printStackTrace();
}
URLConnection connection = null;
try//opens the url link provided from the "link" variable
{
connection = url.openConnection();
} catch (IOException e) {
e.printStackTrace();
}
connection.setDoOutput(true);
return connection;
}
public String getResult(URLConnection connection, String logs) {
//this is the functions that retrieves what the php file echoes
//everything that php throws, the phone receives
String result = "";
OutputStreamWriter wr = null;
try {
wr = new OutputStreamWriter(connection.getOutputStream());//compiles data to be sent to the receiver
} catch (IOException e) {
e.printStackTrace();
}
try {
wr.write(logs);
} catch (IOException e) {
e.printStackTrace();
}
try {
wr.flush();//clears the cache-esque thingy of the writer
} catch (IOException e) {
e.printStackTrace();
}
BufferedReader reader = null;
try {
reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
} catch (IOException e) {
e.printStackTrace();
}
StringBuilder sb = new StringBuilder();
String line = null;
//Read server response
try {
while ((line = reader.readLine()) != null) {
sb.append(line);
}
} catch (IOException e) {
e.printStackTrace();
}
result = sb.toString();
return result;
}
#Override
protected void onPreExecute() {
pDialog.setMessage("Loading...");
pDialog.show();
}
#Override
protected String doInBackground(String... arg0) {
// TODO Auto-generated method stub
String result = "";
//Toast.makeText(View_Classes.this, "ako n una", Toast.LENGTH_LONG).show();
try {
//first data sent is sent in command
command = (String) arg0[0];//it's in array, because everything you input here is placed in arrays
//Toast.makeText(View_Classes.this, "andtio n me", Toast.LENGTH_LONG).show();
if (command == "getCourses") {
connection = getConnection(link);
String logs = "";
logs = "&command=" + URLEncoder.encode(command, "UTF-8");
logs += "&username=" + URLEncoder.encode(username, "UTF-8");
result = getResult(connection, logs);
} else if (command == "getSections") {
connection = getConnection(link);
String logs = "";
logs = "&command=" + URLEncoder.encode(command, "UTF-8");
logs += "&username=" + URLEncoder.encode(username, "UTF-8");
logs += "&course=" + URLEncoder.encode(course, "UTF-8");
result = getResult(connection, logs);
}
return result;
} catch (Exception e) {
return result;
}
}
#Override
protected void onPostExecute(String result) {//this is going to be the next function to be done after the doInBackground function
// TODO Auto-generated method stub
if (pDialog.isShowing()) {
pDialog.dismiss();
}
if (result.equalsIgnoreCase(""))//if there's nothing to return, the text "No records" are going to be thrown
{
} else //Array adapter is needed, to be a place holder of values before passing to spinner
{
}
}
}
Have you tried using an AsyncTask?
You can show your progress bar on the preExecute method and then hide it on postExecute. You can do your querying inside the doInBackground method.
In addition to what #torque203 pointed, I would suggest you to check
http://developer.android.com/reference/android/os/AsyncTask.html#onProgressUpdate(Progress...)
this method was created for that purpose, showing progress to the user.
From developers docs:
private class DownloadFilesTask extends AsyncTask<URL, Integer, Long> {
#Override
protected void onPreExecute() {
//show progress bar here
}
protected Long doInBackground(URL... urls) {
//Pass value to PHP here
//get values from your PHP
}
protected void onPostExecute(Long result) {
//Here you are ready with your PHP value. Dismiss progress bar here.
}
}
public void onPreExecute() {
Progress Dialog pDialog = new ProgressDialog(this);
pDialog.setMessage("Loading...");
pDialog.show();
}
public void doInBackground() {
//do your JSON Coding
}
public void onPostExecute() {
Progress Dialog pDialog = new ProgressDialog(this);
pDialog.setMessage("Loading...");
pDialog.show();
}
public URLConnection getConnection(String link) {
URL url = null;
try//retrieves link from string
{
url = new URL(link);
} catch (MalformedURLException e) {
e.printStackTrace();
}
URLConnection connection = null;
try//opens the url link provided from the "link" variable
{
connection = url.openConnection();
} catch (IOException e) {
e.printStackTrace();
}
connection.setDoOutput(true);
return connection;
}
public String getResult(URLConnection connection, String logs) {
//this is the functions that retrieves what the php file echoes
//everything that php throws, the phone receives
String result = "";
OutputStreamWriter wr = null;
try {
wr = new OutputStreamWriter(connection.getOutputStream());//compiles data to be sent to the receiver
} catch (IOException e) {
e.printStackTrace();
}
try {
wr.write(logs);
} catch (IOException e) {
e.printStackTrace();
}
try {
wr.flush();//clears the cache-esque thingy of the writer
} catch (IOException e) {
e.printStackTrace();
}
BufferedReader reader = null;
try {
reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
} catch (IOException e) {
e.printStackTrace();
}
StringBuilder sb = new StringBuilder();
String line = null;
//Read server response
try {
while ((line = reader.readLine()) != null) {
sb.append(line);
}
} catch (IOException e) {
e.printStackTrace();
}
result = sb.toString();
return result;
}
public class getClass extends AsyncTask<String, Void, String> {
#Override
protected void onPreExecute() {
pDialog.setMessage("Loading...");
pDialog.show();
URLConnection connection = null;
String command;
Context context;
String ip = new returnIP().getIpAddresss();
String link = "http://" + ip + "/android/getClass.php";//ip address/localhost
}
#Override
protected String doInBackground(String... arg0) {
// TODO Auto-generated method stub
String result = "";
//Toast.makeText(View_Classes.this, "ako n una", Toast.LENGTH_LONG).show();
try {
//first data sent is sent in command
command = (String) arg0[0];//it's in array, because everything you input here is placed in arrays
//Toast.makeText(View_Classes.this, "andtio n me", Toast.LENGTH_LONG).show();
if (command == "getCourses") {
connection = getConnection(link);
String logs = "";
logs = "&command=" + URLEncoder.encode(command, "UTF-8");
logs += "&username=" + URLEncoder.encode(username, "UTF-8");
result = getResult(connection, logs);
} else if (command == "getSections") {
connection = getConnection(link);
String logs = "";
logs = "&command=" + URLEncoder.encode(command, "UTF-8");
logs += "&username=" + URLEncoder.encode(username, "UTF-8");
logs += "&course=" + URLEncoder.encode(course, "UTF-8");
result = getResult(connection, logs);
}
return result;
} catch (Exception e) {
return result;
}
}
#Override
protected void onPostExecute(String result) {//this is going to be the next function to be done after the doInBackground function
// TODO Auto-generated method stub
if (pDialog.isShowing()) {
pDialog.dismiss();
}
if (result.equalsIgnoreCase(""))//if there's nothing to return, the text "No records" are going to be thrown
{
} else //Array adapter is needed, to be a place holder of values before passing to spinner
{
}
}
}