2017-01-06 15 views
4

Я создаю приложение для Android, поддерживающее отслеживание друзей. Пока мой друг активировал приложение и ушел вместе со своими GPS и сотовыми данными, мне нужно отслеживать его на своем устройстве. Это концепция.Как я могу получить непрерывные обновления местоположения в android, как на Картах Google?

Я реализовал класс LocationListener, и теперь я могу получить последнее обновленное местоположение из Gps или Network, но не обновляется, если я не запустил Карты Google и не вернусь в свое приложение. После googling я узнал, что кеш местоположения обновляется только GMaps.!

  1. Есть ли альтернативный способ постоянного обновления местоположения?
  2. Что делать, если мне нужно получить местоположение после блокировки устройства без использования Wakelock?

Это мое местоположение класса слушателя:

package com.amazinginside; 

/** AMAZING LOCATION SUPPORT CLASS, Devoloped By SANGEETH NANDAKUMAR */ 

import android.app.AlertDialog; 
import android.app.Service; 
import android.content.Context; 
import android.content.DialogInterface; 
import android.content.Intent; 
import android.location.Location; 
import android.location.LocationListener; 
import android.location.LocationManager; 
import android.os.Bundle; 
import android.os.IBinder; 
import android.provider.Settings; 

public class AmazingLocation extends Service implements LocationListener 
{ 
    private final Context mContext; 
    boolean isGPSEnabled = false; 
    boolean isNetworkEnabled = false; 
    boolean canGetLocation = false; 

    Location location; 
    double latitude=0.0; 
    double longitude=0.0; 

    //MINIMUM DISTANCE FOR UPDATE (meters) 
    private static final long MIN_DISTANCE_CHANGE_FOR_UPDATES = 0; // 0 Meters 

    //MINIMUM TIME BETWEEN UPDATES 
    private static final long MIN_TIME_BW_UPDATES = 1000 * 0; // 0 Seconds 

    //LOCATION MANAGER 
    protected LocationManager locationManager; 

    //CONSTRUCTOR 
    public AmazingLocation(Context context) 
    { 
     this.mContext = context; 
     getLocation(); 
    } 

    //LOCATION PROVISION 
    public Location getLocation() 
    { 
     try 
     { 
      //GET LOCATION MANAGER 
      locationManager = (LocationManager) mContext.getSystemService(LOCATION_SERVICE); 
      //CHECK GPS STATE 
      isGPSEnabled = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER); 
      //CHECK NETWORK STATE 
      isNetworkEnabled = locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER); 

