位置未在 10 分钟间隔内更新
Posted
技术标签:
【中文标题】位置未在 10 分钟间隔内更新【英文标题】:Location not updated on 10 mins of interval 【发布时间】:2021-10-22 12:08:24 【问题描述】:我想跟踪用户位置。所以我编写了一个代码,以便每隔 10 分钟它的位置应该在服务器上命中。如果它没有移动,该位置也应该以 10 分钟的间隔命中。我将位置间隔分钟设置为 10 分钟 public static final long LOCATION_INTERVAL_MINUTES = 10 * 60 * 1000; 它应该用 10 分钟更新位置,但它是随机命中的。我还将 gps 频率距离从 10 增加到 gpsFreqInDistance = 100 。随机命中被停止,但它不会在 10 分钟的间隔内更新。 那么如何以 10 分钟的间隔获取位置。 以下是我的清单
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" /
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
对于 10 版本以上的 Android,您不能同时使用后台位置和前台位置。所以我在我的项目中评论了“ACCESS_BACKGROUND_LOCATION”。
public class LocationMonitoringService implements LocationListener, GpsStatus.Listener
private static final String TAG = LocationMonitoringService.class.getSimpleName();
private Context mContext;
private LocationRepository mLocationRepository;
private ShareLocationAdapterClass mAdapter;
private SyncOfflineRepository syncOfflineRepository;
private long updatedTime = 0;
private List<UserLocationPojo> mUserLocationPojoList;
private SyncOfflineAttendanceRepository syncOfflineAttendanceRepository;
public LocationMonitoringService(final Context context)
mContext = context;
mLocationRepository = new LocationRepository(AUtils.mainApplicationConstant.getApplicationContext());
syncOfflineRepository = new SyncOfflineRepository(AUtils.mainApplicationConstant.getApplicationContext());
syncOfflineAttendanceRepository = new SyncOfflineAttendanceRepository(AUtils.mainApplicationConstant.getApplicationContext());
mUserLocationPojoList = new ArrayList<>();
mAdapter = new ShareLocationAdapterClass();
mAdapter.setShareLocationListener(new ShareLocationAdapterClass.ShareLocationListener()
@Override
public void onSuccessCallBack(boolean isAttendanceOff)
if (isAttendanceOff && !syncOfflineAttendanceRepository.checkIsAttendanceIn())
AUtils.setIsOnduty(false);
((MyApplication) AUtils.mainApplicationConstant).stopLocationTracking();
@Override
public void onFailureCallBack()
);
public void onStartTacking()
LocationManager locationManager = (LocationManager) mContext.getSystemService(Context.LOCATION_SERVICE);
//Exception thrown when GPS or Network provider were not available on the user's device.
try
Criteria criteria = new Criteria();
criteria.setAccuracy(Criteria.ACCURACY_FINE);
criteria.setPowerRequirement(Criteria.NO_REQUIREMENT);
criteria.setAltitudeRequired(false);
criteria.setSpeedRequired(true);
criteria.setCostAllowed(false);
criteria.setBearingRequired(false);
//API level 9 and up
criteria.setHorizontalAccuracy(Criteria.ACCURACY_HIGH);
criteria.setVerticalAccuracy(Criteria.ACCURACY_HIGH);
int gpsFreqInDistance = 100;
assert locationManager != null;
locationManager.addGpsStatusListener(this);
locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, AUtils.LOCATION_INTERVAL,
gpsFreqInDistance, this, null);
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, AUtils.LOCATION_INTERVAL,
gpsFreqInDistance, this, null);
catch (IllegalArgumentException | SecurityException e)
Log.e(TAG, Objects.requireNonNull(e.getLocalizedMessage()));
Log.d(TAG, "onStartTacking: " + e.getMessage());
Log.d(TAG, "onStartTacking: " + e.getLocalizedMessage());
e.printStackTrace();
catch (RuntimeException e)
Log.e(TAG, Objects.requireNonNull(e.getLocalizedMessage()));
Log.d(TAG, "onStartTacking: " + e.getMessage());
e.printStackTrace();
public void onStopTracking()
mAdapter.shareLocation();
LocationManager locationManager = (LocationManager) mContext.getSystemService(Context.LOCATION_SERVICE);
locationManager.removeUpdates(this);
/*
* LOCATION CALLBACKS
*/
//to get the location change
@Override
public void onLocationChanged(Location location)
Log.d("okh ", "onLocationChanged: "+System.currentTimeMillis());
if (location != null)
Log.d(TAG, String.valueOf(location.getAccuracy()));
if (!AUtils.isNullString(String.valueOf(location.getLatitude())) && !AUtils.isNullString(String.valueOf(location.getLongitude())))
Prefs.putString(AUtils.LAT, String.valueOf(location.getLatitude()));
Prefs.putString(AUtils.LONG, String.valueOf(location.getLongitude()));
if (Prefs.getBoolean(AUtils.PREFS.IS_ON_DUTY, false))
if (updatedTime == 0)
updatedTime = System.currentTimeMillis();
Log.d(TAG, "updated Time ==== " + updatedTime);
if ((updatedTime + AUtils.LOCATION_INTERVAL_MINUTES) <= System.currentTimeMillis())
updatedTime = System.currentTimeMillis();
Log.d(TAG, "updated Time ==== " + updatedTime);
sendLocation();
else
Log.d(TAG, "onLocationChanged: no location found !!");
@Override
public void onStatusChanged(String provider, int status, Bundle extras)
Log.d(TAG, "onStatusChanged" + provider + "Status" + status);
@Override
public void onProviderEnabled(String provider)
Log.d(TAG, " onProviderEnabled" + provider);
@Override
public void onProviderDisabled(String provider)
Log.d(TAG, " onProviderDisabled" + provider);
@Override
public void onGpsStatusChanged(int event)
private void sendLocation()
// mAdapter.shareLocation(getTempList());
Log.d("okh", "sendLocation: Current Time In Millies "+ System.currentTimeMillis());
try
Calendar CurrentTime = AUtils.getCurrentTime();
Calendar DutyOffTime = AUtils.getDutyEndTime();
if (CurrentTime.before(DutyOffTime))
Log.i(TAG, "Before");
UserLocationPojo userLocationPojo = new UserLocationPojo();
userLocationPojo.setUserId(Prefs.getString(AUtils.PREFS.USER_ID, ""));
userLocationPojo.setLat(Prefs.getString(AUtils.LAT, ""));
userLocationPojo.setLong(Prefs.getString(AUtils.LONG, ""));
double startLat = Double.parseDouble(Prefs.getString(AUtils.LAT, "0"));
double startLng = Double.parseDouble(Prefs.getString(AUtils.LONG, "0"));
userLocationPojo.setDistance(String.valueOf(AUtils.calculateDistance(
AUtils.mainApplicationConstant.getApplicationContext(), startLat, startLng)));
// userLocationPojo.setDatetime(AUtils.getServerDateTime()); //TODO
userLocationPojo.setDatetime(AUtils.getServerDateTimeLocal());
userLocationPojo.setOfflineId("0");
if (AUtils.isInternetAvailable() && AUtils.isConnectedFast(mContext))
userLocationPojo.setIsOffline(true);
else
userLocationPojo.setIsOffline(false);
String UserTypeId = Prefs.getString(AUtils.PREFS.USER_TYPE_ID, AUtils.USER_TYPE.USER_TYPE_GHANTA_GADI);
if (AUtils.isInternetAvailable())
TableDataCountPojo.LocationCollectionCount count = syncOfflineRepository.getLocationCollectionCount(AUtils.getLocalDate());
if ((UserTypeId.equals(AUtils.USER_TYPE.USER_TYPE_GHANTA_GADI) || UserTypeId.equals(AUtils.USER_TYPE.USER_TYPE_WASTE_MANAGER))
&& (count.getLocationCount() > 0 || count.getCollectionCount() > 0))
syncOfflineRepository.insetUserLocation(userLocationPojo);
else
mUserLocationPojoList.add(userLocationPojo);
mAdapter.shareLocation(mUserLocationPojoList);
mUserLocationPojoList.clear();
else
if (UserTypeId.equals(AUtils.USER_TYPE.USER_TYPE_EMP_SCANNIFY))
Type type = new TypeToken<UserLocationPojo>()
.getType();
mLocationRepository.insertUserLocationEntity(new Gson().toJson(userLocationPojo, type));
else
syncOfflineRepository.insetUserLocation(userLocationPojo);
mUserLocationPojoList.clear();
else
Log.i(TAG, "After");
syncOfflineAttendanceRepository.performCollectionInsert(mContext,
syncOfflineAttendanceRepository.checkAttendance(), AUtils.getCurrentDateDutyOffTime());
AUtils.setIsOnduty(false);
((MyApplication) AUtils.mainApplicationConstant).stopLocationTracking();
Activity activity = ((Activity) AUtils.currentContextConstant);
if (activity instanceof DashboardActivity)
((Activity) AUtils.currentContextConstant).recreate();
AUtils.DutyOffFromService = true;
if (!AUtils.isNull(AUtils.currentContextConstant))
((Activity) AUtils.currentContextConstant).recreate();
catch (Exception e)
e.printStackTrace();
下面是我用过的前台服务
public class ForgroundService extends Service
private LocationMonitoringService monitoringService;
private Handler locationHandler;
private Runnable locationThread;
@Override
public IBinder onBind(Intent intent)
// TODO Auto-generated method stub
return null;
@Override
public void onCreate()
// Toast.makeText(this, " MyService Created ", Toast.LENGTH_LONG).show();
Log.d("okh", "onCreate: " +System.currentTimeMillis());
monitoringService = new LocationMonitoringService(this);
@Override
public int onStartCommand(Intent intent, int flags, int startId)
// Toast.makeText(this, " MyService Started", Toast.LENGTH_LONG).show();
Log.d("okh", "onCreate: " +System.currentTimeMillis());
Log.d("okh", "onStartCommand: ");
final int currentId = startId;
locationThread = new Runnable()
public void run()
monitoringService.onStartTacking();
;
locationHandler = new Handler(Looper.getMainLooper());
locationHandler.post(locationThread);
startLocationForeground();
return Service.START_STICKY;
// return Service.START_NOT_STICKY;
@Override
public void onDestroy()
//Toast.makeText(this, "MyService Stopped", Toast.LENGTH_LONG).show();
locationHandler.removeCallbacks(locationThread);
monitoringService.onStopTracking();
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.N)
stopForeground(STOP_FOREGROUND_REMOVE);
if(Prefs.getBoolean(AUtils.PREFS.IS_ON_DUTY,false))
Intent broadcastIntent = new Intent(this, RestarterBroadcastReceiver.class);
sendBroadcast(broadcastIntent);
private void startLocationForeground()
if (Build.VERSION.SDK_INT >= 26)
String channelId = Build.VERSION.SDK_INT >= Build.VERSION_CODES.O
? this.createNotificationChannel("my_service", "My Background Service")
: "";
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder((Context) this,
channelId);
Notification notification = notificationBuilder
.setOngoing(true)
.setContentText("Please don't kill the app from background. Thank you!!")
.setSmallIcon(getNotificationIcon(notificationBuilder))
.setPriority(-2)
.setCategory("service")
.build();
startForeground(101, notification);
@RequiresApi(26)
private String createNotificationChannel(String channelId, String channelName)
NotificationChannel chan = new NotificationChannel(channelId, (CharSequence)channelName,
NotificationManager.IMPORTANCE_NONE);
chan.setLightColor(Color.BLUE);
chan.setLockscreenVisibility(Notification.VISIBILITY_PRIVATE);
NotificationManager service = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
service.createNotificationChannel(chan);
return channelId;
private int getNotificationIcon(NotificationCompat.Builder notificationBuilder)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP)
int color = 0x008000;
notificationBuilder.setColor(color);
return R.drawable.ic_noti_icon;
return R.drawable.ic_noti_icon;
【问题讨论】:
从哪里调用这个方法?你是传递应用程序上下文还是活动上下文? @Arunachalamk- 我正在传递应用程序上下文 【参考方案1】:为什么你在最后一个参数中传递 null?你试过没有通过吗?
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, AUtils.LOCATION_INTERVAL,
gpsFreqInDistance, this, null);
首先,Google Location Services 在实现这一要求方面远优于传统的 LocationManager。
https://developer.android.com/training/location/request-updates
【讨论】:
@Arunachalam-不,我没试过。你认为这对我有用吗。 @gopssays 请分享您用于 Google 定位服务的代码 sn-p 我使用的是 LocationManager 而不是谷歌位置服务以上是关于位置未在 10 分钟间隔内更新的主要内容,如果未能解决你的问题,请参考以下文章