2012-04-19 57 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

相關問題