나는 현재 사용자의 위치와 다른 활동의 우편 번호 사이의 경로를 그려주는 앱을 가지고있다. 하나의 기능을 제외하고는 모두 잘 작동합니다. 핸들러/실행 가능 메커니즘을 통해 타이머를 구현했습니다. 디스플레이가 예를 들어 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);
}
}
}
그리고'removeCallbacks()'를 호출했다고 확신 하시겠습니까? BTW,'onCreate'에서'Handler'를 반복해서 만들 필요가 없습니다. –
@Code Painters 안녕하세요, 전화를 걸었습니다. – turtleboy
하나의'Handler'와 하나의'Runnable' 만 생성하십시오. 지금 당장 당신은 모든 터치 이벤트마다 하나씩 만들어야합니다. 또한 취소 - 및 - 일정 변경 논리를 덤프하는 것이 좋습니다. 'Runnable'을 2 초마다 실행하도록 설정하고 사용자가 마지막으로 화면을 터치 한 시간 ('dispatchTouchEvent()'에 의해 유지 된 타임 스탬프)이 원하는 타임 아웃 시간을 초과했는지 확인하십시오. – CommonsWare