7

我正在尝试编写一个在后台运行并从 LocationClient (Google Map API Android V2) 接收位置更新的简单 Android 服务。问题是当屏幕关闭时,我的服务不再接收位置更新。我试图检查服务是否处于活动状态,即使屏幕关闭也是如此(我有一个 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);
}
}
4

3 回答 3

2

使用唤醒锁

在 onStartCommand

wl = ((PowerManager)getSystemService(Context.POWER_SERVICE)).newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, yourTAG);
wl.acquire();

在 onDestroy

if (wl != null && wl.isHeld()) {
    wl.release();
}
于 2013-11-22T18:12:10.100 回答
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

    }

******************之前************

如果您主要关心的是不断发现您的位置更新..那么您可以使用下面提到的。

使用这个 ::(这将根据 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!
于 2013-11-01T07:53:40.360 回答
0

我不确定你的问题出在哪里。我用你的代码做了一个项目,它似乎在这里按预期工作。即使屏幕关闭,我也会收到更新。无论如何,这是我采取的步骤,也许您的问题不在于服务,而在于您如何启动它,或者其他地方:

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

    < uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> <use-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />

在应用程序标签中我声明了服务:

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

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

于 2013-10-30T16:21:53.143 回答