我认为有一个管理GPS的服务是明智的选择,特别是如果您有多个可能需要位置信息的活动。我在我的应用程序中采用了这种方法。
首先,我在服务中使用了一个 Ibinder
,并从活动中绑定到它。
bindService (new Intent(....), mServconn, Context.BIND_AUTO_CREATE);
在 onStart() 方法中:
而在每个 activity 的 onStop() 方法中使用 unbindService(mServconn);
。
我曾让服务通过 sendBroadcast()
向已注册的活动中的 BroadcastReceivers
发送广播。位置数据是通过广播意图中的额外信息传递的。
我在服务中使用了一个状态机,包含 3 种状态:IDLE、SEEKING 和 GOT_A_FIX_NOW_SLEEPING。睡眠时间通过服务的公共方法中的 'changeGPSParameters' 方法传递。另一个参数是所需的精度,即在获得更好的定位之前不要发送消息,然后就可以进入睡眠模式。睡眠模式意味着关闭 GPS 直到时间到达。
时间由一个 Runnable 管理,Handler 使用类似下面的代码向其发布消息:
mHandler.postDelayed(this, mSleepTime )
我觉得这个方法很好用。当没有任何活动与该服务绑定时,
onUnbind()
方法将在服务中运行。在那个方法中,您只需确保停止位置监听器并使用
mHandler.removeCallbacks
停止计时器即可。
更新:
下面是一个简单的示例,您可以通过 main.xml 中的两个按钮来启动/停止它,main.xml 应该有一个单独的文本视图来显示计时器状态:
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.view.View;
import android.widget.TextView;
public class TimerLoopActivity extends Activity {
private Handler mHandler = new Handler();
private int mSleepTime = 2;
private int mLoopCount = 0;
private Runnable mUpdateTimeTask = new Runnable() {
public void run() {
mLoopCount++;
setTextBoxMsg("Running - count = " + mLoopCount);
mHandler.removeCallbacks(this);
mHandler.postDelayed(this, mSleepTime * 1000);
}
};
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
setTextBoxMsg("Timer Idle");
}
private void setTextBoxMsg(String string) {
TextView tv = (TextView) findViewById(R.id.textView1);
tv.setText(string);
}
public void myClickHandler(View target) {
switch (target.getId()) {
case R.id.startbutton:
setTextBoxMsg("Starting timer");
startTimer();
break;
case R.id.stopbutton:
setTextBoxMsg("Stopping timer");
mLoopCount = 0;
stopTimer();
break;
}
}
private void stopTimer() { mHandler.removeCallbacks(mUpdateTimeTask); }
private void startTimer() { mHandler.postDelayed(mUpdateTimeTask, mSleepTime * 1000);}
}
您可以将此适应到您的服务中。