每10公里变化一次

时间:2018-04-27 12:43:07

标签: android gps

我想在距离最后知道位置10公里处检查我的服务地点。这是否可以不要求所有时间当前位置? (因为现在app每次都试图获取当前位置)。如果是,那怎么样?我的所有位置代码几乎等于Best way to get user GPS location in background in Android应答代码,该代码在主要活动中开始使用

2 个答案:

答案 0 :(得分:0)

尝试将Service类更改为IntentService

另外,我使用BroadcastReceiver每隔10秒提供一次演示当前位置更新的演示。 同样在本演示中,我在位置更新时使用了通知显示。

如下面的代码。

public class LocationUpdatesBroadcastReceiver extends BroadcastReceiver {
private static final String TAG = "LUBroadcastReceiver";

public static final String ACTION_PROCESS_UPDATES =
        "com.google.android.gms.location.sample.backgroundlocationupdates.action" +
                ".PROCESS_UPDATES";

@Override
public void onReceive(Context context, Intent intent) {
    if (intent != null) {
        final String action = intent.getAction();
        if (ACTION_PROCESS_UPDATES.equals(action)) {
            LocationResult result = LocationResult.extractResult(intent);
            if (result != null) {
                List<Location> locations = result.getLocations();
                LocationResultHelper locationResultHelper = new LocationResultHelper(
                        context, locations);
                // Save the location data to SharedPreferences.
                locationResultHelper.saveResults();
                // Show notification with the location data.
                locationResultHelper.showNotification();
                Log.i(TAG, LocationResultHelper.getSavedLocationResult(context));
            }
        }
    }
}

}

然后第二类如下。在此代码中显示通道因为在Android 8.0中运行

  /**

*此类用于显示通知并将位置数据存储到共享首选项中。    * /

公共类LocationResultHelper {

   final public static String KEY_LOCATION_UPDATES_RESULT = "location-     update-result";

final private static String PRIMARY_CHANNEL = "default";


private Context mContext;
private List<Location> mLocations;
private NotificationManager mNotificationManager;

/**
 * this constructor used to initialised this class.
 * @param context
 * @param locations
 */
public LocationResultHelper(Context context, List<Location> locations) {
    mContext = context;
    mLocations = locations;

    NotificationChannel channel = new NotificationChannel(PRIMARY_CHANNEL,
            context.getString(R.string.default_channel), NotificationManager.IMPORTANCE_DEFAULT);
    channel.setLightColor(Color.GREEN);
    channel.setLockscreenVisibility(Notification.VISIBILITY_PRIVATE);
    getNotificationManager().createNotificationChannel(channel);
}

/**
 * this method used to report location with date and time.
 */
private String getLocationResultTitle() {
    String numLocationsReported = mContext.getResources().getQuantityString(
            R.plurals.num_locations_reported, mLocations.size(), mLocations.size());
    return numLocationsReported + ": " + DateFormat.getDateTimeInstance().format(new Date());
}

/**
 * this method used to give location data.
 * @return
 */
private String getLocationResultText() {
    if (mLocations.isEmpty()) {
        return mContext.getString(R.string.unknown_location);
    }
    StringBuilder sb = new StringBuilder();
    for (Location location : mLocations) {
        sb.append("(");
        sb.append(location.getLatitude());
        sb.append(", ");
        sb.append(location.getLongitude());
        sb.append(")");
        sb.append("\n");
    }
    return sb.toString();
}

/**
 * this method save data into shared preferences.
 */
public void saveResults() {
    PreferenceManager.getDefaultSharedPreferences(mContext)
            .edit()
            .putString(KEY_LOCATION_UPDATES_RESULT, getLocationResultTitle() + "\n" +
                    getLocationResultText())
            .apply();
}

/**
 * this method get shared preferences store location update.
 */
public static String getSavedLocationResult(Context context) {
    return PreferenceManager.getDefaultSharedPreferences(context)
            .getString(KEY_LOCATION_UPDATES_RESULT, "");
}

