【问题标题】:Service not receiving location updates服务未收到位置更新
【发布时间】:2015-12-11 08:37:13
【问题描述】:

我已经实现了一个后台服务来接收位置更新:

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 永远不会被调用。如果我为位置更新实施一个活动,那么它工作正常。 我在这里错过了什么?

【问题讨论】:

  • 嗨,我已经在我的帖子中添加了代码。
  • 假设您正在使用适当的权限和<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>,并正确启动服务,只需尝试将 Log 放入您的服务方法而不是 Toast。服务只是不显示吐司,因为您不在 UI 线程上。
  • 我删除了 toast 并添加了日志...但没有成功。
  • 我猜你必须在 onCreate() 中添加 mgoogleApiClient.connect()
  • Right Kamokaze .... 不见了。现在可以正常工作了。非常感谢。

标签: android android-service


【解决方案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) {
        }

    }

}

【讨论】:

    【解决方案2】:

    这是对我有用的代码!

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

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

    然后我使用了测试

     LocationServices.FusedLocationApi.getLastLocation(googleApiClient);
    

    对于初始请求。

    如果您使用的是模拟器,请不要忘记远程登录 localhost 5543(到您的模拟器),然后使用命令 geo fix 来设置初始位置。 您可以通过地理定位到另一个位置对其进行测试,然后应该调用 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);
                    }
                }
            }
            }
    

    【讨论】:

      猜你喜欢
      • 2011-10-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-05-04
      • 2017-12-02
      • 2017-01-24
      相关资源
      最近更新 更多