2015-06-24 3 views
1

Это своего рода репос, и я сожалею об этом, но в последний раз, когда я разместил его, я думал, что получил его, но, видимо, нет. Когда я попытался вызвать службу, которую я использую, чтобы получить эту ошибку, вызванную: java.lang.IllegalStateException: GoogleApiClient is not connected yet. Потому что я пытался вызвать LocationServices до того, как GoogleApiClient был даже подключен. Поэтому, немного изменив код, я больше не получал ошибку, на самом деле я больше ничего не получал в logcat. Это, как я начинаю свою службу от SearchActivity.class:Получение вызова из Activity, но ничего не получается в logcat?

SearchActivity.class

button = (Button)findViewById(R.id.buttonPressed); 
    button.setOnClickListener(new View.OnClickListener() { 
     @Override 
     public void onClick(View v) { 
      startService(new Intent(getBaseContext(), LocationService.class)); 

     } 
    }); 

Это служба:

LocationService.class

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

    // LogCat tag 
    private static final String TAG = LocationService.class.getSimpleName(); 

    private final static int PLAY_SERVICES_RESOLUTION_REQUEST = 1000; 

    private Location mLastLocation; 

    // Google client to interact with Google API 
    private GoogleApiClient mGoogleApiClient; 

    // boolean flag to toggle periodic location updates 
    private boolean mRequestingLocationUpdates = false; 

    private LocationRequest mLocationRequest; 

    // Location updates intervals in sec 
    private static int UPDATE_INTERVAL = 10000; // 10 sec 
    private static int FATEST_INTERVAL = 5000; // 5 sec 
    private static int DISPLACEMENT = 10; // 10 meters 


    @Override 
    public void onCreate() { 
     super.onCreate(); 

     mGoogleApiClient = new GoogleApiClient.Builder(this) 
       .addConnectionCallbacks(this) 
       .addOnConnectionFailedListener(this) 
       .addApi(LocationServices.API).build(); 


    } 

    @Override 
    public int onStartCommand(Intent intent, int flags, int startId) { 

     if (mGoogleApiClient != null) { 
      if(mGoogleApiClient.isConnected()) { 
       if (mLocationRequest != null) { 
        togglePeriodicLocationUpdates(); 
       } 
      } 
     } 



     return START_NOT_STICKY; 
    } 

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

    protected void createLocationRequest() { 
     mLocationRequest = new LocationRequest(); 
     mLocationRequest.setInterval(UPDATE_INTERVAL); 
     mLocationRequest.setFastestInterval(FATEST_INTERVAL); 
     mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY); 
     mLocationRequest.setSmallestDisplacement(DISPLACEMENT); 
    } 

    private void togglePeriodicLocationUpdates() { 
     mGoogleApiClient.connect(); 
     if(mGoogleApiClient.isConnected()) { 
      if (!mRequestingLocationUpdates) { 

       mRequestingLocationUpdates = true; 

       startLocationUpdates(); 

       Log.d(TAG, "Periodic location updates started!"); 

      } else { 

       mRequestingLocationUpdates = false; 

       // Stopping the location updates 
       stopLocationUpdates(); 

       Log.d(TAG, "Periodic location updates stopped!"); 
      } 
     } 
    } 

    protected void stopLocationUpdates() { 
     LocationServices.FusedLocationApi.removeLocationUpdates(
       mGoogleApiClient, this); 
    } 

    protected void startLocationUpdates() { 
     mGoogleApiClient.connect(); 
     if(mGoogleApiClient.isConnected()) { 
      LocationServices.FusedLocationApi.requestLocationUpdates(
        mGoogleApiClient, mLocationRequest, this); 
     } 
    } 

    @Override 
    public void onConnected(Bundle arg0) { 
     createLocationRequest(); 
    } 

    @Override 
    public void onConnectionSuspended(int arg0) { 
     mGoogleApiClient.connect(); 
    } 

    @Override 
    public void onConnectionFailed(ConnectionResult result) { 
     Log.i(TAG, "Connection failed: ConnectionResult.getErrorCode() = " 
       + result.getErrorCode()); 
    } 

