android runnable没有被取消

时间:2012-11-16 13:28:28

标签: android handler runnable dispatchevent

我有一个应用程序,用于绘制当前用户的位置与另一个活动的邮政编码之间的路线。除了一个功能外,一切都很好。我通过处理程序/ runnable机制实现了一个计时器。如果在预定时间内没有触摸显示器,例如2分钟,那么我返回到用户必须再次登录的菜单屏幕。这是我的应用程序的安全功能。

我已经重写了dispatchTouchEvent方法,以便当用户触摸屏幕时,重置计时器。此部分无法正常工作。无论用户是否触摸屏幕,应用程序都会进入菜单屏幕。

我认为如果我将处理程序和runnable设置为null并在再次启动计时器之前删除对runnable的所有回调将起作用。

任何人都可以告诉我如何取消当前的runnable并重新启动它。

这是完整的代码,谢谢。亚光。

public class GetClientDirections extends MapActivity implements LocationListener{

    private MapController mapController;
    private MapView mapView;

    private List<Overlay> mapOverlays;
    private StringBuffer response = null;
    private static final String TAG = GetClientDirections.class.getSimpleName();
    private double lon;
    private double lat;
    private JSONArray routes = null;
    private JSONObject bounds = null;
    private JSONObject northeast = null;
    private JSONObject anonObject;
    private JSONObject overViewPolyline;
    private String stringUrl;
    private String polyPoints;
    Context context;
    private String endAddr;
    private GeoPoint startAddr;
    BroadcastReceiver locationChangereceiver;
    double lati;
    double lngi;
    boolean isTrafficOn;
    SharedPreferences  appSharedPrefs;
    Handler handler;
    Runnable runnable;
    String rotaAutoLogout;
    int rotaAutoLogoutAsInt;
    final String               QRCODE_ACTION = "com.carefreegroup.QRCODE_ACTION";
    NfcScannerApplication      nfcscannerapplication;
    private LocationManager locationManager;

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.mapview);

        Intent intent = this.getIntent();
        String postcode = intent.getStringExtra("postcode");
        Log.e(TAG, "postcode = " + postcode);
        appSharedPrefs = PreferenceManager.getDefaultSharedPreferences(this);
        nfcscannerapplication = (NfcScannerApplication) getApplication();


                context = this;
                endAddr = postcode;

                isTrafficOn = false;

                rotaAutoLogout = appSharedPrefs.getString("120", null);    
                rotaAutoLogoutAsInt = Integer.parseInt(rotaAutoLogout);

                if(rotaAutoLogoutAsInt > 0){
                    initHandler();
                    handler.postDelayed(runnable, rotaAutoLogoutAsInt * 1000);
                    }   





    }// end of onCreate


    public void initHandler(){

          handler = new Handler();
          runnable = new Runnable() {
                public void run() {
                    returnToMenu();

                }

                private void returnToMenu() {
                    Intent intent2 = new Intent(GetClientDirections.this,
                            NfcscannerActivity.class);
                    intent2.setAction(QRCODE_ACTION);
                    intent2.putExtra("carerid", nfcscannerapplication.getCarerID());
                    startActivity(intent2);
                }
            };

        }


    @Override
    public boolean dispatchTouchEvent(MotionEvent ev) {

        Log.e(TAG, "screen touched");
           if(rotaAutoLogoutAsInt > 0){

            handler.removeCallbacks(runnable);
            handler = null;
            runnable = null;
            initHandler();
            handler.postDelayed(runnable, rotaAutoLogoutAsInt * 1000);
            Log.e(TAG, " reset timer");
           }
            return super.dispatchTouchEvent(ev);

    }




    @Override
    protected void onPause() {
        locationManager.removeUpdates(this);
         handler.removeCallbacks(runnable);
        super.onPause();
    }




    @Override
    protected void onResume() {
        locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
        locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, this);

            handler.removeCallbacks(runnable);
            initHandler();
            handler.postDelayed(runnable, rotaAutoLogoutAsInt * 1000);

        super.onResume();
    }





    @Override
    protected void onStop() {
        handler.removeCallbacks(runnable);

        super.onStop();
    }





    private class AsyncGetRoute extends AsyncTask<Void, Void, Void> {


        @Override
        protected Void doInBackground(Void... params) {

            getRoute();
            return null;
        }


        @Override
        protected void onPostExecute(Void result) {

            String jsonOutput = response.toString();
            Log.e(TAG, "jsonOutput = " + jsonOutput);

            JSONObject results = null;
            try {

                results = new JSONObject(jsonOutput);

                routes = results.getJSONArray("routes");

                anonObject = routes.getJSONObject(0);
                bounds = anonObject.getJSONObject("bounds");
                overViewPolyline = anonObject.getJSONObject("overview_polyline");
                polyPoints = overViewPolyline.getString("points");
                Log.e(TAG, "overview_polyline  = " + overViewPolyline);
                Log.e(TAG, "points  = " + polyPoints);

                northeast = bounds.getJSONObject("northeast");

                lat = (Double) northeast.get("lat");

                lon = (Double) northeast.get("lng");

                Log.e(TAG, "lon/lat = " + lon + " " + lat);

            } catch (NumberFormatException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (JSONException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }



            List<GeoPoint> list = decodePoly(polyPoints);



            mapView = (MapView) findViewById(R.id.cfmapview);
            mapView.setBuiltInZoomControls(true);
            mapView.setEnabled(true);
            mapView.setSatellite(true);

            mapController = mapView.getController();
            mapController.setZoom(10);
            mapOverlays = mapView.getOverlays();
            mapOverlays.clear();
            mapOverlays.add(new RoutePathOverlay(list, getApplicationContext()));
            mapController.animateTo(new GeoPoint(list.get(0).getLatitudeE6(), list
                    .get(0).getLongitudeE6()));

            mapView.invalidate();

            super.onPostExecute(result);
        }


    }





    public void getRoute() {

        response = new StringBuffer();
        URL url = null;
        try {
            url = new URL(stringUrl);
        } catch (MalformedURLException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        HttpURLConnection httpconn = null;
        try {
            httpconn = (HttpURLConnection) url.openConnection();
        } catch (IOException e1) {
            // TODO Auto-generated catch block
            e1.printStackTrace();
        }
        try {
            if (httpconn.getResponseCode() == HttpURLConnection.HTTP_OK) {
                // Log.e(TAG,"response code OK ");
                BufferedReader input = new BufferedReader(
                        new InputStreamReader(httpconn.getInputStream()), 8192);
                String strLine = null;

                while ((strLine = input.readLine()) != null) {
                    // Log.e(TAG,""+strLine);
                    response.append(strLine);
                }
                input.close();
            }
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }


    }// end of getRoute




    private List<GeoPoint> decodePoly(String encoded) {

        List<GeoPoint> poly = new ArrayList<GeoPoint>();
        int index = 0, len = encoded.length();
        int lat = 0, lng = 0;

        while (index < len) {
            int b, shift = 0, result = 0;
            do {
                b = encoded.charAt(index++) - 63;
                result |= (b & 0x1f) << shift;
                shift += 5;
            } while (b >= 0x20);
            int dlat = ((result & 1) != 0 ? ~(result >> 1) : (result >> 1));
            lat += dlat;

            shift = 0;
            result = 0;
            do {
                b = encoded.charAt(index++) - 63;
                result |= (b & 0x1f) << shift;
                shift += 5;
            } while (b >= 0x20);
            int dlng = ((result & 1) != 0 ? ~(result >> 1) : (result >> 1));
            lng += dlng;

            GeoPoint p = new GeoPoint((int) (((double) lat / 1E5) * 1E6),
                    (int) (((double) lng / 1E5) * 1E6));
            poly.add(p);
        }

        return poly;
    }

    @Override
    protected boolean isRouteDisplayed() {
        // TODO Auto-generated method stub
        return false;
    }




    @Override
    public void onLocationChanged(Location location) {
         lati =  (location.getLatitude());
         lngi =  (location.getLongitude());
         startAddr = new GeoPoint((int)(lati*1000000.0), (int)(lngi*1000000.0));
        Log.e(TAG, "lat = " + lati);
        Log.e(TAG, "lon = " + lngi);
        Log.e(TAG, "lat after cast  = " + (int)(lati * 1000000));
        Log.e(TAG, "lon after cast = " + (int)(lngi * 1000000));
        locationManager.removeUpdates(this);
        StringBuilder sb = new StringBuilder();
        sb.append("http://maps.google.com/maps/api/directions/json?origin=");
        //sb.append(startAddr);
        sb.append(lati);
        sb.append(",");
        sb.append(lngi);
        sb.append("&destination=");
        sb.append(endAddr);
        sb.append("&sensor=false");

        stringUrl = sb.toString();
        Log.e(TAG, "url = " + stringUrl);
        AsyncGetRoute agr = new AsyncGetRoute();
        agr.execute();

    }




    @Override
    public void onProviderDisabled(String provider) {
        // TODO Auto-generated method stub

    }




    @Override
    public void onProviderEnabled(String provider) {
        // TODO Auto-generated method stub

    }




    @Override
    public void onStatusChanged(String provider, int status, Bundle extras) {
        // TODO Auto-generated method stub

    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        MenuInflater inflater = getMenuInflater();
        inflater.inflate(R.layout.menutogglemapview, menu);
        return true;

    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {


        switch (item.getItemId()) {

    case R.id.satellite:

        mapView.setSatellite(true);

        return true;

    case R.id.terrain:

        mapView.setSatellite(false);

        return true;

    case R.id.traffic:



        if(isTrafficOn == false){
        mapView.setTraffic(true);
        isTrafficOn = true;
        }else{
            mapView.setTraffic(false);
            isTrafficOn = false;
        }

        return true;



    default:

        return super.onOptionsItemSelected(item);

        }
    }

}

1 个答案:

答案 0 :(得分:1)

您可以使用以下方法简化与启动/停止此计时器相关的所有代码:

//Generic Task Start/Stop 

private Handler mHandler = new Handler();

private void startTimer(Runnable Task, long delay) {  
    mHandler.removeCallbacks(Task);       
    mHandler.postDelayed(Task, delay);    
}

private void stopTimer(Runnable Task) {  
    mHandler.removeCallbacks(Task);       
}

//Now your specific code

private Runnable tReturnToMenu = new Runnable() {
    public void run() {
         returnToMenu();
    }
};

@Override
public boolean dispatchTouchEvent(MotionEvent ev) {

    Log.e(TAG, "screen touched");
       if(rotaAutoLogoutAsInt > 0){
             stopTimer(tButtonFadeOut);
             startTimer(tButtonFadeOut);
             Log.e(TAG, " reset timer");
       }
        return super.dispatchTouchEvent(ev);

}

问候。