2012-04-19 11 views
17

Estoy escribiendo una aplicación de Android que recupera la ubicación actual del teléfono y lo envía también como servidor web. Quiero poder presionar un botón de inicio y hacer que la aplicación continúe recuperando y enviando la ubicación a un intervalo predeterminado (digamos cada 10 minutos) y luego hacer que se detenga en otro botón.¿Cómo repito un método cada 10 minutos después de presionar un botón y lo termino en otro botón? Oprima

Este es el código para mis botones:

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 es la función que obtiene la ubicación y lo envía.

Sé que el uso de un AlarmManager probablemente logre lo que quiero pero no he sido capaz de dar sentido a nada de eso. ¿Hay algún paso o plantilla clara que funcione en mi situación?

+1

No lo entiendo, el administrador de alarmas es una forma ideal de hacerlo ... Estoy haciendo exactamente lo mismo usando el administrador de alarmas. El servicio consumirá memoria y no me gustan especialmente los hilos, así que elegí AlarmManager. ¿Quieres que comparta mi código aquí? – drulabs

+0

Sé que sería ideal simplemente que estoy teniendo muchos problemas para implementarlo. Si no te importa compartir tu código, sería genial. –

+0

@ X-Man - He actualizado la respuesta con detalles sobre el uso de una combinación AlarmManager/BroadcaseReceiver. – coderplus

Respuesta

35

Crear un BroadcastReceiver

public class AlarmReceiver extends BroadcastReceiver 
{ 

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

y añadir la misma a su AndroidManifest para que el receptor se ha registrado

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

Ahora se puede establecer una alarma que se repite desde su Activity que invocará el receptor cada 10 minutos:

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); 

y para cancelar la alarma, llamar cancel() en el AlarmManager usando un equivalente 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); 

o si no desea utilizar AlarmManager/BroadcastReceiver, entonces algo como esto le ayudará a cabo.Antes de ir a por ello, check - difference between timer and alarmmanager

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

inicializar el Timer y Timer tarea:

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

Detener o comenzar la Timer

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

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

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

+0

Esto funciona sin embargo hay un problema. Cuando presiono el botón de inicio que realiza 'myTimer.scheduleAtFixedRate (myTimerTask, 0, 600000);' y presiono el botón parar/cancelarlo y luego presiono iniciar de nuevo, la aplicación falla. –

+0

@coderplus: ¿Qué pasa si elimino la aplicación de la memoria? ¿Seguirá funcionando? –

0

Puede iniciar un servicio que verificará la ubicación del usuario & y lo enviará a su dirección web especificada como se menciona a continuación.

se puede obtener más información sobre el servicio 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; 
     } 
    } 
} 
0

uso de un hilo y un controlador

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"); 
      } 
     } 
    }; 

Para iniciar llamada

alarmCheckThread.start(); 

Para llamadas parada

alarmCheckThread.interrupt(); 
+1

'interrupt' ha quedado en desuso y cómo detenerlo? – zionpi

3

Esto es lo que hice.

creado un objeto gestor de alarma en primer lugar, y ajustar el temporizador de repetición

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 

Creado una actividad basada en que el nombre de la intención que capturará la intención y ejecutar su código en el intervalo especificado, también se puede crear una receptor de difusión si quieres.

Para cancelarlo en su botón haga clic en evento. Escribe esto

alarmMgr.cancel(pendingAlarmIntent); 
+0

¿Qué es el 'contexto'? ¿Cuáles son sus valores? lo siento soy nuevo en programación. –

+2

El contexto es la interfaz a la información global sobre un entorno de aplicación. Esta es una clase abstracta cuya implementación es proporcionada por el sistema Android. Permite el acceso a clases y recursos específicos de la aplicación, así como también llamadas para operaciones de nivel de aplicación, como actividades de inicio, transmisión y recepción de intenciones, etc. Puede leer más aquí (http://developer.android.com/ reference/android/content/Context.html) ... Si no entiendes el contexto, entonces probablemente necesites revisar algunos de los fundamentos de Android primero ... – drulabs

+0

Así que en el código puedo usar el contexto como 'this' ¿derecho? –

Cuestiones relacionadas