/**
 * Get the notification mNotificationManager.
 * <p>
 * Utility method as this helper works with it a lot.
 *
 * @return The system service NotificationManager
 */
private NotificationManager getNotificationManager() {
    if (mNotificationManager == null) {
        mNotificationManager = (NotificationManager) mContext.getSystemService(
                Context.NOTIFICATION_SERVICE);
    }
    return mNotificationManager;
}

/**
 * Displays a notification with the location results.
 */

public void showNotification(){         Intent notificationIntent = new Intent(mContext,MainActivity.class);

    // Construct a task stack.
    TaskStackBuilder stackBuilder = TaskStackBuilder.create(mContext);

    // Add the main Activity to the task stack as the parent.
    stackBuilder.addParentStack(MainActivity.class);

    // Push the content Intent onto the stack.
    stackBuilder.addNextIntent(notificationIntent);

    // Get a PendingIntent containing the entire back stack.
    PendingIntent notificationPendingIntent =
            stackBuilder.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT);

    Notification.Builder notificationBuilder = new Notification.Builder(mContext,
            PRIMARY_CHANNEL)
            .setContentTitle(getLocationResultTitle())
            .setContentText(getLocationResultText())
            .setSmallIcon(R.drawable.common_google_signin_btn_icon_dark)
            .setAutoCancel(true)
            .setContentIntent(notificationPendingIntent);

    getNotificationManager().notify(0, notificationBuilder.build());
}

}

然后为请求位置数据制作第三类

/ **  *此类使用为请求进行位置更新而选择的保存用户并删除位置更新。  * /

public class LocationRequestHelper {

final static public String KEY_LOCATION_UPDATES_REQUESTED = "location-updates-requested";

public static void setRequesting(Context context, boolean value) {
    PreferenceManager.getDefaultSharedPreferences(context)
            .edit()
            .putBoolean(KEY_LOCATION_UPDATES_REQUESTED, value)
            .apply();
}

public static boolean getRequesting(Context context) {
    return PreferenceManager.getDefaultSharedPreferences(context)
            .getBoolean(KEY_LOCATION_UPDATES_REQUESTED, false);
}

}

然后在进行主要活动并实施所有事情之后。

public class MainActivity extends AppCompatActivity implements GoogleApiClient.ConnectionCallbacks,
    GoogleApiClient.OnConnectionFailedListener,
    SharedPreferences.OnSharedPreferenceChangeListener {
private static final String TAG = MainActivity.class.getSimpleName();
private static final int REQUEST_PERMISSIONS_REQUEST_CODE = 34;
/**
 * The used for interval for location updates.
 */
private static final long UPDATE_INTERVAL = 10 * 1000;

/**
 * The fastest interval to update for active location updates.
 */
private static final long FASTEST_UPDATE_INTERVAL = UPDATE_INTERVAL / 2;

/**
 * The max time to wait for location update.
 */
private static final long MAX_WAIT_TIME = UPDATE_INTERVAL * 3;

/**
 * Stores parameters for requests to the FusedLocationProviderApi.
 */
private LocationRequest mLocationRequest;

/**
 * The entry point to Google Play Services.
 */
private GoogleApiClient mGoogleApiClient;

private Button mRequestUpdatesButton;
private Button mRemoveUpdatesButton;
private TextView mLocationUpdatesResultView;

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

/**
 * this method initialized view control.
 */
private void initView() {
    mRequestUpdatesButton = (Button) findViewById(R.id.request_updates_button);
    mRemoveUpdatesButton = (Button) findViewById(R.id.remove_updates_button);
    mLocationUpdatesResultView = (TextView) findViewById(R.id.location_updates_result);

    // Check if the user revoked runtime permissions.
    if (!checkPermissions()) {
        requestPermissions();
    }

    buildGoogleApiClient();

}

@Override
protected void onStart() {
    super.onStart();
    PreferenceManager.getDefaultSharedPreferences(this)
            .registerOnSharedPreferenceChangeListener(this);
}


@Override
protected void onResume() {
    super.onResume();
    updateButtonsState(LocationRequestHelper.getRequesting(this));
    mLocationUpdatesResultView.setText(LocationResultHelper.getSavedLocationResult(this));
}

@Override
protected void onStop() {
    PreferenceManager.getDefaultSharedPreferences(this)
            .unregisterOnSharedPreferenceChangeListener(this);
    super.onStop();
}

/**
 * this method used to location data update settings.
 */
private void createLocationRequest() {
    mLocationRequest = new LocationRequest();

    mLocationRequest.setInterval(UPDATE_INTERVAL);

    // Sets the fastest rate for active location updates. This interval is exact, and your
    // application will never receive updates faster than this value.
    mLocationRequest.setFastestInterval(FASTEST_UPDATE_INTERVAL);
    mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);

    // Sets the maximum time when batched location updates are delivered. Updates may be
    // delivered sooner than this interval.
    mLocationRequest.setMaxWaitTime(MAX_WAIT_TIME);
}

