【问题标题】:Update location in background and check LocationSettings在后台更新位置并检查 LocationSettings
【发布时间】:2016-04-13 12:03:21
【问题描述】:

我想在后台每隔几分钟更新一次用户的位置。
我使用了这个示例代码googlesamples/android-play-location
但将其更改为与Service一起使用

public class MyService extends Service implements
        GoogleApiClient.ConnectionCallbacks,
        GoogleApiClient.OnConnectionFailedListener,
        LocationListener, ResultCallback<LocationSettingsResult>

但我无法检查位置设置

    protected void checkLocationSettings() {
        PendingResult<LocationSettingsResult> result =
                LocationServices.SettingsApi.checkLocationSettings(
                        mGoogleApiClient,
                        mLocationSettingsRequest
                );
        result.setResultCallback(this);
    }

    @Override
    public void onResult(LocationSettingsResult locationSettingsResult) {
        final Status status = locationSettingsResult.getStatus();
        switch (status.getStatusCode()) {
            case LocationSettingsStatusCodes.SUCCESS:
                Log.i(TAG, "All location settings are satisfied.");
                startLocationUpdates();
                break;
            case LocationSettingsStatusCodes.RESOLUTION_REQUIRED:
                Log.i(TAG, "Location settings are not satisfied. Show the user a dialog to" +
                        "upgrade location settings ");

                try {
                    // Show the dialog by calling startResolutionForResult(), and check the result
                    // in onActivityResult().
                    status.startResolutionForResult(MainActivity.this, REQUEST_CHECK_SETTINGS);
                } catch (IntentSender.SendIntentException e) {
                    Log.i(TAG, "PendingIntent unable to execute request.");
                }
                break;
            case LocationSettingsStatusCodes.SETTINGS_CHANGE_UNAVAILABLE:
                Log.i(TAG, "Location settings are inadequate, and cannot be fixed here. Dialog " +
                        "not created.");
                break;
        }
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        switch (requestCode) {
            // Check for the integer request code originally supplied to startResolutionForResult().
            case REQUEST_CHECK_SETTINGS:
                switch (resultCode) {
                    case Activity.RESULT_OK:
                        Log.i(TAG, "User agreed to make required location settings changes.");
                        startLocationUpdates();
                        break;
                    case Activity.RESULT_CANCELED:
                        Log.i(TAG, "User chose not to make required location settings changes.");
                        break;
                }
                break;
        }
    }

因为这个方法需要Activity

status.startResolutionForResult(MainActivity.this, REQUEST_CHECK_SETTINGS);

如果我将之前的代码放在 MainActvity 中,我将没有对 mGoogleApiClient 和 mLocationSettingsRequest 的引用

LocationServices.SettingsApi.checkLocationSettings(mGoogleApiClient, mLLocationSettingsRequest);

即使活动被破坏,我也想升级并在后台保存位置。
使用该服务的正确方法是这样做的吗?
我如何检查位置设置?

[编辑]
我尝试使用PendingIntentIntentService

LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient,
                    mLocationRequest, mPendingIntent);

此方法适用于后台用例,更具体地说 用于接收位置更新,即使应用程序已被 系统。

ServiceLocationListner的版本相比有什么不同?