      if (!isGPSEnabled && !isNetworkEnabled) 
      { 
       //NO LOCATION PROVIDERS 
      } 
      else 
      { 
       this.canGetLocation = true; 

       /** GET LOCATION FROM NETWORK */ 
       //FIRST GET LOCATION FROM NETWORK 
       if (isNetworkEnabled) 
       { 
        //REQUEST LOCATION 
        locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, MIN_TIME_BW_UPDATES, MIN_DISTANCE_CHANGE_FOR_UPDATES, this); 
        if (locationManager != null) 
        { 
         //START WITH LAST KNOWN LOCATION 
         location = locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER); 
         //EXTRACT LOCATION 
         if (location != null) 
         { 
          latitude = location.getLatitude(); 
          longitude = location.getLongitude(); 
         } 
        } 
       } 

       /** GET LOCATION FROM GPS SENSOR */ 
       //THEN GET LOCATION FROM GPS 
       if (isGPSEnabled) 
       { 
        if (location == null) 
        { 
         //REQUEST GPS LOCATION 
         locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, MIN_TIME_BW_UPDATES, MIN_DISTANCE_CHANGE_FOR_UPDATES, this); 

         if (locationManager != null) 
         { 
          //EXTRACT LAST KNOWN LOCATION 
          location = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER); 
          //RETURN LOCATION 
          if (location != null) 
          { 
           latitude = location.getLatitude(); 
           longitude = location.getLongitude(); 
          } 
         } 
        } 
       } 
      } 

     } 
     catch (Exception e) 
     { 
      e.printStackTrace(); 
     } 

     return location; 
    } 

    //STOP GPS SENSOR 
    public void stopUsingGPS() 
    { 
     if(locationManager != null) 
     { 
      locationManager.removeUpdates(AmazingLocation.this); 
     } 
    } 

    //EXTRACT LATTITUDE 
    public double getLatitude() 
    { 
     if(location != null) 
     { 
      latitude = location.getLatitude(); 
     } 

     // return latitude 
     return latitude; 
    } 

    //EXTACT LONGITUDE 
    public double getLongitude() 
    { 
     if(location != null) 
     { 
      longitude = location.getLongitude(); 
     } 

     // return longitude 
     return longitude; 
    } 

    //CAN I GET THE LOCATION.? 
    public AmazingStatus canGetLocation() 
    { 
     AmazingStatus status=new AmazingStatus(); 
     if(this.canGetLocation) 
     { 
      status.setStatus(true); 
      status.setErrorcode(0); 
      status.setErrormsg("Task completed"); 
     } 
     else 
     { 
      status.setStatus(false); 
      status.setErrorcode(145); 
      status.setErrormsg("Please turn on GPS access manually"); 
     } 
     return status; 
    } 

    //SHOW LOCATION SETTINGS 
    public AmazingStatus showSettingsAlert() 
    { 
     final AmazingStatus status=new AmazingStatus(); 
     AlertDialog.Builder alertDialog = new AlertDialog.Builder(mContext); 
     alertDialog.setTitle("REQUIRES LOCATION ACCESS"); 
     alertDialog.setMessage("Please allow GPS access to this app"); 

     //POSSITIVE REPLY 
     alertDialog.setPositiveButton("Allow", new DialogInterface.OnClickListener() 
     { 
      public void onClick(DialogInterface dialog,int which) 
      { 
       Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS); 
       mContext.startActivity(intent); 
       status.setStatus(true); 
       status.setErrorcode(0); 
       status.setErrormsg("Task completed"); 
      } 
     }); 

     //NEGATIVE REPLY 
     alertDialog.setNegativeButton("Deny", new DialogInterface.OnClickListener() 
     { 
      public void onClick(DialogInterface dialog, int which) 
      { 
       status.setStatus(false); 
       status.setErrorcode(408); 
       status.setErrormsg("User denied permission"); 
       dialog.cancel(); 
      } 
     }); 

     // Showing Alert Message 
     alertDialog.show(); 
     return status; 
    } 

    //UNUSED OVERRIDE METHORDS... 
    @Override 
    public void onLocationChanged(Location location) 
    { 
     getLocation(); 
    } 

    @Override 
    public void onProviderDisabled(String provider) 
    { 
    } 

    @Override 
    public void onProviderEnabled(String provider) 
    { 
     getLocation(); 
    } 

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

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

} 

Это мой onCreate() метод:

@Override protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_main); 

    //CREATE A BUTTON HANDLER 
    Button start_btn=(Button)findViewById(R.id.start_location_streaming); 
    //ON BUTTON CLICK EVENT 
    start_btn.setOnClickListener(new View.OnClickListener() 
    { 
     @Override 
     public void onClick(View v) 
     { 
      //REPEAT A METHORD AT SPECIFIC INTERVALS 
      Timer myTimer = new Timer(); 
      myTimer.schedule(new TimerTask() 
      { 
       @Override 
       public void run() 
       { 
        TimerMethod(); 
       } 

      }, 0, 8000); 
     } 
    }); } 

Эти и другие методы:

private void TimerMethod() 
{ 
    //START METHORD 
    this.runOnUiThread(Timer_Tick); 
} 

//LOCATION REPORTING METHORD 
private Runnable Timer_Tick = new Runnable() 
{ 
    public void run() 
    { 
     Toast.makeText(MainActivity.this, "Current latitude : "+Double.toString(getLocation().latitude), Toast.LENGTH_SHORT).show(); 
     Toast.makeText(MainActivity.this, "Current longitude : "+Double.toString(getLocation().longitude), Toast.LENGTH_SHORT).show(); 
    } 
}; 

private LatLng getLocation() 
{ 
    //CREATE A LOCATION CLASS INSTANCE 
    AmazingLocation gps = new AmazingLocation(this); 
    //RETRIVE LOCATION 
    double latitude = gps.getLatitude(); 
    double longitude = gps.getLongitude(); 
    //RETURN LOCATION 
    LatLng loc=new LatLng(latitude,longitude); 
    return loc; 
} 

Теперь проблема есть, тост просто показывает ранее известное местоположение и n ot update, если я не открыл Карты Google и не вернулся.

Любая помощь будет отличной для меня.

+0

Hi Kannan .. Вы можете решить эту проблему? – ASN

+0

Это проблема с моими сервисами Google Play. Профилированное местоположение Провайдер работает – Kannan

ответ

15

