2016-10-14 11 views
-1

Я понимаю, что этот вопрос задавался много раз, но я спрашиваю его сейчас, потому что ответы довольно старые (по сравнению с новым API).Получить текущее местоположение пользователя или последнее известное местоположение

Раньше я использовал диспетчер местоположений, но я нашел его очень ненадежным. Например, в моем приложении, используя getLastKnownLocation и/или текущее местоположение, оно мгновенно загрузится камерой в текущее местоположение пользователя. Но скажите, если бы я перевернул местоположение на своем устройстве прямо до того, как начал свое приложение, у него не было бы камеры в текущем местоположении пользователя, а скорее где-то рядом с Нигерой (по умолчанию, по-моему, по умолчанию).

Только если я использовал приложение Google Maps и указал его местоположение, или, если бы я подождал некоторое время, мое приложение загрузилось с местоположением пользователя в представлении (с помощью moveCamera).

Иногда это сработает, а иногда и нет. Но я хочу использовать Google Api Client или, возможно, что-то более плавное, чтобы найти местоположение пользователя.

Я хочу сделать это следующим образом:

1.) Если пользователь не имеет их расположение на, подсказывать им, чтобы включить его.

2.) После включения местоположения запустите камеру/просмотр Карты с текущим местоположением пользователя в центре.

3.) Наконец, если пользователь решает снять местоположение или переместиться из своего местоположения, не делайте абсолютно ничего.

Здесь я читал много вопросов, но не могу найти ничего, что могло бы помочь мне настроить эту функцию с помощью Google Api Client или чего-либо еще. Я пробовал почти все с помощью диспетчера местоположений, но я все еще не могу заставить его работать плавно. И из-за разочарования я удалил весь код моего менеджера местоположений.

Если вы хотите увидеть, что я записал или пытался, большинство из моих источников пришли от этого вопроса (и связанных с ними):

What is the simplest and most robust way to get the user's current location on Android?

Спасибо, что нашли время, чтобы прочитать это.

+1

посмотреть это поможет вам получить точное текущее местоположение. http://stackoverflow.com/questions/34305377/get-current-location-0-in-marshmallow-where-below-23-api-its-give-exact-current –

+0

Это отлично работает для меня. Большое вам спасибо @VishalThakkar. Вы спасатель жизни. – SaltySea

+0

У меня есть @VishalThakkar – SaltySea

ответ

0

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

На основе этих данных услуг вы можете

  1. Запрашивать, чтобы включить Местоположение
  2. После местоположения получена, карта может быть инициирована
  3. Если место отсоединен, берегите остальной логики

Важные моменты помнить обновления местоположения в том, что

  • Укажите минимальное изменение расстояния для получения обновлений setSmallestDisplacement (API получите обратно данные, даже если мы остаемся в одном месте в течение длительного времени без движения)
  • Set FastestInterval получить данные о местонахождении
  • Установить приоритет параметрsetPriority согласно вашему требованию

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

     private LocationRequest locationRequest; 
     private GoogleApiClient googleApiClient; 
     private Context appContext; 
     private boolean currentlyProcessingLocation = false; 
     private int mInterval=0; 
     private final int CONNTIMEOUT=50000; 
     private static final long MIN_DISTANCE_CHANGE_FOR_UPDATES = 10; // 10 meters 

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

    } 

    @Override 
    public int onStartCommand(Intent intent, int flags, int startId) { 
     appContext=getBaseContext(); 
     Toast.makeText(getBaseContext(), "Location Service Started", Toast.LENGTH_SHORT) 
       .show(); 
     if(intent != null){ 
      mInterval = intent.getIntExtra(Constants.REFRESHTIMETAG, 5); 
      mIMEI = intent.getStringExtra(Constants.IMEITAG); 
      Log.v(Constants.BLL_LOG, "AppLocationService onStartCommand , mInterval=" + mInterval + " | mIMEI=" + mIMEI); 
     } 
     if (!currentlyProcessingLocation) { 
      currentlyProcessingLocation = true; 
      startTracking(); 
     } 

     return START_STICKY; 
    } 

    private void startTracking() { 
     Log.v(Constants.BLL_LOG, "startTracking"); 
     if (GooglePlayServicesUtil.isGooglePlayServicesAvailable(this) == ConnectionResult.SUCCESS) { 
      Log.v(Constants.BLL_LOG, "ConnectionResult SUCCESS"); 
      googleApiClient = new GoogleApiClient.Builder(this) 
        .addApi(LocationServices.API) 
        .addConnectionCallbacks(this) 
        .addOnConnectionFailedListener(this) 
        .build(); 

      if (!googleApiClient.isConnected() || !googleApiClient.isConnecting()) { 
       googleApiClient.connect(); 
       Log.v(Constants.BLL_LOG, "googleApiClient.connect()"); 
      }else{ 
       Log.v(Constants.BLL_LOG, "NOT connected googleApiClient.connect()"); 
       // 
       //INTIMATE UI WITH EITHER HANDLER OR RUNONUI THREAD 
       // 
      } 
     } else { 
      Log.v(Constants.BLL_LOG, "unable to connect to google play services."); 
     } 
    } 

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

    @Override 
    public void onConnected(Bundle bundle) { 
     Log.v(Constants.BLL_LOG, "onConnected"); 
     locationRequest = LocationRequest.create(); 
     locationRequest.setInterval(mInterval * 1000); // milliseconds 
     locationRequest.setFastestInterval(mInterval * 1000); 
     locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY); 
     locationRequest.setSmallestDisplacement(MIN_DISTANCE_CHANGE_FOR_UPDATES);//distance change 
     int permissionCheck = ContextCompat.checkSelfPermission(appContext, Manifest.permission.ACCESS_COARSE_LOCATION); 
     if (permissionCheck!= PackageManager.PERMISSION_DENIED) 
     { LocationServices.FusedLocationApi.requestLocationUpdates(googleApiClient, locationRequest, this);} 

     Handler handler = new Handler(Looper.getMainLooper()); 
     handler.post(new Runnable() { 
      @Override 
      public void run() { 
       Toast.makeText(appContext, "Location Service got connected", Toast.LENGTH_SHORT) 
         .show(); 
      } 
     }); 
    } 

    @Override 
    public void onConnectionSuspended(int i) { 
     Log.v(Constants.BLL_LOG, "onConnectionSuspended"); 
     //INTIMATE UI ABOUT DISCONNECTION STATUS 
    } 

    @Override 
    public void onLocationChanged(Location location) { 
     Log.v(Constants.BLL_LOG, "onLocationChanged position: " + location.getLatitude() + ", " + location.getLongitude() + " accuracy: " + location.getAccuracy()); 
     //if (location.getAccuracy() < 500.0f) 
     Log.v(Constants.BLL_LOG, "onLocationChanged position: location.getAccuracy()= "+location.getAccuracy()); 

     //DO YOUR BUSINESS LOGIC, FOR ME THE SAME WAS TO SEND TO SERVER 
     sendLocationDataToWebsite(location);   

    } 

    @Override 
    public void onConnectionFailed(ConnectionResult connectionResult) { 
     Log.v(Constants.BLL_LOG, "onConnectionFailed"); 
     Handler handler = new Handler(Looper.getMainLooper()); 
     handler.post(new Runnable() { 
      @Override 
      public void run() { 
       Toast.makeText(appContext, "Location Service got disconnected temporarily", Toast.LENGTH_SHORT) 
         .show(); 
      } 
     }); 
    } 

    /** 
    * Send details to server 
    * @param location 
    */ 
    void sendLocationDataToWebsite(Location location){ 


    } 

    @Override 
    public void onDestroy() { 
     super.onDestroy(); 
     if (googleApiClient != null && googleApiClient.isConnected()) { 
      googleApiClient.disconnect(); 
     } 
     this.unregisterReceiver(this.batteryInfoReceiver); 
    } 
} 

