Google map object showing NPE on older devices - java

I am using this piece of code to initialize the google map object:
googleMap = ( (SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map)).getMap();
It works fine on newer devices , but shows NPE on older devices.Please help!!

This is how I solved the NPE of google maps.
public class WBMapFragment extends LogoBaseFragment implements GooglePlayServicesClient.ConnectionCallbacks, GooglePlayServicesClient.OnConnectionFailedListener {
private GoogleMap map;
private MapView mapView;
#Inject
private MapManager mapManager;
/*
* Define a request code to send to Google Play services This code is
* returned in Activity.onActivityResult
*/
private final static int CONNECTION_FAILURE_RESOLUTION_REQUEST = 9000;
private LocationClient mLocationClient;
#Inject
private IUserLocationProvider userLocation;
private BitmapDescriptor mapPin;
private BitmapDescriptor mapPinUsed;
private SupportMapFragment supportMapFragment;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setRetainInstance(true); //< -- very important line
}
#Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
//I needed this for when I return to the fragment that contained the map
getChildFragmentManager().putFragment(outState, "supportFragment", supportMapFragment);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_map, null);
if (savedInstanceState == null) {
if (supportMapFragment == null) {
supportMapFragment = SupportMapFragment.newInstance();
getChildFragmentManager().beginTransaction().add(R.id.mapCont, supportMapFragment,SupportMapFragment.class.getSimpleName()).commit();
}
}
return v;
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
if (savedInstanceState !=null){
supportMapFragment = (SupportMapFragment) getChildFragmentManager().getFragment(savedInstanceState, "supportFragment");
map = null; //<very important to nullify the map, because the new instance of the map will not be the same
}
mLocationClient = new LocationClient(getActivity(), this, this);
}
/*
* Called when the Activity becomes visible.
*/
#Override
public void onStart() {
super.onStart();
// Connect the client.
if (isGooglePlayServicesAvailable()) {
mLocationClient.connect();
initMap();
}
}
public void initMap() {
if (map == null) {
map = (GoogleMap) supportMapFragment.getMap();
if (map == null) {
//this call is made several times, and on first tried map can be null
return;
}
}
map.getUiSettings().setCompassEnabled(false);
map.getUiSettings().setZoomControlsEnabled(false);
map.setOnMyLocationChangeListener(new OnMyLocationChangeListener() {
#Override
public void onMyLocationChange(Location location) {
if (location != null) {
userLocation.saveLocation(location);
}
}
});
}
#Override
public void onResume() {
super.onResume();
initMap();
updateAnnotations();
}
/*
* Called when the Activity is no longer visible.
*/
#Override
public void onStop() {
// Disconnecting the client invalidates it.
mLocationClient.disconnect();
super.onStop();
}
/*
* Handle results returned to the FragmentActivity by Google Play services
*/
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
// Decide what to do based on the original request code
switch (requestCode) {
case CONNECTION_FAILURE_RESOLUTION_REQUEST:
/*
* If the result code is Activity.RESULT_OK, try to connect again
*/
switch (resultCode) {
case Activity.RESULT_OK:
mLocationClient.connect();
break;
}
}
}
private boolean isGooglePlayServicesAvailable() {
// Check that Google Play services is available
int resultCode = GooglePlayServicesUtil.isGooglePlayServicesAvailable(getActivity());
// If Google Play services is available
if (ConnectionResult.SUCCESS == resultCode) {
// In debug mode, log the status
Log.d("Location Updates", "Google Play services is available.");
MapsInitializer.initialize(getActivity().getApplicationContext());
mapPin = BitmapDescriptorFactory.fromResource(R.drawable.envelope);
mapPinUsed = BitmapDescriptorFactory.fromResource(R.drawable.envelope_open);
return true;
} else {
//here google suggests to display an error dialog, but i found that this only cause problems , better show a toast instead
// Get the error dialog from Google Play services
// Dialog errorDialog =
// GooglePlayServicesUtil.getErrorDialog(resultCode, getActivity(),
// CONNECTION_FAILURE_RESOLUTION_REQUEST);
// If Google Play services can provide an error dialog
// if (errorDialog != null) {
// Create a new DialogFragment for the error dialog
// ErrorDialogFragment errorFragment = new ErrorDialogFragment();
// errorFragment.setDialog(errorDialog);
// errorFragment.show(getActivity().getSupportFragmentManager(),
// "Location Updates");
// }
return false;
}
}
/*
* Called by Location Services when the request to connect the client
* finishes successfully. At this point, you can request the current
* location or start periodic updates
*/
#Override
public void onConnected(Bundle dataBundle) {
// Display the connection status
Location location = mLocationClient.getLastLocation();
if (location != null) {
updateAnnotations();
} else {
// makeText( "Current location was null, enable GPS on emulator!",
// Toast.LENGTH_SHORT);
}
}
private Marker addMarker(GoogleMap map, double lat, double lon, String title, String snippet, boolean isWon) {
MarkerOptions options = new MarkerOptions().position(new LatLng(lat, lon)).title(title).snippet(snippet);
if (isWon) {
options.icon(mapPinUsed);
} else {
options.icon(mapPin);
}
Marker marker = map.addMarker(options);
return marker;
}
private void addMarkerToMap(GoogleMap map, WBMarker beacon) {
addMarker(map, beacon.location.Lat, beacon.location.Lng, beacon.name, beacon.address, beacon.isWon);
}
private void updateAnnotations() {
mapManager.getBeaconData(new IBeaconDataReceivedListener() {
#Override
public void onBeaconDataReceived(List<WBMarker> data) {
if (data.size() > 0) {
map.clear();
}
Location loc = userLocation.getLocation();
LatLng userTarget = new LatLng(loc.getLatitude(), loc.getLongitude());
LatLngBounds.Builder builder = new LatLngBounds.Builder();
List<WBMarker> ret = closeAnnotations(data);
for (WBMarker beacon : data) {
addMarkerToMap(map, beacon);
}
builder.include(userTarget);
CameraUpdate update;
if (ret.size() == 0) {
update = CameraUpdateFactory.newCameraPosition(new CameraPosition(userTarget, 17, 0, loc.getBearing()));
} else {
for (WBMarker beacon : ret) {
builder.include(new LatLng(beacon.location.Lat, beacon.location.Lng));
}
update = CameraUpdateFactory.newLatLngBounds(builder.build(), 50);
}
map.animateCamera(update);
}
});
}
private List<WBMarker> closeAnnotations(List<WBMarker> data) {
Location userLoc = userLocation.getLocation();
List<WBMarker> ret = new ArrayList<WBMarker>();
for (WBMarker beacon : data) {
Location loc = beacon.location.getLocation();
float dist = loc.distanceTo(userLoc);
if (dist < 50000.0f) {
ret.add(beacon);
}
}
return ret;
}
/*
* Called by Location Services if the connection to the location client
* drops because of an error.
*/
#Override
public void onDisconnected() {
// Display the connection status
Toast.makeText(getActivity(),"Disconnected. Please re-connect.", Toast.LENGTH_SHORT).show();
}
/*
* Called by Location Services if the attempt to Location Services fails.
*/
#Override
public void onConnectionFailed(ConnectionResult connectionResult) {
/*
* Google Play services can resolve some errors it detects. If the error
* has a resolution, try sending an Intent to start a Google Play
* services activity that can resolve error.
*/
if (connectionResult.hasResolution()) {
try {
// Start an Activity that tries to resolve the error
connectionResult.startResolutionForResult(getActivity(), CONNECTION_FAILURE_RESOLUTION_REQUEST);
/*
* Thrown if Google Play services canceled the original
* PendingIntent
*/
} catch (IntentSender.SendIntentException e) {
// Log the error
e.printStackTrace();
}
} else {
Toast.makeText(getActivity(), "Sorry. Location services not available to you", Toast.LENGTH_LONG).show();
}
}
}
Old answer:
I also ran into this problem. you should make this call in onResume only! as the map may not be ready before then
You should also call
MapsInitializer.initialize(getActivity().getApplicationContext());
and
GooglePlayUtils.isGooglePlayServicesAvailable(context)
before calling for the map

