I'm following this tutorial about Rest API in android. I did everything what was in this video and I'm not getting any data, aslo I've changed the link as shown in but I'm not getting any data. Here is my code:
public class MainActivity extends AppCompatActivity {
private TextView value;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
value = (TextView) findViewById(R.id.textView);
Button btn = (Button) findViewById(R.id.button);
btn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
new JSONTask().execute("https://jsonparsingdemo-cec5b.firebaseapp.com/jsonData/moviesDemoItem.txt");
}
});
}
public class JSONTask extends AsyncTask<String, String, String>{
#Override
protected String doInBackground(String... urls) {
HttpURLConnection connection = null;
BufferedReader reader = null;
try {
URL url = new URL(urls[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);
}
// to bedzie wyswietlone
String finalJson = buffer.toString();
JSONObject parentObject = new JSONObject(finalJson);
JSONArray parrentArray = parentObject.getJSONArray("movies");
JSONObject finalObject = parrentArray.getJSONObject(0);
String movieName = finalObject.getString("movie");
int movieYear = finalObject.getInt("year");
return movieName;
}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);
value.setText(result);
}
}
}
I'm beginner in android, please don't say that I should start with something easier. I'm doing it for my Django project, I want to create mobile app for it. Thanks a lot for help!
Hiiii, i have checked your code and there is a issue because "https" connection.
You can use Volley library for that. Use below code for get response from yout api link.
Firstly add compile ‘com.mcxiaoke.volley:library-aar:1.0.0’ in yout build.gradle file.
now add below code in your activity
JsonObjectRequest jsonObjectRequest = new
JsonObjectRequest(Request.Method.GET, "https://jsonparsingdemo-
cec5b.firebaseapp.com/jsonData/moviesDemoItem.txt", null, new
Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
Toast.makeText(MainActivity.this, ""+response,
Toast.LENGTH_SHORT).show();
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
}
});
RequestQueue requestQueue =
Volley.newRequestQueue(getApplicationContext());
requestQueue.add(jsonObjectRequest);
Related
I want to parse JSON from the Openweather API but after many iterations and debugging, my JSON string is not updating, I do not think that there is any problem still the temperatures( minTemperature and maxTemperature) and the name of the place(mPlace) is not set, also I logged the maxtemperature but the console is showing nothing please look into my code.
public class MainActivity extends AppCompatActivity {
private EditText placeText;
private Button enterPlaceButton;
private TextView minTemperature;
private TextView maxTemperature;
private TextView mPlace;
private static final String AppID ="56a5e01eba3af36a7a9b7b210a437d09";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
setTitle("Weather");
placeText = findViewById(R.id.myPlaceEditText);
enterPlaceButton = findViewById(R.id.enterPlace);
minTemperature = findViewById(R.id.minTemperature);
maxTemperature = findViewById(R.id.maxTemperature);
mPlace = findViewById(R.id.mPlace);
}
#Override
protected void onResume() {
final URL[] url = {null};
enterPlaceButton.setOnClickListener(v -> {
url[0] = makeUrl(placeText.getText().toString());
placeText.setText("");
});
if (url[0] != null) {
MyAsync myAsync = new MyAsync();
myAsync.execute(url[0]);
}
super.onResume();
}
public URL makeUrl(String place) {
Uri.Builder uriBuilder = new Uri.Builder();
uriBuilder.scheme("http");
uriBuilder.authority("api.openweathermap.org/");
uriBuilder.appendPath("data");
uriBuilder.appendPath("2.5");
uriBuilder.appendPath("weather");
uriBuilder.appendQueryParameter("q",place);
uriBuilder.appendQueryParameter("appid",AppID);
try {
return new URL(uriBuilder.build().toString());
} catch (MalformedURLException e) {
Toast.makeText(MainActivity.this, "Sorry could not able to fetch the Data", Toast.LENGTH_SHORT).show();
e.printStackTrace();
}
return null;
}
public class MyAsync extends AsyncTask<URL, Void, String> {
#Override
protected String doInBackground(URL... urls) {
StringBuilder jsonResponseBuilder = new StringBuilder();
try {
HttpURLConnection httpURLConnection = (HttpURLConnection) urls[0].openConnection();
httpURLConnection.setRequestMethod("GET");
httpURLConnection.setReadTimeout(10000);
httpURLConnection.setConnectTimeout(15000);
httpURLConnection.setDoInput(true);
httpURLConnection.setDoOutput(true);
httpURLConnection.connect();
if (httpURLConnection.getResponseCode() == 200) {
InputStreamReader inputStreamReader = new InputStreamReader(httpURLConnection.getInputStream());
BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
String line = bufferedReader.readLine();
while (line != null) {
jsonResponseBuilder.append(line);
line = bufferedReader.readLine();
}
httpURLConnection.disconnect();
}
} catch (IOException e) {
e.printStackTrace();
Toast.makeText(MainActivity.this, "Sorry could not able to fetch the Data", Toast.LENGTH_SHORT).show();
}
Log.d(MyAsync.class.getName(),jsonResponseBuilder.toString());
return jsonResponseBuilder.toString();
}
#Override
protected void onPreExecute() {
super.onPreExecute();
}
#Override
protected void onPostExecute(String s) {
setDataFromJSON(s);
super.onPostExecute(s);
}
public void setDataFromJSON(String s) {
try {
JSONObject jsonObject = new JSONObject(s);
JSONObject getMainObject = jsonObject.getJSONObject("main");
String maxTemp = getMainObject.getString("temp_max");
Log.i(MainActivity.class.getName(), maxTemp);
maxTemperature.setText(maxTemp);
String minTemp = getMainObject.getString("temp_min");
minTemperature.setText(minTemp);
mPlace.setText(jsonObject.getString("name"));
} catch (JSONException e) {
e.printStackTrace();
Toast.makeText(MainActivity.this, "Sorry could not able to fetch the Data", Toast.LENGTH_SHORT).show();
}
}
}
}
This is my main activity which gets a json array from a URL. My problem is that when I try and Unit test what should be in the textview it gives me a null pointer exeption.
public class MainActivity extends AppCompatActivity {
TextView txtJson;
ProgressDialog pd;
public static TextView testString;
String jsonString = null;
List<Location> locations;`enter code here`
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
txtJson = (TextView) findViewById(R.id.tvJsonItem);
testString = (TextView) findViewById(R.id.test_for_string);
new JsonTask().execute("https://wsu-dining-service.s3.amazonaws.com/current-menu.json");
}
protected void postCreate()
{
mapStrinToClass();
testString.setText(locations.get(0).getName());
}
private void mapStrinToClass()
{
ObjectMapper objectMapper = new ObjectMapper();
JsonFactory jsonFactory = objectMapper.getFactory();
try {
JsonParser jsonParser = jsonFactory.createParser(jsonString);
locations = objectMapper.readValue(jsonString,
new TypeReference<List<Location>>() {
});
} catch (IOException e) {
e.printStackTrace();
}
}
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); //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;
}
#Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
if (pd.isShowing()){
pd.dismiss();
}
jsonString = result;
postCreate();
}
}
}
My unit test
* When I run the app the textview is populated with "Tim & Jeanne's Dining Commons" but the test fails and says the testString.getText().toString(); is null
#Test
public void isMenuCorrect() {
String menuTxt = MainActivity.testString.getText().toString();
assert(menuTxt == "Tim & Jeanne's Dining Commons");
}
First of all, you should use Espresso to run UI tests, under the androidTest folder. Example:
onView(allOf(withId(R.id.tvJsonItem), withText("Tim & Jeanne's Dining Commons")).check(matches(isDisplayed()));
Basically what we're doing here is checking if a view with id R.id.tvJsonItem and with a text "Tim & Jeanne's Dining Commons" is displayed on the screen. Now how to run Espresso tests is not in this question's scope.
Second, your production code should never know what's going on in the tests, like you have created a TextView just to be used in your unit tests.
Finally, never have static references to your views since you can't guarantee your activity has been created by the time you try to access them. In fact, a view should only be seen by its parent. In your case, the reference TextView should be private in your activity.
I had wrote a code which use a parse to catch some data from a JSON file but i don't know what kind of structure is better between the sparse array or the array map for memorise these data ?
I had used a array map but I don't know if it's too wasted on so little data data.
public class MainActivity extends AppCompatActivity {
private ProgressDialog pd;
private String TAG = MainActivity.class.getSimpleName();
public ArrayMap<Integer, ValoriDiSueg> ArrayDati = new ArrayMap<>();
Button buttonProg;
TextView textViewProg;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
buttonProg = (Button) findViewById(R.id.button);
textViewProg = (TextView) findViewById(R.id.textView);
buttonProg.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
new JsonCLASS().execute("https://samples.openweathermap.org/data/2.5/weather?q=London,uk&appid=b6907d289e10d714a6e88b30761fae22");
}
});
}
private class JsonCLASS extends AsyncTask<String, String, String> {
#Override
protected void onPreExecute() {
super.onPreExecute();
pd = new ProgressDialog(MainActivity.this);
pd.setMessage("Please wait");
pd.setCancelable(false);
pd.show();
}
#Override
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;
}
The parse of these data
#Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
try {
JSONObject jsonObject = new JSONObject(result);
JSONArray Arr = new JSONArray(jsonObject.getString("weather"));
for (int i = 0; i < Arr.length(); i++){
JSONObject jsonPart = Arr.getJSONObject(i);
ArrayDati.put(i,new ValoriDiSueg( jsonPart.getString("main"), jsonPart.getString("description")));
//ArrayDati.put(i,new ValoriDiSueg("description : "+ jsonPart.getString("description")));
textViewProg.setText(textViewProg.getText()+"main : "+ ArrayDati.get(i).Main +"\n"+textViewProg.getText()+"description : "+ ArrayDati.get(i).Description );
}
} catch (Exception e ){
e.printStackTrace();
}
if (pd.isShowing()) {
pd.dismiss();
}
}
}
}
And I created a class:
public class ValoriDiSueg {
String Main;
String Description;
public ValoriDiSueg(String main, String description) {
this.Main = main;
this.Description = description;
}
}
any suggestions??
In simple:
If your key is int or long, you should use SparseArray, SparseLongArray as it will not boxing/un-boxing the key value when operates. Also, it provides similar classes for int/long values as long as the key is int/long.
If you key is not int nor long, such as an object or String, you should use ArrayMap instead as it will handle the conflicts of key hashes.
There are no much performance and memory usage difference between these two class as they are all requires O(log n) to search and O(n) to insert/delete (in most cases).
I am trying to get mysql data from remote server www.kudossoft.in/get_data030518.php. but i am getting nothing when i check httpurl response code that is blank.
i have also add uses permission for internet in mainifest
my code is following please see.
i have also checked my php files permission that is ok.
and i am also inserting some data from another activity in same database that is working properly.
MainActivity code:
public class MainActivity extends AppCompatActivity {
ListView listView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
listView = (ListView) findViewById(R.id.listView);
getJSON("http://kudossoft.in/get_data300518.php");
}
private void getJSON(final String urlWebService) {
class GetJSON extends AsyncTask<Void, Void, String> {
#Override
protected void onPreExecute() {
super.onPreExecute();
}
#Override
protected void onPostExecute(String s) {
super.onPostExecute(s);
Toast.makeText(getApplicationContext(), s, Toast.LENGTH_SHORT).show();
try {
loadIntoListView(s);
} catch (JSONException e) {
e.printStackTrace();
}
}
#Override
protected String doInBackground(Void... voids) {
try {
URL url = new URL(urlWebService);
HttpURLConnection con = (HttpURLConnection) url.openConnection();
StringBuilder sb = new StringBuilder();
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(con.getInputStream()));
String json;
while ((json = bufferedReader.readLine()) != null) {
sb.append(json + "\n");
}
return sb.toString().trim();
} catch (Exception e) {
return null;
}
}
}
GetJSON getJSON = new GetJSON();
getJSON.execute();
}
private void loadIntoListView(String json) throws JSONException {
JSONArray jsonArray = new JSONArray(json);
String[] heroes = new String[jsonArray.length()];
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject obj = jsonArray.getJSONObject(i);
heroes[i] = obj.getString("name");``
}
ArrayAdapter<String> arrayAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, heroes);
listView.setAdapter(arrayAdapter);
}
}
I am doing long polling in my app, checking for new data every 500ms then update my textview when there is a new change. It's doing fine but after a few minutes, my app just crashes and gives me this error:
java.lang.OutOfMemoryError: pthread_create (1040KB stack) failed: Try again
at java.lang.Thread.nativeCreate(Native Method)
at java.lang.Thread.start(Thread.java:1063)
at com.android.volley.RequestQueue.start(RequestQueue.java:142)
at com.android.volley.toolbox.Volley.newRequestQueue(Volley.java:66)
at com.android.volley.toolbox.Volley.newRequestQueue(Volley.java:78)
at com.example.rendell.longpolling.MainActivity.sendRequest(MainActivity.java:96)
at com.example.rendell.longpolling.MainActivity$1$1.run(MainActivity.java:59)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5253)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:900)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:695)
MainActivity.java
public class MainActivity extends AppCompatActivity {
TextView text;
Date noteTS;
public static final String JSON_URL = "http://192.168.0.100/androidphp/data.php";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
text = (TextView) findViewById(R.id.text);
(new Thread(new Runnable()
{
#Override
public void run()
{
while (!Thread.interrupted())
try
{
Thread.sleep(500);
runOnUiThread(new Runnable() // start actions in UI thread
{
#Override
public void run()
{
// this action have to be in UI thread
/*noteTS = Calendar.getInstance().getTime();
String time = "hh:mm"; // 12:00
text.setText(DateFormat.format(time, noteTS));*/
sendRequest();
}
});
}
catch (InterruptedException e)
{
// ooops
}
}
})).start(); // the while thread will start in BG thread
}
public void sendRequest(){
//While the app fetched data we are displaying a progress dialog
//final ProgressDialog loading = ProgressDialog.show(this,"Fetching Data","Please wait...",false,false);
StringRequest stringRequest = new StringRequest(JSON_URL,
new Response.Listener<String>() {
#Override
public void onResponse(String response) {
//text.setText(response);
//loading.dismiss();
try{
showJSON(response);
}catch(Exception e) {}
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
//Toast.makeText(MainActivity.this, error.getMessage(), Toast.LENGTH_LONG).show();
}
});
RequestQueue requestQueue = Volley.newRequestQueue(this);
requestQueue.add(stringRequest);
}
private void showJSON(String json){
ParseJson pj = new ParseJson(json);
pj.parseJSON();
text.setText(ParseJson.playing[0]);
}
}
ParseJson.java
public class ParseJson {
public static String[] playing;
public static final String JSON_ARRAY = "result";
public static final String RESULT_ID = "playing";
private JSONArray users = null;
private String json;
public ParseJson(String json){
this.json = json;
}
public void parseJSON(){
JSONObject jsonObject=null;
try {
jsonObject = new JSONObject(json);
users = jsonObject.getJSONArray(JSON_ARRAY);
playing = new String[users.length()];
for(int i=0;i<users.length();i++){
JSONObject jo = users.getJSONObject(i);
playing[i] = jo.getString(RESULT_ID);
}
} catch (JSONException e) {
e.printStackTrace();
}
}
}
I'm not sure what is wrong with your code but I can give you few tips
first of all, Read the android documentations on how to make a singleton class for volley, you are creating a new RequestQueue every time you send a request, I use one queue for my whole app, maybe in some cases you create more but I can't think of any right now, most probably this is your main problem since the error is happening at newQueue method
you don't have to make the singleton class but at least try to make the queue as instance variable and add to it each time.
second of all there are simpler ways to perform a task every x seconds, I heared (NOT SURE) that using thread.sleep in android is not recommended
here is how I usually perform such tasks:
Timer timer = new Timer();
final Handler handler = new Handler(){
#Override
public void handleMessage(Message msg) {
// do something on UI
}
};
TimerTask task = new TimerTask () {
#Override
public void run () {
//send volley request here
}
};
timer.schedule(task, 0, 60000); // 60000 is time in ms
Consider using Rxjava with Retrolambda for this
Observable.interval(500, TimeUnit.MILLISECONDS, Schedulers.io()).map(tick -> sendRequest()).doOnError(err -> //handle error).observeOn(AndroidSchedulers.mainThread()).subscribe(//handle subscription);
Update:
For java7 and 6 use this
.map(new Func1<Long, String>() {
#Override
public String call(Long tick) {
return sendRequest();
}
})
sendRequest method
private String sendRequest(){ URL url;
HttpURLConnection urlConnection = null;
JSONArray response = new JSONArray();
try {
url = new URL(params[0]);
urlConnection = (HttpURLConnection) url.openConnection();
int responseCode = urlConnection.getResponseCode();
if(responseCode == HttpStatus.SC_OK){
String responseString = readStream(urlConnection.getInputStream());
Log.v("CatalogClient", responseString);
response = new JSONArray(responseString);
}else{
Log.v("CatalogClient", "Response code:"+ responseCode);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if(urlConnection != null)
urlConnection.disconnect();
}
return response;}
and read stream method
private String readStream(InputStream in) {
BufferedReader reader = null;
StringBuffer response = new StringBuffer();
try {
reader = new BufferedReader(new InputStreamReader(in));
String line = "";
while ((line = reader.readLine()) != null) {
response.append(line);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (reader != null) {
try {
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return response.toString();
}
now in .subscribe() override Action1 and read the string response.