@Override 
public void onLocationChanged(Location location) { 
    // Assign the new location 
    mLastLocation = location; 

    Toast.makeText(getApplicationContext(), "Location changed!", 
      Toast.LENGTH_SHORT).show(); 
} 

@Override 
public boolean stopService(Intent name) { 
    return super.stopService(name); 
} 

AndroidManifest.xml

</activity> 
    <service android:name=".LocationService"> 
    </service> 

Edit:

Ну, я понял, как заставить его работать. Но теперь я столкнулся с проблемой нажатия кнопки 2 раза, прежде чем она начнется нормально. Только пришлось немного изменить onStartCommand().

@Override 
    public int onStartCommand(Intent intent, int flags, int startId) { 

     if (mGoogleApiClient != null) { 
      mGoogleApiClient.connect(); 
      if(mGoogleApiClient.isConnected()) { 

       if (mLocationRequest != null) { 

        togglePeriodicLocationUpdates(); 
       } 
      } 
     } 



     return START_NOT_STICKY; 
    } 
+0

Какой журнал вы ожидаете увидеть в logcat? И почему бы вам не попробовать отладки, чтобы узнать, как это работает? – helleye

+0

Ну, для начала этот 'Log.d (TAG,« Периодические обновления местоположения начались! »); 'и' Log.i (TAG, "Connection failed: ConnectionResult.getErrorCode() =" + result.getErrorCode()); ' – Ivan

+0

Когда ваш код вызывает connect() для подключения к GoogleApi LocationServices, происходит обработка соединения * * асинхронно **. Когда поток выполнения возвращается из вашего вызова connect(), у вас еще нет подключаемого соединения. Если соединение успешно установлено, вызывается обратный вызов onConnected(). Только в этот момент у вас есть полезный mGoogleApiClient. Вы должны посмотреть на некоторые из [доступной документации] (https://developers.google.com/android/guides/api-client#HandlingFailures), чтобы лучше понять эту обработку. Это несколько сложно. –

ответ

0

Вы должны прочитать документацию по GoogleApiClient, в частности (для рассматриваемого вопроса) connect() method. Я выделил соответствующую часть:

Соединяет клиента с сервисами Google Play. Этот метод немедленно возвращает и подключается к службе в фоновом режиме. Если соединение выполнено успешно, вызывается onConnected (Bundle) и помещается в очередь . При сбое вызывается onConnectionFailed (ConnectionResult) .

Если клиент уже подключен или подключен, этот метод делает ничего.

Итак, это то, что в настоящее время происходит с вашим кодом:

  1. Вы нажимаете на кнопку, чтобы запустить службу.
  2. Вы создаете GoogleApiClient в onCreate().
  3. Вы вызываете connect() в onStartCommand, который немедленно возвращается, когда соединение происходит в фоновом режиме.
  4. Вы проверяете isConnected(), однако, поскольку соединение все еще продолжается, вы ничего не делаете и не возвращаетесь из onStartCommand.
  5. Позже вы нажмете кнопку запуска службы снова.
  6. Как уже было создано, он переходит непосредственно к onStartCommand.
  7. К этому моменту GoogleApiClient подключен, поэтому все остальное работает так, как ожидалось.

Что вам нужно сделать, это реализовать onConnected(). Оттуда вызовите togglePeriodicLocationUpdates() вместо этого в onStartCommand(). Это выполнит то, что вы хотите:

  1. Нажмите, чтобы начать сервис.
  2. Служба создает GoogleApiClient в onCreate().
  3. Служба инициирует соединение в onStartCommand().
  4. Когда-нибудь в будущем будет установлено соединение и вызовы службы togglePeriodicLocationUpdates() из onConnected().
Смежные вопросы