Indoor Atlas: Searching in a Map - android

I'm using Indoor Atlas for an educational project based on Android.
I'd like to implement search functionality into a map that I loaded in Indoor Atlas environment, how I can this?
For example I'd like to search a room of specific, apartment, how I can implement this searching functionality?
Thanks for your time

You should mapping the location firstly.
And do test path for making your map more precise.
There is official app of IndoorAtlas, so you can use it.

First you need to map your floor using indooratlas app i.e IndoorAtlas MapCreator 2. Then you can record the coordinates using that app and then you can save the coordinates of the rooms/areas in your server and then can fetch and point it on maps after search.
/*
gimal.adobe.appsbee.com.gimbaladobe.Indooratlasmap
16/12/16
sumit-chakraborty
*/
public class IndoorAtlasMap implements OnMapReadyCallback, GoogleMap.InfoWindowAdapter, GoogleMap.OnInfoWindowClickListener {
private static final String TAG = "IndoorAtlasExample";
private IndoorAtlasCallBack mIndoorAtlasCallBack;
SupportMapFragment mapFragment;
private static final float HUE_IABLUE = 200.0f;
/* used to decide when bitmap should be downscaled */
private static final int MAX_DIMENSION = 1048;
private GoogleMap mMap; // Might be null if Google Play services APK is not available.
private Marker mMarker;
private Marker mMarkerLoc;
private GroundOverlay mGroundOverlay;
private IALocationManager mIALocationManager;
private IAResourceManager mResourceManager;
private IATask<IAFloorPlan> mFetchFloorPlanTask;
private static LatLng latlongfromlistner;
private Target mLoadTarget;
private boolean mCameraPositionNeedsUpdating;
private ArrayList<ListLatlong> latlong;
LayoutInflater inflater = null;
private TextView textViewTitle;
private RelativeLayout rl_custominfo;
public IndoorAtlasMap(IndoorAtlasCallBack mIndoorAtlasCallBack, LayoutInflater inflater) {
this.mIndoorAtlasCallBack = mIndoorAtlasCallBack;
this.inflater = inflater;
}
/**
* Listener that handles location change events.
*/
private IALocationListener mListener = new IALocationListenerSupport() {
/**
* Location changed, move marker and camera position.
*/
#Override
public void onLocationChanged(IALocation location) {
Log.d(TAG, "new location received with coordinates: " + location.getLatitude()
+ "," + location.getLongitude());
System.out.println("!!!!!!aaa" + location.toString());
if (mMap == null) {
// location received before map is initialized, ignoring update here
return;
}
latlongfromlistner = new LatLng(location.getLatitude(), location.getLongitude());
if (mMarker == null) {
// first location, add marker
mMarker = mMap.addMarker(new MarkerOptions().position(latlongfromlistner)
.icon(BitmapDescriptorFactory.defaultMarker(HUE_IABLUE)));
} else {
// move existing markers position to received location
mMarker.setPosition(latlongfromlistner);
}
// our camera position needs updating if location has significantly changed
if (mCameraPositionNeedsUpdating) {
//Create a new CameraPosition
mMap.animateCamera(CameraUpdateFactory.newLatLngZoom(latlongfromlistner, 19.0f));
mCameraPositionNeedsUpdating = false;
}
mMarker.hideInfoWindow();
}
#Override
public void onStatusChanged(String provider, int status, Bundle extras) {
switch (status) {
case IALocationManager.STATUS_CALIBRATION_CHANGED:
String quality = "unknown";
switch (extras.getInt("quality")) {
case IALocationManager.CALIBRATION_POOR:
quality = "Poor";
break;
case IALocationManager.CALIBRATION_GOOD:
quality = "Good";
break;
case IALocationManager.CALIBRATION_EXCELLENT:
quality = "Excellent";
break;
}
MyLog.d(TAG, "Calibration change. Quality: " + quality);
break;
case IALocationManager.STATUS_AVAILABLE:
MyLog.d(TAG, "onStatusChanged: Available");
break;
case IALocationManager.STATUS_LIMITED:
MyLog.d(TAG, "onStatusChanged: Limited");
break;
case IALocationManager.STATUS_OUT_OF_SERVICE:
MyLog.d(TAG, "onStatusChanged: Out of service");
break;
case IALocationManager.STATUS_TEMPORARILY_UNAVAILABLE:
MyLog.d(TAG, "onStatusChanged: Temporarily unavailable");
}
}
};
/**
* Region listener that when:
* <ul>
* <li>region has entered; marks need to move camera and starts
* loading floor plan bitmap</li>
* <li>region has existed; clears marker</li>
* </ul>.
*/
private IARegion.Listener mRegionListener = new IARegion.Listener() {
#Override
public void onEnterRegion(IARegion region) {
System.out.println("!!!!!!aaa enter" + region.toString());
mIndoorAtlasCallBack.hideLoading();
if (region.getType() == IARegion.TYPE_UNKNOWN) {
mIndoorAtlasCallBack.showToast("Moved out of map");
return;
}
// entering new region, mark need to move camera
mCameraPositionNeedsUpdating = true;
final String newId = region.getId();
mIndoorAtlasCallBack.showToast(newId);
fetchFloorPlan(newId);
}
#Override
public void onExitRegion(IARegion region) {
System.out.println("!!!!!!aaa exit" + region.toString());
if (mMarker != null) {
mMarker.remove();
mMarker = null;
}
}
};
public void onCreatePoints(ArrayList<ListLatlong> latlong) {
this.latlong = latlong;
if (null != latlong) {
for (int i = 0; i < latlong.size(); i++) {
String title = latlong.get(i).getLoc() != null ? latlong.get(i).getLoc() : "adobe";
mMarkerLoc = mMap.addMarker(new MarkerOptions().position(latlong.get(i).getLatLng())
.title(title)
.snippet(String.valueOf(latlong.get(i).getId()))
.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_RED)));
}
}
}
/**
* Sets bitmap of floor plan as ground overlay on Google Maps
*/
private void setupGroundOverlay(IAFloorPlan floorPlan, Bitmap bitmap) {
if (mGroundOverlay != null) {
mGroundOverlay.remove();
}
if (mMap != null) {
BitmapDescriptor bitmapDescriptor = BitmapDescriptorFactory.fromBitmap(bitmap);
IALatLng iaLatLng = floorPlan.getCenter();
LatLng center = new LatLng(iaLatLng.latitude, iaLatLng.longitude);
GroundOverlayOptions fpOverlay = new GroundOverlayOptions()
.image(bitmapDescriptor)
.position(center, floorPlan.getWidthMeters(), floorPlan.getHeightMeters())
.bearing(floorPlan.getBearing());
mGroundOverlay = mMap.addGroundOverlay(fpOverlay);
}
}
/**
* Download floor plan using Picasso library.
*/
private void fetchFloorPlanBitmap(final IAFloorPlan floorPlan) {
final String url = floorPlan.getUrl();
//saving floor level and floor name
App.getInstance().getAppPreferences().setFloorId(floorPlan.getFloorLevel());
App.getInstance().getAppPreferences().setFloorName(floorPlan.getName());
if (mLoadTarget == null) {
mLoadTarget = new Target() {
#Override
public void onBitmapLoaded(Bitmap bitmap, Picasso.LoadedFrom from) {
Log.d(TAG, "onBitmap loaded with dimensions: " + bitmap.getWidth() + "x"
+ bitmap.getHeight());
setupGroundOverlay(floorPlan, bitmap);
}
#Override
public void onPrepareLoad(Drawable placeHolderDrawable) {
// N/A
}
#Override
public void onBitmapFailed(Drawable placeHolderDraweble) {
mIndoorAtlasCallBack.showToast("Failed to load bitmap");
mIndoorAtlasCallBack.hideLoading();
}
};
}
if (null != mIndoorAtlasCallBack.getContext()) {
RequestCreator request = Picasso.with(mIndoorAtlasCallBack.getContext()).load(url);
final int bitmapWidth = floorPlan.getBitmapWidth();
final int bitmapHeight = floorPlan.getBitmapHeight();
if (bitmapHeight > MAX_DIMENSION) {
request.resize(0, MAX_DIMENSION);
} else if (bitmapWidth > MAX_DIMENSION) {
request.resize(MAX_DIMENSION, 0);
}
request.into(mLoadTarget);
}
mIndoorAtlasCallBack.onSuccessIndoorMapLoad();
}
/**
* Fetches floor plan data from IndoorAtlas server.
*/
private void fetchFloorPlan(String id) {
// if there is already running task, cancel it
cancelPendingNetworkCalls();
final IATask<IAFloorPlan> task = mResourceManager.fetchFloorPlanWithId(id);
task.setCallback(new IAResultCallback<IAFloorPlan>() {
#Override
public void onResult(IAResult<IAFloorPlan> result) {
if (result.isSuccess() && result.getResult() != null) {
// retrieve bitmap for this floor plan metadata
fetchFloorPlanBitmap(result.getResult());
} else {
// ignore errors if this task was already canceled
if (!task.isCancelled()) {
// do something with error
mIndoorAtlasCallBack.showToast("loading floor plan failed: ");
// remove current ground overlay
if (mGroundOverlay != null) {
mGroundOverlay.remove();
mGroundOverlay = null;
}
}
}
}
}, Looper.getMainLooper()); // deliver callbacks using main looper
// keep reference to task so that it can be canceled if needed
mFetchFloorPlanTask = task;
}
/**
* Helper method to cancel current task if any.
*/
private void cancelPendingNetworkCalls() {
if (mFetchFloorPlanTask != null && !mFetchFloorPlanTask.isCancelled()) {
mFetchFloorPlanTask.cancel();
}
}
#Override
public void onMapReady(GoogleMap mMap) {
this.mMap = mMap;
mMap.setInfoWindowAdapter(this);
mMap.setOnInfoWindowClickListener(this);
}
public void onDestroyView() {
mIALocationManager.removeLocationUpdates(mListener);
mIALocationManager.registerRegionListener(mRegionListener);
onDestroy();
}
public void onDestroy() {
mIALocationManager.destroy();
System.out.println("!!!!!!aaa" + "onDestroyView");
if (null != mMarker) {
mMarker.remove();
}
if (null != mMarkerLoc) {
mMarkerLoc.remove();
}
mIndoorAtlasCallBack.hideLoading();
}
public void onPause() {
mIndoorAtlasCallBack.hideLoading();
}
public void onResume() {
mIALocationManager.requestLocationUpdates(IALocationRequest.create(), mListener);
mCameraPositionNeedsUpdating = true;
}
public void onIndoorAtlasInit(int map_container) {
mIndoorAtlasCallBack.showLoading(mIndoorAtlasCallBack.getContext().getResources().getString(R.string.loading_msg));
FragmentManager fm = mIndoorAtlasCallBack.getChildFragmentManager();
mapFragment = (SupportMapFragment) fm.findFragmentById(R.id.map_container);
if (mapFragment == null) {
mapFragment = SupportMapFragment.newInstance();
fm.beginTransaction().replace(map_container, mapFragment).commit();
}
mapFragment.getMapAsync(this);
Bundle extras = new Bundle(2);
extras.putString(IALocationManager.EXTRA_API_KEY,
App.getInstance().getAppPreferences().getApiKey());
extras.putString(IALocationManager.EXTRA_API_SECRET,
App.getInstance().getAppPreferences().getSecretkey());
mIALocationManager = IALocationManager.create(mIndoorAtlasCallBack.getContext(), extras);
final String floorPlanId = App.getInstance().getAppPreferences().getFloorPlanId();
if (!TextUtils.isEmpty(floorPlanId)) {
final IALocation location = IALocation.from(IARegion.floorPlan(floorPlanId));
mIALocationManager.setLocation(location);
}
mResourceManager = IAResourceManager.create(mIndoorAtlasCallBack.getContext(), extras);
mIALocationManager.requestLocationUpdates(IALocationRequest.create(), mListener);
mIALocationManager.registerRegionListener(mRegionListener);
}
#Override
public View getInfoWindow(final Marker marker) {
View v = inflater.inflate(R.layout.mapinfowindow, null);
if (marker != null && (marker.getTitle() != null && marker.getTitle().length() > 0)) {
MyLog.sout("!!!!oninfowindow", marker.getSnippet());
textViewTitle = (TextView) v.findViewById(R.id.textViewTitle);
rl_custominfo = (RelativeLayout) v.findViewById(R.id.rl_custominfo);
textViewTitle.setText(marker.getTitle());
textViewTitle.setVisibility(View.VISIBLE);
rl_custominfo.setVisibility(View.VISIBLE);
} else{
return null;
}
return (v);
}
#Override
public View getInfoContents(Marker marker) {
return null;
}
#Override
public void onInfoWindowClick(Marker marker) {
MyLog.sout("!!!!oninfo", marker.getSnippet());
LatLng latlng = marker.getPosition();
Double distance = CalculateDistancex.CalculationByDistance(latlng,latlongfromlistner) ;
distance = distance*100;
distance = Double.valueOf(Math.round(distance));
distance = distance /100;
if(null !=marker) {
mIndoorAtlasCallBack.onClickFromInfoWindow(marker.getSnippet(), distance);
}
}
}

