I am having issues with GoogleMap due to the fact that it gets the map asynchronously using MapView#getMapAsync.
I am experiencing a NullPointerException due to the #getMapAsync not returning in time when my Activity is passing markers to the GoogleMap object.
Can this be done synchronously or is there a better solution? Adding it to the fragment bundle would not work for me as the activity may pass the fragment markers after the #commit()
GoogleMapsFragment
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// inflate and return the layout
View v = inflater.inflate(R.layout.fragment_google_map, container,
false);
ButterKnife.bind(this, v);
mMapView.onCreate(savedInstanceState);
mMapView.onResume();// needed to get the map to display immediately
try {
MapsInitializer.initialize(getActivity().getApplicationContext());
} catch (Exception e) {
e.printStackTrace();
}
Bundle bundle = getArguments();
if(bundle != null){
initialMarkers = bundle.getParcelableArrayList("markers");
}
mMapView.getMapAsync(new OnMapReadyCallback() {
#Override
public void onMapReady(GoogleMap googleMap) {
mGoogleMap = googleMap;
if (mCameraPos != null) {
mGoogleMap.moveCamera(CameraUpdateFactory.newCameraPosition(mCameraPos));
mCameraPos = null;
} else {
//Set default camera position over the United States.
CameraPosition cameraPosition = new CameraPosition.Builder()
.target(new LatLng(37.09024, -95.712891)).zoom(3).build();
mGoogleMap.moveCamera(CameraUpdateFactory
.newCameraPosition(cameraPosition));
}
}
});
return v;
}
Activity
#OnClick(R.id.loadListOrMapButton)
public void onClickChangeView() {
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
if (mLocationListViewFrag.isVisible()) {
if (mGoogleMapFrag == null) {
mGoogleMapFrag = new GoogleMapFragment();
fragmentTransaction.add(R.id.fragment_container, mGoogleMapFrag);
}
bListMapButton.setText(getString(R.string.list));
fragmentTransaction.hide(mLocationListViewFrag).show(mGoogleMapFrag);
} else {
bListMapButton.setText(getString(R.string.map));
fragmentTransaction.hide(mGoogleMapFrag).show(mLocationListViewFrag);
}
fragmentTransaction.commit();
fragmentManager.executePendingTransactions();
updateDisplay();
}
UpdateDisplay
public void updateDisplay() {
if (mLocationListViewFrag != null && mLocationListViewFrag.isVisible()) {
Log.d(TAG, "Update Tax Location ListView");
mLocationListViewFrag.setLocations(mLocations);
} else if (mGoogleMapFrag != null && mGoogleMapFrag.isVisible()) {
Log.d(TAG, "Update Google Maps Markers");
//Convert locations to markers to display.
mGoogleMapFrag.clearMarkers();
for (LocationObj aLocation : mLocations) {
mGoogleMapFrag.addMarker(new MarkerOptions().position(
new LatLng(Double.valueOf(aLocation.getLat()), Double.valueOf(aLocation.getLng()))).title(aLocation.getName()));
mGoogleMapFrag.fitBounds();
}
}
}
You should move the code that handles the markers to be within the OnMapReadyCallback (https://developers.google.com/android/reference/com/google/android/gms/maps/OnMapReadyCallback) that you pass to #getMapAsync(OnMapReadyCallback callback). This will ensure the markers aren't placed until the map is available.
EDIT for additional info
Ultimately you have to solve the problem of "what do I do if someone makes #onClickChangeView get called when the map isn't ready?" From a user experience perspective, the loadListOrMapButton shouldn't even be shown until the map finishes loading. You should disable the button by default, then make this button available from within your OnMapReadyCallback. You could either grey out the button (google for "android disable button" for examples) or you could actually hide/show it with View#setVisibility.
Non-recommended approach
Although I'm hesitant to suggest it, you could instead just check if the GoogleMap is ready: from within your OnMapReadyCallback set a boolean that your outside activity can check. Something like
private boolean mapIsReady = false;
mMapView.getMapAsync(new OnMapReadyCallback() {
#Override
public void onMapReady(GoogleMap googleMap) {
// your normal code here
mapIsReady = true;
}
});
public boolean mapIsReady() {
return mapIsReady;
}
Then in the activity
#OnClick(R.id.loadListOrMapButton)
public void onClickChangeView() {
// check for null and all that jazz
if (mapsFragment.mapIsReady()) {
// updateDisplay and everything
} else {
// make a toast or something asking them to try later.
}
}
xml
<com.google.android.gms.maps.MapView
android:id="#+id/mapview"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:apiKey="#string/google_app_id"
android:clickable="true">
</com.google.android.gms.maps.MapView>
MainActivity.java
public class MainActivity extends AppCompatActivity implements OnMapReadyCallback {
LatLng sydney = new LatLng(33.8650, 151.2094);
MapView mapView;
GoogleMap map;
#Override
protected void onCreate(Bundle bundle) {
super.onCreate(bundle);
setContentView(R.layout.activity_main);
mapView = (MapView) findViewById(R.id.mapview);
mapView.getMapAsync(this);
MapsInitializer.initialize(this); /* initialize method should be called when we are not sure that map will be loaded before using it. It initialises the map.*/
mapView.onCreate(null);
mapView.onResume();
}
#Override
public void onMapReady(GoogleMap googleMap) {
map = googleMap;
map.addMarker(new MarkerOptions().position(sydney).draggable(true));
}
}
Related
I wrote a simple App with Two Activities, The First is my MainActivity and the Second is my MapsActivity.
The Code works perfectly in my MainActivity, when i press a Button i will get redirected to my MapsActivity with fixed LatLng and my actual Location.
Now i came to the conclusion that i want to implent a TabLayout (in Total 3 Tabs).
The First Tab should contain the Buttons and the functionality of my MainActivity
As already all Buttons and all the code is in my MainActivity i need to transfer it to the First Fragment.
This didnt work out, since im using alot of findViewById and the Fragment does not like that.
MainActivity:
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
private Button button;
private Button btnred;
private Button btnaura;
private double v1;
private double v12;
private double vend;
private double v1end;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
toolbar.setLogo(R.drawable.fvroth);
button = findViewById(R.id.btnroth);
btnred= findViewById(R.id.btnRednitz);
btnaura = findViewById(R.id.btnaurach);
btnaura.setOnClickListener(this);
button.setOnClickListener(this);
btnred.setOnClickListener(this);
ViewPager2 viewPager2 = findViewById(R.id.viewPager);
viewPager2.setAdapter(new weiherPageAdapter(this));
TabLayout tabLayout =findViewById(R.id.tabLayout);
TabLayoutMediator tabLayoutMediator= new TabLayoutMediator(
tabLayout, viewPager2, new TabLayoutMediator.TabConfigurationStrategy() {
#Override
public void onConfigureTab(#NonNull TabLayout.Tab tab, int position) {
switch (position){
case 0: {
tab.setText("Fliesgewässer");
tab.setIcon(R.drawable.ic_baseline_check_24);
break;
}
case 1: {
tab.setText("Weiher");
tab.setIcon(R.drawable.ic_baseline_account_circle_24);
break;
}
case 2: {
tab.setText("Schon-maß und Zeiten");
tab.setIcon(R.drawable.ic_baseline_announcement_24);
break;
}
}
}
}
);
tabLayoutMediator.attach();
}
public void openMapsActivity(){
Intent intent=new Intent(this,MapsActivity.class);
LatLng position= new LatLng(v1,v12);
intent.putExtra("Pos",position);
LatLng positionende = new LatLng(vend, v1end);
intent.putExtra("PosEnde",positionende);
startActivity(intent);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
#Override
public void onClick(View v) {
switch (v.getId()){
case R.id.btnroth:
v1= 49.21344;
v12= 11.171002;
vend= 49.211946;
v1end= 11.158726;
openMapsActivity();
break;
case R.id.btnRednitz:
v1= 49.250451;
v12= 11.084395;
vend= 49.269385;
v1end= 11.076057;
openMapsActivity();
break;
case R.id.btnaurach:
v1= 49.244672;
v12= 11.043886;
vend=49.254027;
v1end= 11.080881;
openMapsActivity();
break;
}
}
MapActivity
public class MapsActivity extends FragmentActivity implements OnMapReadyCallback {
Location currentLocation;
FusedLocationProviderClient fusedLocationProviderClient;
private static final int REQUEST_CODE = 101;
private GoogleMap mMap;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_maps);
fusedLocationProviderClient = LocationServices.getFusedLocationProviderClient(this);
fetchLastLocation();
// Obtain the SupportMapFragment and get notified when the map is ready to be used.
// Construct a GeoDataClient
}
private void fetchLastLocation() {
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this,new String[]
{Manifest.permission.ACCESS_FINE_LOCATION},REQUEST_CODE);
return;
}
Task<Location> task = fusedLocationProviderClient.getLastLocation();
task.addOnSuccessListener(new OnSuccessListener<Location>() {
#Override
public void onSuccess(Location location) {
if(location != null){
currentLocation = location;
Toast.makeText(getApplicationContext(),currentLocation.getLatitude()+""+currentLocation.getLongitude(),Toast.LENGTH_SHORT).show();
SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
.findFragmentById(R.id.map);
mapFragment.getMapAsync(MapsActivity.this);
}
}
});
}
/**
* Manipulates the map once available.
* This callback is triggered when the map is ready to be used.
* This is where we can add markers or lines, add listeners or move the camera. In this case,
* we just add a marker near Sydney, Australia.
* If Google Play services is not installed on the device, the user will be prompted to install
* it inside the SupportMapFragment. This method will only be triggered once the user has
* installed Google Play services and returned to the app.
*/
#Override
public void onMapReady(GoogleMap googleMap) {
mMap = googleMap;
// Add a marker in Sydney and move the camera
LatLng position = getIntent().getExtras().getParcelable("Pos");
LatLng positionende= getIntent().getExtras().getParcelable("PosEnde");
LatLng aktpos = new LatLng(currentLocation.getLatitude(),currentLocation.getLongitude());
mMap.addMarker(new MarkerOptions().position(position).title("Anfang"));
mMap.addMarker(new MarkerOptions().position(positionende).title("Ende"));
mMap.addMarker(new MarkerOptions().position(aktpos).title("ich").icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_AZURE)));
mMap.animateCamera(CameraUpdateFactory.newLatLngZoom(position,15),1000,null);
}
}
For Better understanding here a Picture of the App.
I want to make an app that has on the main screen a ViewPager with a map and a profile section. Therefore, for position = 0 in the ViewPager, there is the map and for position = 1, there is the profile.
For each one of those two "sections" on the main screen, I have two activities: the map.xml with the MapActivity.java and the profile.xml with Profile.java. Both of those are inflated in the EnumFrag java class, depending on the position ( you see there an if ).
I have two issues:
The first one is that when I try to slide left or right, the map moves, not the ViewPager to the next slide. I tried to put a shape on the edge, but it is not working like the slide gesture is passing through the shape. Any help here, please?
The second is related to the first one, the MapActivity.java class is not even running because onCreate is not running (I put a Toast there so display something and nothing happened). Any help, please? (I create the map class object).
map.xml contains a simple fragment with an id of map.
MapActivity.java:
public class MapActivity extends FragmentActivity implements OnMapReadyCallback {
private GoogleMap map;
private Location me;
private FusedLocationProviderClient fusedLocationProviderClient;
private static final int REQUEST_CODE = 101;
#Override
protected void onCreate(Bundle savedInstanceState) {
Toast.makeText(this, "hey din onCreate", Toast.LENGTH_SHORT).show();
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_map);
fusedLocationProviderClient = LocationServices.getFusedLocationProviderClient(this);
getLastLocation();
}
private void getLastLocation() {
if(ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED){
ActivityCompat.requestPermissions(this,new String[]{Manifest.permission.ACCESS_FINE_LOCATION},REQUEST_CODE);
return;
}
Toast.makeText(getApplicationContext(), "hey...", Toast.LENGTH_SHORT).show();
Task<Location> task = fusedLocationProviderClient.getLastLocation();
task.addOnSuccessListener(new OnSuccessListener<Location>() {
#Override
public void onSuccess(Location location) {
if(location != null){
me = location;
SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map);
mapFragment.getMapAsync(MapActivity.this);
}
else
Toast.makeText(getApplicationContext(), "Deschide-ti locatia", Toast.LENGTH_SHORT).show();
}
});
}
#Override
public void onMapReady(GoogleMap googleMap) {
map = googleMap;
MapStyleOptions mapStyleOptions= MapStyleOptions.loadRawResourceStyle(this,R.raw.map_style);
googleMap.setMapStyle(mapStyleOptions);
LatLng point = new LatLng(me.getLatitude(),me.getLongitude());
MarkerOptions markerOptions = new MarkerOptions().position(point).title("Me");
googleMap.animateCamera(CameraUpdateFactory.newLatLng(point));
googleMap.animateCamera(CameraUpdateFactory.newLatLngZoom(point,16));
googleMap.addMarker(markerOptions);
}
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
if (requestCode == REQUEST_CODE) {
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
getLastLocation();
}
}
}
}
Profile.java
public class Profile extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_profile);
EditText username = findViewById(R.id.usernameProfile);
username.setText(MainScreen.getUsername());
}
}
EnumFragment.java
public class EnumFragments extends PagerAdapter {
private Context context;
public EnumFragments(Context context) {
this.context = context;
}
#NonNull
#Override
public Object instantiateItem(#NonNull ViewGroup container, int position) {
LayoutInflater layoutInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View view;
MapActivity mapActivity = new MapActivity();
switch (position){
case 0:
view = layoutInflater.inflate(R.layout.activity_profile,null);
break;
default:
view = layoutInflater.inflate(R.layout.activity_map,null);
break;
}
ViewPager viewPager = (ViewPager)container;
viewPager.addView(view);
return view;
}
#Override
public void destroyItem(#NonNull ViewGroup container, int position, #NonNull Object object) {
ViewPager viewPager = (ViewPager)container;
View view = (View) object;
viewPager.removeView(view);
}
#Override
public int getCount() {
return 2;
}
#Override
public boolean isViewFromObject(#NonNull View view, #NonNull Object object) {
return view == object;
}
}
MainScreen.java
public class MainScreen extends AppCompatActivity {
private static String username;
private ViewPager viewPager;
private EnumFragments enumFragments;
private static int userID;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main_screen);
Bundle extras = getIntent().getExtras();
userID = extras.getInt("userID");
username = extras.getString("username");
viewPager = findViewById(R.id.mainSlider);
EnumFragments enumFragments = new EnumFragments(this);
viewPager.setAdapter(enumFragments);
}
public static int getUserID() {
return userID;
}
public static String getUsername() {
return username;
}
#Override
public void onBackPressed() {
//Nothing
}
}
Why you don't add the MapActivity into the MainScreen Activity. You even don't use the MapActivity in your PagerAdapter class. I would make an other attribute in the constructor of your PagerAdapter, after this :
private MapActivity current;
public EnumFragments(MapActivity map_activity)
{
this.current = map_activity;
}
then I would put a getter method in the map_activity, wich returns a view, where you can see the current GoogleMap or other features.
Your problem is that you don't use the new MapActivity...
I hope that may helps you
I can't resolve this problem. I trying to create Fragment with a map and I have this done. When I add static Long, Lat value the map show this o a map, But when I trying to make it automatic with getting localization in runnable the application just open the map and don't show specific LongLand values.
How to do this?
For getting long and late I'm using LocalizationManager, of course, I add permissions in manifest and also check runtime
public class LocalizationFragment extends Fragment implements OnMapReadyCallback {
private GoogleMap map;
MapView mapView;
View mview;
private double latitude, longtitude;
private Handler handler;
private Runnable runnable;
public LocalizationFragment() {
// Required empty public constructor
}
#Override
public void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
mview = inflater.inflate(R.layout.fragment_localization, container, false);
handler = new Handler();
getLocation();
if (ContextCompat.checkSelfPermission(getContext(), android.Manifest.permission.CAMERA)
!= PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(getActivity(), new String[]{Manifest.permission.ACCESS_COARSE_LOCATION}, 13);
}
if (ContextCompat.checkSelfPermission(getContext(), android.Manifest.permission.CAMERA)
!= PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(getActivity(), new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, 11);
}
return mview;
}
#OnClick(R.id.button)
public void buttonStart() {
getLocation();
}
#Override
public void onViewCreated(View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
mapView = (MapView) mview.findViewById(R.id.mapView);
if (mapView != null) {
mapView.onCreate(null);
mapView.onResume();
mapView.getMapAsync(this);
}
}
private void getLocation() {
LocationManager locationManager = (LocationManager) getContext().getSystemService(Context.LOCATION_SERVICE);
LocationListener locationListener = new LocationListener() {
#Override
public void onStatusChanged(String provider, int status, Bundle extras) {
// TODO Auto-generated method stub
}
#Override
public void onProviderEnabled(String provider) {
// TODO Auto-generated method stub
}
#Override
public void onProviderDisabled(String provider) {
// TODO Auto-generated method stub
}
#Override
public void onLocationChanged(Location location) {
// TODO Auto-generated method stub
latitude = location.getLatitude();
longtitude = location.getLongitude();
}
};
if (ActivityCompat.checkSelfPermission(getContext(), Manifest.permission.ACCESS_FINE_LOCATION)
!= PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission
(getContext(), Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
return;
}
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, locationListener);
}
#Override
public void onMapReady(final GoogleMap googleMap) {
MapsInitializer.initialize(getContext());
map = googleMap;
googleMap.setMapType(GoogleMap.MAP_TYPE_NORMAL);
runnable = new Runnable() {
#Override
public void run() {
getLocation();
googleMap.addMarker(new MarkerOptions().position(new LatLng(latitude, longtitude)).title("Statue").snippet("Something"));
CameraPosition liberty = CameraPosition.builder().target(new LatLng(latitude, longtitude)).zoom(15).bearing(0).tilt(45).build();
googleMap.moveCamera(CameraUpdateFactory.newCameraPosition(liberty));
handler.postDelayed(this, 5000);
}
};
}
}
You need to add markers form the main thread.add this to your runnable.
runOnUiThread(new Runnable() {
#Override
public void run() {
googleMap.addMarker(new MarkerOptions().position(new LatLng(latitude, longtitude)).title("Statue").snippet("Something"));
}
});
I think this problem come from synchronize data. If you got location after add marker, it is meaningless, you get no location, and you have no marker on map, try to move action add marker into onLocationChanged
A tab within my view pager contains a map view is showing some unexpected behaviour. For some reason whenever I go to a different tab and return to the map view tab, all 4 pins within my map view appear when only 2 of them are supposed to appear. Does anyone know why this has happened? What can be done in order to prevent this from happening?
Stage 1 (flicked the top switch)
Stage 2 (flicked the bottom switch)
Stage 3 (switching to a different tab, then returning back to the map tab)
Java class
public class FragmentCentralPark extends android.support.v4.app.Fragment implements OnMapReadyCallback {
public FragmentCentralPark() {
// Required empty constructor
}
GoogleMap mGoogleMap;
MapView mMapView;
SwitchCompat swt0;
SwitchCompat swt1;
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_centralpark, container, false);
mMapView = (MapView) v.findViewById(R.id.map_centralpark);
mMapView.onCreate(savedInstanceState);
mMapView.getMapAsync(this); //this is important
swt0 = (SwitchCompat) v.findViewById(R.id.switch0_map_centralpark);
swt1 = (SwitchCompat) v.findViewById(R.id.switch1_map_centralpark);
return v;
}
#Override
public void onMapReady(GoogleMap googleMap) {
mGoogleMap = googleMap;
mGoogleMap.getUiSettings().setZoomControlsEnabled(true);
mGoogleMap.setBuildingsEnabled(true);
mGoogleMap.setMapType(GoogleMap.MAP_TYPE_NORMAL);
swt0.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
initMap0(isChecked);
}
});
swt1.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
initMap1(isChecked);
}
});
initMap0(swt0.isChecked());
initMap1(swt1.isChecked());
// Add markers and move the camera
LatLng centralpark_museum1 = new LatLng(40.785407, -73.957145);
mGoogleMap.addMarker(new MarkerOptions()
.position(centralpark_museum1)
);
LatLng centralpark_museum2 = new LatLng(40.782993, -73.958985);
mGoogleMap.addMarker(new MarkerOptions()
.position(centralpark_museum2)
);
// Updates the location and zoom level of the MapView
CameraUpdate cameraUpdate = CameraUpdateFactory.newLatLngZoom(new LatLng(40.780437, -73.981063), 16);
mGoogleMap.animateCamera(cameraUpdate);
}
#Override
public void onResume() {
super.onResume();
mMapView.onResume();
}
#Override
public void onPause() {
super.onPause();
mMapView.onPause();
}
#Override
public void onDestroy() {
super.onDestroy();
mMapView.onDestroy();
}
#Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
mMapView.onSaveInstanceState(outState);
}
#Override
public void onLowMemory() {
super.onLowMemory();
mMapView.onLowMemory();
}
private void initMap0(boolean isChecked){
if (isChecked) {
mGoogleMap.setMapStyle(new MapStyleOptions(getResources()
.getString(R.string.style_json)));
} else {
mGoogleMap.setMapStyle(null);
}
}
private void initMap1(boolean isChecked){
if (isChecked) {
mGoogleMap.clear();
// Add markers and move the camera
LatLng centralpark__theatre1 = new LatLng(40.780287, -73.968832);
mGoogleMap.addMarker(new MarkerOptions()
.position(centralpark_theatre1)
);
LatLng centralpark__theatre2 = new LatLng(40.780437, -73.981063);
mGoogleMap.addMarker(new MarkerOptions()
.position(centralpark_theatre2)
);
// Updates the location and zoom level of the MapView
CameraUpdate cameraUpdate = CameraUpdateFactory.newLatLngZoom(new LatLng(40.780437, -73.981063), 16);
mGoogleMap.animateCamera(cameraUpdate);
} else {
mGoogleMap.clear();
// Add markers and move the camera
LatLng centralpark_museum1 = new LatLng(40.785407, -73.957145);
mGoogleMap.addMarker(new MarkerOptions()
.position(centralpark_museum1)
);
LatLng centralpark_museum2 = new LatLng(40.782993, -73.958985);
mGoogleMap.addMarker(new MarkerOptions()
.position(centralpark_museum2)
);
// Updates the location and zoom level of the MapView
CameraUpdate cameraUpdate = CameraUpdateFactory.newLatLngZoom(new LatLng(40.780437, -73.981063), 16);
mGoogleMap.animateCamera(cameraUpdate);
}
}
}
I am using google maps v2 with actionbar tab fragment. everything is works fine but i need to update my maps location by passing lat long from first tab (first fragment) as map is on second tab. I am passing latlong via constructor.
firstly the problem was handling the lifecycle of fragment on viewpager, but by following this tutorial the problem was solved. now i am using map updation method in "onFragmentPause" but it is throwing null point exception still it works fine if i place it in "onViewCreate()" code showing in details.
Tracking fragment:
public class Track extends Fragment implements FragmentLifecycle {
private static GoogleMap mMap;
private static Double latitude, longitude;
private static String vAddress;
private static View Track;
DataHandler dh;
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
if(activity instanceof DataHandler)
{
dh = (DataHandler)activity;
}
else
throw new ClassCastException();
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
super.onCreateView(inflater, container, savedInstanceState);
Track = inflater.inflate(R.layout.activity_track, container, false);
return Track;
}
public void setUpMapIfNeeded() {
// Try to obtain the map from the SupportMapFragment.
mMap = ((SupportMapFragment) getFragmentManager()
.findFragmentById(R.id.location_map)).getMap();
setUpMap();
}
private static void setUpMap() {
try{
mMap.setMyLocationEnabled(true);
mMap.addMarker(new MarkerOptions().position(new LatLng(latitude, longitude)).title(vAddress).icon(BitmapDescriptorFactory.fromResource(R.drawable.marker2)));
mMap.animateCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(latitude,
longitude), 12.0f));
}
catch(Exception e){
Log.wtf("this error", "ok");
}
}
public void onDestroyView() {
super.onDestroyView();
try {
Fragment fragment = (getFragmentManager().findFragmentById(R.id.location_map));
FragmentTransaction ft = getActivity().getSupportFragmentManager().beginTransaction();
ft.remove(fragment);
ft.commit();
} catch (Exception e) {
e.printStackTrace();
}
}
#Override
public void onPauseFragment() {
}
#Override
public void onResumeFragment() {
Log.i("state", "onResumeFragment()");
latitude= 73.023333; //getting latitude from first tab(fragment)by calling constructor
longitude= 67.939322;
vAddress = "some address";
setUpMapIfNeeded();
}
now if i place setUpMapIfNeeded() in onCreateView and change the rotation, it recreate and update the location but error when put in onResumeFragment().
kindly help me out and sorry if i could not describe effectively.
Error
since logcat shows the error at line 48. that is
.findFragmentById(R.id.location_map)).getMap();
this is Activity_Track
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<fragment
android:id="#+id/location_map"
android:layout_width="match_parent"
android:layout_height="match_parent"
class="com.google.android.gms.maps.SupportMapFragment" />
</LinearLayout>
If i change from static values to this it crashes a give null point exception at line latitude= dh.getLat();
#Override
public void onResumeFragment() {
Log.i("state", "onResumeFragment()");
latitude= dh.getLat(); //getting latitude from first tab(fragment)by calling constructor
longitude= dh.getLong();
vAddress = dh.getAddress();
setUpMap();
}