2010-12-07 6 views
1

나는 Location API를 많이 사용하려고합니다. LocationListener로 TextView를 새로 고치는 간단한 Activity를 수행하면 아무런 문제가 없습니다.Android 위치 및 스레드

중요한 점은, 모든 Location 항목을 주 Activity에 의해 호출되는 Manager 클래스와 같이 배치해야한다는 것입니다. 그래서 나는 그 클래스 안에 모든 것을 넣고 그 위치를 Activity에 말해야한다. 이 활동입니다 :

@Override 
public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState);   
    setContentView(R.layout.main); 
    g = new GPSManager(getApplicationContext()); 
    t = new Thread(g); 
    t.start(); 
    updateWithNewLocation(g.getLocation()); 
}  
private void updateWithNewLocation(Location location) { 
    String latLongString; 
    TextView myLocationText; 
    myLocationText = (TextView)findViewById(R.id.loca); 
    if (location != null) { 
     double lat = location.getLatitude(); 
     double lng = location.getLongitude(); 
     latLongString = "Lat:" + lat + "\nLong:" + lng; 
    } else { 
     latLongString = "No location found"; 
    } 
    myLocationText.setText("Your Current Position is:\n" + 
    latLongString); 
}  

그리고 이것은 "관리자"클래스 :

public GPSManager(Context context) { 
    locationManager = (LocationManager)context.getSystemService(service); 
    String service = Context.LOCATION_SERVICE; 
    Criteria criteria = new Criteria(); 
    criteria.setAccuracy(Criteria.ACCURACY_FINE); 
    criteria.setAltitudeRequired(false); 
    criteria.setBearingRequired(false); 
    criteria.setCostAllowed(true); 
    criteria.setPowerRequirement(Criteria.POWER_LOW); 
    provider = locationManager.getBestProvider(criteria, true); 
} 
public Location getLocation() { 
    return this.location; 
} 
private final LocationListener locationListener = new LocationListener() { 
    public void onLocationChanged(Location location) { 
     Manager.this.location=location; 
    } 
    public void onProviderDisabled(String provider){ 
     locationManager.removeUpdates(this); 
    } 
    public void onProviderEnabled(String provider){ } 
    public void onStatusChanged(String provider, int status, 
     Bundle extras){ } 
    }; 

@Override 
public void run() { 
    Looper.prepare(); 
    locationManager.requestLocationUpdates(provider, 0, 0, 
      locationListener);   
    location = locationManager.getLastKnownLocation(provider); 
    Looper.loop(); 
    Looper.myLooper().quit(); 
} 
private Handler handler = new Handler() { 
@Override 
public void handleMessage(Message msg) { 
    locationManager.removeUpdates(locationListener); 
} 

내가 가지고있는 문제가 아니라, 전혀 작동하지 않는 것입니다! 이 코드를 액티비티에 포함 시키면 관련 스레드가 없습니다. 하지만 이렇게하면 "위치를 찾을 수 없음"이라고 표시됩니다. Manager 클래스가 항상 변경 사항을 수신하도록해야하므로 현재 위치를 요청할 때 업데이트됩니다.

답변

0

옵션 # 1 : "manager"클래스를 삭제하십시오.

옵션 # 2 : "manager"클래스를 Service으로 만듭니다.

옵션 # 3 : "manager"클래스를 사용자 정의 Application으로 만드십시오.

옵션 # 4 : ThreadHandlerThread으로 바꿉니다.

+0

답변 해 주셔서 감사합니다. 관리자 클래스를 삭제하는 것은 분명히 옵션이 아니지만 서비스 또는 응용 프로그램으로 만들지 않으므로 HandlerThread를 만드는 것이 가장 좋은 방법입니다. 문제는 구현 방법에 대한 정보를 찾을 수 없다는 것입니다. 여분의 손을 줄 수 있어요? 고마워요 :) – ferostar

+0

@ Peter Canthropus : 나는 결코 HandlerThread를 사용하지 않았습니다. IMHO의 네 가지 옵션 중 가장 나쁜 것입니다. 제 생각에 당신이 이것을 "매니저"로 끌어 낸 이유는 그것이 당신이 여러 활동에 걸쳐서 일하기를 원한다는 것입니다. 이 경우 일부 스레드를 포크하는 것은 매우 나쁜 생각입니다. 관리자 *는 Android 응용 프로그램 수명주기를 인식하는 일부 구성 요소가 "관리"해야하므로 응용 프로그램이 포 그라운드에 있지 않을 때이 스레드를 완전히 종료 할 수 있습니다. – CommonsWare

0

필자는 LocationListener와 자신의 Threads/HandlerThreads를 섞은 위치 업데이트를 수신하지 못했던 경험이 비슷했습니다. 해결책은 PendingIntent를 사용하는 것이 었습니다 : How to receive location updates without using a service

그냥 작동합니다!