2012-04-19 64 views
17

我正在编写一个Android应用程序,用于检索手机的当前位置并将其发送到网络服务器。 我希望能够按开始按钮并让应用程序以预定的时间间隔(比如每10分钟)继续检索并发送位置,然后在另一次按下按钮时停止。如何在按下按钮后每隔10分钟重复一次方法,并在另一个按钮上按下按钮结束它

这里是我的按钮代码:

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是获取位置,并将其发送的功能。

我知道使用AlarmManager可能会实现我想要的,但我一直无法理解它。是否有任何明确的步骤或模板可用于我的情况。

+1

我不明白,报警管理器是一个理想的方式来做到这一点....我使用报警管理器做同样的事情。服务会吃掉内存,我不特别喜欢线程,所以我选择了AlarmManager。你想让我在这里分享我的代码吗? – drulabs 2012-04-19 05:18:13

+0

我知道这将是理想的,只是我有很多实施它的问题。如果你不介意分享你的代码,那就太棒了。 – 2012-04-19 06:22:42

+0

@ X-Man - 我已经更新了有关使用AlarmManager/BroadcaseReceiver组合的详细信息。 – coderplus 2014-06-18 18:03:28

回答

35

创建BroadcastReceiver

public class AlarmReceiver extends BroadcastReceiver 
{ 

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

,并添加相同的,以你的AndroidManifest,使接收器注册

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

现在,您可以设置从Activity重复报警,将每一个调用接收器10分钟:

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取消报警,使用等效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); 

呼吁AlarmManagercancel()或者如果你不想使用AlarmManager/BroadcastReceiver,那么这样的事情会帮助你。你去为它之前,检查 - difference between timer and alarmmanager

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

初始化TimerTimer任务:

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

停止或启动Timer

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

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

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

+0

这工作但是有问题。当我按下执行'myTimer.scheduleAtFixedRate(myTimerTask,0,600000);'的开始按钮时,按停止/取消按钮,然后再次按下启动应用程序崩溃。 – 2012-04-20 03:40:57

+0

@coderplus:如果我从内存中杀死应用程序会怎么样?它会继续工作吗? – 2015-04-07 10:49:12

0

您可以启动一个服务来检查用户位置&将其发送到您指定的网址,如下所述。

你可以得到有关服务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

使用线程和处理器

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

对于开始通话

alarmCheckThread.start(); 

对于停止呼叫更多信息

alarmCheckThread.interrupt(); 
+1

'中断'已被弃用,以及如何阻止它? – zionpi 2015-05-15 09:35:53

3

这是我做的。

创建警报管理器对象第一,并设置重复的计时器

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 

创建基于这一意图名称的活动,将捕获的意图并执行它在指定的时间间隔的代码,你也可以创建一个广播接收器,如果你喜欢。

要取消它在您的按钮单击事件。写这个

alarmMgr.cancel(pendingAlarmIntent); 
+0

什么是'context'?它的价值是什么?对不起,编程新手。 – 2012-10-09 19:12:17

+2

上下文是有关应用程序环境的全局信息的接口。这是一个抽象类,其实现由Android系统提供。它允许访问特定于应用程序的资源和类,以及对应用程序级操作(如启动活动,广播和接收意图等)的上调。您可以在此处阅读更多内容(http://developer.android.com/ reference/android/content/Context.html)...如果你不了解上下文,那么你可能需要先通过一些android基础知识...... – drulabs 2012-10-22 02:41:40

+0

所以在代码中我可以使用上下文作为'this'对? – 2012-10-22 15:56:33

相关问题