Related

How to get origin and destination points while searching with mapbox

public class MainActivity extends AppCompatActivity implements
OnMapReadyCallback, PermissionsListener {
private static final int REQUEST_CODE_AUTOCOMPLETE = 1;
// variables for adding location layer
private MapView mapView;
private MapboxMap mapboxMap;
// variables for adding location layer
private PermissionsManager permissionsManager;
private LocationComponent locationComponent;
// variables for calculating and drawing a route
private DirectionsRoute currentRoute;
private static final String TAG = "DirectionsActivity";
private NavigationMapRoute navigationMapRoute;
// variables needed to initialize navigation
private Button button;
private CarmenFeature home;
private CarmenFeature work;
private String geojsonSourceLayerId = "geojsonSourceLayerId";
private String symbolIconId = "symbolIconId";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Mapbox access token is configured here. This needs to be called either in your application
// object or in the same activity which contains the mapview.
Mapbox.getInstance(this, getString(R.string.access_token));
// This contains the MapView in XML and needs to be called after the access token is configured.
setContentView(R.layout.activity_main);
mapView = findViewById(R.id.mapView);
mapView.onCreate(savedInstanceState);
mapView.getMapAsync(this);
}
#Override
public void onMapReady(#NonNull final MapboxMap mapboxMap) {
this.mapboxMap = mapboxMap;
mapboxMap.setStyle(Style.MAPBOX_STREETS, new Style.OnStyleLoaded() {
#Override
public void onStyleLoaded(#NonNull Style style) {
enableLocationComponent(style);
addDestinationIconSymbolLayer(style);
initSearchFab();
addUserLocations();
// Add the symbol layer icon to map for future use
style.addImage(symbolIconId, BitmapFactory.decodeResource(
MainActivity.this.getResources(), R.drawable.mapbox_marker_icon_default));
// Create an empty GeoJSON source using the empty feature collection
setUpSource(style);
// Set up a new symbol layer for displaying the searched location's feature coordinates
setupLayer(style);
}
});
}
//search
private void initSearchFab() {
findViewById(R.id.fab_location_search).setOnClickListener(new
View.OnClickListener() {
#Override
public void onClick(View view) {
Intent intent = new PlaceAutocomplete.IntentBuilder()
.accessToken(Mapbox.getAccessToken() != null ? Mapbox.getAccessToken() : getString(R.string.access_token))
.placeOptions(PlaceOptions.builder()
.backgroundColor(Color.parseColor("#EEEEEE"))
.limit(10)
.addInjectedFeature(home)
.addInjectedFeature(work)
.build(PlaceOptions.MODE_CARDS))
.build(MainActivity.this);
startActivityForResult(intent, REQUEST_CODE_AUTOCOMPLETE);
}
});
}
//home and work
private void addUserLocations() {
home = CarmenFeature.builder().text("Mapbox SF Office")
.geometry(Point.fromLngLat(-122.3964485, 37.7912561))
.placeName("50 Beale St, San Francisco, CA")
.id("mapbox-sf")
.properties(new JsonObject())
.build();
work = CarmenFeature.builder().text("Mapbox DC Office")
.placeName("740 15th Street NW, Washington DC")
.geometry(Point.fromLngLat(-77.0338348, 38.899750))
.id("mapbox-dc")
.properties(new JsonObject())
.build();
}
private void setUpSource(#NonNull Style loadedMapStyle) {
loadedMapStyle.addSource(new GeoJsonSource(geojsonSourceLayerId));
}
private void setupLayer(#NonNull Style loadedMapStyle) {
loadedMapStyle.addLayer(new SymbolLayer("SYMBOL_LAYER_ID", geojsonSourceLayerId).withProperties(
iconImage(symbolIconId),
iconOffset(new Float[] {0f, -8f})
));
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == Activity.RESULT_OK && requestCode == REQUEST_CODE_AUTOCOMPLETE) {
// Retrieve selected location's CarmenFeature
CarmenFeature selectedCarmenFeature = PlaceAutocomplete.getPlace(data);
// Create a new FeatureCollection and add a new Feature to it using selectedCarmenFeature above.
// Then retrieve and update the source designated for showing a selected location's symbol layer icon
if (mapboxMap != null) {
Style style = mapboxMap.getStyle();
if (style != null) {
GeoJsonSource source = style.getSourceAs(geojsonSourceLayerId);
if (source != null) {
source.setGeoJson(FeatureCollection.fromFeatures(
new Feature[] {Feature.fromJson(selectedCarmenFeature.toJson())}));
}
// Move map camera to the selected location
mapboxMap.animateCamera(CameraUpdateFactory.newCameraPosition(
new CameraPosition.Builder()
.target(new LatLng(((Point) selectedCarmenFeature.geometry()).latitude(),
((Point) selectedCarmenFeature.geometry()).longitude()))
.zoom(14)
.build()), 4000);
}
}
}
}
//getRoute
private void getRoute(Point origin, Point destination)
{
NavigationRoute.builder(this)
.accessToken(Mapbox.getAccessToken())
.origin(origin)
.destination(destination)
.build()
.getRoute(new Callback<DirectionsResponse>()
{
//onResponse
#Override
public void onResponse(Call<DirectionsResponse> call, Response<DirectionsResponse> response)
{
// You can get the generic HTTP info about the response
Log.d(TAG, "Response code: " + response.code());
if (response.body() == null)
{
Log.e(TAG, "No routes found, make sure you set the right user and access token.");
return;
}
else if (response.body().routes().size() < 1)
{
Log.e(TAG, "No routes found");
return;
}
currentRoute = response.body().routes().get(0);
// Draw the route on the map
if (navigationMapRoute != null)
{
navigationMapRoute.removeRoute();
}
else
{
navigationMapRoute = new NavigationMapRoute(null, mapView, mapboxMap,
R.style.NavigationMapRoute);
}
navigationMapRoute.addRoute(currentRoute);
}//end of onResponse
//onFailure
#Override
public void onFailure(Call<DirectionsResponse> call, Throwable throwable)
{
Log.e(TAG, "Error: " + throwable.getMessage());
}//end of onFailure
});
}//end of getRoute
//addDestinationIconSymbolLayer
private void addDestinationIconSymbolLayer(#NonNull Style loadedMapStyle)
{
loadedMapStyle.addImage("destination-icon-id",
BitmapFactory.decodeResource(this.getResources(), R.drawable.mapbox_marker_icon_default));
GeoJsonSource geoJsonSource = new GeoJsonSource("destination-source-id");
loadedMapStyle.addSource(geoJsonSource);
SymbolLayer destinationSymbolLayer = new SymbolLayer("destination-symbol-layer-id", "destination-source-id");
destinationSymbolLayer.withProperties(
iconImage("destination-icon-id"),
iconAllowOverlap(true),
iconIgnorePlacement(true)
);
loadedMapStyle.addLayer(destinationSymbolLayer);
}//end of addDestinationIconSymbolLayer
//enableLocationComponent
#SuppressWarnings({"MissingPermission"})
private void enableLocationComponent(#NonNull Style loadedMapStyle)
{
// Check if permissions are enabled and if not request
if (PermissionsManager.areLocationPermissionsGranted(this))
{
// Activate the MapboxMap LocationComponent to show user location
// Adding in LocationComponentOptions is also an optional parameter
locationComponent = mapboxMap.getLocationComponent();
locationComponent.activateLocationComponent(this, loadedMapStyle);
locationComponent.setLocationComponentEnabled(true);
// Set the component's camera mode
locationComponent.setCameraMode(CameraMode.TRACKING);
}
else
{
permissionsManager = new PermissionsManager(this);
permissionsManager.requestLocationPermissions(this);
}
}//end of enableLocationComponent
//onRequestPermissionsResult
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults)
{
permissionsManager.onRequestPermissionsResult(requestCode, permissions, grantResults);
}//end of onRequestPermissionsResult
//onExplanationNeeded
#Override
public void onExplanationNeeded(List<String> permissionsToExplain)
{
Toast.makeText(this, R.string.user_location_permission_explanation,
Toast.LENGTH_LONG).show();
}//end of onExplanationNeeded
//onPermissionResult
#Override
public void onPermissionResult(boolean granted)
{
if (granted)
{
enableLocationComponent(mapboxMap.getStyle());
}
else
{
Toast.makeText(this, R.string.user_location_permission_not_granted,
Toast.LENGTH_LONG).show();
finish();
}
}//end of onPermissionResult
// Add the mapView lifecycle to the activity's lifecycle methods
#Override
public void onResume() {
super.onResume();
mapView.onResume();
}
#Override
protected void onStart() {
super.onStart();
mapView.onStart();
}
#Override
protected void onStop() {
super.onStop();
mapView.onStop();
}
#Override
public void onPause() {
super.onPause();
mapView.onPause();
}
#Override
public void onLowMemory() {
super.onLowMemory();
mapView.onLowMemory();
}
#Override
protected void onDestroy() {
super.onDestroy();
mapView.onDestroy();
}
#Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
mapView.onSaveInstanceState(outState);
} }
Could you please detail what you would like to achieve?
Origin and destination are just 2 positions on the map. You can retrieve these in multiple ways. You could select them by clicking on the map, entering an address into a geocoder that would translate the address to a geolocation. Therefore you could make use of the Mapbox Places Plugin.
This example lets you select features of the map by clicking on it. You can adapt it and return the geolocation, which in turn you could use as your destination: https://docs.mapbox.com/android/maps/examples/query-a-map-feature/
You can make use of the Mapbox locationComponent and retrieve the current device location, which you could utilize as your origin.
See this example: https://docs.mapbox.com/android/maps/examples/show-a-users-location/
In below snippet, you could use the location loc as origin:
private void enableLocationComponent(#NonNull Style loadedMapStyle) {
if (PermissionsManager.areLocationPermissionsGranted(this)) {
LocationComponent locationComponent = map.getLocationComponent();
Location loc = locationComponent.getLastKnownLocation();

Android Google Places: Not returning selected place

Followed the tutorial here.
http://www.startingandroid.com/google-places-api-tutorial-for-android/
However, when searching something in the search bar, selecting one from the suggested list, then pressing the Pick Location button, the map displays the user's current location and not the place he/she selected. Can anyone provide a solution for this?
MainActivity.java
public class MainActivity extends AppCompatActivity {
private PlacePicker.IntentBuilder builder;
private PlacesAutoCompleteAdapter mPlacesAdapter;
private Button pickerBtn;
private AutoCompleteTextView myLocation;
private static final int PLACE_PICKER_FLAG = 1;
private static final LatLngBounds BOUNDS_GREATER_SYDNEY = new LatLngBounds(
new LatLng(-34.041458, 150.790100), new LatLng(-33.682247, 151.383362));
protected GoogleApiClient mGoogleApiClient;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addApi(Places.GEO_DATA_API)
.build();
setContentView(R.layout.activity_main);
builder = new PlacePicker.IntentBuilder();
myLocation = (AutoCompleteTextView) findViewById(R.id.myLocation);
mPlacesAdapter = new PlacesAutoCompleteAdapter(this, android.R.layout.simple_list_item_1,
mGoogleApiClient, BOUNDS_GREATER_SYDNEY, null);
myLocation.setOnItemClickListener(mAutocompleteClickListener);
myLocation.setAdapter(mPlacesAdapter);
pickerBtn = (Button) findViewById(R.id.pickerBtn);
pickerBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
try {
builder = new PlacePicker.IntentBuilder();
Intent intent = builder.build(MainActivity.this);
// Start the Intent by requesting a result, identified by a request code.
startActivityForResult(intent, PLACE_PICKER_FLAG);
} catch (GooglePlayServicesRepairableException e) {
GooglePlayServicesUtil
.getErrorDialog(e.getConnectionStatusCode(), MainActivity.this, 0);
} catch (GooglePlayServicesNotAvailableException e) {
Toast.makeText(MainActivity.this, "Google Play Services is not available.",
Toast.LENGTH_LONG)
.show();
}
}
});
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == RESULT_OK) {
switch (requestCode) {
case PLACE_PICKER_FLAG:
Place place = PlacePicker.getPlace(this, data);
myLocation.setText(place.getName() + ", " + place.getAddress());
break;
}
}
}
// Ahh
#Override
protected void onStart() {
super.onStart();
mGoogleApiClient.connect();
}
#Override
protected void onStop() {
mGoogleApiClient.disconnect();
super.onStop();
}
private AdapterView.OnItemClickListener mAutocompleteClickListener
= new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
final PlacesAutoCompleteAdapter.PlaceAutocomplete item = mPlacesAdapter.getItem(position);
final String placeId = String.valueOf(item.placeId);
PendingResult<PlaceBuffer> placeResult = Places.GeoDataApi
.getPlaceById(mGoogleApiClient, placeId);
placeResult.setResultCallback(mUpdatePlaceDetailsCallback);
}
};
private ResultCallback<PlaceBuffer> mUpdatePlaceDetailsCallback
= new ResultCallback<PlaceBuffer>() {
#Override
public void onResult(PlaceBuffer places) {
if (!places.getStatus().isSuccess()) {
Log.e("place", "Place query did not complete. Error: " +
places.getStatus().toString());
return;
}
// Selecting the first object buffer.
final Place place = places.get(0);
}
};
}
PlacesAutoCompleteAdapter.java
public class PlacesAutoCompleteAdapter extends ArrayAdapter<PlacesAutoCompleteAdapter.PlaceAutocomplete> implements Filterable {
private static final String TAG = "PlaceAutocomplete";
/**
* Current results returned by this adapter.
*/
private ArrayList<PlaceAutocomplete> mResultList;
/**
* Handles autocomplete requests.
*/
private GoogleApiClient mGoogleApiClient;
/**
* The bounds used for Places Geo Data autocomplete API requests.
*/
private LatLngBounds mBounds;
/**
* The autocomplete filter used to restrict queries to a specific set of place types.
*/
private AutocompleteFilter mPlaceFilter;
/**
* Initializes with a resource for text rows and autocomplete query bounds.
*
* #see ArrayAdapter#ArrayAdapter(Context, int)
*/
public PlacesAutoCompleteAdapter(Context context, int resource, GoogleApiClient googleApiClient,
LatLngBounds bounds, AutocompleteFilter filter) {
super(context, resource);
mGoogleApiClient = googleApiClient;
mBounds = bounds;
mPlaceFilter = filter;
}
/**
* Sets the bounds for all subsequent queries.
*/
public void setBounds(LatLngBounds bounds) {
mBounds = bounds;
}
/**
* Returns the number of results received in the last autocomplete query.
*/
#Override
public int getCount() {
return mResultList.size();
}
/**
* Returns an item from the last autocomplete query.
*/
#Override
public PlaceAutocomplete getItem(int position) {
return mResultList.get(position);
}
/**
* Returns the filter for the current set of autocomplete results.
*/
#Override
public Filter getFilter() {
Filter filter = new Filter() {
#Override
protected FilterResults performFiltering(CharSequence constraint) {
FilterResults results = new FilterResults();
// Skip the autocomplete query if no constraints are given.
if (constraint != null) {
// Query the autocomplete API for the (constraint) search string.
mResultList = getAutocomplete(constraint);
if (mResultList != null) {
// The API successfully returned results.
results.values = mResultList;
results.count = mResultList.size();
}
}
return results;
}
#Override
protected void publishResults(CharSequence constraint, FilterResults results) {
if (results != null && results.count > 0) {
// The API returned at least one result, update the data.
notifyDataSetChanged();
} else {
// The API did not return any results, invalidate the data set.
notifyDataSetInvalidated();
}
}
};
return filter;
}
private ArrayList<PlaceAutocomplete> getAutocomplete(CharSequence constraint) {
if (mGoogleApiClient.isConnected()) {
Log.i(TAG, "Starting autocomplete query for: " + constraint);
// Submit the query to the autocomplete API and retrieve a PendingResult that will
// contain the results when the query completes.
PendingResult<AutocompletePredictionBuffer> results =
Places.GeoDataApi
.getAutocompletePredictions(mGoogleApiClient, constraint.toString(),
mBounds, mPlaceFilter);
// This method should have been called off the main UI thread. Block and wait for at most 60s
// for a result from the API.
AutocompletePredictionBuffer autocompletePredictions = results
.await(60, TimeUnit.SECONDS);
// Confirm that the query completed successfully, otherwise return null
final Status status = autocompletePredictions.getStatus();
if (!status.isSuccess()) {
Toast.makeText(getContext(), "Error contacting API: " + status.toString(),
Toast.LENGTH_SHORT).show();
Log.e(TAG, "Error getting autocomplete prediction API call: " + status.toString());
autocompletePredictions.release();
return null;
}
Log.i(TAG, "Query completed. Received " + autocompletePredictions.getCount()
+ " predictions.");
// Copy the results into our own data structure, because we can't hold onto the buffer.
// AutocompletePrediction objects encapsulate the API response (place ID and description).
Iterator<AutocompletePrediction> iterator = autocompletePredictions.iterator();
ArrayList resultList = new ArrayList<>(autocompletePredictions.getCount());
while (iterator.hasNext()) {
AutocompletePrediction prediction = iterator.next();
// Get the details of this prediction and copy it into a new PlaceAutocomplete object.
resultList.add(new PlaceAutocomplete(prediction.getPlaceId(),
prediction.getFullText(null)));
}
// Release the buffer now that all data has been copied.
autocompletePredictions.release();
return resultList;
}
Log.e(TAG, "Google API client is not connected for autocomplete query.");
return null;
}
/**
* Holder for Places Geo Data Autocomplete API results.
*/
public class PlaceAutocomplete {
public CharSequence placeId;
public CharSequence description;
PlaceAutocomplete(CharSequence placeId, CharSequence description) {
this.placeId = placeId;
this.description = description;
}
#Override
public String toString() {
return description.toString();
}
}
}