Related

Change the position of the marker when the camera is moving in google maps

I have added google maps SDK to my project and have added a marker at the current position. If the user moves the camera the marker also changes its position by setting marker.setPosition(lat, long); in onCameraMove() callback,
But I am getting a flicker when the marker changes its position. I want to make it smooth as in Ola app.
Attaching the code for reference
public class StoreAddressActivity extends BaseActivity<FragmentStoreAddressBinding, WebsiteCreationViewModel> implements GoogleMap.OnMyLocationButtonClickListener,
GoogleMap.OnMyLocationClickListener, OnMapReadyCallback, ActivityCompat.OnRequestPermissionsResultCallback,
GoogleMap.OnMarkerClickListener, OnCameraMoveListener, GoogleMap.OnCameraIdleListener, Navigator.StoreAddressNavigator {
private static final String TAG = StoreAddressActivity.class.getSimpleName();
#Inject
ViewModelProviderFactory factory;
private WebsiteCreationViewModel websiteCreationViewModel;
private FragmentStoreAddressBinding fragmentStoreAddressBinding;
private FusedLocationProviderClient mFusedLocationClient;
private Location mLastLocation;
private UiSettings mUiSettings;
private Marker currentLocationMarker;
private static final int DEFAULT_ZOOM = 15;
private static final int LOCATION_PERMISSION_REQUEST_CODE = 1;
private boolean locationPermissionGranted = false;
private GoogleMap map;
private StringBuilder mResult;
private int previousLength;
private boolean backSpace;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
fragmentStoreAddressBinding = getViewDataBinding();
fragmentStoreAddressBinding.setNavigator(this);
init();
}
private void init() {
mFusedLocationClient = LocationServices.getFusedLocationProviderClient(this);
SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map);
mapFragment.getMapAsync(this);
String apiKey = getString(R.string.google_maps_key);
if (!Places.isInitialized()) {
Places.initialize(getApplicationContext(), apiKey);
}
PlacesClient placesClient = Places.createClient(this);
fragmentStoreAddressBinding.mapLocationEdittext.addTextChangedListener(new TextWatcher() {
#Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
previousLength = s.length();
}
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
#Override
public void afterTextChanged(Editable s) {
backSpace = previousLength > s.length();
if (!backSpace) {
// Create a new token for the autocomplete session. Pass this to FindAutocompletePredictionsRequest,
// and once again when the user makes a selection (for example when calling fetchPlace()).
AutocompleteSessionToken token = AutocompleteSessionToken.newInstance();
// Create a RectangularBounds object.
RectangularBounds bounds = RectangularBounds.newInstance(
new LatLng(-33.880490, 151.184363), //dummy lat/lng
new LatLng(-33.858754, 151.229596));
// Use the builder to create a FindAutocompletePredictionsRequest.
FindAutocompletePredictionsRequest request = FindAutocompletePredictionsRequest.builder()
// Call either setLocationBias() OR setLocationRestriction().
//.setLocationBias(bounds)
//.setLocationRestriction(bounds)
.setCountry("IN")
.setTypeFilter(TypeFilter.ADDRESS)
.setSessionToken(token)
.setQuery(s.toString())
.build();
placesClient.findAutocompletePredictions(request).addOnSuccessListener(response -> {
mResult = new StringBuilder();
for (AutocompletePrediction prediction : response.getAutocompletePredictions()) {
mResult.append(" ").append(prediction.getFullText(null) + "\n");
Log.d(TAG, prediction.getPlaceId());
Log.d(TAG, prediction.getPrimaryText(null).toString());
}
Log.d(TAG, mResult.toString());
// mSearchResult.setText(String.valueOf(mResult));
}).addOnFailureListener((exception) -> {
if (exception instanceof ApiException) {
ApiException apiException = (ApiException) exception;
Log.e(TAG, "Place not found: " + apiException.getStatusCode());
}
});
}
}
});
}
#Override
public WebsiteCreationViewModel getViewModel() {
websiteCreationViewModel = new ViewModelProvider(this, factory).get(WebsiteCreationViewModel.class);
return websiteCreationViewModel;
}
#Override
public int getBindingVariable() {
return BR.viewModel;
}
#Override
public int getLayoutId() {
return R.layout.fragment_store_address;
}
#Override
public boolean onMyLocationButtonClick() {
return false;
}
#Override
public void onMyLocationClick(#NonNull Location location) {
}
#Override
public void onMapReady(GoogleMap googleMap) {
map = googleMap;
mUiSettings = map.getUiSettings();
mUiSettings.setZoomControlsEnabled(true);
mUiSettings.setMyLocationButtonEnabled(false);
map.setMapType(GoogleMap.MAP_TYPE_NORMAL);
map.setOnMarkerClickListener(this);
map.setOnCameraMoveListener(this);
map.setOnCameraIdleListener(this);
if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (ContextCompat.checkSelfPermission(this,
Manifest.permission.ACCESS_FINE_LOCATION)
== PackageManager.PERMISSION_GRANTED) {
locationPermissionGranted = true;
map.setMyLocationEnabled(true);
} else {
//Request Location Permission
checkLocationPermission();
}
} else {
locationPermissionGranted = true;
map.setMyLocationEnabled(true);
}
getDeviceLocation();
}
private void checkLocationPermission() {
if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION)
!= PackageManager.PERMISSION_GRANTED) {
// Should we show an explanation?
if (ActivityCompat.shouldShowRequestPermissionRationale(this,
Manifest.permission.ACCESS_FINE_LOCATION)) {
// Show an explanation to the user *asynchronously* -- don't block
// this thread waiting for the user's response! After the user
// sees the explanation, try again to request the permission.
new AlertDialog.Builder(this)
.setTitle("Location Permission Needed")
.setMessage("This app needs the Location permission, please accept to use location functionality")
.setPositiveButton("OK", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialogInterface, int i) {
//Prompt the user once explanation has been shown
ActivityCompat.requestPermissions(StoreAddressActivity.this,
new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
LOCATION_PERMISSION_REQUEST_CODE);
}
})
.create()
.show();
} else {
// No explanation needed, we can request the permission.
ActivityCompat.requestPermissions(this,
new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
LOCATION_PERMISSION_REQUEST_CODE);
}
}
}
/**
* Enables the My Location layer if the fine location permission has been granted.
*/
private void enableMyLocation() {
if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION)
== PackageManager.PERMISSION_GRANTED) {
locationPermissionGranted = true;
if (map != null) {
map.setMyLocationEnabled(true);
}
} else {
// Permission to access the location is missing. Show rationale and request permission
requestPermissionsSafely(new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, LOCATION_PERMISSION_REQUEST_CODE);
}
}
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
if (requestCode != LOCATION_PERMISSION_REQUEST_CODE) {
return;
}
if (PermissionUtils.isPermissionGranted(permissions, grantResults, Manifest.permission.ACCESS_FINE_LOCATION)) {
// Enable the my location layer if the permission has been granted.
locationPermissionGranted = true;
enableMyLocation();
} else {
locationPermissionGranted = false;
}
}
#Override
public void onPause() {
super.onPause();
}
/**
* Demonstrates converting a {#link Drawable} to a {#link BitmapDescriptor},
* for use as a marker icon.
*/
private BitmapDescriptor vectorToBitmap(#DrawableRes int id) {
Drawable vectorDrawable = ResourcesCompat.getDrawable(getResources(), id, null);
Bitmap bitmap = Bitmap.createBitmap(vectorDrawable.getIntrinsicWidth(),
vectorDrawable.getIntrinsicHeight(), Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
vectorDrawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
vectorDrawable.draw(canvas);
return BitmapDescriptorFactory.fromBitmap(bitmap);
}
private void getDeviceLocation() {
/*
* Get the best and most recent location of the device, which may be null in rare
* cases when a location is not available.
*/
try {
if (locationPermissionGranted) {
Task<Location> locationResult = mFusedLocationClient.getLastLocation();
locationResult.addOnCompleteListener(this, new OnCompleteListener<Location>() {
#Override
public void onComplete(#NonNull Task<Location> task) {
if (task.isSuccessful()) {
// Set the map's camera position to the current location of the device.
mLastLocation = task.getResult();
if (mLastLocation != null) {
LatLng latLng = new LatLng(mLastLocation.getLatitude(), mLastLocation.getLongitude());
LocationAddress locationAddress = new LocationAddress();
locationAddress.getAddressFromLocation(mLastLocation.getLatitude(), mLastLocation.getLongitude(),
getApplicationContext(), new GeocoderHandler());
// currentLocationMarker = map.addMarker(new MarkerOptions()
// .position(latLng)
// .icon(vectorToBitmap(R.drawable.ic_location_marker))
// .title("MOVE PIN TO ADJUST")
// .draggable(false));
MarkerOptions markerOpt = new MarkerOptions();
markerOpt.position(latLng)
.title("MOVE PIN TO ADJUST").icon(vectorToBitmap(R.drawable.ic_location_marker));
//Set Custom InfoWindow Adapter
CustomInfoWindowAdapter adapter = new CustomInfoWindowAdapter(StoreAddressActivity.this);
map.setInfoWindowAdapter(adapter);
currentLocationMarker = map.addMarker(markerOpt);
currentLocationMarker.showInfoWindow();
map.moveCamera(CameraUpdateFactory.newLatLngZoom(
latLng, DEFAULT_ZOOM));
}
}
}
});
}
} catch (SecurityException e) {
}
}
#Override
public boolean onMarkerClick(Marker marker) {
return false;
}
#Override
public void onCameraMove() {
LatLng target = map.getCameraPosition().target;
//currentLocationMarker.setPosition(target);
animateMarker(currentLocationMarker, target, false);
// CameraUpdate cameraUpdate = CameraUpdateFactory.newLatLngZoom(target, DEFAULT_ZOOM);
// map.animateCamera(cameraUpdate, 4000, null);
}
#Override
public void onCameraIdle() {
Log.d(TAG, "Camera is idle");
LatLng target = map.getCameraPosition().target;
if (currentLocationMarker != null)
currentLocationMarker.setPosition(target);
LocationAddress locationAddress = new LocationAddress();
locationAddress.getAddressFromLocation(target.latitude, target.longitude,
getApplicationContext(), new GeocoderHandler());
fragmentStoreAddressBinding.currentLocationTextview.setText(getString(R.string.go_to_current_location));
}
#Override
public void currentLocationClick() {
if (mLastLocation != null) {
fragmentStoreAddressBinding.currentLocationTextview.setText(getString(R.string.this_is_current_location));
LatLng latLng = new LatLng(mLastLocation.getLatitude(), mLastLocation.getLongitude());
CameraUpdate cameraUpdate = CameraUpdateFactory.newLatLngZoom(latLng, DEFAULT_ZOOM);
map.moveCamera(cameraUpdate);
map.animateCamera(cameraUpdate, 4000, null);
LocationAddress locationAddress = new LocationAddress();
locationAddress.getAddressFromLocation(mLastLocation.getLatitude(), mLastLocation.getLongitude(),
getApplicationContext(), new GeocoderHandler());
}
}
private class GeocoderHandler extends Handler {
#Override
public void handleMessage(Message message) {
String locationAddress;
switch (message.what) {
case 1:
Bundle bundle = message.getData();
locationAddress = bundle.getString("address");
break;
default:
locationAddress = null;
}
fragmentStoreAddressBinding.mapLocationEdittext.setText(locationAddress);
}
}
public void animateMarker(final Marker marker, final LatLng toPosition,
final boolean hideMarker) {
if(currentLocationMarker == null)
return;
final Handler handler = new Handler();
final long start = SystemClock.uptimeMillis();
Projection proj = map.getProjection();
Point startPoint = proj.toScreenLocation(marker.getPosition());
final LatLng startLatLng = proj.fromScreenLocation(startPoint);
final long duration = 250;
final LinearInterpolator interpolator = new LinearInterpolator();
handler.post(new Runnable() {
#Override
public void run() {
long elapsed = SystemClock.uptimeMillis() - start;
float t = interpolator.getInterpolation((float) elapsed
/ duration);
// double lng = t * toPosition.longitude + (1 - t)
// * startLatLng.longitude;
// double lat = t * toPosition.latitude + (1 - t)
// * startLatLng.latitude;
marker.setPosition(new LatLng(toPosition.latitude, toPosition.longitude));
// if (t < 1.0) {
// // Post again 16ms later.
// handler.postDelayed(this, 16);
// } else {
// if (hideMarker) {
// marker.setVisible(false);
// } else {
// marker.setVisible(true);
// }
// }
}
});
}

Intent among three activities error

I searched all the question about android intent among three activities in stack overflow, but there were unfortunate without the expect occasion i faced, the first activity which include a simple button but it does't matter and through that activity i pass a data to the second activity, and i want to click the textView(a button) and pass some data to the third activity, the total program is too long and here is the snippet:
#Override
public void onClick(View view) {
switch (view.getId()){
case R.id.btn_search:
Intent third = new Intent(this, ThirdActivity.class);
startActivity(third);
break;
default:
break;
}
}
what i expect is that click the button and jump to the third activity, but actually every click it back to the first activity, i am curious if i can not use intent in the second activity?but i think it's ridiculous. Is there any suggestion about this problem.
UPDATE:here is the whole class but there are many empty implementation, and SDK is gaode map, so don't care about the total logic and just pay attention on the onclick event:
public class AroundSearchActivity extends Activity implements AMap.OnMapClickListener,
AMap.OnMarkerClickListener, AMap.OnInfoWindowClickListener, AMap.InfoWindowAdapter,
View.OnClickListener, PoiSearch.OnPoiSearchListener, LocationSource, AMapLocationListener
{
private AMap map;
private MapView mapView;
private AMapLocation mapLocation;
private AMapLocationClient mapLocationClient;
private AMapLocationClientOption mapLocationClientOption;
private OnLocationChangedListener locationChangedListener;
private double latitude;
private double longitude;
private double previousLatitude = 0;
private Marker currentMarker;
private RelativeLayout detail;
private TextView name;
private TextView address;
private EditText input_text;
private PoiSearch poiSearch;
private PoiSearch.Query query;
private PoiResult result;
private ArrayList<PoiItem> poiItems;
private Marker mLastMarker;
private Marker detailMarker;
private MyPoiOverlay poiOverlay;
private String searchStr;
private int[] showMarkers = {
R.drawable.poi_marker_1,R.drawable.poi_marker_2,R.drawable.poi_marker_3,R.drawable.poi_marker_4,R.drawable.poi_marker_5,
R.drawable.poi_marker_6,R.drawable.poi_marker_7,R.drawable.poi_marker_8,R.drawable.poi_marker_9,R.drawable.poi_marker_10,
};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.poiaroundsearch_activity);
mapView = (MapView) findViewById(R.id.mapView);
mapView.onCreate(savedInstanceState);
init();
}
public void init(){
if (map == null){
map = mapView.getMap();
}
setUpMap();
map.setOnMapClickListener(this);
map.setOnMarkerClickListener(this);
map.setOnInfoWindowClickListener(this);
map.setInfoWindowAdapter(this);
TextView search = (TextView) findViewById(R.id.btn_search);
search.setOnClickListener(this);
setup();
}
public void setup(){
detail = (RelativeLayout) findViewById(R.id.poi_detail);
detail.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
//toggle detail click event
Toast.makeText(AroundSearchActivity.this, "hello", Toast.LENGTH_SHORT).show();
}
});
name = (TextView) findViewById(R.id.poi_name);
address = (TextView) findViewById(R.id.poi_address);
input_text = (EditText) findViewById(R.id.input_edittext);
}
#Override
protected void onResume() {
super.onResume();
mapView.onResume();
searchMap();
}
#Override
protected void onPause() {
super.onPause();
mapView.onDestroy();
deactivate();
}
public void setUpMap(){
map.setLocationSource(this);
map.getUiSettings().setMyLocationButtonEnabled(true);
map.setMyLocationEnabled(true);
map.setMyLocationType(AMap.LOCATION_TYPE_LOCATE);
}
#Override
protected void onDestroy() {
super.onDestroy();
locationChangedListener = null;
if (mapLocationClient != null){
mapLocationClient.stopLocation();
mapLocationClient.onDestroy();
}
mapLocationClient = null;
}
#Override
public void onLocationChanged(AMapLocation aMapLocation) {
if (locationChangedListener != null && aMapLocation != null){
if(aMapLocation.getErrorCode() == 0){
latitude = aMapLocation.getLatitude();
longitude = aMapLocation.getLongitude();
locationChangedListener.onLocationChanged(aMapLocation);
Log.i("CurrentLocation", "latitude is " + latitude + " ,longitude is:" + longitude);//get current latitude and longitude
if (currentMarker != null) currentMarker = null;
currentMarker = map.addMarker(new MarkerOptions().
position(new LatLng(latitude, longitude))
.icon(null)
.draggable(true));
currentMarker.showInfoWindow();
map.moveCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(latitude, longitude), 16));
if (previousLatitude == 0){
searchMap();
}else{
String pre = String.valueOf(previousLatitude);
String a = pre.substring(pre.indexOf(".") + 1, pre.indexOf(".") + 4);
String cur = String.valueOf(latitude);
String b = cur.substring(cur.indexOf(".") + 1, cur.indexOf(".") + 4);
if (!a.equals(b)){
searchMap();
}
}
previousLatitude = latitude;
}else{
int errorCode = aMapLocation.getErrorCode();
Toast.makeText(this, "定位失败:"+errorCode, Toast.LENGTH_SHORT);
}
}
}
#Override
public View getInfoWindow(Marker marker) {
return null;
}
#Override
public View getInfoContents(Marker marker) {
return null;
}
#Override
public void activate(OnLocationChangedListener onLocationChangedListener) {
locationChangedListener = onLocationChangedListener;
if (mapLocationClient == null){
mapLocationClient = new AMapLocationClient(this);
mapLocationClientOption = new AMapLocationClientOption();
mapLocationClient.setLocationListener(this);mapLocationClientOption.setLocationMode(AMapLocationClientOption.AMapLocationMode.Hight_Accuracy);
mapLocationClient.setLocationOption(mapLocationClientOption);
mapLocationClient.startLocation();
}
}
#Override
public void deactivate() {
locationChangedListener = null;
if (mapLocationClient != null){
mapLocationClient.stopLocation();
mapLocationClient.onDestroy();
}
mapLocationClient = null;
}
#Override
public void onClick(View view) {
switch (view.getId()){
case R.id.btn_search:
Intent third = new Intent(this, ThirdActivity.class);
startActivity(third);
break;
default:
break;
}
}
#Override
public void onInfoWindowClick(Marker marker) {
}
#Override
public void onMapClick(LatLng latLng) {
whetherToShowInfo(false);
if (mLastMarker != null){
resetLastMarker();
}
}
#Override
public boolean onMarkerClick(Marker marker) {
if (marker.getObject() != null){
//whether to show the marker detail information
whetherToShowInfo(true);
//get the current location
PoiItem currentItem = (PoiItem) marker.getObject();
//aim at the next marker and preserve the current marker
if (mLastMarker == null){
mLastMarker = marker;
}else {
resetLastMarker();
mLastMarker = marker;
}
detailMarker = marker;
detailMarker.setIcon(BitmapDescriptorFactory.fromResource(R.drawable.poi_marker_pressed));
setPoiMarkerContent(currentItem);
}else {
whetherToShowInfo(false);
resetLastMarker();
}
return true;
}
#Override
public void onPoiSearched(PoiResult poiResult, int errorCode) {
if (errorCode == 1000){
if (poiResult != null && poiResult.getQuery() != null){
if (poiResult.getQuery().equals(query)){//判断是不是同一组查询
result = poiResult;//将搜索结果赋值给result
poiItems = result.getPois();
//列出所有poi搜索结果
for (int i = 0; i < poiItems.size(); i++){
Log.i("result"+i, poiItems.get(i).getSnippet());
}
List<SuggestionCity> suggestionCities = result.getSearchSuggestionCitys();
if (poiItems != null && poiItems.size() > 0){
whetherToShowInfo(false);
if (mLastMarker != null) {
resetLastMarker();
}
if (poiOverlay != null){
poiOverlay.removeFromMap();
}
map.clear();
poiOverlay = new MyPoiOverlay(this, map, poiItems);
poiOverlay.addToMap();
poiOverlay.zoomToSpan();//move to the current scene
map.addMarker(new MarkerOptions().anchor(0.5f, 0.5f)
.icon(BitmapDescriptorFactory.fromResource(R.drawable.point4))
.draggable(false)
.position(new LatLng(latitude, longitude)));
}else{
if (suggestionCities != null && suggestionCities.size() > 0){
showSuggestCity(suggestionCities);
}
}
}
}else {
Toast.makeText(this, "Sorry! No result match your request", Toast.LENGTH_SHORT).show();
}
}else {
Log.e("errorInfo", "Search failed:" + errorCode);
}
}
#Override
public void onPoiItemSearched(PoiItem poiItem, int i) {
}
public void whetherToShowInfo(boolean w){
if (w){
detail.setVisibility(View.VISIBLE);
}else{
detail.setVisibility(View.GONE);
}
}
public void resetLastMarker(){
int index = poiOverlay.getPoiIndex(mLastMarker);
if (index < 10){
mLastMarker.setIcon(BitmapDescriptorFactory.fromBitmap(BitmapFactory.decodeResource(getResources(), showMarkers[index])));
}else{
mLastMarker.setIcon(BitmapDescriptorFactory.fromBitmap(BitmapFactory.decodeResource(getResources(), R.drawable.marker_other_highlight)));
}
mLastMarker = null;
}
public void showSuggestCity(List<SuggestionCity> suggestionCities){
String information = "City information/n";
for (int i = 0; i < suggestionCities.size(); i++){
information += "City name" + suggestionCities.get(i).getCityName() +
", City administrative code::" + suggestionCities.get(i).getAdCode();
}
Toast.makeText(this, information, Toast.LENGTH_SHORT);
}
public void searchMap(){
Toast.makeText(this, searchStr, Toast.LENGTH_SHORT).show();
Intent intent = getIntent();
searchStr = intent.getStringExtra("keyword");
int currentPage = 0;
query = new PoiSearch.Query(searchStr.trim(), "", "Beijing");
query.setPageSize(20);
query.setPageNum(currentPage);
LatLonPoint lp = new LatLonPoint(latitude, longitude);
if (lp != null){
poiSearch = new PoiSearch(this, query);
poiSearch.setOnPoiSearchListener(this);
poiSearch.setBound(new PoiSearch.SearchBound(lp, 2000, true));
poiSearch.searchPOIAsyn();
}
}
public void setPoiMarkerContent(PoiItem item){
name.setText(item.getTitle());
address.setText(item.getSnippet());
}
}

