0

I am trying to send JSON string {"latitude":53.86897577,"longitude":10.66560449,"formatted":"24.04.2015 16:26:35","route":4} to the server every 60 seconds but I am always getting the same data. How can I manage it to get always new data in the JSON string. I tried to set timer but without success. I can see the data in the xml file how they are changing but how to realize that with serliziation ?

MainActivity class:

    public class MainActivity extends ActionBarActivity {

        int route_number;
        double pLong;
        double pLat;
        String formatted;


        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);


            LocationManager lm = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
            LocationListener ll = new myLocationListener();
            lm.requestLocationUpdates(LocationManager.GPS_PROVIDER, 1000, 0, ll);
            enableGPS(lm);

          PostData sender = new PostData();
        }   

     class myLocationListener implements LocationListener {

    @Override
    public void onLocationChanged(Location location) {


        if (location != null) {
            pLong = location.getLongitude();
            pLat = location.getLatitude();
            SimpleDateFormat sdf = new SimpleDateFormat("dd.MM.yyyy HH:mm:ss",
                    java.util.Locale.getDefault());
            formatted = sdf.format(location.getTime());

        }
                 String jSONString=  convertToJSON(pLong, pLat, formatted);

                 sender.timer(jSONString);
    }

    @Override
    public void onStatusChanged(String provider, int status, Bundle extras) {
        // TODO Auto-generated method stub

    }

    @Override
    public void onProviderEnabled(String provider) {
        // TODO Auto-generated method stub

    }

    @Override
    public void onProviderDisabled(String provider) {
        // TODO Auto-generated method stub

    }
}

    private String convertToJSON(double pLong, double pLat, String formatted) {
        //envelop the data in JSON format.                  
        Data d = new Data(pLat, pLong, formatted,route_number);
        Gson gson = new GsonBuilder().registerTypeAdapter(Data.class, new DataSerializer()).create();
         //return gson.toJson(d);
         String a = gson.toJson(d);
        // System.out.println(a);
         return a;
    }
    }

PostData class:

public class PostData {
    String jSONString;
    Handler handler = new Handler();

    public PostData() {
        super();


    }

    public String getjSONString() {
        return jSONString;
    }

    public void setjSONString(String jSONString) {
        this.jSONString = jSONString;
    }

    public void timer(String jSONString) {

        new Thread(new Runnable() {
            @Override
            public void run() {
                boolean run = true;
                while (run) {
                   handler.postDelayed(new Runnable() {
                       @Override
                       public void run() {
                           new MyAsyncTask().execute(jSONString);
                       }
                   }, 30000);
                }
            }
        }).start();
    }

    class MyAsyncTask extends AsyncTask<String, Integer, Void> {

        @Override
        protected Void doInBackground(String... params) {
            // TODO Auto-generated method stub

                System.out.println("The output of : doInBackground " +jSONString);

            return null;

        }

    }

}

}

Passed JSON String with fourth key which I am getting from the inner class BroadcastReceiver in my MainActivity:

{
  "latitude":53.86897577,
  "longitude":10.66560449,
  "formatted":"24.04.2015 16:26:35",
  "route":4

}
Mr Asker
  • 2,300
  • 11
  • 31
  • 56

1 Answers1

1

It looks like you just need in initiate a call to timer() in onLocationChanged(). Just change timer() to take the jSONString instead of setting it in the constructor.

The other main issue is that you should reference the varargs passed into your AsyncTask.

Note that what I'm proposing here removes your background Thread, and only sends data to the server when the location changes.

Note that you will need to walk around to get the onLocationChanged() events to happen.

I assume you will be adding code to send the jSONString to your server in your AsyncTask, and that looks good.

First, fix your AsyncTask:

class MyAsyncTask extends AsyncTask<String, Integer, Void> {

    @Override
    protected Void doInBackground(String... params) {
        //System.out.println("The output of : doInBackground " +jSONString);
        System.out.println("The output of : doInBackground " +params[0]); //use the first index of params

        return null;
    }
}

In the timer() method, add jSONString as a parameter, and remove the parameter from your constructor:

public PostData() {
    super();
}

public String getjSONString() {
    return jSONString;
}

public void setjSONString(String jSONString) {
    this.jSONString = jSONString;
}

public void timer(String jSONString) {
     this.jSONString = jSONString; //add this here
     new MyAsyncTask().execute(jSONString);
}

onLocationChanged method:

@Override
public void onLocationChanged(Location location) {
    if (location != null) {
        pLong = location.getLongitude();
        pLat = location.getLatitude();
        SimpleDateFormat sdf = new SimpleDateFormat("dd.MM.yyyy HH:mm:ss", java.util.Locale.getDefault());
        formatted = sdf.format(location.getTime());

        //add code below:
        String jSONString=  convertToJSON(pLong, pLat, formatted);

        sender.timer(jSONString);
    }
}

Then in MainActivity, just intialize PostData, but don't call timer because you don't have location data yet:

LocationManager lm = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
LocationListener ll = new myLocationListener();
lm.requestLocationUpdates(LocationManager.GPS_PROVIDER, 1000, 0, ll);
enableGPS(lm);

PostData sender = new PostData(); //just initialize sender here
Ziem
  • 6,579
  • 8
  • 53
  • 86
Daniel Nugent
  • 43,104
  • 15
  • 109
  • 137
  • I did as you proposed. my PostData class hast construtor to pass the JSONString to it so when I put this line `PostData sender = new PostData();` in the onCreate method I am getting this error `he constructor PostData() is undefined` ? I have fourth element in the JSOn string which represents the strongest wifi access point I am getting this value of this element from inner class BoradcastReiceiver in the MainActivity therefore I thought timer and AsyncTask class are better. – Mr Asker Apr 24 '15 at 15:58
  • please see my updated code or please update your answer to get the point because I still getting just the same time in the DataPost class. – Mr Asker Apr 24 '15 at 16:15
  • Thanks for updating your answer: I am getting now the right data but I have two simple question ;) why should I initialize sender `PostData sender = new PostData()` in inCreate methodsince when I did that I got this error `sender cannot be resolved` but when I initialized it outside the MainActivity or in the onLocationChanged mehod it works fine. Second question: it is not better approach in my case to excute the AsyncTask from timer? I want to send the data to the server just if the location changed – Mr Asker Apr 24 '15 at 18:21
  • @MrAsker No problem, glad it's working for you now! I'm not sure why the placement of `PostData sender = new PostData() ` in `onCreate()` would cause a problem, but as long as it gets initialized before you refrence it, it should be fine. As for the timer, I think that you can remove all of your Threads and `postDelayed()` calls, and just execute the `AsyncTask` when the `onLocationChanged` callback occurs, as I have outlined in the answer. – Daniel Nugent Apr 24 '15 at 18:36
  • Please can you take a look at this question here:? http://stackoverflow.com/questions/29863769/send-latitude-and-longitude-from-the-boadcastreceiver-when-the-internet-connecti – Mr Asker Apr 25 '15 at 11:23