Mock Location using FusedLocation

My question is I've got my method for mock location setup to an onclick button, however, I've got a location that is stored in a variable called lbldummylocation. both latitude and longitude coordinates are in one textview.
When I click my button setPhoneLocation (the method of the same name)
is invoked and the location stored in that textview(lbldummylocation) becomes my phone's location!
My Location Manager points Null and can't set textview in lat/long? I am using GoogleMPIClient and FusedLocation. please help! any ideas?
Class:
/**
* Everything for Location Requests
* */
private final static int PLAY_SERVICES_RESOLUTION_REQUEST = 1000; //1 sec
private Location mLastLocation;
// Google client to interact with Google API
private GoogleApiClient mGoogleApiClient;
// boolean flag to toggle periodic location updates
private boolean mRequestingLocationUpdates = false;
private LocationRequest mLocationRequest;
private LocationManager mLocationManager;
// Location updates intervals in sec
private static int UPDATE_INTERVAL = 10000; // 10 sec
private static int FATEST_INTERVAL = 5000; // 5 sec
private static int DISPLACEMENT = 10; // 10 meters
/**
* Fields
* */
// UI elements
private TextView lblLocation, lblLocation2, lblLocation3, lblDummyLocation;
private Button btnShowLocation, btnStartLocationUpdates, btnAddLocation, btnViewPhoneLocation, btnViewAllPhoneLocation, btnSetPhoneLocation, btnStartLocationService, btnStopLocationService;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_user_location);
lblDummyLocation = (TextView) findViewById(R.id.lblDummyLocation);
btnSetPhoneLocation = (Button) findViewById(R.id.btnSetPhoneLocation);
// First we need to check availability of play services
if (checkPlayServices()) {
// Building the GoogleApi client
buildGoogleApiClient();
createLocationRequest();
}
//Get location button click listener
btnSetPhoneLocation.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
setMockLocation();
}
});
}
private void setMockLocation() {
mLocationManager.removeTestProvider(LocationManager.GPS_PROVIDER);
mLocationManager.addTestProvider
(
LocationManager.GPS_PROVIDER,
"requiresNetwork" == "",
"requiresSatellite" == "",
"requiresCell" == "",
"hasMonetaryCost" == "",
"supportsAltitude" == "",
"supportsSpeed" == "",
"supportsBearing" == "",
android.location.Criteria.POWER_LOW,
android.location.Criteria.ACCURACY_FINE
);
Location newLocation = new Location(LocationManager.GPS_PROVIDER);
newLocation.setLatitude (lblDummyLocation);
newLocation.setLongitude(lblDummyLocation);
newLocation.setAccuracy(500);
mLocationManager.setTestProviderEnabled
(
LocationManager.GPS_PROVIDER,
true
);
mLocationManager.setTestProviderStatus
(
LocationManager.GPS_PROVIDER,
LocationProvider.AVAILABLE,
null,
System.currentTimeMillis()
);
mLocationManager.setTestProviderLocation
(
LocationManager.GPS_PROVIDER,
newLocation
);
}
#Override
protected void onStart() {
super.onStart();
if (mGoogleApiClient != null) {
mGoogleApiClient.connect();
}
}
#Override
protected void onResume() {
super.onResume();
checkPlayServices();
// Resuming the periodic location updates
if (mGoogleApiClient.isConnected() && mRequestingLocationUpdates) {
startLocationUpdates();
}
}
#Override
protected void onStop() {
super.onStop();
if (mGoogleApiClient.isConnected()) {
mGoogleApiClient.disconnect();
}
}
#Override
protected void onPause() {
super.onPause();
stopLocationUpdates();
}
/**
* Method to display the location on UI
* */
private void displayLocation() {
mLastLocation = LocationServices.FusedLocationApi
.getLastLocation(mGoogleApiClient);
if (mLastLocation != null) {
double latitude = mLastLocation.getLatitude();
double longitude = mLastLocation.getLongitude();
lblLocation.setText(latitude + ", " + longitude);
lblLocation2.setText("" + latitude);
lblLocation3.setText("" + longitude);
} else {
lblLocation
.setText("(Couldn't get the location. Make sure location is enabled on the device)");
}
}
/**
* Method to toggle periodic location updates
* */
private void togglePeriodicLocationUpdates() {
if (!mRequestingLocationUpdates) {
// Changing the button text
btnStartLocationUpdates
.setText(getString(R.string.btn_stop_location_updates));
mRequestingLocationUpdates = true;
// Starting the location updates
startLocationUpdates();
Log.d(TAG, "Periodic location updates started!");
} else {
// Changing the button text
btnStartLocationUpdates
.setText(getString(R.string.btn_start_location_updates));
mRequestingLocationUpdates = false;
// Stopping the location updates
stopLocationUpdates();
Log.d(TAG, "Periodic location updates stopped!");
}
}
/**
* Creating google api client object
* */
protected synchronized void buildGoogleApiClient() {
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API).build();
}
/**
* Creating location request object
* */
protected void createLocationRequest() {
mLocationRequest = new LocationRequest();
mLocationRequest.setInterval(UPDATE_INTERVAL);
mLocationRequest.setFastestInterval(FATEST_INTERVAL);
mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
mLocationRequest.setSmallestDisplacement(DISPLACEMENT);
}
/**
* Method to verify google play services on the device
* */
private boolean checkPlayServices() {
int resultCode = GooglePlayServicesUtil
.isGooglePlayServicesAvailable(this);
if (resultCode != ConnectionResult.SUCCESS) {
if (GooglePlayServicesUtil.isUserRecoverableError(resultCode)) {
GooglePlayServicesUtil.getErrorDialog(resultCode, this,
PLAY_SERVICES_RESOLUTION_REQUEST).show();
} else {
Toast.makeText(getApplicationContext(),
"This device is not supported.", Toast.LENGTH_LONG)
.show();
finish();
}
return false;
}
return true;
}
/**
* Starting the location updates
* */
protected void startLocationUpdates() {
LocationServices.FusedLocationApi.requestLocationUpdates(
mGoogleApiClient, mLocationRequest, this);
}
/**
* Stopping location updates
*/
protected void stopLocationUpdates() {
LocationServices.FusedLocationApi.removeLocationUpdates(
mGoogleApiClient, this);
}
/**
* Google api callback methods
*/
#Override
public void onConnectionFailed(ConnectionResult result) {
Log.i(TAG, "Connection failed: ConnectionResult.getErrorCode() = "
+ result.getErrorCode());
}
#Override
public void onConnected(Bundle arg0) {
// Once connected with google api, get the location
displayLocation();
if (mRequestingLocationUpdates) {
startLocationUpdates();
}
}
#Override
public void onConnectionSuspended(int arg0) {
mGoogleApiClient.connect();
}
#Override
public void onLocationChanged(Location location) {
// Assign the new location
mLastLocation = location;
Toast.makeText(getApplicationContext(), "Location changed!",
Toast.LENGTH_SHORT).show();
// Displaying the new location on UI
displayLocation();
}

