2012-11-16 4 views
0

나는 현재 사용자의 위치와 다른 활동의 우편 번호 사이의 경로를 그려주는 앱을 가지고있다. 하나의 기능을 제외하고는 모두 잘 작동합니다. 핸들러/실행 가능 메커니즘을 통해 타이머를 구현했습니다. 디스플레이가 예를 들어 2 분 동안 미리 결정된 시간 동안 터치되지 않으면, 사용자가 다시 로그인해야하는 메뉴 화면으로 돌아갑니다. 내 앱의 보안 기능입니다.android runnable not cancelled

사용자가 화면을 터치하면 타이머가 재설정되도록 dispatchTouchEvent 메서드를 재정의했습니다. 이 부분이 올바르게 작동하지 않습니다. 사용자가 화면을 터치했는지 여부에 관계없이 앱이 메뉴 화면으로 이동합니다.

나는 타이머를 다시 시작하기 전에 null로 핸들러와 runnable을 설정하고 runnable에 대한 모든 콜백을 제거한다고 생각했다.

누구나 현재 실행 파일을 취소하고 다시 시작하는 방법을 알려줄 수 있습니까?

다음은 전체 코드입니다. 미리 감사드립니다. 매트.

//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); 

} 

감사합니다 :

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); 

     } 
    } 

} 
+0

그리고'removeCallbacks()'를 호출했다고 확신 하시겠습니까? BTW,'onCreate'에서'Handler'를 반복해서 만들 필요가 없습니다. –

+0

@Code Painters 안녕하세요, 전화를 걸었습니다. – turtleboy

+1

하나의'Handler'와 하나의'Runnable' 만 생성하십시오. 지금 당장 당신은 모든 터치 이벤트마다 하나씩 만들어야합니다. 또한 취소 - 및 - 일정 변경 논리를 덤프하는 것이 좋습니다. 'Runnable'을 2 초마다 실행하도록 설정하고 사용자가 마지막으로 화면을 터치 한 시간 ('dispatchTouchEvent()'에 의해 유지 된 타임 스탬프)이 원하는 타임 아웃 시간을 초과했는지 확인하십시오. – CommonsWare

답변

1

는 다음과 같은 방법을 사용하여 시작 /을 stoping이 타이머를 관련된 모든 코드를 단순화 할 수 있습니다.

+0

'Task' 매개 변수를 소문자로 만들 것을 제안합니다. –

+0

@Luis Hi Luis, 아니요. 사용자가 화면에 닿았는지에 관계없이 작업 시작 2 분 후 returnToMenu 메서드를 호출합니다. 시간이 재설정되지 않습니다. 원래 코드는 실제로 오프닝 포스트에있는 활동 이전의 2 가지 활동에서 작동합니다. 이 활동으로는 효과가없는 것 같습니다. 이 액티비티와의 차이점은 Google지도 뷰가 있고 위치 수신기를 구현한다는 것입니다. – turtleboy

+0

@Luis 실제로 저는 이것을 다시 테스트했으며이 액티비티 이전의 2 가지 액티비티에있는 원래 코드는 returnToMenu 터치 이벤트에 관계없이 2 분 후 그래서 아무도 작동하지 않습니다. 어떤 이유로 타이머가 재설정되지 않습니다. – turtleboy