Android定期GPS轮询服务,最大限度延长电池寿命
我正在尝试编写一项服务,它将每X分钟尝试获取设备的GPS位置,并在后台运行和录制,即使应用程序不在焦点位置 所以,是时候创建一个服务了 我创建了一个服务,设置了locationListener,获得了LocationManager和RequestLocationUpdate。。。世界上一切都好。。基本骨架工作 现在,我不希望GPS持续运行,因为这会耗尽电池,我希望发生的是服务,启动GPS,请求更新,然后关机(至少它对GPS位置感兴趣),然后5或10分钟后再这样做 很简单,在侦听器的onLocationChanged()方法上,我添加了行LocationManager(removeUpdates(locationListener))。。因此,当我的服务要求更新时,它只得到一个,然后关闭 我决定添加一个小while循环,有效地注册我的位置侦听器,并睡眠X分钟。所以从逻辑上讲,它应该注册它需要信息,然后再睡觉。。一个更新进来了,我在onLocationChange中得到了更新,它注销了它在事件中的权益,关闭GPS直到下一次执行循环 现在,我有两个问题1)从逻辑上看,这似乎可以吗?还是有更优雅的方式?请记住,我希望它记录启动应用程序是否处于焦点的信息,老实说,即使启动应用程序被终止,我也希望服务继续潜在运行,但这是我尚未完全做出的设计决策 第二个问题是,我需要将这个循环放在一个线程中,因为在oncreate中使用它会导致服务最终被终止,因为从oncreate返回要花很长时间,那么什么是最好的方法呢?AsyncTask是一个选项,但这是一个理论上永远无法完成的任务。。处理程序似乎也有点傻,因为没有真正的回调,它只是注册GPS更新,而不感兴趣的代码在LocationListener onLocationChange()中 一旦实例化,这个线程就不会产生真正的通信,尽管当服务将被某些用户交互关闭时,需要向其发出死亡/结束的信号Android定期GPS轮询服务,最大限度延长电池寿命,android,service,background,gps,Android,Service,Background,Gps,我正在尝试编写一项服务,它将每X分钟尝试获取设备的GPS位置,并在后台运行和录制,即使应用程序不在焦点位置 所以,是时候创建一个服务了 我创建了一个服务,设置了locationListener,获得了LocationManager和RequestLocationUpdate。。。世界上一切都好。。基本骨架工作 现在,我不希望GPS持续运行,因为这会耗尽电池,我希望发生的是服务,启动GPS,请求更新,然后关机(至少它对GPS位置感兴趣),然后5或10分钟后再这样做 很简单,在侦听器的onLocat
所以我应该只使用一个基本线程吗?即使任务永远不会回来,也要执行它?还是使用处理程序是更好的选择?还是我的模型只是一种完全不好的形式?我认为有一个服务来管理GPS是明智的做法,特别是如果你有一个以上的活动可能需要位置信息。我在我的应用程序中采用了这种方法 首先,我在服务中使用了一个
Ibinder
,并通过与的活动绑定到它
bindService (new Intent(....), mServconn, Context.BIND_AUTO_CREATE);
在onStart()中
和解除绑定服务(mServconn)每个活动的onStop()中的代码>
我在活动中注册了使用sendBroadcast()
到BroadcastReceivers
的服务。位置数据通过广播目的中的附加程序传递
我在服务中使用了一个状态机,它有三种状态:空闲状态、查找状态和正在睡眠状态。睡眠时间通过服务的公共方法中公开的“changeGPSParameters”方法传入。另一个参数是所需的准确度,即在得到比所需准确度更好的修正之前,不要广播消息,然后才能睡觉。睡眠意味着关闭GPS,直到时间过去
计时由Runnable管理,处理程序使用类似于
mHandler.postDelayed(this, mSleepTime );
我发现这很有效。当没有任何活动绑定到服务时,onUnbind()
将在服务中运行。在这种方法中,您只需确保使用mHandler.removeCallbacks停止位置侦听器并停止计时器
更新
下面是一个简单的Runnable示例,您可以通过main.xml中的两个按钮启动/停止Runnable,该按钮应有一个文本视图来显示计时器状态:
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; //seconds
private int mLoopCount = 0;
private Runnable mUpdateTimeTask = new Runnable() {
public void run() {
// Code here for when timer completes
mLoopCount++;
setTextBoxMsg("Running - count = " + mLoopCount);
mHandler.removeCallbacks(this);
mHandler.postDelayed(this, mSleepTime * 1000); // keep looping
}
};
@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);}
}
您可以对此进行调整,以便将其用于您的服务。Nick,谢谢您的输入。虽然我猜我的问题是服务中的实际可运行性,以及如何按照我的要求工作。一般的开始循环注册事件,在运行中睡眠,我准备一个循环器,创建监听器,然后我启动一个while(true)循环,为位置管理器设置条件,和请求更新;Looper.loop()和循环结束。依靠onLocationChange回调来注销我的兴趣,所有内容都将休眠,直到下一次触发。但我的代码似乎永远不会离开Looper.Loop()代码,直到我最终得到更新。内部while True循环在第一次回调之前按预期循环,但是在那之后,代码在while(True)循环结束时从未离开looper.Loop()调用,而while(True)循环正在驱动所有事情。老实说,我不完全确定为什么我甚至需要looper,因为我没有尝试或希望向循环发送消息,但是显然Android需要编译它,并且在我的while(true)循环结束时没有looper.loop(),对onLocationChanged的回调永远不会发生。。所以我需要它们。显然地但是现在我陷入了如何调用Looper.quit()的困境,当我的线程卡在Looper中时。loop()调用我认为我做错了什么。我将用一个基本的Runnable/handler示例编辑我的答案,您可以对其进行调整