Showing my track with Google map api v2 in android

I am trying to make an app that will show my current location and will track me from there with a line.I have been using Google maps Api v2 for android so i was trying to work with polylines to help me show my tracks but its not showing.
Can anyone help me with that..Thankyou.
Total code is provided.
public class MainActivity extends FragmentActivity implements ConnectionCallbacks,
OnConnectionFailedListener, LocationListener,
OnMyLocationButtonClickListener, OnClickListener, android.location.LocationListener {
private GoogleMap mMap;
private LocationClient mLocationClient;
private TextView mMessageView;
private boolean setIt;
// These settings are the same as the settings for the map. They will in fact give you updates
// at the maximal rates currently possible.
private static final LocationRequest REQUEST = LocationRequest.create()
.setInterval(5000) // 5 seconds
.setFastestInterval(16) // 16ms = 60fps
.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.my_location_demo);
mMessageView = (TextView) findViewById(R.id.message_text);
Button b1=(Button)findViewById(R.id.start);
Button b2=(Button)findViewById(R.id.stop);
b1.setOnClickListener(this);
b2.setOnClickListener(this);
}
#Override
protected void onResume() {
super.onResume();
setUpMapIfNeeded();
setUpLocationClientIfNeeded();
mLocationClient.connect();
}
#Override
public void onPause() {
super.onPause();
if (mLocationClient != null) {
mLocationClient.disconnect();
}
}
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) {
mMap.setMyLocationEnabled(true);
mMap.setOnMyLocationButtonClickListener(this);
}
}
}
private void setUpLocationClientIfNeeded() {
if (mLocationClient == null) {
mLocationClient = new LocationClient(
getApplicationContext(),
this, // ConnectionCallbacks
this); // OnConnectionFailedListener
}
}
/**
* Button to get current Location. This demonstrates how to get the current Location as required
* without needing to register a LocationListener.
*/
public void showMyLocation(View view) {
if (mLocationClient != null && mLocationClient.isConnected()) {
String msg = "Location = " + mLocationClient.getLastLocation();
Toast.makeText(getApplicationContext(), msg, Toast.LENGTH_SHORT).show();
}
}
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
LocationManager locationmanager = (LocationManager) getSystemService(LOCATION_SERVICE);
locationmanager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, this);
if (v.getId() == R.id.start) {
setIt = true;
};
if (v.getId() == R.id.stop) {
mMap.clear();
};
}
PolylineOptions rectOptions = new PolylineOptions().width(3).color(
Color.RED);
#Override
public void onLocationChanged(Location location) {
mMessageView.setText("Location = " + location);
rectOptions.add(new LatLng(location.getLatitude(), location.getLongitude()));
if (setIt == true){
mMap.addPolyline(rectOptions);
}
}
#Override
public void onConnected(Bundle connectionHint) {
mLocationClient.requestLocationUpdates(
REQUEST,
this); // LocationListener
}
/**
* Callback called when disconnected from GCore. Implementation of {#link ConnectionCallbacks}.
*/
#Override
public void onDisconnected() {
// Do nothing
}
/**
* Implementation of {#link OnConnectionFailedListener}.
*/
#Override
public void onConnectionFailed(ConnectionResult result) {
// Do nothing
}
#Override
public boolean onMyLocationButtonClick() {
{
setIt = true;
};
Toast.makeText(this, "MyLocation button clicked", Toast.LENGTH_SHORT).show();
// Return false so that we don't consume the event and the default behavior still occurs
// (the camera animates to the user's current position).
return false;
}
#Override
public void onProviderDisabled(String arg0) {
// TODO Auto-generated method stub
}
#Override
public void onProviderEnabled(String arg0) {
// TODO Auto-generated method stub
}
#Override
public void onStatusChanged(String arg0, int arg1, Bundle arg2) {
// TODO Auto-generated method stub
}
}
This is very easy to in Google Map API V2 . If you would like to do this then you can follow this reference link:
Go this stackoverflow link
This man already give useful solution. I have done the same way as this site told.
For your facility I have written the main things:
1.create a list of LatLng points such as:
List<LatLng> routePoints;
2.Add the route points to the list (could/should be done in a loop):
routePoints.add(mapPoint);
3.Create a Polyline and feed it the list of LatLng points as such:
Polyline route = map.addPolyline(new PolylineOptions()
.width(_strokeWidth)
.color(_pathColor)
.geodesic(true)
.zIndex(z));
route.setPoints(routePoints);
Try this and give feedback!!!

