1

Я новичок в Android и работаю над созданием приложения, которое отслеживает расстояние пользователей. Он только начинает отслеживать, когда пользователь нажимает кнопку и останавливается, когда снова нажимает. Кажется, что существует большая информация о путанице и методы, как это сделать, поэтому я, по крайней мере, имею общее представление о лучших практиках.Понимание того, как Service, LocationListener и BroadcastReceiver работают, чтобы получить местоположение в фоновом режиме

public class BackgroundLocationService extends Service implements GooglePlayServicesClient.ConnectionCallbacks, GooglePlayServicesClient.OnConnectionFailedListener, LocationListener { 

    IBinder mBinder = new LocalBinder(); 

    private LocationClient mLocationClient; 
    private LocationRequest mLocationRequest; 
    private boolean mInProgress; 

    //Milliseconds per second 
    private static final int MILLISECONDS_PER_SECOND = 1000; 
    // Update frequency in seconds 
    private static final int UPDATE_INTERVAL_IN_SECONDS = 30; 
    // Update frequency in milliseconds 
    public static final long UPDATE_INTERVAL = MILLISECONDS_PER_SECOND * UPDATE_INTERVAL_IN_SECONDS; 
    // The fastest update frequency, in seconds 
    private static final int FASTEST_INTERVAL_IN_SECONDS = 30; 
    // A fast frequency ceiling in milliseconds 
    public static final long FASTEST_INTERVAL = MILLISECONDS_PER_SECOND * FASTEST_INTERVAL_IN_SECONDS; 
    private static final int TWO_MINUTES = 1000 * 60 * 2; 

    public Location previousBestLocation = null; 

    private Boolean servicesAvailable = false; 

    public class LocalBinder extends Binder { 
    public BackgroundLocationService getServerInstance() { 
     return BackgroundLocationService.this; 
    } 
    } 

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

     mInProgress = false; 
     mLocationRequest = LocationRequest.create(); 
     mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY); 
     mLocationRequest.setInterval(UPDATE_INTERVAL); 
     mLocationRequest.setFastestInterval(FASTEST_INTERVAL); 

     // Check that Google Play Services are connected 
     servicesAvailable = servicesConnected(); 

     // Create the client 
     mLocationClient = new LocationClient(this, this, this); 

    }//end 

    private boolean servicesConnected() { 

     // Check that Google Play services is available 
     int resultCode = GooglePlayServicesUtil.isGooglePlayServicesAvailable(this); 

     // If Google Play services is available 
     if (ConnectionResult.SUCCESS == resultCode) { 
      return true; 
     } else { 
      return false; 
     } 

    }//end 

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

     super.onStartCommand(intent, flags, startId); 

     if(!servicesAvailable || mLocationClient.isConnected() || mInProgress) 
     return START_STICKY; 

     setUpLocationClientIfNeeded(); 
     if(!mLocationClient.isConnected() || !mLocationClient.isConnecting() && !mInProgress) { 
      mInProgress = true; 
      mLocationClient.connect(); 
     } 

     return START_STICKY; 
    }//end 


    private void setUpLocationClientIfNeeded() { 
    if (mLocationClient == null) 
      mLocationClient = new LocationClient(this, this, this); 
    } 


    @Override 
    public void onLocationChanged(Location location) { 

     String msg = Double.toString(location.getLatitude()) + "," +Double.toString(location.getLongitude()); 
     Toast.makeText(this, msg, Toast.LENGTH_SHORT).show(); 

    }//end 

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

    public String getTime() { 
    SimpleDateFormat mDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); 
    return mDateFormat.format(new Date()); 
    } 


    @Override 
    public void onDestroy(){ 
     // Turn off the request flag 
     mInProgress = false; 
     if(servicesAvailable && mLocationClient != null) { 
      mLocationClient.removeLocationUpdates(this); 
      // Destroy the current location client 
      mLocationClient = null; 
     } 
     // Display the connection status 
     Toast.makeText(this, DateFormat.getDateTimeInstance().format(new Date()) + ": Disconnected. Please re-connect.", Toast.LENGTH_SHORT).show(); 
     super.onDestroy(); 
    } 

    /* 
    * Called by Location Services when the request to connect the 
    * client finishes successfully. At this point, you can 
    * request the current location or start periodic updates 
    */ 
    @Override 
    public void onConnected(Bundle bundle) { 

     // Request location updates using static settings 
     mLocationClient.requestLocationUpdates(mLocationRequest, this); 

    } 

    /* 
    * Called by Location Services if the connection to the 
    * location client drops because of an error. 
    */ 
    @Override 
    public void onDisconnected() { 
     // Turn off the request flag 
     mInProgress = false; 
     // Destroy the current location client 
     mLocationClient = null; 
     // Display the connection status 
     Toast.makeText(this, DateFormat.getDateTimeInstance().format(new Date()) + ": Disconnected. Please re-connect.", Toast.LENGTH_SHORT).show(); 

    } 

    /* 
    * Called by Location Services if the attempt to 
    * Location Services fails. 
    */ 
    @Override 
    public void onConnectionFailed(ConnectionResult connectionResult) { 
    mInProgress = false; 

     /* 
     * Google Play services can resolve some errors it detects. 
     * If the error has a resolution, try sending an Intent to 
     * start a Google Play services activity that can resolve 
     * error. 
     */ 
     if (connectionResult.hasResolution()) { 

     // If no resolution is available, display an error dialog 
     } else { 

     } 
    } 

} 

