1

I'm still learning Java/Android development and I need some guidance to implement an Async task. I'm mostly unsure of where to start it in my program. I have outlined some code below, could someone show me where and how to implement the task? My app sends GPS coordinates to a database every second and I need a separate task so I don't bog down the main thread and risk an ARN error. Here is my code:

This first block is from my main activity. When the button is pressed, a three second countdown is initiated, and when it finishes (onFinish) the user data is sent to one database (SendUserActivity.sendId..., this is actually a class, not an activity, just poorly named) and the app then begins to track the user and send the coordinates to a different database every second (location.startLocation...) (two databases to avoid repeating all of the user's data).

MainActivity.java:

public void onFinish() {
   button.setText("SENT");  
   SendUserActivity.sendId(usr_id1, first, last);                   
   location.startLocation(getBaseContext(), usr_id1);

This is the second block of code from the LocationActivity class (also a class and not an activity, poor naming again). It requests a location update every second and then posts it to a PHP script that inserts it in a MySQL database.

public class LocationActivity {

    private LocationManager locManager;
    private LocationListener locListener;

    public void startLocation(Context context, String usr_id2)
    {   
        final String usr = usr_id2;

    //get a reference to the LocationManager
    locManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);


    //checked to receive updates from the position
    locListener = new LocationListener() {
        public void onLocationChanged(Location location) {
            send(location, usr);
        }
        public void onProviderDisabled(String provider){
            //labelState.setText("Provider OFF");
        }
        public void onProviderEnabled(String provider){
            //labelState.setText("Provider ON ");
        }
        public void onStatusChanged(String provider, int status, Bundle extras){
            //Log.i("", "Provider Status: " + status);
            }
        };
        locManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 1000, 0, locListener);
    }

    public void send(Location loc, String usr_id2) {

         Log.i("", String.valueOf(loc.getLatitude() + " - " + String.valueOf(loc.getLongitude())));

         String lat = String.valueOf(loc.getLatitude()); 
         String lon = String.valueOf(loc.getLongitude());

        HttpClient httpclient = new DefaultHttpClient();
        HttpPost httppost = new HttpPost("http://example.com/test/example.php");

         try {
           List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(2);
           nameValuePairs.add(new BasicNameValuePair("lat", lat)); 
           nameValuePairs.add(new BasicNameValuePair("lon", lon));
           nameValuePairs.add(new BasicNameValuePair("id", usr_id2));
           httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
           httpclient.execute(httppost);
         } 
         catch (ClientProtocolException e) {
             // TODO Auto-generated catch block
         } 
         catch (IOException e) {
             // TODO Auto-generated catch block
         }
    }
}

To reiterate my question, how would I implement an async task to send the GPS information to the database? I have read about IntentServices, but some have suggested that I use an async task. Either way, let me know where and how to implement one of these; I'd really appreciate it. Thanks!

mkyong
  • 12,497
  • 12
  • 37
  • 56
  • basically everything that need to wait for external system, outside the phone need to be in Async. For your case is the send() need to be in async. – Rudy Mar 01 '12 at 10:41

2 Answers2

3

In this case basically you wrap your send method into the doInBackground() method of asynctask and a result in the onPostExecute(...) will be set into a DB. Make AsyncTask an inner class if you like. There're plenty of examples of how to make an AsyncTask. Here for example just a question

Using AsyncTask with database and

Android AsyncTask and SQLite DB instance.

This site has very good tutorials http://www.vogella.de/articles/AndroidPerformance/article.html

and ofcourse of Mark Murphy's (CommonsWare) https://github.com/commonsguy/cw-lunchlist/blob/master/15-Internet/LunchList/src/apt/tutorial/FeedActivity.java


Cheers

Community
  • 1
  • 1
Sergey Benner
  • 4,421
  • 2
  • 22
  • 29
  • Shouldn't I have an entire task for the `LocationActivity` class? – mkyong Mar 01 '12 at 10:50
  • not really but still possible check here http://about-android.blogspot.com/2010/04/find-current-location-in-android-gps.html ... and here http://stackoverflow.com/questions/8253887/how-to-excute-asynctask-inside-onlocationchanged-method-in-android and check this one --- I guess its your perfect case ://stackoverflow.com/questions/7617957/should-i-create-service-for-gps-tracking-app – Sergey Benner Mar 01 '12 at 10:54
  • Also, since the send method is called every second, will this create a new task each time? – mkyong Mar 01 '12 at 10:56
  • The new task is created when you need it at any place read here http://stackoverflow.com/questions/6373826/execute-asynctask-several-times and more to that http://stackoverflow.com/questions/2711183/asynctask-threading-rule-can-it-really-only-be-used-once. You just call its execute(....) method with parameters at this point.You shouldn't care about its threads either. Read this post http://stackoverflow.com/questions/3077461/asynctask-threads-never-die-android – Sergey Benner Mar 01 '12 at 11:12
1

I think that a "GPS collector" is more suited to a Service.

Your service could look like:

import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Binder;
import android.os.Bundle;
import android.os.IBinder;

public class GPSCollectService extends Service implements LocationListener{
private LocationManager mLocationManager;

public class GPSBinder extends Binder {
    GPSCollectService getService() {
        return GPSCollectService.this;
    }
}

@Override
public IBinder onBind(Intent intent) {
    return mBinder;
}

private final IBinder mBinder = new GPSBinder();

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
    return START_STICKY;
}

@Override
public void onCreate() {
    startservice();
}

@Override
public void onDestroy(){
    mLocationManager.removeUpdates(this);
    mLocationManager = null;
}

private void startservice() {
    mLocationManager = (LocationManager)getSystemService(Context.LOCATION_SERVICE);
    mLocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 1000, 0, this);   
}

public void onLocationChanged(Location arg0) {
    if (arg0 != null){
        //Your database storing code here
        }
    }

public void onProviderDisabled(String arg0) {}
public void onProviderEnabled(String arg0) {}
public void onStatusChanged(String arg0, int arg1, Bundle arg2) {}
}

and in your main activity:

private Intent msvcGPSCollect = null;

@Override
public void onDestroy(){
    finishServices();

    super.onDestroy();
}

private void startBackgroundServices(){
    msvcGPSCollect = new Intent(this, GPSCollectService.class);
    startService(msvcGPSCollect);
}

private void finishServices(){
    if (msvcGPSCollect != null)
        stopService(msvcGPSCollect);
}

EDIT: I've not actually answered your question!

Where I've put:

\\ Your database storing code here

you'll need to call your own Async Task.

Example of an async task call:

PushGPSAsync myAsyncTask = new PushGPSAsync();
myAsyncTask.execute();

Example of an async task:

public class PushGPSAsync extends AsyncTask<Void, Void, Boolean>{
    @Override
    protected Boolean doInBackground(Void... params){
        pushGPS();
        return null;
    }

    @Override
    public void onPostExecute(Boolean result){
        //Call a post execute function here
    }
}

private boolean pushGPS(Void... params){
    //store the GPS
}
Adam
  • 456
  • 2
  • 10