Google Maps v2 my location with Google Play

I would like to ask about a strange situation, that happened during usage of Google Maps API v2.
There is an error in logcat that says:
The Google Play services resources were not found. Check your project
configuration to ensure that the resources are included.
The things that I have:
Google Map is displayed perfectly along with markers - I have acquired relevant code from Google.
google-play-services.jar library is included perfectly with Eclipse
(project->properties->android->add...).
The checkboxes in Eclipse (project->properties->java build path->order build path) are all checked properly.
The code
GooglePlayServicesUtil.isGooglePlayServicesAvailable(context);
returns true.
This code is running at a device, Nexus 4, not emulator.
I am trying to invoke event, that would allow me to get current position by this class:
public class FindMyLocationManager implements LocationListener, LocationSource
{
private OnLocationChangedListener mListener;
private LocationManager locationManager;
private GoogleMap map;
private Context ctx;
private int intervalTime;
private int intervalDistance;
public void setMap(GoogleMap map)
{
this.map = map;
}
public int getIntervalTime()
{
return intervalTime;
}
public void setIntervalTime(int intervalTime)
{
this.intervalTime = intervalTime;
}
public int getIntervalDistance()
{
return intervalDistance;
}
public void setIntervalDistance(int intervalDistance)
{
this.intervalDistance = intervalDistance;
}
public FindMyLocationManager(Context mContext)
{
this.ctx = mContext;
locationManager = (LocationManager)mContext.getSystemService(Context.LOCATION_SERVICE);
}
#Override
public void activate(OnLocationChangedListener listener)
{
mListener = listener;
isGooglePlayOk(); //returns true
if(isGPSAvailable())
{
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, intervalTime, intervalDistance, this);
}
else if(isCompassAvailable())
{
Log.d("DEBUG", "No GPS here");
}
else
{
Log.d("DEBUG", "Nothing here");
}
}
private boolean isGPSAvailable()
{
return locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
}
public boolean isGooglePlayOk()
{
int isAvailable = GooglePlayServicesUtil.isGooglePlayServicesAvailable(ctx);
if(isAvailable == ConnectionResult.SUCCESS)
{
Toast.makeText(ctx, "Can connect to Goolge Play", Toast.LENGTH_SHORT).show();
return true;
}
else if(GooglePlayServicesUtil.isUserRecoverableError(isAvailable))
{
Dialog dialog = GooglePlayServicesUtil.getErrorDialog(isAvailable, (Activity)ctx, 9001);
dialog.show();
}
else
{
Toast.makeText(ctx, "Can't connect to Goolge Play", Toast.LENGTH_SHORT).show();
}
return false;
}
private boolean isCompassAvailable()
{
PackageManager pm =
ctx.getPackageManager();
return pm.hasSystemFeature(PackageManager.FEATURE_SENSOR_COMPASS);
}
#Override
public void deactivate()
{
locationManager.removeUpdates((android.location.LocationListener)this);
mListener = null;
}
public void restart()
{
locationManager.removeUpdates((android.location.LocationListener)this);
if(isGPSAvailable())
{
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, intervalTime, intervalDistance, this);
}
else if(isCompassAvailable())
{
Log.d("DEBUG", "No GPS");
}
else
{
Log.d("DEBUG", "Nothing at all");
}
}
// the compiler never enters here
#Override
public void onLocationChanged(Location location)
{
Toast.makeText(this.ctx, location.getLatitude() + " " + location.getLongitude(), Toast.LENGTH_LONG).show();
if(mListener != null)
{
mListener.onLocationChanged(location);
}
map.animateCamera(CameraUpdateFactory.newLatLng(new LatLng(location.getLatitude(), location.getLongitude())));
}
#Override
public void onProviderDisabled(String arg0)
{
// TODO Auto-generated method stub
}
#Override
public void onProviderEnabled(String arg0)
{
// TODO Auto-generated method stub
}
#Override
public void onStatusChanged(String arg0, int arg1, Bundle arg2)
{
// TODO Auto-generated method stub
}
}
And here is the usage of above code:
// this method is called in many places in the program, like onCreate of my view with map or onResume
private void setUpMapIfNeeded()
{
if(map == null)
{
map = ((SupportMapFragment)getFragmentManager().findFragmentById(R.id.map)).getMap();
if(map != null)
{
map.setMyLocationEnabled(true);
locationManager.setMap(map);
locationManager.setIntervalDistance(0);
locationManager.setIntervalTime(0);
map.setLocationSource(locationManager); //Here I apply the object from above class
//if(currentModel != null)
//currentModel = getCurrentModel(); TODO
//moveCameraInstantly(map.);
focusCamera();
fillMapWithMarkers(FindMyApplication.MAP_MARKER_MODELS);
}
}
}
UPDATE
So it seems that the error itself is harmless, but I still don't get the onLocationChanged event.
UPDATE 2
This code is based on How to get My Location changed event with Google Maps android API v2? .
If i understand correctly you have defined the location update method, but have not started requesting the location updates.
To send the request for location updates, create a location client and a request in onCreate():
protected void onCreate(Bundle savedInstanceState) {
...
mLocationClient = new LocationClient(this, this, this);
mLocationRequest = LocationRequest.create();
}
Then connect it in onStart():
protected void onStart() {
...
mLocationClient.connect();
}
Then make the update request in onConnected():
public void onConnected(Bundle dataBundle) {
...
mLocationClient.requestLocationUpdates(mLocationRequest, this);
}
Here is a complete guide on how to do this correctly:
http://developer.android.com/training/location/receive-location-updates.html#StartUpdates
The Google Play services resources were not found. error is a common bug in the library.
if the map shows like it should then you did everything correctly, there is something in the library that is causing the problem that google needs to fix. I get this error in my app even when I dont use google maps.
since you have google play service you should be using the new location API and not the old one.
http://developer.android.com/training/location/index.html
EDIT
Also this piece of code seems suspicious:
if(map == null) {
map = <something new>;
if(map != null) {
<do thing>
}
}
Is your map always null before entering this method?
EDIT2
map.setOnMyLocationChangeListener(new GoogleMap.OnMyLocationChangeListener() {
#Override
public void onMyLocationChange(Location location) {
Log.d("DEBUG", "setOnMyLocationChangeListener");
setUpMapIfNeeded();
}
});
if it doesn't work, then try also:
map.setOnCameraChangeListener(new GoogleMap.OnCameraChangeListener() {
#Override
public onCameraChange(CameraPosition cameraPosition) {
Log.d("DEBUG", "setOnCameraChangeListener");
setUpMapIfNeeded();
}
});
I need log results on this.

Categories