屏幕关闭后无法接收LocationClient的位置更新

时间:2013-07-17 15:25:04

标签: android android-service android-maps-v2

我正在尝试编写一个在后台运行的简单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);
}
}

3 个答案:

答案 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)

我不确定你的问题在哪里。我用你的代码创建了一个项目,它似乎在这里按照需要工作。即使屏幕关闭,我也收到了更新。在任何情况下,这里都是我采取的步骤,也许你的问题不在服务中,而是在你如何启动它或其他地方:

  1. 我创建了一个带有单个主要活动的默认android项目。
  2. 我将您的代码包含在名为“LocationService”的单独文件中
  3. 我将google play服务库添加到项目中。
  4. 我在清单中添加了以下权限:

    &LT; uses-permission android:name =“android.permission.ACCESS_FINE_LOCATION”/&gt; &LT; uses-permission android:name =“android.permission.ACCESS_COARSE_LOCATION”/&gt;

  5. 并在应用程序标签中声明了服务:

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

    如果这不能解决您的问题:请包含其余代码。