19

I am writing an Android app that retrieves the phone's current location and sends it too a webserver. I want to be able to press a start button and have the app continue to retrieve and send the location at a predetermined interval (say every 10 minutes) and then have it stop on another button press.

Here is the code for my buttons:

public void onCreate(Bundle savedInstanceState) {

    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

   startButton.setOnClickListener(new OnClickListener() {
    @Override
    //When the button is clicked
    public void onClick(View v) {
            finishButton.setEnabled(true);
            startButton.setEnabled(false);

            //Loops every 10mins
            pingCurrentLocation();

        }
    });

  finishButton.setOnClickListener(new OnClickListener() {
    @Override
    //When the button is clicked
    public void onClick(View v) {
            startButton.setEnabled(true);
            finishButton.setEnabled(false);

            pingCurrentLocation();

        }
    });  
}

pingCurrentLocation is the function that gets the location and sends it.

I know that using an AlarmManager would probably achieve what I want but I have been unable to make sense of any of it. Are there any clear steps or templates that will work in my situation.

X-Man
  • 193
  • 1
  • 1
  • 5
  • 1
    I don't get it, Alarm manager is an ideal way to do it.... I am doing the exact same thing using alarm manager. Service will eat up memory and I don't particularly like threads so I chose AlarmManager. Do you want me to share my code here ? – drulabs Apr 19 '12 at 05:18
  • I know it would be ideal its just that im having a lot of problems implementing it. If you wouldn't mind sharing your code that would be great. – X-Man Apr 19 '12 at 06:22
  • @X-Man - I have updated the answer with details on using an AlarmManager/BroadcaseReceiver combination. – coderplus Jun 18 '14 at 18:03

5 Answers5

39

Create a BroadcastReceiver

public class AlarmReceiver extends BroadcastReceiver
{   

 @Override
 public void onReceive(Context context, Intent intent)
  {   
    //get and send location information
  }
}

and add the same to your AndroidManifest so that the Receiver is registered

<receiver
    android:name="com.coderplus.AlarmReceiver"
    android:exported="false">
</receiver>

Now you can set a repeating alarm from your Activity which will invoke the receiver every 10 minutes:

AlarmManager alarmManager=(AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(context, AlarmReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, intent, 0);
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP,System.currentTimeMillis(),600000,
                                                                      pendingIntent);

and to cancel the alarm, call cancel() on the AlarmManager using an equivalent PendingIntent

