1

I'm trying to make an Android service, which should be started on device boot. It should send position data to a mySQL database every 5 minutes, through a POST to a php web service.

it is supposed to send the following data:

regID = same regId it used to register to GCM
name = a user name
latitude = the current latitude
longitude = the current longitude

I've never done a service before, so I'm quite confused on the right way to do it.

I would appreciate if you could guide me towards the right direction.

this is what I've done so far:

package servicio;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;

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

import com.google.android.gcm.GCMRegistrar;

public class GeoService extends Service {

    LocationManager manejador;
    String proveedor;
    Location localizacion;
    LocationListener locListener;
    String latitud, longitud;
    final String regId = GCMRegistrar
            .getRegistrationId(getApplicationContext());

    // double latitud, longitud;

    @Override
    public void onCreate() {
        manejador = (LocationManager) getSystemService(LOCATION_SERVICE);

    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {

        Criteria req = new Criteria();
        req.setAccuracy(Criteria.ACCURACY_FINE);

        // Lista de proveedores por criterio
        proveedor = manejador.getBestProvider(req, false);
        localizacion = manejador.getLastKnownLocation(proveedor);

        // location listener
        locListener = new LocationListener() {

            @Override
            public void onLocationChanged(Location location) {
                latitud = String.valueOf(location.getLatitude());
                longitud = String.valueOf(location.getLongitude());

                Thread sendGpsPositionToDB = new Thread(new Runnable() {

                    @Override
                    public void run() {
                        String server = "http://www.grupobcn.es/aquacleanmessenger/";
                        String serverUrl = server + "addposicion.php";
                        List<NameValuePair> params = new ArrayList<NameValuePair>();
                        params.add(new BasicNameValuePair("iddevice", regId));
                        params.add(new BasicNameValuePair("latitud", latitud));
                        params.add(new BasicNameValuePair("longitud", longitud));

                        HttpClient httpclient = new DefaultHttpClient();
                        HttpPost httppost = new HttpPost(serverUrl);

                        try {
                            httppost.setEntity(new UrlEncodedFormEntity(params));
                            HttpResponse response = httpclient
                                    .execute(httppost);
                        } catch (IOException e) {
                        }
                    }

                });

                sendGpsPositionToDB.start();
            }

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

            }

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

            }

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

            }

        };

        manejador.requestLocationUpdates(LocationManager.GPS_PROVIDER, 300000,
                0, locListener);

        return START_STICKY;
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
    }

    @Override
    public IBinder onBind(Intent intencion) {
        return null;
    }

}
jacho981
  • 87
  • 1
  • 10

1 Answers1

1

You can achieve this by registering a broadcast receiver and defining the RECEIVE_BOOT_COMPLETED permission.

When users install the app, the OS will look at the manifest and register for auto startup. Anytime the device is booted, the OS will call your onReceive() so you can start your service there as follows:

In your manifest:

<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />

<service android:name=".GeoService" />

<receiver android:name="servicio.AutoStartGeo">  
    <intent-filter>  
        <action android:name="android.intent.action.BOOT_COMPLETED" />  
    </intent-filter>  
</receiver>

Define the AutoStartGeo Class:

public class AutoStartGeo extends BroadcastReceiver{

@Override
public void onReceive(Context context, Intent intent) {
      if (intent.getAction() != null){
    Intent startServiceIntent = new Intent(context, GeoService.class);
    context.startService(startServiceIntent);       
}
}

}

Not that this won't work if the app is installed on the SD card because the app won't be available after the android.intent.action.BOOT_COMPLETED event. You must inform users about this or force your app to be installed internally via: android:installLocation="internalOnly"

Also note that on Android 3.0 and later, users needs to have started the app at least once before the app can receive the android.intent.action.BOOT_COMPLETED event.

Nana Ghartey
  • 7,901
  • 1
  • 24
  • 26
  • Thx, thats great for the starting on boot issue. What about the service itself? Does the code i posted make any sense at all? Is it correct? – jacho981 Jun 03 '14 at 10:36
  • 1
    It makes sense. Use the alarm manager or timertask to schedule the REST calls every 5 minutes. Check here for more - http://stackoverflow.com/questions/10221996/how-do-i-repeat-a-method-every-10-minutes-after-a-button-press-and-end-it-on-ano – Nana Ghartey Jun 03 '14 at 15:30