I have main activity with fragments and one of the fragments is Map Fragment. Now, when i tap there, every time it opens slow. I am using singleton instance of fragment, but it still doesnt work as expected. Here is a good of that class:
public MapsFragment() {
gson = new Gson();
}
public static MapsFragment getInstance() {
if (mInstance == null)
mInstance = new MapsFragment();
return mInstance;
}
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable final Bundle savedInstanceState) {
final View v = inflater.inflate(R.layout.fragment_maps, container, false);
mOnSavedinstance = savedInstanceState;
mMapView = (MapView) v.findViewById(R.id.map);
mMapWrapperLayout = (MapWrapperLayout) v.findViewById(R.id.map_relative_layout);
mMapView.getMapAsync(MapsFragment.this);
mMapView.onCreate(savedInstanceState);
mMapView.requestFocus();
MapsInitializer.initialize(getActivity());
return v;
}
#Override
public void onMapReady(GoogleMap googleMap) {
mGoogleMap = googleMap;
// MapWrapperLayout initialization
// 39 - default marker height
// 20 - offset between the default InfoWindow bottom edge and it's content bottom edge
mMapWrapperLayout.init(mGoogleMap, Constants.MARKER_HEIGHT);
if (ActivityCompat.checkSelfPermission(getActivity(), Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(getActivity(), Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
mGoogleMap.setMyLocationEnabled(false);
}
mGoogleMap.setMapType(GoogleMap.MAP_TYPE_NORMAL);
setUpMap();
}
private void setUpMap() {
new Thread(new Runnable() {
#Override
public void run() {
final ArrayList<MarkerOptions> markerOptionses = new ArrayList<MarkerOptions>();
int counter = 0;
for (final Places places : Model.getInstance().getPlaces()) {
LatLng location = new LatLng(Double.parseDouble(places.getLat()), Double.parseDouble(places.getLon()));
final MarkerOptions options = new MarkerOptions();
options.snippet(gson.toJson(places));
options.position(location);
options.title(String.valueOf(counter));
markerOptionses.add(options);
counter++;
}
getActivity().runOnUiThread(new Runnable() {
#Override
public void run() {
for (MarkerOptions markerOptionse : markerOptionses) {
mGoogleMap.addMarker(markerOptionse).setIcon(BitmapDescriptorFactory.fromResource(Model.getInstance().getPlaces()
.get(Integer.parseInt(markerOptionse.getTitle())).getMapsRes(getActivity())));
}
}
});
final CameraPosition cameraPosition = new CameraPosition.Builder()
.target(new LatLng(45.4654, 9.1859)) // Sets the center of the map to location user
.zoom(Constants.CAMERA_ZOOM_LOCATION) // Sets the zoom
.build(); // Creates a CameraPosition from the builder
getActivity().runOnUiThread(new Runnable() {
#Override
public void run() {
mGoogleMap.animateCamera(CameraUpdateFactory.newCameraPosition(cameraPosition));
mGoogleMap.setMapType(GoogleMap.MAP_TYPE_NORMAL);
mGoogleMap.setOnMapClickListener(MapsFragment.this);
// mGoogleMap.setOnInfoWindowClickListener(mInfoListener);
}
});
}
}).start();
}
#Override
public void onResume() {
mMapView.onResume();
super.onResume();
}
#Override
public void onDestroy() {
super.onDestroy();
mGoogleMap.clear();
mMapView.onDestroy();
}
#Override
public void onLowMemory() {
super.onLowMemory();
mMapView.onLowMemory();
}
You can try to add markers only if it would be visible? I mean: first move camera to start position and set zoomLevel and just after that add Markers but only if it's in visible sector. And update markers on camera move.
Related
This question already has answers here:
Location is empty at the start
(5 answers)
Closed 3 years ago.
This topic is populated in SO, but due to my limited knowledge in java, I am unable to get my location.
If I manually put latitude and longitude, my code is working as expected. I use this to put the latitude and longitude hardcoded:
class latlang {
public static double Lat=28.28;
public static double Lang=84.0;
}
which is used in other fragments, as, but not only in map:
MapFragment.java
public class MapFragment extends Fragment {
private MapView mMapView;
private GoogleMap googleMap;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_map, container, false);
mMapView = rootView.findViewById(R.id.mapView);
mMapView.onCreate(savedInstanceState);
mMapView.onResume(); // needed to get the map to display immediately
try {
MapsInitializer.initialize(getActivity().getApplicationContext());
} catch (Exception e) {
e.printStackTrace();
}
mMapView.getMapAsync(mMap -> {
googleMap = mMap;
LatLng sydney = new LatLng(latlang.Lat, latlang.Lang);
googleMap.addMarker(new MarkerOptions().position(sydney).title("Marker Title").snippet("Marker Description"));
// For zooming automatically to the location of the marker
CameraPosition cameraPosition = new CameraPosition.Builder().target(sydney).zoom(12).build();
googleMap.animateCamera(CameraUpdateFactory.newCameraPosition(cameraPosition));
});
return rootView;
}
#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 onLowMemory() {
super.onLowMemory();
mMapView.onLowMemory();
}
}
Kindly help. I am totally confused with FusedLocationProviderClient
main_activity.java
public class MainActivity extends AppCompatActivity {
private FusedLocationProviderClient mFusedLocationClient;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
SectionsPagerAdapter sectionsPagerAdapter = new SectionsPagerAdapter(this, getSupportFragmentManager());
ViewPager viewPager = findViewById(R.id.view_pager);
viewPager.setAdapter(sectionsPagerAdapter);
//new SecondFragment();
//TabLayout tabs = findViewById(R.id.tabs);
//tabs.setupWithViewPager(viewPager);
FloatingActionButton fab = findViewById(R.id.fab);
FontDrawable drawable = new FontDrawable(this, R.string.fa_plus_solid, true, false);
drawable.setTextColor(ContextCompat.getColor(this, android.R.color.white));
fab.setImageDrawable(drawable);
fab.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
.setAction("Action", null).show();
}
});
//Check permission
if (ContextCompat.checkSelfPermission(getApplicationContext(),
android.Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED &&
ActivityCompat.checkSelfPermission(getApplicationContext(),
android.Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this,
new String[]{android.Manifest.permission.ACCESS_FINE_LOCATION,
android.Manifest.permission.ACCESS_COARSE_LOCATION}, 101);
}
}
}
First you need to initialize the fusedLocationClient like this :
In Fragment:
fusedLocationClient = LocationServices.getFusedLocationProviderClient(getContext());
In Activity:
fusedLocationClient = LocationServices.getFusedLocationProviderClient(this);
then to retrieve last known location :
fusedLocationClient.getLastLocation()
.addOnSuccessListener(getActivity(), new OnSuccessListener<Location>() {
#Override
public void onSuccess(Location location) {
// Got last known location. In some rare situations, this can be null.
if (location != null) {
// Logic to handle location object
double latitude= location.getLatitude();
double longitude= location.getLongitude();
} else {
//handle null location
}
}
});
Hope this helps!
In my Android application I have an Activity which shows list of map fragments, following is the code for it:
public class TTMapFragment extends TTFragment {
private final static String LOG_AREA = "TTMapFragment";
private SupportMapFragment mMapFragment;
private Bundle mBundle;
protected int leftPosition;
protected int topPosition;
private GoogleMap googleMap;
public GoogleMap getMap() {
if (googleMap == null) {
final CountDownLatch latch = new CountDownLatch(1);
getActivity().runOnUiThread(new Runnable() {
#Override
public void run() {
getSupportMapFragment().getMapAsync(new OnMapReadyCallback() {
#Override
public void onMapReady(GoogleMap googleMap) {
TTMapFragment.this.googleMap = googleMap;
latch.countDown();
}
});
}
});
try {
latch.await(2, TimeUnit.SECONDS);
} catch (InterruptedException e) {}
}
return googleMap;
}
public int getMapViewResourceID(return R.id.trip_small_map;);
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
final View inflatedView = super.onCreateView(inflater, container, savedInstanceState);
MapsInitializer.initialize(getActivity());
setUpMapIfNeeded();
mMapFragment = getSupportMapFragment();
mMapFragment.onCreate(mBundle);
mMapFragment.getMapAsync(new OnMapReadyCallback() {
#Override
public void onMapReady(GoogleMap googleMap) {
TTMapFragment.this.googleMap = googleMap;
int width = 0;
int height = 0;
if (mMapFragment.getView() != null) {
width = mMapFragment.getView().getWidth();
height = mMapFragment.getView().getHeight();
}
// code to get data for map and add markers on the map
//Then I call this
CameraUpdate cu = CameraUpdateFactory.newLatLngBounds(bound, width, height, padding);
try {
getMap().moveCamera(cu);
} catch (IllegalStateException e) {
// here IO get this exception : view size too small
TTLog.d(LOG_AREA, "handled view size too small issue");
}
}
});
return inflatedView;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mBundle = savedInstanceState;
}
public SupportMapFragment getSupportMapFragment() {
setUpMapIfNeeded();
return mMapFragment;
}
private void setUpMapIfNeeded() {
if (mMapFragment == null) {
mMapFragment = ((SupportMapFragment) getChildFragmentManager()
.findFragmentById(getMapViewResourceID()));
}
}
public void clearMap(){
getMap().clear();
System.gc();
TTLog.d(LOG_AREA, "clearMap done");
}
#Override
public void onDestroy() {
TTLog.d(LOG_AREA, "onDestroy");
clearMap();
super.onDestroy();
}
#Override
public void onLowMemory() {
super.onLowMemory();
System.gc();
}
}
When I call getMap().moveCamera(cu) I get a IllegalStateException: View size too small after padding. Can Anyone suggest me when can I call moveCamera() function?
Another thing I observed is, width and height are zero for the first fragment but after that It gives me non zero width and height.
I have two FrameLayout in an activity, I just replace fragments inside those FrameLayout.
It works great with everyfragment BUT the one containing the MapFragment for the GoogleMap.
When I first launch the app it works and I see the map (everything works) but when I replace the fragment and replace it back I just get a blank space like nothing is loaded.
public class MapFragment extends CustomFragment {
private GoogleMap mMap;
private Marker currentMarker;
private OnFragmentInteractionListener mListener;
public static final String ID = "MAP_FRAGMENT";
private static View view;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = null;
try {
view = inflater.inflate(R.layout.fragment_map, container, false);
} catch (InflateException e) {
Log.d("","");
}finally{
setUpMapIfNeeded();
if(view!=null)this.view=view;
return this.view;
}
}
#Override
public void onDestroyView() {
super.onDestroyView();
Fragment f = getFragmentManager().findFragmentById(R.id.map);
if (f != null)getActivity().getFragmentManager().beginTransaction().remove(f).commit();
mMap=null;
currentMarker=null;
}
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
try {
mListener = (OnFragmentInteractionListener) activity;
} catch (ClassCastException e) {
throw new ClassCastException(activity.toString()
+ " must implement OnFragmentInteractionListener");
}
}
#Override
public void onDetach() {
super.onDetach();
mListener = null;
}
private void setUpMapIfNeeded() {
// Do a null check to confirm that we have not already instantiated the map.
if (mMap == null) {
// Try to obtain the map from the SupportMapFragment.
mMap = ((com.google.android.gms.maps.MapFragment)getFragmentManager().findFragmentById(R.id.map)).getMap();
// Check if we were successful in obtaining the map.
if (mMap != null) {
setUpMap();
}
}
}
private void setUpMap() {
}
#Override
public void onPause() {
super.onPause();
}
#Override
public void update(FragmentMessage message) {
if(mMap!=null) {
Location loc = (Location) message.getMessages()[0];
if (currentMarker != null)
currentMarker.remove();
currentMarker = mMap.addMarker(new MarkerOptions().position(new LatLng(loc.getLatitude(), loc.getLongitude())).title("Marker"));
CameraPosition cameraPosition = new CameraPosition.Builder()
.target(new LatLng(loc.getLatitude(), loc.getLongitude())) // Sets the center of the map to Mountain View
.zoom(15) // Sets the zoom
.build(); // Creates a CameraPosition from the builder
mMap.animateCamera(CameraUpdateFactory.newCameraPosition(cameraPosition));
}
}
}
The mMap is never null, so the MapFragment is working I guess but I don't get anything on the screen (see screenshots below).
Does anyone have an idea ? I really don't know what is wrong.
I've the next problem, I'm trying to show some markers in a Google Map, but only show the first marker, not the others. It don't throw any exception, but only shows the first marker (the phone position).
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
context = getActivity().getApplicationContext();
v = inflater.inflate(R.layout.fragment_map, container, false);
Bundle b = getArguments();
receiveExtraData(b);
MapsInitializer.initialize(getActivity());
mMapView = (MapView) v.findViewById(R.id.map);
mMapView.onCreate(mBundle);
setUpMapIfNeeded(v);
return v;
}
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
try {
listener = (FragmentsListener) activity;
} catch (ClassCastException e) {}
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mBundle = savedInstanceState;
}
private void setUpMapIfNeeded(View inflatedView) {
if (mMap == null) {
mMap = ((MapView) inflatedView.findViewById(R.id.map)).getMap();
if (mMap != null) {
setUpMap();
}
}
}
private void setUpMap() {
GPSPoint point = new GPSPoint(context);
LatLng latLng = point.getCurrentPositionLatLng();
MarkerOptions phoneMarker = new MarkerOptions().position(latLng).title("Marker");
mMap.addMarker(phoneMarker);
phoneMarker.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_GREEN));
CameraPosition cameraPosition = new CameraPosition.Builder().target(latLng).zoom(20).build();
mMap.animateCamera(CameraUpdateFactory.newCameraPosition(cameraPosition));
addDevicesMarkers(connectedDevices);
}
#Override
public void onResume() {
super.onResume();
mMapView.onResume();
}
#Override
public void onPause() {
super.onPause();
mMapView.onPause();
}
#Override
public void onDestroy() {
mMapView.onDestroy();
super.onDestroy();
}
private void receiveExtraData(Bundle b){
connectedDevices = b.getParcelableArrayList(BundlesKeys.BLUETOOTH_DEVICES_ARRAY);
}
private void getDevicePosition(BluetoothDevice bDevice){
listener.getDeviceLocation(bDevice);
}
private void addDevicesMarkers(ArrayList<BluetoothDevice> list){
if (!list.isEmpty()){
BluetoothDevice device = list.get(0);
getDevicePosition(device);
}
}
public void addMarker(LatLng pos){
MarkerOptions deviceMarker = new MarkerOptions().position(pos).title("Device");
mMap.addMarker(deviceMarker);
}
Somebody knows the fix?? Somebody knows how to program a listener for devices location events?
You just have to use mMap.addMarker() as many times as the number of markers that you want to show. If you are using it only one time, like you are doing inside setUpMap(), you will only see one marker.
Don't forget to change your MarkerOptions attributes for each marker.
I have a strange problem with a com.google.android.gms.maps.MapView.
To check if my App crashes after the garbage collector is doing his job i force my HTC One (4.2.2) to allow only 1 running app in background. If I leave my app(home button) while showing a MapView, start any other app and resume to my app, my MapView is still showing up...but I can not move or zoom the map, it's not responding at all. Other activities are working fine. I really have no clue where the problem might be.
Hope that someone can help me out?
Here is the sourcecode of my fragment that shows the MapView
public class FragmentAdvertlistMap extends Fragment {
com.google.android.gms.maps.MapView m;
GoogleMap mMap;
ArrayList<Advert> ads;
HashMap<Marker, String> myMarker;
public final LatLngBounds.Builder builder= new LatLngBounds.Builder();
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
try {
MapsInitializer.initialize(getActivity());
} catch (GooglePlayServicesNotAvailableException e) {
// TODO handle this situation
}
View inflatedView = inflater.inflate(R.layout.activity_advert_tab2, container, false);
m = (com.google.android.gms.maps.MapView)inflatedView.findViewById(R.id.map_tab);
m.onCreate(savedInstanceState);
myMarker = new HashMap<Marker, String>();
ads= AdvertListActivity.getAdverts();
setUpMapIfNeeded(inflatedView);
mMap.setOnInfoWindowClickListener(new OnInfoWindowClickListener() {
#Override
public void onInfoWindowClick(Marker arg0) {
Intent myIntent = new Intent(getActivity(), AdvertLocationActivity.class);
Advert putadvert = DefaultApplication.dbc.getAdvertForAdvertID(Integer.parseInt(myMarker.get(arg0)));
myIntent.putExtra("advert", putadvert);
startActivity(myIntent);
}
});
return inflatedView;
}
private void setUpMapIfNeeded(View inflatedView) {
if (mMap == null) {
mMap = ((com.google.android.gms.maps.MapView) inflatedView.findViewById(R.id.map_tab)).getMap();
if (mMap != null) {
this.initMarker();
}
}
}
public void initMarker(){
for(int i=0;i<ads.size();i++){
Advert tempAd = ads.get(i);
LatLng tlalo = new LatLng(tempAd.mainLocation.latitude,tempAd.mainLocation.longitude);
builder.include(tlalo);
String address = "";
if(tempAd.mainLocation.contact_street != null){
address = address + tempAd.mainLocation.contact_street;
}
if(tempAd.mainLocation.contact_street_number != null){
address = address + " " + tempAd.mainLocation.contact_street_number;
}
Marker marker = mMap.addMarker(new MarkerOptions()
.position(tlalo)
.anchor(0.5f, 0.5f)
.title(tempAd.name)
.snippet(address)
.icon(BitmapDescriptorFactory.fromResource(R.drawable.androidpin)));
myMarker.put(marker,String.valueOf(tempAd.myid));
}
mMap.setOnCameraChangeListener(new OnCameraChangeListener() {
#Override
public void onCameraChange(CameraPosition arg0) {
mMap.moveCamera(CameraUpdateFactory.newLatLngBounds(builder.build(), 100));
mMap.setOnCameraChangeListener(null);
}
});
}
#Override
public void onResume() {
super.onResume();
m.onResume();
}
#Override
public void onPause() {
super.onPause();
m.onPause();
}
#Override
public void onDestroy() {
super.onDestroy();
m.onDestroy();
}
#Override
public void onLowMemory() {
super.onLowMemory();
m.onLowMemory();
}
}
try add this in onCreateView()
container.removeAllViews();
I found it in another similar question to yours but I lost the original link of the answer...