배경 :
사용자의 위치를 중심으로 텍스트에 위치 정보를 제공 할 수있는 앱을 만듭니다. 이렇게하려면 기본 설정에서 테스트하기 위해 간단한 자격 증명 검사와 서버 주소가 필요합니다.Google지도 현재 조각을 단편으로 대체하는 부분
문제 :
사용자가 다른 단편 등 마커 적절한지도 형태 (하이브리드), 자신의 위치를 보여주는지도 원본 단편에서 탐색하고지도 단편 복귀하려 할 때마다, LatLng 0,0 및 일반지도 (예 : 사용자 위치 표시 없음)가 기본값입니다.
초기 생각은 다른 조각으로 전환 할 때지도 조각의 상태를 저장하고 스택에서 다른 조각을 팝 때 다시로드하려고 시도했습니다. 그러나 나는 전환해야 할 때마다 MainActivity의 현재 조각을 바꾸는 것이 더 간단 할 것이라고 생각했습니다. 따라서 앱을 열면 MainActivity는 새로운 MapFragment를 만들고 PreferencesFragment로 대체하고 'saving'이 현재 MapFragment를 만들어 현재 단편을 바꿉니다. 생각이지도 내 기능을 처음로드로 내 문제를 해결할 수 있습니다.
지도 조각 포함 MFragment의 코드 :
public class MFragment extends Fragment implements android.location.LocationListener,
GooglePlayServicesClient.ConnectionCallbacks,
GooglePlayServicesClient.OnConnectionFailedListener{
private final static int CONNECTION_FAILURE_RESOLUTION_REQUEST = 9000;
private static GoogleMap map;
private static LocationClient lClient;
private final static String TAG = "MFragment";
private String provider;
private Location loc;
private LocationManager lManager;
private LatLng currentLatLng;
private final long MIN_TIME = 1000;
private final float MIN_DIST = 10;
private Update updateMarkers = new Update();
private View view;
private MapFragment mFrag;
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
mFrag = MapFragment.newInstance();
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
super.onCreateView(inflater, container, savedInstanceState);
//sets the layout for this fragment
view = inflater.inflate(R.layout.fragment_map, container, false);
//insert MapFragment into this Fragment
getActivity().getFragmentManager().beginTransaction()
.replace(R.id.mapview, mFrag)
.commit();
//get a handle on the map from the MapFragment
// map = mFrag.getMap();
//instantiates the location manager
lManager = (LocationManager) getActivity().getSystemService(Context.LOCATION_SERVICE);
//instantiate the location client
lClient = new LocationClient(getActivity(), this, this);
lClient.connect();
//run through initialization of all objects
setUpMapIfNeeded();
Log.d(TAG, "Successfully created MFragment");
return view;
}
/**
* instantiates map from the MapFragment if map is null.
*/
private void setUpMapIfNeeded() {
if (getActivity() != null && getActivity().getFragmentManager() != null &&
map == null) {
map = mFrag.getMap();
Log.d(TAG, "Map generated.");
setUpMap();
} else if (lClient.isConnected()) {
updateMap();
} else {
setUpMap();
}
}
/**
* sets up the location data for the map. conditional clause so that the GPS doesn't crash
* if the app can't get a location straight away.
*/
private void setUpMap() {
if (map != null) {
map.setMyLocationEnabled(true);
map.setMapType(GoogleMap.MAP_TYPE_HYBRID);
Criteria crit = new Criteria();
provider = lManager.getBestProvider(crit, false);
if (lManager.isProviderEnabled(LocationManager.GPS_PROVIDER)) {
loc = lManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
} else {
loc = lManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
}
lManager.requestLocationUpdates(provider, MIN_TIME, MIN_DIST, this);
}
}
protected void updateMap() {
if (servicesConnected()) {
map.clear();
currentLatLng = new LatLng(this.loc.getLatitude(), this.loc.getLongitude());
map.animateCamera(CameraUpdateFactory.newLatLngZoom(currentLatLng, 14));
map.addMarker(new MarkerOptions()
.position(currentLatLng)
.title("You"));
map.setOnMarkerClickListener(new OnMarkerClickListener() {
@Override
public boolean onMarkerClick(Marker m) {
SMSFragment sFrag = new SMSFragment();
sFrag.setMarker(m);
getActivity().getFragmentManager().beginTransaction()
.replace(android.R.id.content, sFrag)
.commit();
return false;
}
});
}
}
/**
* checks for connection to google play services
* @return
*/
private boolean servicesConnected() {
int resultCode = GooglePlayServicesUtil
.isGooglePlayServicesAvailable(getActivity().getApplicationContext());
if (ConnectionResult.SUCCESS == resultCode) {
Log.d(TAG, getString(R.string.play_available));
return true;
} else {
if (GooglePlayServicesUtil.isUserRecoverableError(resultCode)) {
GooglePlayServicesUtil
.getErrorDialog(resultCode, getActivity(),
CONNECTION_FAILURE_RESOLUTION_REQUEST).show();
} else {
Log.i(TAG, "This device is not supported");
}
return false;
}
}
@Override
public void onConnectionFailed(ConnectionResult connectionResult) {
if (connectionResult.hasResolution()) {
try {
connectionResult
.startResolutionForResult(getActivity(), CONNECTION_FAILURE_RESOLUTION_REQUEST);
} catch (IntentSender.SendIntentException e) {
e.printStackTrace();
}
} else {
Toast.makeText(getActivity(), R.string.connect_failed, Toast.LENGTH_SHORT).show();
}
}
/**
* Called after location client connects
*/
@Override
public void onConnected(Bundle arg0) {
updateMap();
}
/**
* simple display message after disconnecting.
*/
@Override
public void onDisconnected() {
Toast.makeText(getActivity(), R.string.disconnected, Toast.LENGTH_SHORT).show();
}
public void onStart() {
super.onStart();
lClient.connect();
setUpMapIfNeeded();
}
public void onResume() {
super.onResume();
lClient.connect();
setUpMapIfNeeded();
}
public void onPause() {
lClient.disconnect();
super.onPause();
}
public void onStop() {
lClient.disconnect();
super.onStop();
}
public void onDestroy() {
lClient.disconnect();
super.onDestroy();
}
@Override
public void onLocationChanged(Location location) {
this.loc = location;
updateMap();
}
@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
}
public void updateMarkers(List<Record> records){
//update map with markers corresponding to each latitude, longitude passed back from records
for (Record r : records){
map.addMarker(new MarkerOptions()
.position(new LatLng(r.getValueOfLatitude(), r.getValueOfLongitude())));
}
}
private class Update extends AsyncTask<Void, Void, Boolean> {
private List<Record> records;
protected Update() {
super();
records = new ArrayList<Record>();
}
@Override
protected Boolean doInBackground(Void... params) {
Connect conn = new Connect(getActivity());
try {
records = conn.getAll();
return true;
} catch (IOException e) {
e.printStackTrace();
}
return false;
}
protected void onPostExecute(Boolean result) {
if (result) {
updateMarkers(records);
} else {
Toast.makeText(getActivity(), R.string.rec_fail, Toast.LENGTH_SHORT).show();
}
}
}
}
그리고 (PrefsFragment에서 MFragment에) 다른 조각에서 조각을 교체하는 예 :
register = (Button) v.findViewById(R.id.register);
save.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
saveToPreferences(v);
((MainActivity)getActivity()).replaceFragment();
}
});
register.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
getActivity().getFragmentManager().beginTransaction()
.replace(android.R.id.content, new RegFragment())
.commit();
}
});
return v;
}
를 버튼은 호출 저장을 메소드를 MainActivity에서 MapFragment로 대체하려고 시도했지만, FragmentManager를 사용하여 등록 버튼과 유사한 메소드를 사용하여 맵 문제를 해결하지는 않습니다.
도움을 주시면 감사하겠습니다.
내가 액티비티 내에서 Map을 처리하는 가장 좋은 방법은 무엇일까? 액티비티가 setUpMapIfNeeded(), setUpMap(), updateMap(), 등등과지도는 여전히 일부 사용자 정의를 사용할 수 있습니까? 앱에서지도를 사용하는 것은 이번이 처음입니다. 경험 부족에 사과드립니다. – fakataha
MapFragment 또는 SupportMapFragment를 확장하는 클래스를 만들고 그 안에지도 논리 인 setUpMapIfNeeded() 메서드와 나머지를 추가하는 것이 좋습니다. – BladeCoder