OnMarkerClick startactivity(intent), load object from Parse

I want to load images from Parse Cloud. I have created custom marker with the photo loaded from Parse Cloud. The photo marker icons are working perfectly fine. But I want to start and pass the intent when I click on the marker icon. But no matter which options I select to view in intent it just views only the first object in my Parse Class .Check the screenshot of the map here.When on i click on any image,the same image i.e the first object in the class gets loaded.
super.onCreate(savedInstanceState);
setContentView(R.layout.map_fragment);
mapFragment = (SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map);
mHandler.postDelayed(new Runnable() {
public void run() {
onResume();
}
}, 3000);
mylocation = MainActivity.mlastlocation;
// Gets to GoogleMap from the MapView and does initialization stuff
mapFragment.getMap().setMyLocationEnabled(true);
// Enable the current location "blue dot"
mapFragment.getMap().setOnCameraChangeListener(new GoogleMap.OnCameraChangeListener() {
public void onCameraChange(CameraPosition position) {
if (mylocation == null) {
Toast.makeText(MapFeedsFragment.this, "null", Toast.LENGTH_SHORT).show();
}
if (mylocation != null)
Toast.makeText(MapFeedsFragment.this, "not null", Toast.LENGTH_SHORT).show();
ParseMap aroundposts = new ParseMap();
doMapQuery();
}
});
}
private ParseGeoPoint geoPointFromLocation(Location location) {
latitude = location.getLatitude();
longitude = location.getLongitude();
ParseGeoPoint myloc = new ParseGeoPoint(latitude, longitude);
return myloc;
}
private void doMapQuery() {
final int myUpdateNumber = ++mostRecentMapUpdate;
//Location myLoc = (currentLocation == null) ? lastLocation : currentLocation;
// If location info isn't available, clean up any existing markers
if (mylocation == null) {
cleanUpMarkers(new HashSet<String>());
return;
}
final ParseGeoPoint myPoint = geoPointFromLocation(mylocation);
// Create the map Parse query
ParseQuery<ParseMap> mapQuery = ParseMap.getQuery();
// Set up additional query filters
//mapQuery.whereWithinKilometers("location", myPoint, MAX_POST_SEARCH_DISTANCE);
mapQuery.include("user");
mapQuery.orderByDescending("createdAt");
//mapQuery.setLimit(MAX_POST_SEARCH_RESULTS);
// Kick off the query in the background
mapQuery.findInBackground(new FindCallback<ParseMap>() {
#Override
public void done(List<ParseMap> objects, ParseException e) {
if (e != null) {
//if (Application.APPDEBUG) {
// Log.d(Application.APPTAG, "An error occurred while querying for map posts.", e);
//}
return;
}
/*
* Make sure we're processing results from
* the most recent update, in case there
* may be more than one in progress.
*/
if (myUpdateNumber != mostRecentMapUpdate) {
return;
}
// Posts to show on the map
Set<String> toKeep = new HashSet<String>();
// Loop through the results of the search
for (final ParseMap post : objects) {
// Add this post to the list of map pins to keep
toKeep.add(post.getObjectId());
// Check for an existing marker for this post
Marker oldMarker = mapMarkers.get(post.getObjectId());
// Set up the map marker's location
String uri = post.getPhotoThumb().getUrl();
// final MarkerOptions finalMarkerOpts = markerOpts;
Picasso.with(MapFeedsFragment.this)
.load(uri)
.resize(100,100)
.centerCrop()
.into(new Target() {
#Override
public void onBitmapLoaded(final Bitmap bitmap, Picasso.LoadedFrom from) {
/* Save the bitmap or do something with it here */
final MarkerOptions markerOpts =
new MarkerOptions().position(new LatLng(post.getLocation().getLatitude(), post
.getLocation().getLongitude())).icon(BitmapDescriptorFactory.fromBitmap(bitmap)).title(post.getUser());
// Add a new marker
Marker marker = mapFragment.getMap().addMarker(markerOpts);
mapMarkers.put(post.getObjectId(), marker);
mapMarkers.put(post.getVideo().getUrl(),marker);
mapMarkers.put(post.getUserId(),marker);
mapMarkers.put(String.valueOf(post.getViews()),marker);
}
#Override
public void onBitmapFailed(Drawable errorDrawable) {
}
#Override
public void onPrepareLoad(Drawable placeHolderDrawable) {
}
});
mapFragment.getMap().setOnMarkerClickListener(new GoogleMap.OnMarkerClickListener() {
#Override
public boolean onMarkerClick(Marker marker) {
Intent intent = new Intent (MapFeeds.this,PhotoView.class);
intent.putExtra("objectId",post.getObjectId());
intent.putExtra("photo", String.valueOf(post.getPhoto().getUrl()));
intent.putExtra("userId",post.getUserId());
intent.putExtra("objectId",post.getObjectId());
startActivity(intent);
return false;
}
});
}
}
});
}