/**
 * this method used to invoke google location service.
 */
private void buildGoogleApiClient() {
    if (mGoogleApiClient != null) {
        return;
    }
    mGoogleApiClient = new GoogleApiClient.Builder(this)
            .addConnectionCallbacks(this)
            .enableAutoManage(this, this)
            .addApi(LocationServices.API)
            .build();
    createLocationRequest();
}

@Override
public void onConnected(@Nullable Bundle bundle) {
    Log.i(TAG, "GoogleApiClient connected");
}

/**
 * this method call particular class or services
 * if you used intent service then pass intent in class name LocationUpdatesIntentService
 *if you used Broadcast  service then pass intent in class name LocationUpdatesBroadcastReceiver
 * @return
 */
private PendingIntent getPendingIntent() {
    Intent intent = new Intent(this, LocationUpdatesBroadcastReceiver.class);
    intent.setAction(LocationUpdatesBroadcastReceiver.ACTION_PROCESS_UPDATES);
    return PendingIntent.getBroadcast(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
}

@Override
public void onConnectionSuspended(int i) {
    final String text = "Connection suspended";
    Log.w(TAG, text + ": Error code: " + i);
    showSnackbar("Connection suspended");
}

@Override
public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {
    final String text = "Exception while connecting to Google Play services";
    Log.w(TAG, text + ": " + connectionResult.getErrorMessage());
    showSnackbar(text);
}

/**
 * this method show snack bar notification.
 */
private void showSnackbar(final String text) {
    View container = findViewById(R.id.activity_main);
    if (container != null) {
        Snackbar.make(container, text, Snackbar.LENGTH_LONG).show();
    }
}

/**
 * this method check permission and return current state of permission need.
 */
private boolean checkPermissions() {
    int permissionState = ActivityCompat.checkSelfPermission(this,
            Manifest.permission.ACCESS_FINE_LOCATION);
    return permissionState == PackageManager.PERMISSION_GRANTED;
}

/**
 * this method request to permission asked.
 */
private void requestPermissions() {
    boolean shouldProvideRationale =
            ActivityCompat.shouldShowRequestPermissionRationale(this,
                    Manifest.permission.ACCESS_FINE_LOCATION);

    if (shouldProvideRationale) {
        Log.i(TAG, "Displaying permission rationale to provide additional context.");
        Snackbar.make(
                findViewById(R.id.activity_main),
                R.string.permission_rationale,
                Snackbar.LENGTH_INDEFINITE)
                .setAction(R.string.ok, new View.OnClickListener() {
                    @Override
                    public void onClick(View view) {
                        // Request permission
                        ActivityCompat.requestPermissions(MainActivity.this,
                                new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
                                REQUEST_PERMISSIONS_REQUEST_CODE);
                    }
                })
                .show();
    } else {
        Log.i(TAG, "Requesting permission");
        // previously and checked "Never ask again".
        ActivityCompat.requestPermissions(MainActivity.this,
                new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
                REQUEST_PERMISSIONS_REQUEST_CODE);
    }
}

/**
 * Callback received when a permissions request has been completed.
 */
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions,
                                       @NonNull int[] grantResults) {
    Log.i(TAG, "onRequestPermissionResult");
    if (requestCode == REQUEST_PERMISSIONS_REQUEST_CODE) {
        if (grantResults.length <= 0) {
            // If user interaction was interrupted, the permission request is cancelled and you
            // receive empty arrays.
            Log.i(TAG, "User interaction was cancelled.");
        } else if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
            // Permission was granted. Kick off the process of building and connecting
            // GoogleApiClient.
            buildGoogleApiClient();
        } else {
            // Permission denied.
            Snackbar.make(
                    findViewById(R.id.activity_main),
                    R.string.permission_denied_explanation,
                    Snackbar.LENGTH_INDEFINITE)
                    .setAction(R.string.settings, new View.OnClickListener() {
                        @Override
                        public void onClick(View view) {
                            // Build intent that displays the App settings screen.
                            Intent intent = new Intent();
                            intent.setAction(
                                    Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
                            Uri uri = Uri.fromParts("package",
                                    BuildConfig.APPLICATION_ID, null);
                            intent.setData(uri);
                            intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                            startActivity(intent);
                        }
                    })
                    .show();
        }
    }
}

