I am having some random crashes in super.onResume with Google maps. It only happens in debug mode, not in production. It is weird how the map is added to the fragment (not coded by myself), but it was working properly before. Just some day started to crash. Below you can see the error and the code. I would really appreciate some help!
Fatal Exception: java.lang.NullPointerException
com.google.maps.api.android.lib6.e.y.b (Unknown Source)
com.google.android.gms.maps.MapFragment.onResume (Unknown Source)
com.xxxx.xxxx.Fragments.FragmentMap.onResume (FragmentMap.java:983)
com.xxxx.xxxx.Fragments.FragmentMap.onConnected(FragmentMap.java:2667)
com.google.android.gms.common.internal.zzk.zzk (Unknown Source)
dalvik.system.NativeStart.main (NativeStart.java)
And this is the Fragment where is painting the Map:
public class FragmentMap extends MapFragment implements LocationListener,
GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener, ResultCallback<LocationSettingsResult> {
GoogleMap map;
GoogleApiClient
{...}
#Override
public void onCreate(Bundle savedInstanceState) {
//Instantiate here all not view objects (Fragments good practices)
super.onCreate(savedInstanceState);
setRetainInstance(true);
if (checkPlayServices()) {
// Building the GoogleApi client
buildGoogleApiClient();
createLocationRequest();
buildLocationSettingsRequest();
checkLocationSettings();
}
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
map = this.getMap();
map.getUiSettings().setZoomControlsEnabled(false);
map.getUiSettings().setMyLocationButtonEnabled(false);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View mapView = super.onCreateView(inflater, container, savedInstanceState);
RelativeLayout rl = new RelativeLayout(getActivity());
if (condition1) {
View firstOverlay = inflater.inflate(R.layout.first_map_layout, null);
rl.addView(mapView);
rl.addView(firstOverlay);
setHasOptionsMenu(true);
} else {
View srcvAddress = inflater.inflate(R.layout.address_finder, null);
rl.addView(mapView);
rl.addView(srcvAddress);
}
return rl;
}
#Override
public void onResume() {
super.onResume(); <----------------------- **HERE CRASHES!!**
stopUpdatePositionService();
if (mGoogleApiClient.isConnected()) {
{...}
}
}
/**
* Creating google api client object
*/
private synchronized void buildGoogleApiClient() {
mGoogleApiClient = new GoogleApiClient.Builder(getActivity())
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API).build();
}
/**
* Stopping location updates
*/
private void stopLocationUpdates() {
if (mGoogleApiClient.isConnected())
LocationServices.FusedLocationApi.removeLocationUpdates(
mGoogleApiClient, this);
}
#Override
public void onStart() {
super.onStart();
if (mGoogleApiClient != null) {
mGoogleApiClient.connect();
}
}
/**
* Google api callback methods
*/
#Override
public void onConnectionFailed(#NonNull 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
onResume();
//displayLocation();
}
#Override
public void onConnectionSuspended(int arg0) {
mGoogleApiClient.connect();
}
/**
* Creating location request object
*/
private void createLocationRequest() {
mLocationRequest = new LocationRequest();
mLocationRequest.setInterval(UPDATE_INTERVAL);
mLocationRequest.setFastestInterval(FATEST_INTERVAL);
mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
mLocationRequest.setSmallestDisplacement(DISPLACEMENT);
}
Thanks in advance!
map=this.getmap();---> might be the problem
instead try this
map= ((MapFragment) getFragmentManager().findFragmentById(R.id.map)).getMap();//where R.id.map is google map fragment
Note for future: Forget about getMap. It is already deprecated. When I moved everything to the new getMapAsync it is working everything fine
Related
I am a newbie to android development. I want to develop an app which have three tabs.
First tab will be My Location in which there is a map and a pin which is marking my location
On second tab there will be a camera option, through which i can take pictures and those pictures will be saved in the memory located by OS to the app.
The saved pictures will be shown in a slider
As for 2 and 3, i'll have some idea but for 1 i couldn't find any help. I did find some tutorials but all of them are for eclipse but i am using android studio.
During a study i found that Fragment is a way to do it so i started to follow this tutorial, but as i said earlier i am newbie and all tutorials are for eclipse.
Update 1
I have created 3 classes and 3 layout files each for each tab, bellow is the class for MyLocation tab
public class MyLocation extends Fragment{
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.my_location, container, false);
return rootView;
} }
I am stuck to it now and don't know what to do
Any help would be highly appreciated
If you want to create google map inside fragment than go threw this code
public class GoogleMapFragment extends Fragment implements OnMapReadyCallback,
GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener{
private GoogleMap googleMap;
GoogleApiClient mGoogleApiClient;
Location mLastLocation;
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_demo, container, false);
}
#Override
public void onViewCreated(View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
if (mGoogleApiClient == null) {
mGoogleApiClient = new GoogleApiClient.Builder(getActivity())
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API)
.build();
}
mGoogleApiClient.connect();
}
#Override
public void onResume() {
super.onResume();
intiGoogleMap();
}
#Override
public void onStart() {
mGoogleApiClient.connect();
super.onStart();
}
#Override
public void onStop() {
mGoogleApiClient.disconnect();
super.onStop();
}
#Override
public void onDestroyView() {
super.onDestroyView();
SupportMapFragment supportMapFragment = ((SupportMapFragment) getFragmentManager().findFragmentById(R.id.mapMapAddress));
if (supportMapFragment != null)
getFragmentManager().beginTransaction().remove(supportMapFragment).commit();
}
private void intiGoogleMap() {
SupportMapFragment supportMapFragment = ((SupportMapFragment) getFragmentManager().findFragmentById(R.id.mapMapAddress));
supportMapFragment.getMapAsync(this);
}
#Override
public void onConnected(#Nullable Bundle bundle) {
//First check permissions if accept or reject
if (AppUtils.checkPermission(Manifest.permission.ACCESS_FINE_LOCATION, getActivity()) &&
AppUtils.checkPermission(Manifest.permission.ACCESS_COARSE_LOCATION, getActivity())) {
mLastLocation = LocationServices.FusedLocationApi.getLastLocation(
mGoogleApiClient);
if (googleMap != null)
if (mLastLocation != null) {
//here you can place your marker
}
} else {
Toast.makeText(getActivity(), "Check your permission", Toast.LENGTH_LONG).show();
}
}
#Override
public void onConnectionSuspended(int i) {
}
#Override
public void onConnectionFailed(#NonNull ConnectionResult connectionResult) {
}
#Override
public void onMapReady(GoogleMap googleMap) {
if (googleMap != null) {
this.googleMap = googleMap;
this.googleMap.getUiSettings().setMyLocationButtonEnabled(true);
this.googleMap.getUiSettings().setCompassEnabled(true);
}
}
}
and fragment_demo.xml is
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<fragment
android:id="#+id/mapMapAddress"
android:name="com.google.android.gms.maps.SupportMapFragment"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</RelativeLayout>
and try to run this will be showing of google map, and make sure all permissions and you have created app in google developer console. Also make sure adding Android Key in manifest file.
I try to learn Android by myself. And in my app, I want to use fragment to show google map and when user open my app, I want to get current location by using GoogleApiClient
My fragment code:
public class HomeFragment extends Fragment implements GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener {
public interface comuticateParent {
public void sendMess(String text);
}
private static final String ARG_PARAM1 = "param1";
private static final String ARG_PARAM2 = "param2";
// TODO: Rename and change types of parameters
private String mParam1;
private String mParam2;
public HomeFragment() {
// Required empty public constructor
}
public static HomeFragment newInstance(String param1, String param2) {
HomeFragment fragment = new HomeFragment();
Bundle args = new Bundle();
args.putString(ARG_PARAM1, param1);
args.putString(ARG_PARAM2, param2);
fragment.setArguments(args);
return fragment;
}
comuticateParent callback;
Button btn1;
TextView textView;
MapView mMapView;
GoogleApiClient mGoogleApiClient;
Location mLastLocation;
LocationRequest mLocationRequest;
private GoogleMap googleMap;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getArguments() != null) {
mParam1 = getArguments().getString(ARG_PARAM1);
mParam2 = getArguments().getString(ARG_PARAM2);
}
if (mGoogleApiClient == null) {
mGoogleApiClient = new GoogleApiClient.Builder(getActivity())
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API)
.build();
}
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_home, container, false);
mMapView = (MapView) rootView.findViewById(R.id.mapView);
mMapView.onCreate(savedInstanceState);
mMapView.onResume(); // needed to get the map to display immediately
try {
MapsInitializer.initialize(getActivity().getApplicationContext());
} catch (Exception e) {
e.printStackTrace();
}
mMapView.getMapAsync(new OnMapReadyCallback() {
#Override
public void onMapReady(GoogleMap mMap) {
googleMap = mMap;
googleMap.setMyLocationEnabled(true);
mLastLocation = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
Log.d("onCreateView", Boolean.toString(mGoogleApiClient.isConnected()));
googleMap.animateCamera(CameraUpdateFactory.newLatLngZoom(mylocation, 13));
}
});
return rootView;
}
#Override
public void onStart() {
mGoogleApiClient.connect();
Log.d("ConnectonStart", "Connected ");
Log.d("ONstart", Boolean.toString(mGoogleApiClient.isConnected()));
super.onStart();
}
#Override
public void onStop() {
mGoogleApiClient.disconnect();
super.onStop();
}
#Override
public void onResume() {
mGoogleApiClient.connect();
super.onResume();
mMapView.onResume();
}
#Override
public void onPause() {
super.onPause();
mMapView.onPause();
}
#Override
public void onDestroy() {
super.onDestroy();
mMapView.onDestroy();
}
#Override
public void onLowMemory() {
super.onLowMemory();
mMapView.onLowMemory();
}
#Override
public void onConnected(Bundle bundle) {
Log.d("Connect", "Connected ");
Log.d("onConnected", Boolean.toString(mGoogleApiClient.isConnected()));
}
#Override
public void onConnectionSuspended(int i) {
}
#Override
public void onConnectionFailed(ConnectionResult connectionResult) {
Log.d("Connect", "failed ");
}
#Override
public void onAttach(Context context) {
super.onAttach(context);
Activity activity;
if (context instanceof Activity) {
activity = (Activity) context;
callback = (comuticateParent) getActivity();
}
}
}
And problem here:
-Log in method onCreateView appears before log in method onconnected, so I can't get getLastLocation() because The googleAPIClient is not connect yet.
I have search in google but I don't know how to fix it.
Please help me!
Sorry about my best English.
First problem Log in method onCreateView appears before log in method onconnected, because GoogleApiClient will accessing Google APIs, verify app configuration, verify certificate fingerprint, etc. It take too long to process. To avoid blocking the UI thread, it'll execute in another thread and use asynchronous callback.
Second problem I can't get getLastLocation() because The googleAPIClient is not connect yet, because FusedLocationApi will only maintain background, so you need to get GoogleMap in background.
See my sample here: https://gist.github.com/quydm/a458d908c4da2496672f83372304f417
You will have to wait until the GoogleApiClient has connected before you can request location updates. In order to do so, you would move this block of code (currently found in your onCreateView() method):
mLastLocation = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
Log.d("onCreateView", Boolean.toString(mGoogleApiClient.isConnected()));
googleMap.animateCamera(CameraUpdateFactory.newLatLngZoom(mylocation, 13));
to the body of the overridden method onConnected().
You cannot have this code directly in onCreateView() because of the very problem you had. The connection must be established first before any location requests are sent. The connection can establish quickly or take longer than normal. It depends on many things outside of your control.
For that reason, I would suggest showing some sort of progress bar to indicate that location services is connecting and then remove the progress bar when onConnected() is called. Of course this depends entirely on your app. If location services is critical for the user to have then this is a must, if not, then you may not need to add it.
I'm trying to mark current user location in a maps activity but the call of LocationServices.FusedLocationApi.getLastLocation always returns null
public class MapsActivity extends AppCompatActivity implements OnMapReadyCallback,GoogleApiClient.ConnectionCallbacks,GoogleApiClient.OnConnectionFailedListener {
private GoogleMap mMap;
private GoogleApiClient mGoogleApiClient=null;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_maps);
// Obtain the SupportMapFragment and get notified when the map is ready to be used.
SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
.findFragmentById(R.id.map);
mapFragment.getMapAsync(this);
if (mGoogleApiClient == null) {
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API)
.build();
}
mGoogleApiClient.connect();
}
#Override
public void onConnectionFailed(ConnectionResult connectionResult) {
}
#Override
public void onConnectionSuspended(int i) {
}
#Override
public void onConnected(Bundle bundle) {
}
#Override
protected void onStart() {
if(mGoogleApiClient.isConnected())
Toast.makeText(this,"Client Connect",Toast.LENGTH_SHORT).show();
else
mGoogleApiClient.connect();
super.onStart();
}
#Override
public void onMapReady(GoogleMap googleMap) {
mMap = googleMap;
if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION)
== PackageManager.PERMISSION_GRANTED) {
mLastLocation = LocationServices.FusedLocationApi.getLastLocation(
mGoogleApiClient);
LatLng myLocation = null;
if(mLastLocation!=null) {
myLocation = new LatLng(mLastLocation.getLatitude(),
mLastLocation.getLongitude());
mMap.animateCamera(CameraUpdateFactory.newLatLngZoom(myLocation,
mMap.getMaxZoomLevel() - 5));
}
} else {
// Show rationale and request permission.
}
}
}
Also i have added the permission in manifest file
when checking for mGoogleApiClient for connectivity it's always not connected
You need to register a listener to the location events, and start listening for a short period of time to several locations received, and compare their accuracy , source, etc, to determine which is the best one, and use that one.
Read Location strategies google documentation, which is pretty useful and has code examples of what you need to do to get accurate locations.
Also add this permission to the manifest:
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
Am trying to build an application that requests the current location using the GoogleClientApi and LocationServices, but the Location is always null even that I enabled the WiFi,Mobile Data and GPS , tested it on several devices all the same
the permissions from the manifest.xml :
<uses-permission android:name="com.google.android.providers.gsf.permission.READ_GSERVICES" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
Activity:
public class FindStation extends Fragment implements GoogleApiClient.ConnectionCallbacks,GoogleApiClient.OnConnectionFailedListener,com.google.android.gms.location.LocationListener
{
public static FragmentManager fragmentManager;
Button goButton;
Spinner spinner;
SupportMapFragment mapFragment;
GoogleMap map;
List<Stations> stationsList;
ArrayList<String> stationsAddresses;
private static View view;
ArrayList<MarkerOptions> markers;
GoogleApiClient mGoogleApiClient;
LocationServices locationServices;
Location location;
private static String TAG="FIND_STATION";
Context context;
LocationRequest mLocationRequest;
LocationListener locationListener;
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
context= getActivity();
locationListener=this;
mLocationRequest = new LocationRequest();
mLocationRequest.setInterval(10000);
mLocationRequest.setFastestInterval(5000);
mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
mLocationRequest.setSmallestDisplacement(10);
/*mGoogleApiClient = new GoogleApiClient.Builder(getActivity())
.addApi(LocationServices.API)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.build();*/
buildGoogleApiClient();
if (view != null) {
ViewGroup parent = (ViewGroup) view.getParent();
if (parent != null)
parent.removeView(view);
}
try {
view = inflater.inflate(R.layout.activity_find_station, container, false);
} catch (InflateException e) {
}
inflater.inflate(R.layout.activity_find_station,container,false);
stationsAddresses = new ArrayList<>();
goButton= (Button) view.findViewById(R.id.button);
//goButton.setVisibility(View.INVISIBLE);
spinner= (Spinner) view.findViewById(R.id.spinner);
stationsList = Stations.listAll(Stations.class);
markers = new ArrayList<>();
for (int i = 0; i <stationsList.size() ; i++) {
stationsAddresses.add(stationsList.get(i).getStationLocation());
markers.add(new MarkerOptions().position(new LatLng(stationsList.get(i).getStationLat(), stationsList.get(i).getStationLong())).title(stationsList.get(i).getStationName()));
}
goButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//location= LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
}
});
try {
initialize();
} catch (Exception e) {
e.printStackTrace();
}
try {
// map.setMyLocationEnabled(true);
} catch (Exception e) {
e.printStackTrace();
}
/*thread = new Thread(new MyThread());
thread.start();*/
return view;
}
private void initialize() {
if (map==null) {
Fragment fragment= getChildFragmentManager().findFragmentById(R.id.map);
mapFragment= (SupportMapFragment) fragment;
map=mapFragment.getMap();
for (int i = 0; i <markers.size() ; i++) {
map.addMarker(markers.get(i));
}
// check if map is created successfully or not
if (map==null) {
Toast.makeText(super.getActivity(),
"Sorry! unable to create maps", Toast.LENGTH_SHORT)
.show();
}
}
}
public void onDestroyView() {
super.onDestroyView();
android.support.v4.app.FragmentManager fm = getActivity().getSupportFragmentManager();
SupportMapFragment fragment = (SupportMapFragment) fm.findFragmentById(R.id.map);
if (fragment!=null) {
android.support.v4.app.FragmentTransaction ft = fm.beginTransaction();
ft.remove(fragment);
ft.commit();
}
}
#Override
public void onConnected(Bundle bundle) {
location= LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
if (location!=null){
Log.d(TAG,location.toString());
CameraUpdate update = CameraUpdateFactory.newLatLngZoom(new LatLng(location.getLatitude(),location.getLongitude()),3f);
map.animateCamera(update);
}
Log.d(TAG,"connected");
}
#Override
public void onConnectionSuspended(int i) {
Log.d(TAG,"connection suspended "+String.valueOf(i));
}
#Override
public void onConnectionFailed(ConnectionResult connectionResult) {
Log.d(TAG,"connection failed");
}
#Override
public void onLocationChanged(Location location) {`enter code here`
Log.d(TAG,location.toString());
this.location=location;
if (location!=null) {
CameraUpdate update = CameraUpdateFactory.newLatLngZoom(new LatLng(location.getLatitude(), location.getLongitude()), 3f);
map.animateCamera(update);
Log.d(TAG, "camera updated to new position");
goButton.setVisibility(View.VISIBLE);
}
}
#Override
public void onStart() {
super.onStart();
mGoogleApiClient.connect();
Log.d(TAG,"connect() was called");
}
protected synchronized void buildGoogleApiClient() {
mGoogleApiClient = new GoogleApiClient.Builder(context)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API)
.build();
}
}
the strange thing is that the onConnect() method is called but after that the Location is always null and onLocationChanged() is never called
using the maps, i tried the enabling my location and it works when you have the button on the right top corner it returns the location and animates the camera.
UPDATE 1
updated the onConnected() method and made it request locations updates,
public void onConnected(Bundle bundle) {
LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, locationListener);
if (location!=null){
Log.d(TAG,location.toString());
CameraUpdate update = CameraUpdateFactory.newLatLngZoom(new LatLng(location.getLatitude(),location.getLongitude()),3f);
map.animateCamera(update);
}
Log.d(TAG,"connected");}
then with a button i call lastKnownLocation() since the onLocationChanged() is not called still, and still the returned Location is null
UPDATE 2 :
The very same code worked on Android 5.0.1 and worked perfectly
all the other devices was on android 2.3.7,4.0.1 none of them worked,
Any idea about what difference in the Android APIs regarding the location?
You need to call requestLocationUpdates() in order to register the listener and have onLocationChanged() invoked.
Be sure to un-register the listener as soon as possible to avoid excessive battery drain.
Also note that the getLastLocation() method can and will return null. The main problem is that it doesn't prompt a request to the OS for a new location lock, instead it just checks if there was a last known location from some other app's location request. If no other app had recently made a location request, then you get a null location returned to you.
The only way to guarantee that you actually get a location is to request one, and this is done with a call to requestLocationUpdates().
Here is a working example for reference:
public class MainActivity extends FragmentActivity
implements OnMapReadyCallback,
GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener,
LocationListener {
private GoogleMap map;
private LocationRequest mLocationRequest;
private GoogleApiClient mGoogleApiClient;
private Location mLastLocation;
private Marker marker;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
#Override
protected void onResume() {
super.onResume();
buildGoogleApiClient();
mGoogleApiClient.connect();
if (map == null) {
SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
.findFragmentById(R.id.map);
mapFragment.getMapAsync(this);
}
}
#Override
public void onMapReady(GoogleMap retMap) {
map = retMap;
setUpMap();
}
public void setUpMap(){
map.setMapType(GoogleMap.MAP_TYPE_HYBRID);
map.setMyLocationEnabled(true);
}
#Override
protected void onPause(){
super.onPause();
if (mGoogleApiClient != null) {
LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, this);
}
}
protected synchronized void buildGoogleApiClient() {
Toast.makeText(this, "buildGoogleApiClient", Toast.LENGTH_SHORT).show();
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API)
.build();
}
#Override
public void onConnected(Bundle bundle) {
Toast.makeText(this,"onConnected",Toast.LENGTH_SHORT).show();
mLocationRequest = new LocationRequest();
mLocationRequest.setInterval(1000);
mLocationRequest.setFastestInterval(1000);
mLocationRequest.setPriority(LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY);
//mLocationRequest.setSmallestDisplacement(0.1F);
LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this);
}
#Override
public void onConnectionSuspended(int i) {
Toast.makeText(this,"onConnectionSuspended",Toast.LENGTH_SHORT).show();
}
#Override
public void onConnectionFailed(ConnectionResult connectionResult) {
Toast.makeText(this,"onConnectionFailed",Toast.LENGTH_SHORT).show();
}
#Override
public void onLocationChanged(Location location) {
mLastLocation = location;
//remove previous current location Marker
if (marker != null){
marker.remove();
}
double dLatitude = mLastLocation.getLatitude();
double dLongitude = mLastLocation.getLongitude();
marker = map.addMarker(new MarkerOptions().position(new LatLng(dLatitude, dLongitude))
.title("My Location").icon(BitmapDescriptorFactory
.defaultMarker(BitmapDescriptorFactory.HUE_RED)));
map.moveCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(dLatitude, dLongitude), 8));
}
}
One more thing, if your map is in a Fragment, there is no need to have a nested SupportMapFragment. You can just have your Fragment extend SupportMapFragment. This removes the need of having a nested Fragment, and you don't even need to inflate any layout xml, here is a simple example:
public class MapTabFragment extends SupportMapFragment
implements OnMapReadyCallback {
private GoogleMap mMap;
private Marker marker;
public MapTabFragment() {
}
#Override
public void onResume() {
super.onResume();
setUpMapIfNeeded();
}
private void setUpMapIfNeeded() {
if (mMap == null) {
getMapAsync(this);
}
}
#Override
public void onMapReady(GoogleMap googleMap) {
mMap = googleMap;
setUpMap();
}
private void setUpMap() {
mMap.setMyLocationEnabled(true);
mMap.setMapType(GoogleMap.MAP_TYPE_HYBRID);
mMap.getUiSettings().setMapToolbarEnabled(false);
mMap.setOnMapClickListener(new GoogleMap.OnMapClickListener() {
#Override
public void onMapClick(LatLng point) {
//remove previously placed Marker
if (marker != null) {
marker.remove();
}
//place marker where user just clicked
marker = mMap.addMarker(new MarkerOptions().position(point).title("Marker")
.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_MAGENTA)));
}
});
}
}
in the last update of google services, Google has depercated LocationClient api and now say use GoogleApiClient.
Now need create the App with GPS report any 30 seconds to my webserver but dont found (or dont understant) how work this new api.
If you have a example using GoogleApiClient please past the link to see or download.
And if have a Service with GoogleApiClient please past the link
Thanks for your help.
If you have installed android sdk then just checkout following directory \extras\google\google_play_services\samples\maps\src\com\example\mapdemo\.
It is having one example of showing current location in GoogleMap and it is using GoogleApiClient to retrieve current location on periodic interval of 5 seconds as described in following code. You can modify it according to your requirements.
MyLocationDemoActivity.java
public class MyLocationDemoActivity extends FragmentActivity
implements
ConnectionCallbacks,
OnConnectionFailedListener,
LocationListener,
OnMyLocationButtonClickListener {
private GoogleMap mMap;
private GoogleApiClient mGoogleApiClient;
private TextView mMessageView;
// 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);
}
#Override
protected void onResume() {
super.onResume();
setUpMapIfNeeded();
setUpGoogleApiClientIfNeeded();
mGoogleApiClient.connect();
}
#Override
public void onPause() {
super.onPause();
if (mGoogleApiClient != null) {
mGoogleApiClient.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 setUpGoogleApiClientIfNeeded() {
if (mGoogleApiClient == null) {
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addApi(LocationServices.API)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.build();
}
}
/**
* 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 (mGoogleApiClient != null && mGoogleApiClient.isConnected()) {
String msg = "Location = "
+ LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
Toast.makeText(getApplicationContext(), msg, Toast.LENGTH_SHORT).show();
}
}
/**
* Implementation of {#link LocationListener}.
*/
#Override
public void onLocationChanged(Location location) {
mMessageView.setText("Location = " + location);
}
/**
* Callback called when connected to GCore. Implementation of {#link ConnectionCallbacks}.
*/
#Override
public void onConnected(Bundle connectionHint) {
LocationServices.FusedLocationApi.requestLocationUpdates(
mGoogleApiClient,
REQUEST,
this); // LocationListener
}
/**
* Callback called when disconnected from GCore. Implementation of {#link ConnectionCallbacks}.
*/
#Override
public void onConnectionSuspended(int cause) {
// Do nothing
}
/**
* Implementation of {#link OnConnectionFailedListener}.
*/
#Override
public void onConnectionFailed(ConnectionResult result) {
// Do nothing
}
#Override
public boolean onMyLocationButtonClick() {
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;
}
}
I had exactly your same problem. You need to explicitely use GoogleMap.setLocationSource().
Here is an example: Android: Google Maps location with low battery usage