计时器未在预定时间调用

时间:2017-07-08 05:50:48

标签: java android service timer timertask

我想每10分钟跟踪一个位置,并通过TraceDelivery异步任务将其发送到服务器。为此,我尝试使用服务和计时器每10分钟获取一次位置。

但是当我从另一个活动中调用该服务时,它只能运行一次,即一旦TraceDelivery api被调用但不再被调用。为了进行测试,我只给了第二次延迟,但是它还没有被再次调用。

另外,如果我检查mLatLang是否为null,然后调用TraceDelivery,它至少不会被调用一次。但如果location为null,则会在mLatLang上使用空指针进行崩溃。

服务代码:

public class LocationTrackerService extends IntentService implements GoogleApiClient.ConnectionCallbacks,GoogleApiClient.OnConnectionFailedListener{

    private Handler handler;
    private Timer timer;
    private TimerTask timerTask;
    private GoogleApiClient mGoogleApiClient;
    Location mLastLocation;
    private LatLng mLatLang;
    LocationManager mLocationManager = null;
    boolean gps_enabled = false;
    boolean network_enabled = false;


    LocationListener[] mLocationListeners = new LocationListener[]{
            new LocationListener(LocationManager.NETWORK_PROVIDER),
            new LocationListener(LocationManager.GPS_PROVIDER)

    };

    /**
     * A constructor is required, and must call the super IntentService(String)
     * constructor with a name for the worker thread.
     */
    public LocationTrackerService() {
        super("HelloIntentService");
    }

    /**
     * The IntentService calls this method from the default worker thread with
     * the intent that started the service. When this method returns, IntentService
     * stops the service, as appropriate.
     */
    @Override
    protected void onHandleIntent(Intent intent) {
        // Normally we would do some work here, like download a file.
        // For our sample, we just sleep for 5 seconds.
        try {
            Thread.sleep(1000);

            buildGoogleApiClient();
            mGoogleApiClient.connect();

            handler = new Handler();

                initializeLocationManager();
                requestLocation();


                startTimer(intent.getStringExtra("dl_id"), intent.getStringExtra("pt_id"), intent.getStringExtra("ur_id"),intent.getStringExtra("address"),
                        intent.getStringExtra("api_key"));


        } catch (InterruptedException e) {
            // Restore interrupt status.
            Thread.currentThread().interrupt();
        }
    }
    public void startTimer(String dlId,String ptId,String urId,String add,String key) {
        //set a new Timer
        timer = new Timer();

        //initialize the TimerTask's job
        initializeTimerTask(dlId, ptId, urId,key);

        //schedule the timer, after the first 5000ms the TimerTask will run every 10000ms
        timer.schedule(timerTask, 1000, 1000);//
    }

    public void initializeTimerTask(final String dlId, final String ptId, final String urId, final String key) {

        timerTask = new TimerTask() {
            public void run() {

                //use a handler to run a toast that shows the current timestamp
                handler.post(new Runnable() {
                    public void run() {

                            TraceDeliveryAsyncTask traceDeliveryAsyncTask = new TraceDeliveryAsyncTask(LocationTrackerService.this);
                            traceDeliveryAsyncTask.execute(dlId, ptId, urId, String.valueOf(mLatLang.latitude),
                                    String.valueOf(mLatLang.longitude),"", key);

                            Log.e("timer","success");


                    }
                });
            }
        };
    }

    public void stoptimertask() {
        //stop the timer, if it's not already null
        if (timer != null) {
            timer.cancel();
            timer = null;
        }
    }

    protected synchronized void buildGoogleApiClient() {

        mGoogleApiClient = new GoogleApiClient.Builder(LocationTrackerService.this)
                .addConnectionCallbacks(LocationTrackerService.this)
                .addOnConnectionFailedListener(LocationTrackerService.this)
                .addApi(LocationServices.API)
                .build();
    }

    @Override
    public void onConnected(Bundle bundle) {
        // Toast.makeText(getActivity(),"onConnected",Toast.LENGTH_SHORT).show();

    }

    @Override
    public void onConnectionSuspended(int i) {
        //  Toast.makeText(getActivity(),"onConnectionSuspended",Toast.LENGTH_SHORT).show();
    }

    @Override
    public void onConnectionFailed(ConnectionResult connectionResult) {
        //    Toast.makeText(getActivity(),"onConnectionFailed",Toast.LENGTH_SHORT).show();
    }

    private void initializeLocationManager() {
        // Log.e(Application.TAG, "initializeLocationManager");
        if (mLocationManager == null) {
            mLocationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
        }

        try {
            gps_enabled = mLocationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
        } catch (Exception ex) {
        }

        try {
            network_enabled = mLocationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
        } catch (Exception ex) {
        }

        if (!gps_enabled && !network_enabled) {
            // notify user
            if(!CommonUtils.isGPSEnabled(getApplicationContext()))
                startActivity(new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS));
        }

    }

    public class LocationListener implements android.location.LocationListener {

        public LocationListener() {
        }

        public LocationListener(String provider) {
            Log.e(TAG, "LocationListener " + provider);
            mLastLocation = new Location(provider);
        }

        @Override
        public void onLocationChanged(Location location) {
            Log.e(TAG, "onLocationChanged: " + location);

            //get current location

            if(mLastLocation != null && !mLastLocation.equals("")) {
                mLastLocation.set(location);
                mLatLang = new LatLng(mLastLocation.getLatitude(), mLastLocation.getLongitude());
            }
            else {

            }

        }

        @Override
        public void onProviderDisabled(String provider) {
            Log.e(TAG, "onProviderDisabled: " + provider);

        }

        @Override
        public void onProviderEnabled(String provider) {
            Log.e(TAG, "onProviderEnabled: " + provider);

        }

        @Override
        public void onStatusChanged(String provider, int status, Bundle extras) {
            Log.e(TAG, "onStatusChanged: " + provider);
        }
    }

    //request for location, first by network, then by gps

    public void requestLocation() {

        try {
            mLocationManager.requestLocationUpdates(
                    LocationManager.NETWORK_PROVIDER, 0, 0,
                    mLocationListeners[0]);
        } catch (java.lang.SecurityException ex) {
            Log.i(TAG, "fail to request location update, ignore", ex);
        } catch (IllegalArgumentException ex) {
            Log.d(TAG, "network provider does not exist, " + ex.getMessage());
        }

        try {
            mLocationManager.requestLocationUpdates(
                    LocationManager.GPS_PROVIDER, 0, 0,
                    mLocationListeners[1]);
        } catch (java.lang.SecurityException ex) {
            Log.i(TAG, "fail to request location update, ignore", ex);
        } catch (IllegalArgumentException ex) {
            Log.d(TAG, "gps provider does not exist " + ex.getMessage());
        }
    }

}

我怎样才能做到这一点? 请帮忙。谢谢..

2 个答案:

答案 0 :(得分:1)

Android AlarmManager类可以触发意图以设定的时间间隔发送到您的应用程序并执行定义的任务。可能是您一直在寻找什么

答案 1 :(得分:1)

IntentService将立即停止完成OnHandleIntent中的任务,

因此,不要使用IntentService尝试使用Service进行长时间运行。