Hey all I am writing an android aplication which gets a JSON object from a node.js server. My code is below (I do not have access to the server code). Is there any way to consistently check the server for a change in the JSON object (if they update it)? Right now it only does one GET and stops. I want to be able to query for a change and continue working with the new updates. Thoughts? Thanks.
Called from OnCreate():
new Read().execute("JSONkey");
Here is my Read ASyncTask:
public class Read extends AsyncTask<String, Integer, String>{
#Override
protected String doInBackground(String...param) {
try {
read_json = getCoords();
httpText.append(read_json.toString() + "\n");
try{
}catch(Exception e){ e.printStackTrace(); }
JSONArray data = read_json.getJSONArray(param[0]);
for (int i = 0; i < data.length(); ++i){
JSONObject info = data.getJSONObject(i);
Coordinate pt = new Coordinate(info.getInt("point"), info.getString("name"), info.getDouble("lat"), info.getDouble("long"));
coords.put(pt.getPoint(), pt);
coordList.add(new GeoPoint(pt.getLat(),pt.getLong()));
}
return "Success"; //get "text"
} catch (Exception e){
return "Fail";
}
}
#Override
protected void onPostExecute(String result){
//Doing something with JSON
//new Read().execute("coords"); tried doing this, but I feel it is not right.
}
}
and the GetCoords():
public JSONObject getCoords()
throws ClientProtocolException, IOException, JSONException{
StringBuilder url = new StringBuilder(URL);
HttpGet get = new HttpGet(url.toString());
HttpResponse response = client.execute(get);
int status = response.getStatusLine().getStatusCode();
if(status == 200){
HttpEntity entity = response.getEntity();
String data = EntityUtils.toString(entity);
JSONObject last = new JSONObject(data);
return last;
}else{
return null;
}
}
The proper way to do this is with a WebSocket but given the constrain of not being able to control the server side, your best bet is to
Put your code inside a service:
http://developer.android.com/reference/android/app/IntentService.html
Then use the Alarm Manager to schedule periodic updates.
http://developer.android.com/reference/android/app/AlarmManager.html
Related
I am totally new in java and android.. I am sure I did it wrong on the code, please help me fix it
I try to send the content of a tweet as a String from an android application to this online parser: http://demo.ark.cs.cmu.edu/parse, and I want to retrieve the result of the parsing, here is my code:
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.test);
String Tobetag = urlEncode(contentTweet);
new Analyser().execute();
}
private String urlEncode(String s){
try {
return URLEncoder.encode(s,"UTF-8").replace("+", "%20");
}
catch ( UnsupportedEncodingException e) {
throw new RuntimeException(s,e);
}
}
private class Analyser extends AsyncTask<Integer, Integer, Integer>
{
private String mUrl = "http://demo.ark.cs.cmu.edu/parse?sentence=";
#Override
protected Integer doInBackground(Integer... params) {
// TODO Auto-generated method stub
try
{
DefaultHttpClient client = new DefaultHttpClient();
HttpGet request = new HttpGet();
request.setURI(new URI(mUrl + mTobetag));
HttpResponse response = client.execute(request);
InputStream in = response.getEntity().getContent();
BufferedReader reader = new BufferedReader( new InputStreamReader(in) );
String result = reader.readLine();
System.out.println("Top");
System.out.println(result);
System.out.println("Bottom");
in.close();
}
catch(Exception e)
{
Log.e("Twitter", "doInBackground_" + e.toString());
}
return new Integer(1);
}
protected void onProgressUpdate(Integer... progress) {
}
#Override
protected void onPostExecute(Integer i) {
}
}
I ran the code, no error reported but I didn't get the parse result, I only have this:
What can I do to get the result I wanted?
P.S. Also I am not sure I used the urlencoder right, it turn the slashes of the tweet content into %2F, but when I use the online parser by a browser, it shows that it doesn't change the slashed at all, please help
You are reading only the first line of the response, if you want to read the entire response you can do it like this:
String result = "";
for(String line;(line=br.readLine())!=null;){
result += line;
}
This will get you the entire http://demo.ark.cs.cmu.edu/parse page as a response, if you want the response to be only a JSON object, use this URL instead http://demo.ark.cs.cmu.edu/parse/api/v1/parse?sentence=....
Hey guys im creating an app where it populates a list view with data from mysql, the data that will fill the list view consists of courseid, courseName and lecturerName. However when i click the button to view the list it creates the progress dialog as it should however it gets stuck and then the application stop responding.
Below is the code to which i believe is causing the error because the logcat mentions something about doInBackground which is in this class:
the log cat file is: http://gyazo.com/950bcce9d14f267f495a4801434c6151
i really appreciate your time and help, i further want to say i am sorry about my debugging skills im still getting used to android.
public class AllCoursesActivity extends ListActivity {
//progress dialog
private ProgressDialog pDialog;
//create json parser object to understand the php files that were created
JSONParser jsonParser = new JSONParser();
ArrayList<HashMap<String, String>> courseList;
//url to get all the product list
private static String url_all_courses = "http://10.0.0.2/get_all_courses.php";
//JSON node Names
private static final String TAG_SUCCESS = "success";
private static final String TAG_COURSES = "courses";
private static final String TAG_COURSEID = "courseid";
private static final String TAG_COURSENAME = "courseName";
//products JSON array
JSONArray courses =null;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.allcourses);
//hashmap for listview
courseList = new ArrayList<HashMap<String, String>>();
//loading courses in background thread
new LoadAllCourses().execute();
//GET list view
ListView lv = getListView();
}
class LoadAllCourses extends AsyncTask<String, String, String>{
//before starting the background thread show some progress dialog
protected void onPreExecute(){
super.onPreExecute();
pDialog = new ProgressDialog(AllCoursesActivity.this);
pDialog.setMessage("Loading Courses. Please Wait");
pDialog.setCancelable(false);
pDialog.setIndeterminate(false);
pDialog.show();
}
//getting all products from the URL
#Override
protected String doInBackground(String... args) {
//building parameters
List<NameValuePair> params = new ArrayList<NameValuePair>();
//Getting JSON String from URL
JSONObject json = jsonParser.makeHttpRequest(url_all_courses, "GET", params);
//check log cat for json response
Log.d("All Products: ", json.toString());
try {
//checking for success TAG
int success = json.getInt(TAG_SUCCESS);
if (success == 1){
//it means courses were found
//Getting Array of products
courses = json.getJSONArray(TAG_COURSES);
//looping through all products
for (int i = 0; i < courses.length(); i++){
JSONObject c = courses.getJSONObject(i);
//storing each JSON Item in the variable
String courseid = c.getString(TAG_COURSEID);
String coursename = c.getString(TAG_COURSENAME);
//creating new HASHMAP
HashMap<String, String> map = new HashMap<String, String>();
//adding each child node to hashmap key => value
map.put(TAG_COURSEID, courseid);
map.put(TAG_COURSENAME, coursename);
//adding Hash list to array list
courseList.add(map);
}
}else {
//no courses found
//go back to dashboard
Intent i = new Intent(getApplicationContext(),MainScreenActivity.class);
//closing all previous activities
i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(i);
}
}catch(JSONException e){
e.printStackTrace();
}
return null;
}
//after completing background task Dismiss the progress dialog
protected void onPostExecute(String file_url){
//dismiss the dialog after getting all the courses
pDialog.dismiss();
//updating ui from background thread
runOnUiThread(new Runnable() {
#Override
public void run() {
//updating parsed JSon data into list view
ListAdapter adapter = new SimpleAdapter(AllCoursesActivity.this, courseList,
R.layout.listcourse, new String[]{TAG_COURSEID, TAG_COURSENAME},
new int[]{R.id.courseid, R.id.coursename});
//updating listview
setListAdapter(adapter);
}
});
}
}
}
Edit: Sorry if i didnt include my JSONParser class
public class JSONParser {
static InputStream is = null;
static JSONObject jObj = null;
static String json = "";
public JSONParser() {
}
//function to get url
//by making post or get method
public JSONObject makeHttpRequest(String url, String method, List<NameValuePair> params) {
//making the http request
try {
//check for request method
if (method == "POST") {
//request method is post
//default http client
DefaultHttpClient httpClient = new DefaultHttpClient();
HttpPost httpPost = new HttpPost(url);
httpPost.setEntity(new UrlEncodedFormEntity(params));
HttpResponse httpResponse = httpClient.execute(httpPost);
HttpEntity httpEntity = httpResponse.getEntity();
is = httpEntity.getContent();
} else if (method == "GET") {
DefaultHttpClient httpClient = new DefaultHttpClient();
String paramString = URLEncodedUtils.format(params, "utf-8");
url += "?" + paramString;
HttpGet httpGet = new HttpGet(url);
HttpResponse httpResponse = httpClient.execute(httpGet);
HttpEntity httpEntity = httpResponse.getEntity();
is = httpEntity.getContent();
}
}catch (UnsupportedEncodingException e){
e.printStackTrace();
}catch (ClientProtocolException e){
e.printStackTrace();
}catch (IOException e){
e.printStackTrace();
}
try {
BufferedReader reader = new BufferedReader(new InputStreamReader(is, "iso-8859-1"), 8);
StringBuilder sb = new StringBuilder();
String line = null;
while ((line = reader.readLine()) != null){
sb.append(line + "\n");
}
is.close();
json = sb.toString();
}catch (Exception e){
Log.e("Buffer Error", "Error converting result" + e.toString());
}
//try parse the string to json object
try {
jObj = new JSONObject(json);
}catch (JSONException e) {
Log.e("JSON Parser", "Error Parsing data" + e.toString());
}
return jObj;
}
}
You're getting a NullPointerException and it's probably happening here:
Log.d("All Products: ", json.toString());
Search for "caused by" in your log cat output. It says that it was caused by attempting to use org.json.JSONObject.toString() on a null object. Add a check to make sure your object isn't null before you use it.
It looks like your JSON object is set to null on this line:
Log.d("All Products: ", json.toString());
Add a null check for your JsonObject before you log it.
It looks like we used the same tutorial for this, see my slightly different working implementation here:
https://github.com/dmnugent80/ShareApp/blob/master/app/src/main/java/com/share/daniel/share/MainActivity.java
Here is how to check if null:
if (json != null){
Log.d("MyApp", "All Products: " + json.toString());
}
else{
Log.d("MyApp", "json is null ");
}
Hey thank you for all the help but i realised what the problem was. You guys were right in that it could not return anything but this is because it wasnt connecting to the databaseproperly. i used my ip address from ip config and also i didnt link the php file correctly for example:
http://192.xxx.xx.x/android_api/get_all_courses.php
This above fixed the problem thanks for all the help and solutions
I'm doing an appplication on Android, and I have to start Google Navigation (with longitude and latitude). All I've got is an adress (here an example : " * * * "). From that I have to get the coordinates.
So I use Google Geocoding, and did a HTTP request from Java :
public class LocationInfo extends AsyncTask<String, Void, JSONObject> {
#Override
protected JSONObject doInBackground(String... adresse) {
HttpGet httpGet = new HttpGet(
"https://maps.googleapis.com/maps/api/geocode/json"
+ "?address=" + adresse
+ "&sensor=true");
HttpClient client = new DefaultHttpClient();
HttpResponse response;
StringBuilder stringBuilder = new StringBuilder();
try {
response = client.execute(httpGet);
HttpEntity entity = response.getEntity();
InputStream stream = entity.getContent();
int b;
while ((b = stream.read()) != -1) {
stringBuilder.append((char) b);
}
} catch (ClientProtocolException e) {
} catch (IOException e) {
}
JSONObject jsonObject = new JSONObject();
try {
jsonObject = new JSONObject(stringBuilder.toString());
} catch (JSONException e) {
}
return jsonObject;
}
}
With this request I have the result ZERO_RESULT, but when I try it on my browser, I have a normal result.
It worked fine for a few hours on my devices, and after, i had this issue...
Anyone have an answer ?
Thanks !
adresse is not a string here but a vararg. You probably want to pick the first string in there so use adresse[0] here.
I managed to build a JSON array and I have a onClick event where I send this JSONArray through POST towards a php file that will process the array.
Right now I have no idea if the array arrives at the destination or not, if the array is interpreted correctly by the PHP or not.
The code for my POST call (Android) is:
Button bsave = (Button) findViewById(R.id.button3);
View.OnClickListener eventHandlerx = new View.OnClickListener() {
#Override
public void onClick(View arg0) {
JSONObject j1;
JSONArray jsonarray=new JSONArray();
ListView lst = (ListView) findViewById(R.id.mylistview);
int count = lst.getCount();
for (int i = 0; i < count; i++)
{
ViewGroup row = (ViewGroup) lst.getChildAt(i);
TextView tvId = (TextView) row.findViewById(R.id.fID);
TextView tvNume = (TextView) row.findViewById(R.id.fTitlu);
TextView tvUM = (TextView) row.findViewById(R.id.fUM);
TextView tvPU = (TextView) row.findViewById(R.id.fPU);
TextView tvCant = (TextView) row.findViewById(R.id.fCant);
jsonarray.put("Item");
j1 = new JSONObject();
try {
j1.put("idx", newid);
j1.put("id", tvId.getText());
j1.put("nume", tvNume.getText());
j1.put("um", tvUM.getText());
j1.put("pu", tvPU.getText());
j1.put("cant", tvCant.getText());
} catch (JSONException e) {
e.printStackTrace();
}
jsonarray.put(j1);
}
Log.d("JSON array","Array to send:"+jsonarray.toString());
sendJson( urlx, jsonarray);
}
private void sendJson(final String urlx, final JSONArray jsonarray) {
Thread t = new Thread() {
public void run() {
Looper.prepare(); //For Preparing Message Pool for the child Thread
HttpClient client = new DefaultHttpClient();
HttpConnectionParams.setConnectionTimeout(client.getParams(), 10000); //Timeout Limit
HttpResponse response;
try {
HttpPost post = new HttpPost(urlx);
StringEntity se = new StringEntity( jsonarray.toString());
se.setContentType(new BasicHeader(HTTP.CONTENT_TYPE, "application/json"));
post.setEntity(se);
response = client.execute(post);
/*Checking response */
if(response!=null){
HttpEntity entity = response.getEntity();
if (entity != null) {
Log.e("POST response",EntityUtils.toString(entity));
}else{
Log.e("POST response","NULL "+EntityUtils.toString(entity));
}
}else{
Log.e("POST response","NULL");
}
} catch(Exception e) {
e.printStackTrace();
Log.e("postJSON","Error at POST with json:"+e.toString());
}
Looper.loop(); //Loop in the message queue
}
};
t.start();
}
};
bsave.setOnClickListener(eventHandlerx);
How do I check if the array was successfully POSTED to php? I assume I could do it in a php file... But how do I see the result?
No matter what I do, the Log shows me:
org.apache.http.conn.EofSensorInputStream#somehexa
So I am stuck. Please give me some solutions.
What should a php file look like in order to return the POSTED value, and what should my Android code look like in order to interpret the result (just display it somewhere like Log for debugging purposes)
The php I use is:
<?php
ob_start();
var_dump($_POST);
die();
$json = file_get_contents('php://input');
$obj = json_decode($json);
print $obj;
result = $obj;
$page = ob_get_contents();
ob_end_flush();
$fp = fopen("output.txt","w");
fwrite($fp,$page);
fclose($fp);
?>
However, the file does not show up...
and Eclipse does not give me anything in Log...
Thank you
If this is just for testing the easiest way to see the data is to do var_dump($_POST); inside PHP file you are submitting the form to, and log the response to some file on web server or to console in your android app. You can put die(); after var_dump if you want to break the execution of the rest of the code while you are testing.
edit:
Since you are using php://input stream and already have some code you can just use var_dump($json) or just echo it back you your app instead of what i suggested earlier. This will return the raw data you posted but you will need some kind of code in your app to display the HttpResponse. You can try something like this:
HttpEntity entity = response.getEntity();
String phpResponse = EntityUtils.toString(entity);
and then log the phpResponse variable.
Also, your file is not generated since everything after die(); is not executed, you can remove it and check again if the file is there.
I have an asynctask which gets its data through php. The asynctask works fine, it passes the values to a global arraylist. However, when i try to call the variable on onCreate after .execute(), it returns a null size/value(s). I would like to know why this global variable returns a null when its supposed to have a value. Thanks in advance!
this is the code for asyntask:
private class get_pendingreq extends AsyncTask<String, Integer, String>
{
#Override
protected String doInBackground(String... arg0)
{
InputStream is = null;
String result = "";
try
{
HttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost(url+"pending_requests.php");
List<NameValuePair> parameter = new ArrayList<NameValuePair>();
parameter.add(new BasicNameValuePair("email", globalVariables.accountemail));
httppost.setEntity(new UrlEncodedFormEntity(parameter));
HttpResponse response = httpclient.execute(httppost);
HttpEntity entity = response.getEntity();
is = entity.getContent();
} catch (Exception e)
{
Log.e("log_tag", "Error in http connection " + e.toString());
}
try
{
BufferedReader reader = new BufferedReader(
new InputStreamReader(is, "iso-8859-1"), 8);
StringBuilder sb = new StringBuilder();
String line = null;
while ((line = reader.readLine()) != null)
{
sb.append(line + "\n");
}
is.close();
result = sb.toString();
} catch (Exception e)
{
Log.e("log_tag", "Error converting result " + e.toString());
}
return result;
}
#Override
protected void onPostExecute(String result)
{
super.onPostExecute(result);
try
{
/* JSON parsing starts here */
JSONObject jArray = new JSONObject(result);
/*globalVariables.pendingdate = new ArrayList<String>();*/
JSONArray request = jArray.getJSONArray("request");
for (int i = 0; i < request.length(); i++)
{
JSONObject e = request.getJSONObject(i);
/* puts values to arraylist<String> */
globalVariables.pendingdate.add(e.getString("date"));
}
Log.d("striiing", globalVariables.pendingdate.toString());
} catch (JSONException e)
{
e.printStackTrace();
}
}
}
Main activity:
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.calendar);
new get_pendingreq().execute();
System.out.print("alalala" + globalVariables.pendingdate.size());
}//this returns null
Global Variable:
public static ArrayList<String> pendingdate = new ArrayList<String>;
Because AsyncTask not finished. Put System.out.print("finish"); in onPostExcute() and see who is printed first.
The idea behind an AsyncTask is that it runs asynchronously from the main thread, thus on a background thread. That way it doesn't block the execution of any code on the main thread.
Knowing that, the following lines will execute right after each other:
new get_pendingreq().execute();
System.out.print("alalala" + globalVariables.pendingdate.size());
Your get_pendingreq class will not do any actual work until after a small delay, meaning that after calling the first lines in above snippet, nothing has really happened. You've only instructed the platform to start the async task somewhere in the near future.
Now, the globalVariables.pendingdate field you're accessing on the second line will not have any values until the async task finishes its work. That doesn't happen until onPostExecute() is executed. In other words: you're trying to print the values at the wrong moment in time.
Simply move that print to the end of the async task's onPostExectute() method (but obviously before the return - why's that even there at all?).
I highly recommend you have a read through the AsyncTask class documentation and the Processes and Threads article.
It is clear form the name indeed AsyncTask runs Asynchronously ...
Let me explain taking your code into consideration:
new get_pendingreq().execute();
This line will create a new thread for execution and it will run
asynchronously and so the next line(i.e.System.out.print("alalala" +
globalVariables.pendingdate.size());) gets executed immidiatly after this line without waiting the async task to get executed completly.so put this system.print line inside
the post execute method...
Are u sure, that globalVariables.pendingdate.add(e.getString("date")); realy have field "data" ?