LocationListener and memory leaks

According to the sample app that finds the user location it is a good idea to listen for location changes in the activity:
class MyActivity extends Activity implements LocationListener {
#Inject
private LocationManager locationManager;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, this);
}
#Override
public void onLocationChanged(Location location) {
// do something with location
}
// ...
}
However, I'm not sure about that. When there is a configuration change, my activity gets destroyed and recreated, registering itself as listener next time. The reference to the old Activity is held in the LocationManager, isn't it?
If I extract the LocationListener to separate object, still I have the problem of how to notify the current activity about new location (not necessarily the same as the requesting activity).
Is there any common pattern to solve this?
In this example you have also another problem: your GPS listener will work always and will drain battery.
The better practice is:
1) register LocationListener into Activity's onStart()
2) remove LocationListener into Activity's onStop()
This will fix both problems.
If you need that your app track user position in background (for example, GPS tracker) use Service (http://developer.android.com/reference/android/app/Service.html)
I had memory leaks using all these suggestions. I got them to stop by applying this method at the point I didn't need the Listener anymore, to onDestroy, and onStop. I also added it to onPause, but you'll have to decide if this is best for your application.
private void stopLocationListener() {
if (locationManager !=null) locationManager.removeUpdates(locationListener);
if (locationManager !=null) locationManager =null;
if (locationListener !=null) locationListener =null;
}
You can make a separate class to do the same and then implement the LocationListenerFinder.onLocationChanged interface to your activity
Now you won't face the leak problem.
public class LocationListenerFinder implements LocationListener {
onLocationChanged onLocationChanged;
public LocationListenerFinder(Context context) {
onLocationChanged = (LocationListenerFinder.onLocationChanged) context;
}
#Override
public void onLocationChanged(Location location) {
onLocationChanged.onLocationChanged(location);
onLocationChanged = null;
}
public interface onLocationChanged {
void onLocationChanged(Location location);
}
}
In my case activity was this... you can refer the same and can convert as per your need.
public class ActivityMapNearByPlace extends FragmentActivity implements OnMapReadyCallback,
GoogleApiClient.ConnectionCallbacks,
GoogleApiClient.OnConnectionFailedListener, LocationListenerFinder.onLocationChanged {
private GoogleMap mMap;
ArrayList<LatLng> listMarkerPoints;
GoogleApiClient mGoogleApiClient;
Location mLastLocation;
Marker mCurrLocationMarker;
LocationRequest mLocationRequest;
private boolean locationPermission;
private ArrayList<NearByPlaces> listNearByFacility;
private int facilityPosition, locationPosition;
private ImageView ivBack, ivMyLocation;
private TextView tvPlaceOriginName, tvPlaceDestinationName, tvPlaceKmDistance, tvPlaceTime;
private TableRow trPlaceTimeKm;
private Marker currentSelectedMarker;
private Map<Integer, Map<String, Object>> mapDistancePathData;
private Polyline polyline;
private boolean flagCalculatingPath = false;
private FetchUrl fetchUrl;
private SupportMapFragment mapFragment;
private LocationListenerFinder locationListenerFinder;
//private WeakLocationListener locationListener;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_map_near_by_place);
initView();
initListener();
if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
checkLocationPermission();
} else {
locationPermission = true;
}
// Initializing
listMarkerPoints = new ArrayList<>();
getBundleData();
listNearByFacility.get(0).getNearBy();
LatLng origin = new LatLng(Double.valueOf(listNearByFacility.get(0).getGeoLocLat()), Double.valueOf(listNearByFacility.get(0).getGeoLocLong()));
listMarkerPoints.add(origin);
// Obtain the SupportMapFragment and get notified when the map is ready to be used.
mapFragment = (SupportMapFragment) getSupportFragmentManager()
.findFragmentById(R.id.map);
mapFragment.getMapAsync(this);
}
#Override
protected void onRestart() {
super.onRestart();
//if (mGoogleApiClient != null) mGoogleApiClient.connect();
}
#Override
protected void onStop() {
super.onStop();
//if (mGoogleApiClient != null) mGoogleApiClient.disconnect();
}
#Override
protected void onDestroy() {
super.onDestroy();
if (mGoogleApiClient != null && mGoogleApiClient.isConnected()) {
LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, locationListenerFinder);
mGoogleApiClient.disconnect();
mGoogleApiClient.unregisterConnectionCallbacks(this);
mGoogleApiClient.unregisterConnectionFailedListener(this);
// locationListener.clearData();
locationListenerFinder = null;
}
mGoogleApiClient = null;
fetchUrl.cancel(true);
if (mMap != null) mMap.setMyLocationEnabled(false);
//if (mapFragment != null) mapFragment.onDestroy();
}
#Override
public void onBackPressed() {
finish();
}
private void initListener() {
ivBack.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
onBackPressed();
}
});
ivMyLocation.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if (mCurrLocationMarker.getTag() != null && !flagCalculatingPath) {
locationPosition = (int) mCurrLocationMarker.getTag();
if (mapDistancePathData.get(locationPosition) != null) {
if (polyline != null) {
polyline.remove();
}
Map<String, Object> hashMapDistancePathInfo = mapDistancePathData.get(locationPosition);
setPathInfo((String) hashMapDistancePathInfo.get("duration"), (String) hashMapDistancePathInfo.get("distance"), (PolylineOptions) hashMapDistancePathInfo.get("polyLineOptions"), "Current Location");
trPlaceTimeKm.setVisibility(View.VISIBLE);
} else {
Locations locations = new Locations();
locations.setName("Current Location");
locations.setLatitude(String.valueOf(mLastLocation.getLatitude()));
locations.setLongitude(String.valueOf(mLastLocation.getLongitude()));
findDistanceAndMarkDirection(locations);
}
}
//mMap.moveCamera(CameraUpdateFactory.newLatLng(latLng));
//mMap.animateCamera(CameraUpdateFactory.zoomTo(11));
}
});
}
private void initView() {
ivBack = (ImageView) findViewById(R.id.iv_back_btn);
ivMyLocation = (ImageView) findViewById(R.id.iv_my_location);
tvPlaceOriginName = (TextView) findViewById(R.id.tv_near_by_place_origin);
tvPlaceDestinationName = (TextView) findViewById(R.id.tv_near_by_place_destination);
tvPlaceKmDistance = (TextView) findViewById(R.id.tv_near_by_place_km);
tvPlaceTime = (TextView) findViewById(R.id.tv_near_by_place_time);
trPlaceTimeKm = (TableRow) findViewById(R.id.tr_near_by_place_km_time);
}
private void getBundleData() {
listNearByFacility = (ArrayList<NearByPlaces>) getIntent().getBundleExtra("nearByLocationBundle").getSerializable("nearByLocationData");
facilityPosition = getIntent().getIntExtra("facilityPosition", 0);
locationPosition = getIntent().getIntExtra("locationPosition", 0);
}
/**
* 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;
//Initialize Google Play Services
if (locationPermission) {
buildGoogleApiClient();
checkLocationStatus();
//mMap.setMyLocationEnabled(true);
loadMap();
}
mMap.setOnMarkerClickListener(new GoogleMap.OnMarkerClickListener() {
#Override
public boolean onMarkerClick(Marker marker) {
if (marker.getTag() != null && !flagCalculatingPath) {
locationPosition = (int) marker.getTag();
if (mapDistancePathData.get(locationPosition) != null) {
if (polyline != null) {
polyline.remove();
}
Map<String, Object> hashMapDistancePathInfo = mapDistancePathData.get(locationPosition);
setPathInfo((String) hashMapDistancePathInfo.get("duration"), (String) hashMapDistancePathInfo.get("distance"), (PolylineOptions) hashMapDistancePathInfo.get("polyLineOptions"), listNearByFacility.get(0).getNearBy().get(facilityPosition).getLocations().get(locationPosition).getName());
trPlaceTimeKm.setVisibility(View.VISIBLE);
} else {
findDistanceAndMarkDirection(listNearByFacility.get(0).getNearBy().get(facilityPosition).getLocations().get(locationPosition));
}
}
return false;
}
});
mMap.getUiSettings().setMyLocationButtonEnabled(false);
mMap.getUiSettings().setRotateGesturesEnabled(false);
}
private void loadMap() {
NearByPlaces originLocation = listNearByFacility.get(0);
if (listMarkerPoints.size() > 1) {
mMap.clear();
listMarkerPoints.remove(1);
}
// Adding new item to the ArrayList
NearBy nearBy = listNearByFacility.get(0).getNearBy().get(facilityPosition);
tvPlaceOriginName.setText(originLocation.getProjectName());
//tvPlaceDestinationName.setText(nearBy.getLocations().get(locationPosition).getName());
if (mapDistancePathData == null) {
mapDistancePathData = new HashMap<>();
}
// .get(locationPosition);
// LatLng destination = new LatLng(Double.valueOf(location.getLatitude()), Double.valueOf(location.getLongitude()));
//listMarkerPoints.add(destination);
MarkerOptions options = new MarkerOptions();
options.position(listMarkerPoints.get(0));
options.icon(BitmapDescriptorFactory.fromBitmap(getBitmapMarker(originLocation.getProjectName(), R.drawable.ic_marker_red)));
//options.title(originLocation.getProjectName());
mMap.addMarker(options).showInfoWindow();
for (int position = 0; position < nearBy.getLocations().size(); position++) {
Locations locations = nearBy.getLocations().get(position);
// Creating MarkerOptions
options = new MarkerOptions();
LatLng markerPosition = new LatLng(Double.valueOf(locations.getLatitude()), Double.valueOf(locations.getLongitude()));
// Setting the videoPlayPosition of the marker
options.position(markerPosition);
/**
* For the start location, the color of marker is GREEN and
* for the end location, the color of marker is RED.
*/
options.icon(BitmapDescriptorFactory.fromBitmap(getBitmapMarker(locations.getName(), 0)));
//options.title(locationRanges.getName());
// Add new marker to the Google Map Android API V2
Marker marker = mMap.addMarker(options);
// marker.showInfoWindow();
marker.setTag(position);
}
findDistanceAndMarkDirection(nearBy.getLocations().get(locationPosition));
}
public Bitmap getBitmapMarker(String title, int id) {
View customMarkerView = this.getLayoutInflater().inflate(R.layout.layout_marker_with_title, null);
customMarkerView.measure(View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED),
View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED));
customMarkerView.layout(0, 0, customMarkerView.getMeasuredWidth(), customMarkerView.getMeasuredHeight());
TextView tvMarkerProjectName = (TextView) customMarkerView.findViewById(R.id.tv_marker_project_name);
if (id != 0) {
ImageView ivMarkerImage = (ImageView) customMarkerView.findViewById(R.id.iv_marker_image);
ivMarkerImage.setImageResource(id);
}
tvMarkerProjectName.setText(title);
customMarkerView.setDrawingCacheEnabled(true);
customMarkerView.buildDrawingCache();
Bitmap bm = customMarkerView.getDrawingCache();
return bm;
}
private void findDistanceAndMarkDirection(Locations destinationLocation) {
flagCalculatingPath = true;
if (polyline != null) {
polyline.remove();
}
trPlaceTimeKm.setVisibility(View.INVISIBLE);
tvPlaceDestinationName.setText(destinationLocation.getName());
// Checks, whether start and end locationRanges are captured
LatLng latLngDest = new LatLng(Double.valueOf(destinationLocation.getLatitude()), Double.valueOf(destinationLocation.getLongitude()));
LatLng origin = listMarkerPoints.get(0);
// Getting URL to the Google Directions API
String url = getUrl(origin, latLngDest);
//Log.d("onMapClick", url.toString());
fetchUrl = new FetchUrl();
// Start downloading json data from Google Directions API
fetchUrl.execute(url);
//move map camera
mMap.moveCamera(CameraUpdateFactory.newLatLng(origin));
mMap.animateCamera(CameraUpdateFactory.zoomTo(12));
}
private void setPathInfo(String duration, String distance, PolylineOptions polylineOptions, String destName) {
tvPlaceTime.setText(duration);
tvPlaceKmDistance.setText(distance);
polyline = mMap.addPolyline(polylineOptions);
tvPlaceDestinationName.setText(destName);
}
private String getUrl(LatLng origin, LatLng dest) {
// Origin of route
String str_origin = "origin=" + origin.latitude + "," + origin.longitude;
// Destination of route
String str_dest = "destination=" + dest.latitude + "," + dest.longitude;
// Sensor enabled
String sensor = "sensor=false";
// Building the parameters to the web service
String parameters = str_origin + "&" + str_dest + "&" + sensor;
// Output format
String output = "json";
// Building the url to the web service
String url = "https://maps.googleapis.com/maps/api/directions/" + output + "?" + parameters;
return url;
}
/**
* A method to download json data from url
*/
private String downloadUrl(String strUrl) throws IOException {
String data = "";
InputStream iStream = null;
HttpURLConnection urlConnection = null;
try {
URL url = new URL(strUrl);
// Creating an http connection to communicate with url
urlConnection = (HttpURLConnection) url.openConnection();
urlConnection.setReadTimeout(15000 /* milliseconds */);
urlConnection.setConnectTimeout(15000 /* milliseconds */);
urlConnection.setDoInput(true);
// Connecting to url
urlConnection.connect();
// Reading data from url
iStream = urlConnection.getInputStream();
BufferedReader br = new BufferedReader(new InputStreamReader(iStream));
StringBuffer sb = new StringBuffer();
String line = "";
while ((line = br.readLine()) != null) {
sb.append(line);
}
data = sb.toString();
//Log.d("downloadUrl", data.toString());
br.close();
} catch (Exception e) {
// Log.d("Exception", e.toString());
} finally {
iStream.close();
urlConnection.disconnect();
}
return data;
}
// Fetches data from url passed
private class FetchUrl extends AsyncTask<String, Void, String> {
#Override
protected void onCancelled() {
//super.onCancelled();
}
#Override
protected String doInBackground(String... url) {
// For storing data from web service
String data = "";
try {
// Fetching the data from web service
data = downloadUrl(url[0]);
//Log.d("Background Task data", data.toString());
} catch (Exception e) {
// Log.d("Background Task", e.toString());
}
return data;
}
#Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
if (!TextUtils.isEmpty(result)) {
ParserTask parserTask = new ParserTask();
// Invokes the thread for parsing the JSON data
parserTask.execute(result);
} else {
flagCalculatingPath = false;
}
}
}
/**
* A class to parse the Google Places in JSON format
*/
private class ParserTask extends AsyncTask<String, Integer, List<List<HashMap<String, String>>>> {
// Parsing the data in non-ui thread
#Override
protected List<List<HashMap<String, String>>> doInBackground(String... jsonData) {
JSONObject jObject;
List<List<HashMap<String, String>>> routes = null;
try {
jObject = new JSONObject(jsonData[0]);
//Log.d("ParserTask", jsonData[0].toString());
DataParser parser = new DataParser();
//Log.d("ParserTask", parser.toString());
// Starts parsing data
routes = parser.parse(jObject);
//Log.d("ParserTask", "Executing routes");
//Log.d("ParserTask", routes.toString());
} catch (Exception e) {
//Log.d("ParserTask", e.toString());
e.printStackTrace();
}
return routes;
}
// Executes in UI thread, after the parsing process
#Override
protected void onPostExecute(List<List<HashMap<String, String>>> result) {
ArrayList<LatLng> points;
PolylineOptions lineOptions = null;
HashMap<String, Object> hashMapDistancePathInfo = null;
// Traversing through all the routes
for (int i = 0; i < result.size(); i++) {
points = new ArrayList<>();
lineOptions = new PolylineOptions();
// Fetching i-th route
List<HashMap<String, String>> path = result.get(i);
// Fetching all the points in i-th route
for (int j = 1; j < path.size(); j++) {
HashMap<String, String> point = path.get(j);
double lat = Double.parseDouble(point.get("lat"));
double lng = Double.parseDouble(point.get("lng"));
LatLng position = new LatLng(lat, lng);
points.add(position);
}
// Adding all the points in the route to LineOptions
lineOptions.addAll(points);
lineOptions.width(5);
lineOptions.color(Color.RED);
tvPlaceTime.setText(path.get(0).get("duration"));
tvPlaceKmDistance.setText(path.get(0).get("distance"));
trPlaceTimeKm.setVisibility(View.VISIBLE);
hashMapDistancePathInfo = new HashMap<>();
hashMapDistancePathInfo.put("duration", path.get(0).get("duration"));
hashMapDistancePathInfo.put("distance", path.get(0).get("distance"));
hashMapDistancePathInfo.put("polyLineOptions", lineOptions);
//Log.d("onPostExecute", "onPostExecute lineoptions decoded");
}
// Drawing polyline in the Google Map for the i-th route
if (lineOptions != null) {
mapDistancePathData.put(locationPosition, hashMapDistancePathInfo);
polyline = mMap.addPolyline(lineOptions);
} else {
//Log.d("onPostExecute", "without Polylines drawn");
}
flagCalculatingPath = false;
}
}
protected synchronized void buildGoogleApiClient() {
mGoogleApiClient = new GoogleApiClient.Builder(getApplicationContext())
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API)
.build();
mGoogleApiClient.connect();
}
#Override
public void onConnected(Bundle bundle) {
mLocationRequest = new LocationRequest();
mLocationRequest.setInterval(1000);
mLocationRequest.setFastestInterval(1000);
mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
locationListenerFinder = new LocationListenerFinder(this);
if (locationPermission) {
LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, locationListenerFinder);
}
}
#Override
public void onConnectionSuspended(int i) {
mLocationRequest = null;
}
#Override
public void onLocationChanged(Location location) {
mLastLocation = location;
if (mCurrLocationMarker != null) {
mCurrLocationMarker.remove();
}
int size = listNearByFacility.get(0).getNearBy().get(facilityPosition).getLocations().size();
ivMyLocation.setVisibility(View.VISIBLE);
//Place current location marker
LatLng latLng = new LatLng(location.getLatitude(), location.getLongitude());
MarkerOptions markerOptions = new MarkerOptions();
markerOptions.position(latLng);
markerOptions.icon(BitmapDescriptorFactory.fromBitmap(getBitmapMarker("Current Location", R.drawable.ic_marker_blue)));
//MarkerOptions markerOptions = new MarkerOptions();
//markerOptions.videoPlayPosition(latLng);
//markerOptions.title("Current Location");
//markerOptions.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_MAGENTA));
mCurrLocationMarker = mMap.addMarker(markerOptions);
mCurrLocationMarker.setTag(size + 1);
//move map camera
// mMap.moveCamera(CameraUpdateFactory.newLatLng(latLng));
//mMap.animateCamera(CameraUpdateFactory.zoomTo(11));
if (mGoogleApiClient != null && mGoogleApiClient.isConnected()) {
LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, locationListenerFinder);
mGoogleApiClient.disconnect();
mGoogleApiClient.unregisterConnectionCallbacks(this);
mGoogleApiClient.unregisterConnectionFailedListener(this);
//locationListener.clearData();
mLocationRequest = null;
locationListenerFinder = null;
}
mGoogleApiClient = null;
}
#Override
public void onConnectionFailed(ConnectionResult connectionResult) {
}
public void checkLocationPermission() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (!Utility.isPermissionAllowed(this, Manifest.permission.ACCESS_FINE_LOCATION)) {
Utility.showPermissionDialog(this, Manifest.permission.ACCESS_FINE_LOCATION, BookingKARConstants.PERMISSIONS_REQUEST_ACCESS_FINE_LOCATION);
locationPermission = false;
return;
} else {
locationPermission = true;
return;
}
}
locationPermission = true;
}
#Override
public void onRequestPermissionsResult(int requestCode,
String permissions[], int[] grantResults) {
//Checking the request code of our request
if (requestCode == BookingKARConstants.PERMISSIONS_REQUEST_ACCESS_FINE_LOCATION) {
// If request is cancelled, the result arrays are empty.
if (grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// permission was granted. Do the
locationPermission = true;
if (mGoogleApiClient == null) {
buildGoogleApiClient();
checkLocationStatus();
}
loadMap();
//mMap.setMyLocationEnabled(true);
} else {
// Permission denied, Disable the functionality that depends on this permission.
Toast.makeText(this, "permission denied", Toast.LENGTH_LONG).show();
finish();
}
return;
}
// other 'case' lines to check for other permissions this app might request.
// You can add here other case statements according to your requirement.
}
private void checkLocationStatus() {
LocationManager lm = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
boolean gps_enabled = false;
boolean network_enabled = false;
try {
gps_enabled = lm.isProviderEnabled(LocationManager.GPS_PROVIDER);
} catch (Exception ex) {
}
try {
network_enabled = lm.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
} catch (Exception ex) {
}
if (!gps_enabled && !network_enabled) {
// notify user
AlertDialog.Builder dialog = new AlertDialog.Builder(this);
dialog.setMessage(getResources().getString(R.string.gps_network_not_enabled));
dialog.setPositiveButton(getResources().getString(R.string.open_location_settings), new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface paramDialogInterface, int paramInt) {
// TODO Auto-generated method stub
Intent myIntent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
startActivity(myIntent);
//get gps
}
});
dialog.setNegativeButton(getString(R.string.Cancel), new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface paramDialogInterface, int paramInt) {
// TODO Auto-generated method stub
}
});
dialog.show();
}
}
/*class WeakLocationListener implements LocationListener {
private final WeakReference<LocationListener> locationListenerRef;
public WeakLocationListener(#NonNull LocationListener locationListener) {
locationListenerRef = new WeakReference<>(WeakLocationListener.this);
}
#Override
public void onLocationChanged(android.location.Location location) {
if (locationListenerRef.get() == null) {
return;
}
locationListenerRef.get().onLocationChanged(location);
}
public interface onLocationChanged {
void onLocationChanged(Location location);
}
public void clearData() {
if (locationListenerRef.get() != null) {
locationListenerRef.clear();
}
}*/
//}
}
#Override
public void onDestroy() {
super.onDestroy();
mLocationManager.removeUpdates(locationListener);
}