@Override
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String s) {
    if (s.equals(LocationResultHelper.KEY_LOCATION_UPDATES_RESULT)) {
        mLocationUpdatesResultView.setText(LocationResultHelper.getSavedLocationResult(this));
    } else if (s.equals(LocationRequestHelper.KEY_LOCATION_UPDATES_REQUESTED)) {
        updateButtonsState(LocationRequestHelper.getRequesting(this));
    }
}

/**
 * Handles the Request Updates button and requests start of location updates also disable button after selected.
 */
public void requestLocationUpdates(View view) {
    try {
        Log.i(TAG, "Starting location updates");
        LocationRequestHelper.setRequesting(this, true);
        LocationServices.FusedLocationApi.requestLocationUpdates(
                mGoogleApiClient, mLocationRequest, getPendingIntent());
    } catch (SecurityException e) {
        LocationRequestHelper.setRequesting(this, false);
        e.printStackTrace();
    }
}

/**
 * Handles the Remove Updates button, and requests removal of location updates also disable button after selected.
 */
public void removeLocationUpdates(View view) {
    Log.i(TAG, "Removing location updates");
    LocationRequestHelper.setRequesting(this, false);
    LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient,
            getPendingIntent());
}

/**
 * maintain button state is selected or not if selected then show disable.
 */
private void updateButtonsState(boolean requestingLocationUpdates) {
    if (requestingLocationUpdates) {
        mRequestUpdatesButton.setEnabled(false);
        mRemoveUpdatesButton.setEnabled(true);
    } else {
        mRequestUpdatesButton.setEnabled(true);
        mRemoveUpdatesButton.setEnabled(false);
    }
}

}

然后将boradcast接收器添加到应用程序标签之间的android清单文件中。

        <receiver
        android:name=".notification.LocationUpdatesBroadcastReceiver"
        android:exported="true">
        <intent-filter>
            <action android:name=".notification.LocationUpdatesBroadcastReceiver.ACTION_PROCESS_UPDATES" />
        </intent-filter>
    </receiver>

在这个演示中使用了两个按钮,它通过在LocationRequestHelper中定义布尔值来启用或禁用mange。

您需要参考以下链接的更多信息.. https://codelabs.developers.google.com/codelabs/background-location-updates-android-o/index.html?index=..%2F..%2Findex#0

答案 1 :(得分:0)

不确定距离,但您可以使用定期工作的JobScheduler(最多15分钟)

否则您可以使用ForegroundService一直获取位置。

Android Oreo将不允许长时间运行后台服务。