Так на мои вопросы:

  • С моей главной Activity как я начинаю мою службу? Как остановить его?
  • Как мой класс Activity знает, когда мои Service получает Location обновлений, чтобы я мог обновить интерфейс?
  • Нужен ли мне BroadcastReceiver?
  • Что-нибудь нужно войти в мой Manifest?

ответ

2

Давайте ваши вопросы по порядку:

  1. http://www.androidhive.info/2012/07/android-gps-location-manager-tutorial/
  2. onLocationChanged (Место нахождения)
  3. нет, Гото 1
  4. Да, опять же, Гото 1

Редактировать: Отчет о возврате t о MainActivity

В вас MainActivity добавить интерфейс, как это:

public class MainActivity implements NewLocationsListener { 

    public interface NewLocationsListener { 

     public void onNewLocation(Location location); 
    } 

    private GPSTracker gps; 

    ... 

    // when your button is clicked or where ever you want to start gps 
    gps = new GPSTracker(this, this); 

    ... 

    // and get Locations in onNewLocation 
    public void onNewLocation(Location location) { 
     // location reported back from gps 
    } 

    // if you want gps to stop after exiting your app 
    @Override 
    protected void onPause() { 
     if (gps != null) { 
      gps.stopUsingGPS(); 
     } 
     super.onPause(); 
    } 

} 

И добавить к GPSTracker:

private NewLocationsListener mListener; 

public GPSTracker(Context context, NewLocationsListener listener) { 
    this.mContext = context; 
    this.mListener = listener; 
    getLocation(); 
} 


@Override 
public void onLocationChanged(Location location) { 
    // report back to MainActivity 
    mListener.onNewLocation(location); 
    canGetLocation = true; 
} 

edit2: Пример того, как обрабатывать выхода повторно вводить и изменения ориентации:

Поскольку вы, как вы говорите, новы для Android, я подумал, что могу добавить это.

public class StrategyActivity extends Activity { 

    public static final String TAG = "StrategyActivity"; 

    protected GPSTracker gps; 

    private Button startButton; 
    private boolean isStarted = false; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 

     startButton = (Button) findViewById(R.id.start_button); 

     if (savedInstanceState != null) { 
      isStarted = savedInstanceState.getBoolean("isStarted"); 
     } 
    } 


    @Override 
    protected void onResume() { 
     if (isStarted) { 
      startStrategy(); 
     } 
     updateOnOffButton(); 
     super.onResume(); 
    } 

    @Override 
    protected void onSaveInstanceState(Bundle outState) { 
     outState.putBoolean("isStarted", isStarted); 
     super.onSaveInstanceState(outState); 
    } 

    @Override 
    public void onBackPressed() { 
     if (isStarted) { 
      stopStrategy(); 
     } 
     super.onBackPressed(); 
    } 

    @Override 
    protected void onPause() { 
     if (isStarted) { 
      killStrategy(); 
     } 
     super.onPause(); 
    } 

    @Override 
    protected void onDestroy() { 
     killStrategy(); 
     super.onDestroy(); 
    } 

    public void startStopClicked(View view) { 
     if (isStarted) { 
      stopStrategy(); 
     } else { 
      startStrategy(); 
     } 
    } 

    private void updateOnOffButton() { 
     if (isStarted) { 
      startButton.setText("Stop"); 
     } else { 
      startButton.setText("Start"); 
     } 
    } 


    protected void killStrategy() { 
     if (gps != null) { 
      gps.stopUsingGPS(); 
     } 
    } 

    protected void startStrategy() { 
     isStarted = true; 
     gps = new GPSTracker(this); 
     updateOnOffButton(); 
     Toast.makeText(this, "Started", Toast.LENGTH_LONG).show(); 
    } 

    protected void stopStrategy() { 
     isStarted = false; 
     killStrategy(); 
     updateOnOffButton(); 
     Toast.makeText(this, "Stopped", Toast.LENGTH_LONG).show(); 
    } 
} 
+0

Хорошо, у меня есть работа и предоставление обновлений местоположения, даже когда я покидаю приложение. В моей «Деятельности» я начал свою службу, используя «startService» (новый Intent (this, BackgroundLocationService.class)). '. Все еще неясно, как моя «Сервис» может поговорить с моей основной «Деятельностью», чтобы сообщить об этом каждый раз, когда я получаю обновление местоположения. –

+0

, работающий на примере, скоро отчитается – cYrixmorten

+0

Я действительно работаю сейчас с «LocalBroadcastManager». Я могу отправить строку. Но теперь я борюсь с тем, как отправить объект «Местоположение». –