【问题讨论】:

    标签: java android service location fusedlocationproviderapi


    【解决方案1】:

    [解决方案]
    我找到了解决问题的方法。
    要访问主要活动,我使用了方法

    MainActivity.getInstance()

    MainActivity

    public class MainActivity extends AppCompatActivity {
        private static MainActivity instance;
    
        public static MainActivity getInstance() {
            Log.i("MainActivity", "getInstance");
            return instance;
        }
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            Log.i(TAG, "onCreate");
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            // Instance of the MainActivity
            instance = this;
        }
        ...
    
        @Override
        protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        Log.i(TAG, "onActivityResult");
        switch (requestCode) {
            // Check for the integer request code originally supplied to startResolutionForResult().
            case REQUEST_CHECK_SETTINGS:
                switch (resultCode) {
                    case Activity.RESULT_OK:
                        Log.i(TAG, "User agreed to make required location settings changes.");
                        startService(intent);
                        break;
                    case Activity.RESULT_CANCELED:
                        Log.i(TAG, "User chose not to make required location settings changes.");
                        break;
                }
                break;
            }
        }
    }
    

    服务

    @Override
    public void onResult(LocationSettingsResult locationSettingsResult) {
        final Status status = locationSettingsResult.getStatus();
        switch (status.getStatusCode()) {
            case LocationSettingsStatusCodes.SUCCESS:
                // All location settings are satisfied. The client can
                // initialize location requests here.
                Log.i(TAG, "All location settings are satisfied.");
                startLocationUpdates();
                break;
            case LocationSettingsStatusCodes.RESOLUTION_REQUIRED:
                // Location settings are not satisfied, but this can be fixed
                // by showing the user a dialog.
                Log.i(TAG, "Location settings are not satisfied. Show the user a dialog to " +
                        "upgrade location settings ");
                try {
                    // Show the dialog by calling startResolutionForResult(),
                    // and check the result in onActivityResult().
                    status.startResolutionForResult(MainActivity.getInstance(), REQUEST_CHECK_SETTINGS);
                } catch (IntentSender.SendIntentException e) {
                    // Ignore the error.
                    Log.i(TAG, "PendingIntent unable to execute request.");
                }
                break;
            // The status will never be SETTINGS_CHANGE_UNAVAILABLE if use builder.setAlwaysShow(true);
            case LocationSettingsStatusCodes.SETTINGS_CHANGE_UNAVAILABLE:
                // Location settings are not satisfied. However, we have no way
                // to fix the settings so we won't show the dialog.
                Log.i(TAG, "Location settings are inadequate, and cannot be fixed here. Dialog " +
                        "not created.");
                break;
        }
    }
    

    【讨论】:

      【解决方案2】:

      你可以使用位置变化监听器

        public class LocationService extends Service 
          {
                 public static final String BROADCAST_ACTION = "Hello World";
                 private static final int TWO_MINUTES = 1000 * 60 * 2;
                 public LocationManager locationManager;
                 public MyLocationListener listener;
                 public Location previousBestLocation = null;
      
                 Intent intent;
                 int counter = 0;
      
              @Override
              public void onCreate() 
              {
                  super.onCreate();
                  intent = new Intent(BROADCAST_ACTION);      
              }
      
              @Override
              public void onStart(Intent intent, int startId) 
              {      
                  locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
                  listener = new MyLocationListener();        
                  locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 4000, 0, listener);
                  locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 4000, 0, listener);
              }
      
              @Override
              public IBinder onBind(Intent intent) 
              {
                  return null;
              }
      
              protected boolean isBetterLocation(Location location, Location currentBestLocation) {
                  if (currentBestLocation == null) {
                      // A new location is always better than no location
                      return true;
                  }
      
                  // Check whether the new location fix is newer or older
                  long timeDelta = location.getTime() - currentBestLocation.getTime();
                  boolean isSignificantlyNewer = timeDelta > TWO_MINUTES;
                  boolean isSignificantlyOlder = timeDelta < -TWO_MINUTES;
                  boolean isNewer = timeDelta > 0;
      
                  // If it's been more than two minutes since the current location, use the new location
                  // because the user has likely moved
                  if (isSignificantlyNewer) {
                      return true;
                  // If the new location is more than two minutes older, it must be worse
                  } else if (isSignificantlyOlder) {
                      return false;
                  }
      
                  // Check whether the new location fix is more or less accurate
                  int accuracyDelta = (int) (location.getAccuracy() - currentBestLocation.getAccuracy());
                  boolean isLessAccurate = accuracyDelta > 0;
                  boolean isMoreAccurate = accuracyDelta < 0;
                  boolean isSignificantlyLessAccurate = accuracyDelta > 200;
      
                  // Check if the old and new location are from the same provider
                  boolean isFromSameProvider = isSameProvider(location.getProvider(),
                          currentBestLocation.getProvider());
      
                  // Determine location quality using a combination of timeliness and accuracy
                  if (isMoreAccurate) {
                      return true;
                  } else if (isNewer && !isLessAccurate) {
                      return true;
                  } else if (isNewer && !isSignificantlyLessAccurate && isFromSameProvider) {
                      return true;
                  }
                  return false;
              }
      
      
      
          /** Checks whether two providers are the same */
              private boolean isSameProvider(String provider1, String provider2) {
                  if (provider1 == null) {
                    return provider2 == null;
                  }
                  return provider1.equals(provider2);
              }
      
      
      
          @Override
              public void onDestroy() {       
                 // handler.removeCallbacks(sendUpdatesToUI);     
                  super.onDestroy();
                  Log.v("STOP_SERVICE", "DONE");
                  locationManager.removeUpdates(listener);        
              }   
      
              public static Thread performOnBackgroundThread(final Runnable runnable) {
                  final Thread t = new Thread() {
                      @Override
                      public void run() {
                          try {
                              runnable.run();
                          } finally {
      
                          }
                      }
                  };
                  t.start();
                  return t;
              }
      
      
      
      
          public class MyLocationListener implements LocationListener
              {
      
                  public void onLocationChanged(final Location loc)
                  {
                      Log.i("**************************************", "Location changed");
                      if(isBetterLocation(loc, previousBestLocation)) {
                          loc.getLatitude();
                          loc.getLongitude();             
                          intent.putExtra("Latitude", loc.getLatitude());
                          intent.putExtra("Longitude", loc.getLongitude());     
                          intent.putExtra("Provider", loc.getProvider());                 
                          sendBroadcast(intent);          
      
                      }                               
                  }
      
                  public void onProviderDisabled(String provider)
                  {
                      Toast.makeText( getApplicationContext(), "Gps Disabled", Toast.LENGTH_SHORT ).show();
                  }
      
      
                  public void onProviderEnabled(String provider)
                  {
                      Toast.makeText( getApplicationContext(), "Gps Enabled", Toast.LENGTH_SHORT).show();
                  }
      
      
                  public void onStatusChanged(String provider, int status, Bundle extras)
                  {
      
                  }
      
              }
          }
      

      【讨论】:

      • 我使用了 LocationListener 并且 FusedLocationAPI 运行良好。我的问题是 checkLocationSettings。
      猜你喜欢
      • 2013-01-12
      • 1970-01-01
      • 1970-01-01
      • 2014-12-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-11-16
      相关资源
      最近更新 更多