AlarmManager alarmManager=(AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(context, AlarmReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, intent, 0);
alarmManager.cancel(pendingIntent);

or if you don't want to use AlarmManager / BroadcastReceiver, then something like this will help you out. Before you go for it, check - difference between timer and alarmmanager

private class MyTimerTask extends TimerTask {
    @Override
    public void run() {           
      //get and send location information 
    }
}

initialize the Timer and Timer task:

Timer myTimer = new Timer();
MyTimerTask myTimerTask= new MyTimerTask();

Stopping or starting the Timer

//to Stop
myTimer.cancel();
//to start
myTimer.scheduleAtFixedRate(myTimerTask, 0, 600000); //(timertask,delay,period)

Refer http://developer.android.com/reference/java/util/TimerTask.html

http://developer.android.com/reference/java/util/Timer.html

Community
  • 1
  • 1
coderplus
  • 5,793
  • 5
  • 34
  • 54
  • This works however there is a problem. When I press the start button which performs `myTimer.scheduleAtFixedRate(myTimerTask, 0, 600000);` and press the stop/cancel button it and then press start again the apps crashes. – X-Man Apr 20 '12 at 03:40
  • @coderplus: What if I kill the application from memory? Will it still work? – Bhargav Jhaveri Apr 07 '15 at 10:49
  • how you unregister the receiver here? – Priyanka Aug 28 '19 at 07:23
3

Use Android-TimerTask or Android-AlarmManager for sending location data to every 10 minutes. Look at this SO question Track Gps At every 10 minutes using timer in android also this one Good way of getting the user's location in Android

TimerTask:

The TimerTask class represents a task to run at a specified time. The task may be run once or repeatedly.

Community
  • 1
  • 1
user370305
  • 108,599
  • 23
  • 164
  • 151
3

Here is what I did.

created an alarm manager object first, and set the repeating timer

AlarmManager alarmMgr = alarmMgr=(AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
Intent alarmIntent = alarmIntent = new Intent("AlarmIntentReceiver"); 
PendingIntent pendingAlarmIntent = pendingAlarmIntent = PendingIntent.getBroadcast(context.getApplicationContext(), 0, alarmIntent, 0);
alarmMgr.setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP, 30*1000, 3*60*1000,  pendingAlarmIntent); //start in 30 secs and rest in 3 mins interval

Created an activity based on that intent name that will capture the intent and execute it's code in the interval specified, you can also create a broadcast receiver if you like.

To cancel it in your button click event. Write this

alarmMgr.cancel(pendingAlarmIntent);
drulabs
  • 3,071
  • 28
  • 35
  • What is the `context` ? What is its values? sorry im new to programming. – baTimá Oct 09 '12 at 19:12
  • 3
    Context is interface to global information about an application environment. This is an abstract class whose implementation is provided by the Android system. It allows access to application-specific resources and classes, as well as up-calls for application-level operations such as launching activities, broadcasting and receiving intents, etc. You can read more here (http://developer.android.com/reference/android/content/Context.html)... If you don't understand context then you probably need to go through some of android fundamentals first... – drulabs Oct 22 '12 at 02:41
0

You can start a service which will check for user location & send it to your specified web address as mentioned below.

you can get more information about service here

public class TaxiLocationUpdator extends Service{
    Location location;
    Timer timer = new Timer();
    private final Handler handler = new Handler();
    Intent intent;

    @Override
    public IBinder onBind(Intent arg0) {
        // TODO Auto-generated method stub
        return null;
    }

    public void  onCreate(){
        super.onCreate();
        updateNotification();
    }

    //int onStartCommand(Intent intent, int flags, int startId) 
    public void onStart(Intent intent,int startId){
        super.onStart(intent, startId);
        handler.removeCallbacks(sendUpdatesToUI);
            handler.postDelayed(sendUpdatesToUI, 1000); // 1 second
        Log.v("Location Servics", "Start Service");
    }

     private Runnable sendUpdatesToUI = new Runnable() {
            public void run() {
                DisplayLoggingInfo();           
                    handler.postDelayed(this, 15000); // 60 seconds here you can give your time
            }
        };    

    public void onDestroy(){
        super.onDestroy();
        Log.v("Location Servics", "Destroy Service");
    }

    public boolean isOnline(){
            ConnectivityManager cm = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
            NetworkInfo netInfo = cm.getActiveNetworkInfo();
            boolean isconnected;
            if (netInfo==null || !netInfo.isConnected())
            isconnected=false;
            else
            isconnected=true;
            Log.v("isOnliNe",isconnected+"");
            return isconnected;
        }

    protected void updateNotification() {
             LocationManager lm = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
             LocationListener locationListener = new MyLocationlistener();

             lm.requestLocationUpdates(LocationManager.GPS_PROVIDER, normallocationwait, 0.250f, locationListener);
             location = lm.getLastKnownLocation(LocationManager.GPS_PROVIDER);
       }

       private class MyLocationlistener implements LocationListener {

         public void onLocationChanged(Location location){
             if(location!=null){
                 if(location.hasAccuracy()){
                       dumpLocation(location);
                 }else{
                       dumpLocation(location);
                }
             } 
         }

         public void onProviderDisabled(String provider){
             Log.v("Loc Update","\nProvider disabled: " + provider);
         }

         public void onProviderEnabled(String provider){
             Log.v("Loc Update","\nProvider enabled: " + provider);
         }

         public void onStatusChanged(String provider, int status, Bundle extras){
             Log.v("Loc Update","\nProvider status changed: " + provider + ", status="
                        + status + ", extras=" + extras);
         }

         private void dumpLocation(Location location) {
                 if (location == null)
                        Log.v("Loc Update","\nLocation[unknown]");
                 else{
                         Log.v("Loc Update","\n" + location.toString());
                         Log.v("Demo", location.toString());
                                 String url  = Your url;
                         Toast.makeText(getBaseContext(), "Location Update", Toast.LENGTH_SHORT).show();
                         if(isOnline()){
                            HttpClient httpclient = new DefaultHttpClient();
                            HttpPost httppost = new HttpPost(url);
                            try {
                                HttpResponse response = httpclient.execute(httppost);
                                Log.v("Message", response.toString());
                              } catch (ClientProtocolException e) {
                                  Log.e("Sending Message",e.getMessage().toString());
                              } catch (IOException e) {
                                  Log.e("Sending Message",e.getMessage().toString());
                            }
                     }
                } 
          }

         public boolean isOnline(){
            ConnectivityManager cm = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
            NetworkInfo netInfo = cm.getActiveNetworkInfo();
            boolean isconnected;
            if (netInfo==null || !netInfo.isConnected())
            isconnected=false;
            else
            isconnected=true;
            Log.v("isOnliNe",isconnected+"");
            return isconnected;
         }
     }
}
Sandip Jadhav
  • 7,377
  • 8
  • 44
  • 76
0

Use a thread and a handler

   Handler alarmCheckHandler = new Handler() {

        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);

                System.out.println("getting message from alarm thread");
                //Call your function for ping



    };
Thread alarmCheckThread = new Thread() {
        public void run() {
            int i = 0;
            synchronized (this) {
                while (checkflag) {
                    i++;
                    try {
                        sleep(1000);
                    } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                    if (i == 600) {
                        alarmCheckHandler.sendMessage(alarmCheckHandler
                                .obtainMessage());
                        i = 0;
                    }

                }
                System.out.println("End of unlimited while loop reched");
            }
        }
    };

For start call

alarmCheckThread.start();

For stop call

alarmCheckThread.interrupt();
Zacharias Manuel
  • 8,983
  • 1
  • 17
  • 30