Android: How to Periodically Send Location to a Server

Send Current Location to server periodically in android

Register an alarm using AlarmManager to wake up after 5min when user open the application first time. create a service(fetch location and update to server) to run when alarm notifies your application. After the service finished the work , register for an alarm again to wake up after 5min. by this way you can achieve your task.

ref

Android: How to periodically send location to a server

http://developer.android.com/reference/android/app/AlarmManager.html

http://developer.android.com/reference/android/app/Service.html

1st Edit - Adding code sample

Step 1 - Create alarm manager and register alarm

AlarmManager alarmMgr = (AlarmManager) getSystemService(Context.ALARM_SERVICE);

Intent intent = new Intent(Main.this, YourWakefulReceiver.class);
bool flag = (PendingIntent.getBroadcast(Main.this, 0,
intent, PendingIntent.FLAG_NO_CREATE)==null);
/*Register alarm if not registered already*/
if(flag){
PendingIntent alarmIntent = PendingIntent.getBroadcast(Main.this, 0,
intent, PendingIntent.FLAG_UPDATE_CURRENT);

// Create Calendar obj called calendar
Calendar calendar = Calendar.getInstance();

/* Setting alarm for every one hour from the current time.*/
int intervalTimeMillis = 1000 * 60 * 60; // 1 hour
alarmMgr.setRepeating(AlarmManager.RTC_WAKEUP,
calendar.getTimeInMillis(), intervalTimeMillis,
alarmIntent);
}

Step 2 - Create Receiver class

public class YourWakefulReceiver extends WakefulBroadcastReceiver {

@Override
public void onReceive(Context context, Intent intent) {
Intent service = new Intent(context, SimpleWakefulService.class);
startWakefulService(context, service);
}
}
}

Setp 3 - Create Service class

public class SimpleWakefulService extends IntentService {

private static String tagName = "YourService";

public SimpleWakefulService() {
super("YourService");
}

@Override
protected void onHandleIntent(Intent intent) {
// Start your location
LocationUtil.startLocationListener();
try {
// Wait for 10 seconds
Thread.sleep(1000*10);
} catch (InterruptedException e) {
}
//Stop location listener
LocationUtil.stopLocationListener();
// upload or save location
uploadGps();

SimpleWakefulReceiver.completeWakefulIntent(intent);
}

}

Step 4 - Register service and receiver

<service android:name="com.envision.ghari.services.SimpleWakefulService"></service>
<receiver android:name="com.envision.ghari.receivers.YourWakefulReceiver"></receiver>

Note : This code is to understand the implementation. It will not compile.

how to send location data (latitude, longitude) periodically to web server

you need to make a service for that if you want to send data continuous to the server even after your application is closed.

Here is how i made my service.

 public class FeatureService extends Service
{

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

@Override
public void onCreate()
{
// make your api call here and other implementations according to your requirement.
super.onCreate();

}

@Override
public void onDestroy()
{
// what you want when service is destroyed
}

Declare your service in Manifest

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">

<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".MainActivity"
android:screenOrientation="portrait">
<intent-filter>
<action android:name="android.intent.action.MAIN" />

<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>

<service
android:name="Your Serive"
android:enabled="true">
</service>
</application>

And Finally call your service like this in onCreate of your relevant activity.

Intent i= new Intent(this,FeatureService.class);
startService(i);

Android: How to periodically send location to a server

You need to create a separate class that is a subclass of the Service class.

Service Documentation

Your primary application should can call startService and stopService to start up the background process. Theres also some other useful calls in the context class to manage the service:

Context Documentation

Android periodically get location and post to server using Service


When the user reboots the device, How to start the service again without opening the app?

you can implement receiver registered in the manifest which have intent filter to catch the [RECEIVE_BOOT_COMPLETED][1] broadcast. this requires also to add user permission: android.permission.RECEIVE_BOOT_COMPLETED

see the example

Is there any native or third party library to handle this part?

there is the perfect third library called Google Play Services which is perfect for receiving location updates in background under all kind of available configurations. when requesting the right configuration (such accuracy/priority/interval) it's saving also lot's of battery. another great advantage - your app don't have to run at all in order to receive the location updates. instead, google play services will launch your service with the location object each time there will be update.

see the example and documentation for more info

note that either way you'll have to register to boot complete event as mentioned before, to re - register to location updates after boot complete.

How to send location of the device on server when needed

I would definitely suggest using Google Cloud Messaging here. This has the benefit that once a device runs your app, you can make it register against GCM and you can send them some message that would make them register their coordinates into your database.

This approach would need that you have to implement some server (for instance, a web server with PHP) and make the users communicate with it, so the flow would be:

