我正在尝试编写一个在后台运行的简单Android服务,并从LocationClient(Google Map API Android V2)接收位置更新。问题是,当屏幕关闭时,我的服务不再接收位置更新。我试图检查服务是否处于活动状态,即使关闭屏幕也是如此(它有一个TimerTask调度日志)。当屏幕打开时,我可以接收位置更新,但是当屏幕关闭时,我只看到TimerTask的日志,我没有收到任何位置更新。唤醒屏幕再次打开位置更新。怎么解决这个问题?
这是我的简单服务:
public class LocationService extends Service implements GooglePlayServicesClient.ConnectionCallbacks, GooglePlayServicesClient.OnConnectionFailedListener, LocationListener{
private static final String TAG = LocationService.class.getSimpleName();
private LocationClient mLocationClient;
private Timer timer;
private static final LocationRequest REQUEST = LocationRequest.create()
.setInterval(5*1000) // 5 seconds
.setFastestInterval(3*1000) // 3 seconds
.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
@Override
public void onCreate() {
Log.d(TAG, "Creating..");
mLocationClient = new LocationClient(this, this, this);
timer = new Timer();
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.d(TAG, "Starting..");
if(!mLocationClient.isConnected() || !mLocationClient.isConnecting()) {
Log.d(TAG, "Connecting location client..");
mLocationClient.connect();
}
timer.scheduleAtFixedRate(new TimerTask(){
@Override
public void run() {
Log.d(TAG, "TimerTask executing");
}}, 0, 3*1000);
return START_STICKY;
}
@Override
public void onConnectionFailed(ConnectionResult result) {
Log.d(TAG, "Connection failed..");
stopSelf();
}
@Override
public void onConnected(Bundle bundle) {
System.out.println("Connected ...");
mLocationClient.requestLocationUpdates(REQUEST, this);
}
@Override
public void onDisconnected() {
Log.d(TAG, "Disconnected..");
stopSelf();
}
@Override
public IBinder onBind(Intent arg0) {
throw new UnsupportedOperationException("Not yet implemented");
}
@Override
public void onLocationChanged(Location location) {
Log.d(TAG, "Received location update");
}
@Override
public void onDestroy() {
Log.d(TAG, "Destroying..");
timer.cancel();
mLocationClient.removeLocationUpdates(this);
}
}
答案 0 :(得分:1)
<强>更新: - 强>
首先,您需要在OnCreate()中定义LocationClient,它将调用您的onConnected()......
像这样定义你的locationClient ..
locationClient = new LocationClient(this, this, this);
locationClient.connect();
现在你的onConnected()..只需要像这样请求位置更新..
@Override
public void onConnectionFailed(ConnectionResult arg0) {
// TODO Auto-generated method stub
}
@Override
public void onConnected(Bundle arg0) {
src = locationClient.getLastLocation();
System.out.println("======================location 1==" + src);
LocationRequest lrequest = new LocationRequest();
lrequest.setInterval(0);
lrequest.setSmallestDisplacement(0);
lrequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
locationClient.requestLocationUpdates(lrequest, new LocationListener() {
@Override
public void onLocationChanged(Location arg0) {
System.out.println("======================location 1233==" +
arg0);
/*Toast.makeText(getApplicationContext(),
"Location is 12" + arg0.getLatitude(),
Toast.LENGTH_SHORT).show();*/
}
});
}
@Override
public void onDisconnected() {
// TODO Auto-generated method stub
}
*************** 在 ************
之前如果您主要关注的是持续更新您的位置..那么U可以使用下述内容。
使用此::(这将定期更新用户基于GPS的位置)
For OnCreate()::
----------------------
@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.speed);
initui();
lm = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
location = lm.getLastKnownLocation(LocationManager.GPS_PROVIDER);
provider = lm.isProviderEnabled(LocationManager.GPS_PROVIDER);
if(!provider){
String text = "ENABLE GPS TO ACCESS SPEEDO METER!";
Toast.makeText(Speedometer.this, text, Toast.LENGTH_LONG).show();
Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
startActivity(intent);
}
if (location != null) {
/*lat = (int) (location.getLatitude() * 1E6);
longi = (int)(location.getLongitude() * 1E6);*/
String text = "Got Coordinates";
Toast.makeText(Speedometer.this, text, Toast.LENGTH_SHORT).show();
}
//lm.requestLocationUpdates(LocationManager.GPS_PROVIDER, 1000, 2, this);
}
Now use onLocationChanged()
---------------------------
@Override
public void onLocationChanged(Location loc) {
// TODO Auto-generated method stub
float distance = 0;
//float prevDis = 0;
try{
if(prevLoc==null)
{
prevLoc = loc;
//Toast.makeText(MainActivity.this, "PrevLOC" + prevLoc, Toast.LENGTH_SHORT).show();
Log.i("Main Activity", "Prev LOC" + prevLoc);
}
else {
try{
Runtime r = Runtime.getRuntime();
r.gc();
}catch(Exception e){
e.printStackTrace();
}
// When prevLoc is not null
Log.i("Main Activity", "Prev LOC in new LOC BLAH BLAH BLAH" + prevLoc);
newLoc = loc;
//Toast.makeText(MainActivity.this, "NewLoc" + newLoc, Toast.LENGTH_SHORT).show();
Log.i("Main Activity", "New LOC" + newLoc);
distance = prevLoc.distanceTo(newLoc);
Log.i("Main Activity", "New DISTANCE DISTANCE DISTANCE DISTANCE DISTANCE DISTANCE " + distance);
distance = (float) (3.6*distance);
speed = distance;
prevLoc = newLoc;
Log.i("Main Activity", "New Coordinates set to PrevLoc" + prevLoc);
}
}catch(Exception e){
e.printStackTrace();
}
if(speed <= 160){
try
{
mView.calculateAngleOfDeviation(speed);
}
catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
}else
{
Toast.makeText(Speedometer.this, "CONTROL SPEED", Toast.LENGTH_SHORT).show();
}
}
You can also utilize same in your activity ::
-----------------------------------------------
@Override
public void onProviderDisabled(String provider) {
// TODO Auto-generated method stub
}
@Override
public void onProviderEnabled(String provider) {
// TODO Auto-generated method stub
}
@Override
public void onStatusChanged(String provider, int status, Bundle extras) {
// TODO Auto-generated method stub
}
@Override
protected void onPause() {
// TODO Auto-generated method stub
stopListening();
super.onPause();
}
private void stopListening() {
// TODO Auto-generated method stub
try{
if(lm != null){
lm.removeUpdates(this);
}else{
lm.removeUpdates(this);
}
}catch(Exception e){
e.printStackTrace();
}
}
@Override
protected void onResume() {
// TODO Auto-generated method stub
super.onResume();
startListening();
}
private void startListening() {
// TODO Auto-generated method stub
try{
lm.requestLocationUpdates(LocationManager.GPS_PROVIDER, 1000, 0, this);
}catch(Exception e){
e.printStackTrace();
}
}
@Override
protected void onDestroy() {
// TODO Auto-generated method stub
super.onDestroy();
lm.removeUpdates(Speedometer.this);
//System.exit(0);
finish();
}
Finally there's always a lot of way to do single thing.
Hope it helps...
Cheers!
答案 1 :(得分:1)
使用WakeLock
onStartCommand中的
wl = ((PowerManager)getSystemService(Context.POWER_SERVICE)).newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, yourTAG);
wl.acquire();
在onDestroy中
if (wl != null && wl.isHeld()) {
wl.release();
}
答案 2 :(得分:0)
我不确定你的问题在哪里。我用你的代码创建了一个项目,它似乎在这里按照需要工作。即使屏幕关闭,我也收到了更新。在任何情况下,这里都是我采取的步骤,也许你的问题不在服务中,而是在你如何启动它或其他地方:
我在清单中添加了以下权限:
&LT; uses-permission android:name =“android.permission.ACCESS_FINE_LOCATION”/&gt; &LT; uses-permission android:name =“android.permission.ACCESS_COARSE_LOCATION”/&gt;
并在应用程序标签中声明了服务:
<service
android:name=".LocationService"
android:process=":Location_Service_Test" />
最后我将以下内容添加到主要活动的onCreate中:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//Start the service
Intent service = new Intent(this, LocationService.class);
startService(service);
}
如果这不能解决您的问题:请包含其余代码。