在后台更新位置并检查LocationSettings

时间:2016-04-13 12:03:22

标签: java android service location fusedlocationproviderapi

我想在后台每隔几分钟更新用户的位置。
我使用了此示例代码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,   mLocationSettingsRequest);

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

[编辑]
我尝试使用PendingIntentIntentService

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

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

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

2 个答案:

答案 0 :(得分: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;
    }
}

答案 1 :(得分:0)

您可以使用位置更改侦听器

  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)
            {

            }

        }
    }