  1. Your server sends a broadcast message to all registered devices telling them they have to register against the GCM service.

  2. The devices get the message, and you implement the BroadcastReceiver to get both latitude and longitude and send it to your remote server, say http://www.mysuperserver.com/getlonglat.php, via a POST request.

  3. Your server takes both parameters and you save them or do whatever you need.

If you want to follow this approach, this are the steps you have to follow:

  1. Go to https://console.developers.google.com. With your Google account, register a new project. This will provide you an API key and a Sender ID.

  2. You'll need to make the device register against your project in GCM. You can achieve this by importing Google Play Services within your project, and once done, do something alike to this:

    GoogleCloudMessaging gcm = GoogleCloudMessaging.getInstance(context);
    final String regid = gcm.register("YOUR_SENDER_ID");
  3. At this time, the GCM server already knows that this user has registered whithin your project and has given him a regid.

  4. The next step is informing your own remote server that the user has done so, and save somewhere the regid that it has been given, so you can later send them messages. So in the client side, make a HTTP POST request against your server sending that regid and process it with somethat like this:

    $regid = $_POST['regid'];

    if (($regId) && ($ipAddr))
    sql_query("INSERT INTO gcm_subscribers(regid) VALUES($regid')");
  5. Once done, you know who have already registered against your database. You can SELECT all the users and send them a signal to send you back their coordinates. In the following example, the parameters would be, firstly, an array of registration IDs and secondly the message to send (for instance, $messageData = "sendMeYourCoords!").

    function sendNotification($registrationIdsArray, $messageData) {
    $apiKey = "YOUR_API_KEY";

    $headers = array("Content-Type:" . "application/json", "Authorization:" . "key=" . $apiKey);
    $data = array(
    'data' => $messageData,
    'registration_ids' => $registrationIdsArray
    );

    $ch = curl_init();

    curl_setopt( $ch, CURLOPT_HTTPHEADER, $headers );
    curl_setopt( $ch, CURLOPT_URL, "https://android.googleapis.com/gcm/send" );
    curl_setopt( $ch, CURLOPT_SSL_VERIFYHOST, 0 );
    curl_setopt( $ch, CURLOPT_SSL_VERIFYPEER, 0 );
    curl_setopt( $ch, CURLOPT_RETURNTRANSFER, true );
    curl_setopt( $ch, CURLOPT_POSTFIELDS, json_encode($data) );

    $response = curl_exec($ch);
    curl_close($ch);

    return $response;
    }
  6. Once in your client, just process that GCM message and make another POST to another URL on your remote server and pass it the longitude and latitude. To process the messages I'm including a few links below.

And for getting the coordinates without GPS seems there aren't too much solutions, but there are some. This would be an example: How to get Latitute Longitude value without using GPS in Android?

More about this:

  • Reference on Google Cloud Messaging

  • Android Push Notifications using Google Cloud Messaging GCM - Android Example

  • Google Cloud Messaging using PHP

  • Connection between PHP (server) and Android (client) Using HTTP and JSON

  • Notificaciones Push Android: Google Cloud Messaging (GCM). Implementación Cliente (Nueva Versión) (spanish)

Service to send GPS coordinates to server

Use an AlarmManager that starts a service every X sec.

The service should include a class that implements a location listener.

Refer this tutorial link that will helps you to know about the service and time intervals.

And you simply get the coordinates within an activity from the service and send it to the server using Async task.

Hope it will helps you.



Related Topics



Leave a reply



Submit