Android Google API V2 enable/disable TileProvider

My probleme is simple, i want to enable and disable a TileUrlProvider on the Google Maps API v2.
My approche was :
public class BackTileSelectorActivity extends FragmentActivity {
private GoogleMap mMap;
private TileOverlayOptions osmTileProviderOptions;
private TileOverlayOptions moonTileProviderOptions;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_back_tile_selector);
setUpMapIfNeeded();
}
#Override
protected void onResume() {
super.onResume();
setUpMapIfNeeded();
}
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 = ((SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map))
.getMap();
// Check if we were successful in obtaining the map.
if (mMap != null) {
setUpMap();
}
}
}
private void setUpMap() {
mMap.setMapType(GoogleMap.MAP_TYPE_NORMAL);
mMap.animateCamera(
CameraUpdateFactory.newLatLngZoom(
new LatLng(47.224217, -1.631409),
16
)
);
osmTileProviderOptions = new TileOverlayOptions().tileProvider(new OSMTileProvider());
osmTileProviderOptions.visible(false);
mMap.addTileOverlay(osmTileProviderOptions);
moonTileProviderOptions = new TileOverlayOptions().tileProvider(new MoonTileProvider());
moonTileProviderOptions.visible(false);
mMap.addTileOverlay(moonTileProviderOptions);
}
public void setGoogleMapNormalEnabled(View v) {
osmTileProviderOptions.visible(false);
moonTileProviderOptions.visible(false);
mMap.setMapType(GoogleMap.MAP_TYPE_NORMAL);
}
public void setOSMMapEnabled(View v) {
osmTileProviderOptions.visible(true);
moonTileProviderOptions.visible(false);
mMap.setMapType(GoogleMap.MAP_TYPE_NONE);
}
public void setMoonMapEnabled(View v) {
osmTileProviderOptions.visible(false);
moonTileProviderOptions.visible(true);
mMap.setMapType(GoogleMap.MAP_TYPE_NONE);
}
public void setGoogleMapHybridEnabled(View v) {
osmTileProviderOptions.visible(false);
moonTileProviderOptions.visible(false);
mMap.setMapType(GoogleMap.MAP_TYPE_HYBRID);
}
public void setGoogleMapSatelliteEnabled(View v) {
osmTileProviderOptions.visible(false);
moonTileProviderOptions.visible(false);
mMap.setMapType(GoogleMap.MAP_TYPE_SATELLITE);
}
public void setGoogleMapTerrainEnabled(View v) {
osmTileProviderOptions.visible(false);
moonTileProviderOptions.visible(false);
mMap.setMapType(GoogleMap.MAP_TYPE_TERRAIN);
}
}
the tile provider look like this :
public class MoonTileProvider extends UrlTileProvider {
private static final int TILE_WIDTH = 256;
private static final int TILE_HEIGHT = 256;
private static final String MOON_MAP_URL_FORMAT =
"http://mw1.google.com/mw-planetary/lunar/lunarmaps_v1/clem_bw/%d/%d/%d.jpg";
public MoonTileProvider() {
super(TILE_WIDTH, TILE_HEIGHT);
}
#Override
public URL getTileUrl(int x, int y, int zoom) {
// The moon tile coordinate system is reversed. This is not normal.
int reversedY = (1 << zoom) - y - 1;
String s = String.format(Locale.US, MOON_MAP_URL_FORMAT, zoom, x, reversedY);
URL url = null;
try {
url = new URL(s);
} catch (MalformedURLException e) {
throw new AssertionError(e);
}
return url;
}
}
and :
public class OSMTileProvider extends UrlTileProvider {
private static final int TILE_WIDTH = 256;
private static final int TILE_HEIGHT = 256;
private static final String OSM_MAP_URL_FORMAT = "http://a.tile.cloudmade.com/BC9A493B41014CAABB98F0471D759707/997/256/%d/%d/%d.png";
public OSMTileProvider() {
super(TILE_WIDTH, TILE_HEIGHT);
}
#Override
public URL getTileUrl(int x, int y, int zoom) {
String s = String.format(Locale.US, OSM_MAP_LOCAL_URL_FORMAT, zoom, x, y);
URL url = null;
try {
url = new URL(s);
} catch (MalformedURLException e) {
return null;
}
return url;
}
}
The tileProvider work fine when is call like this :
private GoogleMap mMap;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.google_map_api_layout);
setUpMapIfNeeded();
}
#Override
protected void onResume() {
super.onResume();
setUpMapIfNeeded();
}
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 = ((SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map))
.getMap();
// Check if we were successful in obtaining the map.
if (mMap != null) {
setUpMap();
}
}
}
private void setUpMap() {
mMap.setMapType(GoogleMap.MAP_TYPE_NONE);
mMap.animateCamera(
CameraUpdateFactory.newLatLngZoom(
new LatLng(47.224217, -1.631409),
16
)
);
TileProvider tileProvider = new OSMTileProvider();
mMap.addTileOverlay(new TileOverlayOptions().tileProvider(tileProvider));
}
But i can my tiles are never loaded in the map.
The others google maps tiles works fine...
Any suggestions?
I had the same problem.. It turned out that the .visible() functions doesn't do anything than returning the object, but with changed visibility.
So, if you have to change the visibility i would recommend you to do a .clear() on your map object and then re-add your overlays. If there are other solutions to this, please let me know.
You can hold a reference to your TileProvider and then call .remove() to remove it from the map when you need to:
TileOverlay mTileOverlay;
Add the tile as before:
TileProvider tileProvider = new OSMTileProvider();
mTileOverlay = mMap.addTileOverlay(new TileOverlayOptions().tileProvider(tileProvider));
Remove it like this:
if (null != mTileOverlay) {
mTileOverlay.remove();
}

Categories

Resources