Использование Плавленый поставщик место в Android установить интервал в том, что:

Для примера создать свою деятельность, как это:

public class LocationActivity extends Activity implements 
     LocationListener, 
     GoogleApiClient.ConnectionCallbacks, 
     GoogleApiClient.OnConnectionFailedListener { 

    private static final String TAG = "LocationActivity"; 
    private static final long INTERVAL = 1000 * 10; 
    private static final long FASTEST_INTERVAL = 1000 * 5; 
    Button btnFusedLocation; 
    TextView tvLocation; 
    LocationRequest mLocationRequest; 
    GoogleApiClient mGoogleApiClient; 
    Location mCurrentLocation; 
    String mLastUpdateTime; 

    protected void createLocationRequest() { 
     mLocationRequest = new LocationRequest(); 
     mLocationRequest.setInterval(INTERVAL); 
     mLocationRequest.setFastestInterval(FASTEST_INTERVAL); 
     mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY); 
    } 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     Log.d(TAG, "onCreate ..............................."); 
     //show error dialog if GoolglePlayServices not available 
     if (!isGooglePlayServicesAvailable()) { 
      finish(); 
     } 
     createLocationRequest(); 
     mGoogleApiClient = new GoogleApiClient.Builder(this) 
       .addApi(LocationServices.API) 
       .addConnectionCallbacks(this) 
       .addOnConnectionFailedListener(this) 
       .build(); 

     setContentView(R.layout.activity_main); 
     tvLocation = (TextView) findViewById(R.id.tvLocation); 

     btnFusedLocation = (Button) findViewById(R.id.btnShowLocation); 
     btnFusedLocation.setOnClickListener(new View.OnClickListener() { 
      @Override 
      public void onClick(View arg0) { 
       updateUI(); 
      } 
     }); 

    } 

    @Override 
    public void onStart() { 
     super.onStart(); 
     if (mGoogleApiClient.isConnected()) { 
      startLocationUpdates(); 
      Log.d(TAG, "Location update resumed ....................."); 
     } 
    } 

    @Override 
    public void onStop() { 
     super.onStop(); 
     Log.d(TAG, "onStop fired .............."); 
     mGoogleApiClient.disconnect(); 
     Log.d(TAG, "isConnected ...............: " + mGoogleApiClient.isConnected()); 
    } 

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

    @Override 
    public void onConnected(Bundle bundle) { 
     Log.d(TAG, "onConnected - isConnected ...............: " + mGoogleApiClient.isConnected()); 
     startLocationUpdates(); 
    } 

    protected void startLocationUpdates() { 
     PendingResult<Status> pendingResult = LocationServices.FusedLocationApi.requestLocationUpdates(
       mGoogleApiClient, mLocationRequest, this); 
     Log.d(TAG, "Location update started ..............: "); 
    } 

    @Override 
    public void onConnectionSuspended(int i) { 

    } 

    @Override 
    public void onConnectionFailed(ConnectionResult connectionResult) { 
     Log.d(TAG, "Connection failed: " + connectionResult.toString()); 
    } 

    @Override 
    public void onLocationChanged(Location location) { 
     Log.d(TAG, "Firing onLocationChanged.............................................."); 
     mCurrentLocation = location; 
     mLastUpdateTime = DateFormat.getTimeInstance().format(new Date()); 
     updateUI(); 
    } 

    private void updateUI() { 
     Log.d(TAG, "UI update initiated ............."); 
     if (null != mCurrentLocation) { 
      String lat = String.valueOf(mCurrentLocation.getLatitude()); 
      String lng = String.valueOf(mCurrentLocation.getLongitude()); 
      tvLocation.setText("At Time: " + mLastUpdateTime + "\n" + 
        "Latitude: " + lat + "\n" + 
        "Longitude: " + lng + "\n" + 
        "Accuracy: " + mCurrentLocation.getAccuracy() + "\n" + 
        "Provider: " + mCurrentLocation.getProvider()); 
     } else { 
      Log.d(TAG, "location is null ..............."); 
     } 
    } 

    @Override 
    protected void onPause() { 
     super.onPause(); 
     stopLocationUpdates(); 
    } 

    protected void stopLocationUpdates() { 
     LocationServices.FusedLocationApi.removeLocationUpdates(
       mGoogleApiClient, this); 
     Log.d(TAG, "Location update stopped ......................."); 
    } 

    @Override 
    public void onResume() { 
     super.onResume(); 
     if (mGoogleApiClient.isConnected()) { 
      startLocationUpdates(); 
      Log.d(TAG, "Location update resumed ....................."); 
     } 
    } 
} 

