2

現在、アプリの起動時に開始するロケーションサービスがあります。私のonCreateメソッドは次のとおりです:-

public void onCreate() {
    Criteria criteria = new Criteria();
    criteria.setAccuracy(Criteria.ACCURACY_FINE);
    criteria.setCostAllowed(false);
    // Get a location manager from the system services
    locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);

    // if GPS is not enabled. Show alert to user.
    if ( !locationManager.isProviderEnabled( LocationManager.GPS_PROVIDER ) ) {
        showEnableLocationsDialog();
    }

    // Get the location provider that best matches the criteria
    String bestProvider = locationManager.getBestProvider(criteria, false);

    if (bestProvider != null) {
        // Get the user's last known location
        location = locationManager.getLastKnownLocation(bestProvider);

        MyApp myApp = (MyApp) getApplicationContext();
        myApp.setLocation(location);
        if (locationManager.isProviderEnabled(bestProvider)) {
            locationManager.requestLocationUpdates(bestProvider, 0, 0, this);
        }
    }
}

GPSが有効になっていない場合、ユーザーにGPSを有効にするように求めるダイアログを表示します。私の質問は、ユーザーがGPSを有効にするために設定ページに移動することを選択した場合、サービスがすでに「実行中」であるため、ユーザーがアプリを再度起動したときにgetBestProvider()とrequestLocationUpdates()の残りのフローが影響を受けるかどうかです。バックグラウンド?(私はAndroid開発全体に慣れていないので、推測です)。

私のクラスの完全なコードは以下のとおりです:-

public class LocationService extends Service implements LocationListener {

private LocationManager locationManager;

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

@Override
public void onCreate() {
    Criteria criteria = new Criteria();
    criteria.setAccuracy(Criteria.ACCURACY_FINE);
    criteria.setCostAllowed(false);
    // Get a location manager from the system services
    locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);

    // if GPS is not enabled. Show alert to user.
    if ( !locationManager.isProviderEnabled( LocationManager.GPS_PROVIDER ) ) {
        showEnableLocationsDialog();
    }

    // Get the location provider that best matches the criteria
    String bestProvider = locationManager.getBestProvider(criteria, false);

    if (bestProvider != null) {
        // Get the user's last known location
        location = locationManager.getLastKnownLocation(bestProvider);
        MyApp myApp = (MyApp) getApplicationContext();
        myApp.setLocation(location);
        if (locationManager.isProviderEnabled(bestProvider)) {
            locationManager.requestLocationUpdates(bestProvider, 0, 0, this);
        }
    }
}

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
    // We want this service to continue running until it is explicitly
    // stopped, so return sticky.
    return START_STICKY;
}

public void onLocationChanged(Location newLocation) {        
    // if a newer location is available, check if its better than current available one
    MyApp myApp = (MyApp) getApplicationContext();
    Location location = myApp.getLocation();
    boolean isBetterLocation = isBetterLocation(location, newLocation);
    if(isBetterLocation) {
        location = newLocation;
    }
}

public static Location getBestLocation(LocationManager locationManager) {

    Location location_gps = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
    Location location_network = locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);

    // If both are available, get the most recent
    if(location_gps!=null && location_network !=null) {
        return (location_gps.getTime() > location_network.getTime())?location_gps:location_network;
    }
    else if(location_gps==null && location_network ==null){
        return null;
    }
    else
        return (location_gps==null)?location_network:location_gps;

}

public void onProviderEnabled(String s){}
public void onProviderDisabled(String s){}
public void onStatusChanged(String s, int i, Bundle b){}

@Override
public void onDestroy() {       
    locationManager.removeUpdates(this);
}

private void showEnableLocationsDialog() {
    AlertDialog.Builder myAlertDialog = new AlertDialog.Builder(this);
    myAlertDialog.setTitle("No location services enabled");
    myAlertDialog.setMessage("To find your location, please enable at least one service in the Settings");
    myAlertDialog.setPositiveButton("Settings", new DialogInterface.OnClickListener() {
        public void onClick(DialogInterface arg0, int arg1) {
            // show settings screen
            Intent settingsIntent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
            startActivity(settingsIntent);
        }}
            );
    myAlertDialog.setNegativeButton("Skip", new DialogInterface.OnClickListener() {       
        public void onClick(DialogInterface arg0, int arg1) {
            // do something when the Cancel button is clicked
        }}
            );
    myAlertDialog.show();
}

private static final int TWO_MINUTES = 1000 * 60 * 2;

/** Determines whether one Location reading is better than the current Location fix
 * @param location  The new Location that you want to evaluate
 * @param currentBestLocation  The current Location fix, to which you want to compare the new one
 */
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);
}
}

また、位置情報の更新を常に要求するのは得策ではなく、代わりにAlarmManagerを使用する必要があることについても読みました。これについてもアドバイスはありますか?

4

0 に答える 0