位置未在 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 分钟间隔内更新的主要内容,如果未能解决你的问题,请参考以下文章

轮询位置更新频率降低对电池的影响?

如何在 iPhone 的特定时间间隔内从后台执行位置

融合位置 GPS 在打开 Google 地图之前不会更新

使用 Fused 提供程序更新位置的间隔

没有位置服务的 iOS 后台轮询

Oreo+ 中位置更新的前台服务不起作用