Google играть услуги, необходимые:

+0

Извините за слишком поздний ответ. К сожалению, мой SDK сервисов Google Play был нарушен, чтобы обеспечить поддержку провайдера Fused Location Provider. После долгого исследования я сделал это, и ваш код работает плавно. #Upvoted – Kannan

+0

Рабочее решение, отличное управление всем государством. Спасибо –

0

Вы должны использовать службы Android, а не приложение. Таким образом, вы сможете непрерывно запускать код в фоновом режиме, и вы получите местоположение, даже если приложение закрывается.

https://www.tutorialspoint.com/android/android_services.htm

+0

Благодарим вас за помощь. Если я не закрыл пользовательский интерфейс моего приложения, может ли этот LocationListner работать в фоновом режиме, не убивая ОС? Если да, то почему он не поддерживает координаты местоположения? – Kannan

+0

@ Каннан, да. Если приложение ui не закрыто, то LocalListener должен работать, не будучи убитым. Я думаю, что он не обновляется, потому что вам нужно включить gps, а затем запросить местоположение. Что делает Google Maps, так это то, что он включает gps и обновляет текущее местоположение, поэтому поэтому вы получаете обновленное местоположение при открытии G. Maps. – Technologuy

+0

Спасибо tec technologys, я попробовал с GPS и включен сервис передачи данных 4G. Мне нужен способ избавиться от ранее известного точного местоположения, чтобы постоянно обновлять контакты. Это происходит, только когда я запускаю Карты Google и вернусь. Только Google Maps может обновлять уловы местоположения. Мне нужно обновить в своем приложении – Kannan

0

Ваш код сломан. Вы используете вариант старой части кода с именем GPSTracker. Этот код ужасно разработан и полон ошибок, особенно он не знает разницы между включенным и фактически включенным провайдером. Проверьте http://gabesechansoftware.com/location-tracking/ для устранения всех проблем в этом коде и рабочих абстракций, которые я написал (ProviderLocationTracker и FallbackLocationTracker).

+0

Спасибо, мистер Габ. На самом деле я удивлен, потому что этот код был прерван. Позвольте мне проверить ссылку, которую вы предоставили. – Kannan

3

Я верю, а не изобретаю колесо, вы можете использовать одну из сторонних библиотек, которые легко реализовать, и в этом случае аккумулятор эффективен. Одна из найденных библиотек - SmartLocation. Вы можете добавить следующую зависимость в свой файл build.gradle (app), чтобы начать использовать библиотеку.

compile 'io.nlopez.smartlocation:library:3.2.9' 

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

В качестве примера вы можете попробовать использовать следующий код в своей деятельности.

Button start_btn=(Button)findViewById(R.id.start_location_streaming); 

Context context = start_btn.getContext(); 

Handler handler = new Handler(); 

start_btn.setOnClickListener(new View.OnClickListener() { 
    @Override 
    public void onClick(View v) { 
     SmartLocation.with(context).location().start(locationListener); 
    } 
}); 

OnLocationUpdatedListener locationListener = new OnLocationUpdatedListener({ 
    @Override 
    public void onLocationUpdated(Location location) { 
     double lat = location.getLatitude(); 
     double lng = location.getLongitude(); 
     handler.postDelayed(locationRunnable,8000); 
    } 
}); 

Runnable locationRunnable = new Runnable({ 
    @Override 
    public void run() { 
     SmartLocation.with(context).location().start(locationListener); 
    } 
}); 

Вы можете остановить отслеживание местоположения в OnStop() метод

@Override 
public void onStop() { 
    SmartLocation.with(context).location().stop(); 
    super.onStop(); 
} 

SmartLocation библиотека даст вам больше, чем то, что, как ожидается, просто попробовать, что один раз.

Примечание: Убедитесь, что ваше приложение имеет ACCESS_FINE_LOCATION и ACCESS_COARSE_LOCATION (оба) для получения точных результатов. Не забудьте спросить разрешения во время выполнения для Android 6.0 и выше.

+0

Спасибо, Хитеш. Я тоже считаю, что изобретать колесо не является разумным выбором. Позвольте мне попробовать эту библиотеку SmartLocation – Kannan

+0

Определенно. Но мне нужно заставить его работать, и тогда я сделаю отметку – Kannan

+0

, его лучший способ - лучший способ - и легкий - thanx allooooot –

 Смежные вопросы

  • Нет связанных вопросов^_^