服务未收到位置更新

时间:2015-03-06 06:36:04

标签: android android-service

我已实施后台服务以接收位置更新:

public class TestActivity extends Service implements LocationListener, GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener {
private static String TAG = TestActivity_backup.class.getName();
private final static int CONNECTION_FAILURE_RESOLUTION_REQUEST = 9000;

private LocationRequest mLocationRequest;    
GoogleApiClient mGoogleApiClient=null;


@Override
public void onCreate() {
    super.onCreate();
    if (!isGooglePlayServicesAvailable()) {
        stopSelf();
    }
    setContentView(R.layout.activity_test);

    // Create the LocationRequest object
    mLocationRequest = LocationRequest.create()
            .setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY)
            .setInterval(10000).setFastestInterval(5000).setSmallestDisplacement(20);        
    this.buildGoogleApiClient();

}

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
    this.destination = intent.getStringExtra("DESTINATION");
    LatLng latLng = intent.getParcelableExtra("LOCATION");
    this.location = new Location("");
    this.location.setLatitude(latLng.latitude);
    this.location.setLongitude(latLng.longitude);

    return START_NOT_STICKY;
}

@Override
public void onLocationChanged(Location location){
    Toast.makeText(TestActivity.this, "User location changed", Toast.LENGTH_SHORT).show();        
}

@Override
public void onConnected(Bundle bundle) {
    Toast.makeText(TestActivity.this, "Location  service connected", Toast.LENGTH_SHORT).show();        
}   


@Override
public IBinder onBind(Intent intent) {
    return null;
}

@Override
public void onDestroy() {
    super.onDestroy();
}

@Override
public void onConnectionSuspended(int i) {
    Log.i(TAG, "Location services suspended. Please reconnect.");
}

@Override
public void onConnectionFailed(ConnectionResult connectionResult) {
    //TODO
}

protected synchronized void buildGoogleApiClient() {
    mGoogleApiClient = new GoogleApiClient.Builder(this)
            .addConnectionCallbacks(this)
            .addOnConnectionFailedListener(this)
            .addApi(LocationServices.API)
            .build();
}


private boolean isGooglePlayServicesAvailable() {
    int status = GooglePlayServicesUtil.isGooglePlayServicesAvailable(this);
    if (ConnectionResult.SUCCESS == status) {
        return true;
    } else {
        //GooglePlayServicesUtil.getErrorDialog(status, this, 0).show();
        return false;
    }
}    

}

我已经实现了所有相关的方法.onCreate和onStartCommand被调用但是onConnec 永远不会调用ted和onLocationChanged。如果我为位置更新实现一个活动,那么它的工作正常。 我在这里缺少什么?

2 个答案:

答案 0 :(得分:1)

不要忘记添加权限ACCESS_FINE_LOCATIONACCESS_COARSE_LOCATION,具体取决于upon Accuracy

并使用此代码

public class LocationService extends Service {

    private LocationListener locationListener;

    @Override
    public IBinder onBind(final Intent intent) {
        return null;
    }

    @Override
    public int onStartCommand(final Intent intent, final int flags, final int startId) {
        super.onStartCommand(intent, flags, startId);
        return Service.START_STICKY;
    }

    @Override
    public void onCreate() {
        super.onCreate();
        final LocationManager locationManager = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE);
        this.locationListener = new MyLocationListener();
        locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 100, 0, this.locationListener);
    }

    private static class MyLocationListener implements LocationListener {

        @Override
        public void onLocationChanged(final Location location) {
        }

        @Override
        public void onProviderDisabled(final String provider) {
        }

        @Override
        public void onProviderEnabled(final String provider) {
        }

        @Override
        public void onStatusChanged(final String provider, final int status, final Bundle extras) {
        }

    }

}

答案 1 :(得分:0)

这是我的代码,对我有用!

不要忘记在mgoogleApiClient.connect()中添加onCreate() 然后看一下googleapiClient的onConnected方法 - 这里我用

创建了LocationRequest
LocationServices.FusedLocationApi.requestLocationUpdates(
                    googleApiClient, mLocationRequest, this);