Примечание: Эта услуга должна быть по-прежнему проходят в обновленной версии

+0

как вы используете эту услугу ... вам нужно добавить фильтр намерений в манифест или что-то в этом роде ... как вы получаете значения из другого вида деятельности? – Juan

+0

@Juan Это вне контекста, но я отправляю этот https://developer.android.com/guide/components/bound-services.html – Stallion

0

Менеджер местоположений прекрасно работает для меня, но для уровня API 23 вам необходимо сделать некоторые обходные пути. Для получения разрешения на уровне API 23 вам необходимо написать логику разрешения в основном потоке.

Это пример, который я использовал в одном из моих кодов.

/*Checking for permission if API level is more than 23 or 23, if condition match function calls*/ 
    if (Build.VERSION.SDK_INT >= 23) { 
     requestMultiplePermissions(); 
    } 

    /*Background Thread for splash screen with 2 seconds*/ 
    final Thread splashScreenThread = new Thread() { 

     public void run() { 

      try { 
       Thread.sleep(2000); 

      } catch (InterruptedException exception) { 
       exception.printStackTrace(); 
      } finally { 
       Intent homeScreen = new Intent(SplashScreen.this, MainActivity.class); 
       startActivity(homeScreen); 
       finish(); 

      } 
     } 
    }; 

    splashScreenThread.start(); 


} 

/*Standar Permission chcking code for API level 23 or more*/ 
private void requestMultiplePermissions() { 
    String locationPermission = Manifest.permission.ACCESS_FINE_LOCATION; 
    int hasLocPermission = checkSelfPermission(locationPermission); 
    List<String> permissions = new ArrayList<String>(); 
    if (hasLocPermission != PackageManager.PERMISSION_GRANTED) { 
     permissions.add(locationPermission); 
    } 

    if (!permissions.isEmpty()) { 
     String[] params = permissions.toArray(new String[permissions.size()]); 
     requestPermissions(params, 1); 
    } else { 
     // We already have permission, so handle as normal 

    } 

} 

/*This is function is used when permissions is granted by user, here we are firing a Intent after getting permission 
* */ 
@Override 
public void onRequestPermissionsResult(int requestCode, String[] permissions, 
             int[] grantResults) { 
    Toast.makeText(SplashScreen.this, " " + grantResults, Toast.LENGTH_SHORT).show(); 
    switch (requestCode) { 
     case 1: 
      if (grantResults[0] == PackageManager.PERMISSION_GRANTED) { 
       // Handle permission granted firing the Intent 
       Intent intent = new Intent(SplashScreen.this, MainActivity.class); 
       startActivity(intent); 
       finish(); 

      } else { 
       // Handle permission denied, giving Alertbox to user with some text 
       new AlertDialog.Builder(this) 
         .setMessage("The app cannot continue without permissions") 
         .setCancelable(false) 
         .setPositiveButton("Ok", new DialogInterface.OnClickListener() { 
          public void onClick(DialogInterface dialog, int id) { 
           SplashScreen.this.finish(); 
          } 
         }) 
         .show(); 


      } 
      break; 
     default: 
      super.onRequestPermissionsResult(requestCode, permissions, grantResults); 
    } 
    // 

Введите приведенный выше код в вашем Mainactivity или где вы хотите, то я предпочитаю, чтобы попросить разрешения, когда начинается приложение.

+0

, лучше спросить разрешения перед тем, как ваше приложение будет использовать его, чтобы пользователь понял в этот момент и зачем вам это нужно. Для меня это основная причина, по которой я не разрешаю разрешения, если не знаю, когда это используется –