然后进行测试我用了

 LocationServices.FusedLocationApi.getLastLocation(googleApiClient);

表示初始请求。

如果您正在使用模拟器,请不要忘记telnet localhost 5543(到您的模拟器),然后使用命令geo fix来设置初始位置。 您可以使用geofixing测试它到另一个位置,然后应该调用onLocationChanged Methode ...

 package com.pekam.androidservice;
    import java.text.DateFormat;
    import java.util.ArrayList;
    import java.util.Date;
    import java.util.Timer;
    import java.util.TimerTask;

    import com.google.android.gms.common.GooglePlayServicesUtil;
    import com.google.android.gms.location.LocationRequest;
    import com.google.android.gms.common.ConnectionResult;
    import com.google.android.gms.common.api.GoogleApiClient;
    import com.pekam.myandroidtheme.*;
    import android.app.Notification;
    import android.app.NotificationManager;
    import android.app.PendingIntent;
    import android.app.Service;
    import android.content.Intent;
    import android.location.Location;
    import android.os.Bundle;
    import android.os.Handler;
    import android.os.IBinder;
    import android.os.Message;
    import android.os.Messenger;
    import android.os.RemoteException;
    import android.util.Log;
    import android.widget.Toast;

    import com.google.android.gms.location.*;
    import com.google.android.gms.location.LocationListener;

    public class MyService  extends Service implements GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener,LocationListener  {

            private NotificationManager nm;
            private Timer timer = new Timer();
            private int counter = 0;
            private int incrementby = 1;
            private static boolean isRunning = false;
            private GoogleApiClient googleApiClient;
            private LocationRequest mLocationRequest = new LocationRequest();
            private String strLOG="LOG";


            ArrayList<Messenger> mClients = new ArrayList<Messenger>(); // Keeps track of all current registered clients.
            int mValue = 0; // Holds last value set by a client.
            static final int MSG_REGISTER_CLIENT = 1;
            static final int MSG_UNREGISTER_CLIENT = 2;
            static final int MSG_SET_INT_VALUE = 3;
            static final int MSG_SET_STRING_VALUE = 4;
            static final int MSG_SET_STRING_LOG =5;

            final Messenger mMessenger = new Messenger(new IncomingHandler()); // Target we publish for clients to send messages to IncomingHandler.


        // LocationRequest
        @Override
        public void onLocationChanged(Location location) {
            Location mCurrentLocation = location;
            sendLogMessageToUI("Last Known Loc" + mCurrentLocation.getLongitude() + mCurrentLocation.getLatitude());
        }


        //GoogleApiClient
        @Override
        public void onConnectionFailed(ConnectionResult bundle) {

        }

        @Override
        public void onConnected(Bundle bundle) {
            Log.i("onConnected", "GoogleApiClient" );
            try {
                Toast.makeText(this, "Location  service connected", Toast.LENGTH_SHORT).show();

                createLocationRequest();
                LocationServices.FusedLocationApi.requestLocationUpdates(
                        googleApiClient, mLocationRequest, this);
                LocationServices.FusedLocationApi.getLastLocation(googleApiClient);

            } catch (Throwable t) { //you should always ultimately catch all exceptions in timer tasks.
                Log.e("Google APi Connected", "Google APi Connected Failed.", t);
            }
        }

        @Override
        public void onConnectionSuspended(int i) {

        }

        //Service
            @Override
            public void onCreate() {
                super.onCreate();
                Log.i("MyService", "Service Started.");
                showNotification();
                timer.scheduleAtFixedRate(new TimerTask(){ public void run() {onTimerTick();}}, 0, 1900L);
                isRunning = true;


                try {
                    googleApiClient =  new GoogleApiClient.Builder(this)

                           .addApi(LocationServices.API)
                           .addConnectionCallbacks(this)
                           .addOnConnectionFailedListener(this)

                           .build();

                    googleApiClient.connect();

                } catch (Exception e) {
                    e.printStackTrace();
                } finally {
                }
            }
            @Override
            public int onStartCommand(Intent intent, int flags, int startId) {
                Log.i("MyService", "Received start id " + startId + ": " + intent);
                return START_STICKY; // run until explicitly stopped.
            }
            @Override
            public IBinder onBind(Intent intent) {
            return mMessenger.getBinder();
        }

        public static boolean isRunning()
            {
                return isRunning;
            }


        private void onTimerTick() {
                Log.i("TimerTick", "Timer doing work." + counter);
                try {
                    counter += incrementby;
                    sendMessageToUI(counter);
               //     LocationServices.FusedLocationApi.setMockMode(googleApiClient, true);
                  //  double latitude = LocationServices.FusedLocationApi.getLastLocation(googleApiClient).getLatitude();




                } catch (Throwable t) { //you should always ultimately catch all exceptions in timer tasks.
                    Log.e("TimerTick", "Timer Tick Failed.", t);            
                }
            }
        private boolean isGooglePlayServicesAvailable() {
            int status = GooglePlayServicesUtil.isGooglePlayServicesAvailable(this);
            if (ConnectionResult.SUCCESS == status) {
                return true;
            } else {
                //GooglePlayServicesUtil.getErrorDialog(status, this, 0).show();
                return false;
            }
        }
        private void showNotification() {
            nm = (NotificationManager)getSystemService(NOTIFICATION_SERVICE);
            // In this sample, we'll use the same text for the ticker and the expanded notification
            CharSequence text = getText(R.string.service_started);
            // Set the icon, scrolling text and timestamp
            Notification notification = new Notification(R.drawable.ic_launcher, text, System.currentTimeMillis());
            // The PendingIntent to launch our activity if the user selects this notification
            PendingIntent contentIntent = PendingIntent.getActivity(this, 0, new Intent(this, TabBarActivity.class), 0);
            // Set the info for the views that show in the notification panel.
            notification.setLatestEventInfo(this, getText(R.string.service_label), text, contentIntent);
            // Send the notification.
            // We use a layout id because it is a unique number.  We use it later to cancel.
            nm.notify(R.string.service_started, notification);
        }
        protected void createLocationRequest() {

            mLocationRequest.setInterval(10000);
            mLocationRequest.setFastestInterval(5000);
            mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
        }
        private void sendMessageToUI(int intvaluetosend) {
            for (int i=mClients.size()-1; i>=0; i--) {
                try {
                    // Send data as an Integer
                    mClients.get(i).send(Message.obtain(null, MSG_SET_INT_VALUE, intvaluetosend, 0));

                    //Send data as a String
                    Bundle b = new Bundle();
                    b.putString("str1", "ab" + intvaluetosend + "cd");
                    Message msg = Message.obtain(null, MSG_SET_STRING_VALUE);
                    msg.setData(b);
                    mClients.get(i).send(msg);

                } catch (RemoteException e) {
                    // The client is dead. Remove it from the list; we are going through the list from back to front so this is safe to do inside the loop.
                    mClients.remove(i);
                }
            }
        }
        private void sendLogMessageToUI(String strLOG) {
            for (int i=mClients.size()-1; i>=0; i--) {
                try {
                    // Send data as an Integer
                    mClients.get(i).send(Message.obtain());
                    //Send data as a String
                    Bundle b = new Bundle();
                    b.putString("strLOG", strLOG);
                    Message msg = Message.obtain(null, MSG_SET_STRING_LOG);
                    msg.setData(b);
                    mClients.get(i).send(msg);

                } catch (RemoteException e) {
                    // The client is dead. Remove it from the list; we are going through the list from back to front so this is safe to do inside the loop.
                    mClients.remove(i);
                }
            }
        }
        class IncomingHandler extends Handler { // Handler of incoming messages from clients.
            @Override
            public void handleMessage(Message msg) {
                switch (msg.what) {
                    case MSG_REGISTER_CLIENT:
                        mClients.add(msg.replyTo);
                        break;
                    case MSG_UNREGISTER_CLIENT:
                        mClients.remove(msg.replyTo);
                        break;
                    case MSG_SET_INT_VALUE:
                        incrementby = msg.arg1;
                        break;
                    default:
                        super.handleMessage(msg);
                }
            }
        }
        }