I am trying to get the current location of the user from an asynctask. My application depends on the latitude and longitude values. I am trying to show a ProgressDialog to the user till the location is fetched.
Problem :- The location value is always null. I know that getting gps location takes time. But my location value is null even after waiting for sometimes. Its always null.
Below is my code :-
public class MainActivity extends ActionBarActivity {
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//some action …
}
#Override
public boolean onOptionsItemSelected(MenuItem item)
{
if (id == R.id.action_settings)
{
return true;
}
if(id == R.id.action_location)
{
LocationTask locGetter = new LocationTask(MainActivity.this);
locGetter.execute();
}
return super.onOptionsItemSelected(item);
}
}
Below is my AsyncTask
public class LocationTask extends AsyncTask<Void,Void,Void> implements LocationListener
{
private ProgressDialog dialog;
private Activity callingActivity;
LocationManager locationManager;
String provider = LocationManager.GPS_PROVIDER;
public LocationTask(Activity activity)
{
callingActivity = activity;
}
#Override
protected void onPreExecute()
{
dialog= ProgressDialog.show(callingActivity,"Getting Co-ordinates","Please Wait....");
}
#Override
protected Void doInBackground(Void... voids)
{
locationManager = (LocationManager) callingActivity.getSystemService(Context.LOCATION_SERVICE);
Location location = locationManager.getLastKnownLocation(provider);
showLocation(location);
return null;
}
private void showLocation(Location location)
{
if(location == null)
{
Log.d("Location","Failed to get location");
}
else
{
Log.d("Location","Latitude :- "+location.getLatitude()+" Longitude :- "+location.getLongitude());
}
}
#Override
protected void onPostExecute(Void aVoid)
{
dialog.dismiss();
super.onPostExecute(aVoid);
}
#Override
public void onLocationChanged(Location location)
{
showLocation(location);
}
#Override
public void onStatusChanged(String s, int i, Bundle bundle) {
}
#Override
public void onProviderEnabled(String s) {
}
#Override
public void onProviderDisabled(String s) {
}
}
UPDATE :-
As mentioned by Ivan I have modified my AsyncTask to get location as below :-
#Override
protected Void doInBackground(Void... voids) {
locationManager = (LocationManager) callingActivity.getSystemService(Context.LOCATION_SERVICE);
locationManager.requestLocationUpdates(provider,0,0,this);
if(locationManager != null) {
Location location = locationManager.getLastKnownLocation(provider);
showLocation(location);
}
return null;
}
But this throws "windows leaked" exception in the dialog= ProgressDialog.show(callingActivity,"Getting Co-ordinates","Please Wait...."); inside onPrexecute() method.
Seems to me that you might be missing the requestLocationUpdates(...) call.
Please check this related question for a better understanding on what might be missing, as it sure doesn't look to be a problem with it being inside an AsyncTask, although I don't really see the need for the AsyncTask in your snippet.
Have you tried using String locationProvider = LocationManager.NETWORK_PROVIDER;
to determine if it's the provider that's the issue?
Ivan has mentioned that you won't get updates, but as I understand you're still just looking for the last known location.
Related
please help me with this, I´m working with android studio – java. I have an Activity(MainActivity) where I want to show the information about location; but I want this information come from other class(Location) toward this MainActivity, how can I make this location class send the location data automatically.
Well, I had try to call the method in MainActivity where I get the location data from class-location, but this methods has parameters “Location location”, so I can’t call it directly.
And I had try put a method inside the “location method” to send the information, but It doesn’t work
I declare the location variables global and put It in other method to send them but doesn’t’ work
I´m trying using the location information (latitude and longitude) from a class using extra, but how can get the data.
Anyway… please help me, the Idea is pass the location information: “getLatitude()”and “getLongitude()” for a class to my MainActivity automatically and to a DDBB later.
So much thank for any help
this is "the MainActivity" class
public class MainActivity extends AppCompatActivity {
TextView tvlatitud, tvlongitud;
Location location;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tvlongitud = findViewById(R.id.tv_longitud);
tvlatitud = findViewById(R.id.tv_latitud);
location = new Location(this);
askLocation();
}
public void askLocation(){
location.updateGPS();
}
public void showData(String lat, String lon ){
tvlatitud.setText(lat);
tvlongitud.setText(lon);
}
and this is the Location class
public class Location extends AppCompatActivity {
private static final int PERMISSIONS_FINE_LOCATION = 99;
FusedLocationProviderClient fusedLocationProviderClient;
LocationRequest locationRequest;
String latitude1, longitude1;
private MainActivity mainActivity;
public Location(MainActivity mainActivity){
this.mainActivity = mainActivity;
}
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
locationRequest = new LocationRequest();
locationRequest.setInterval(1000 * 30);
locationRequest.setFastestInterval(1000 * 50);
locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
updateGPS();
}
public void updateGPS() {
fusedLocationProviderClient = LocationServices.getFusedLocationProviderClient(Location.this);
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
fusedLocationProviderClient.getLastLocation().addOnSuccessListener(this, new OnSuccessListener<android.location.Location>() {
#Override
public void onSuccess(android.location.Location location) {
updateUIValues(location);
mainActivity.showData(latitude1, longitude1);
}
});
} else {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
requestPermissions(new String[]{Manifest.permission.ACCESS_FINE_LOCATION,}, PERMISSIONS_FINE_LOCATION);
}
}
}
private void updateUIValues(android.location.Location location) {
latitude1 = String.valueOf(location.getLatitude());
longitude1 = String.valueOf(location.getLongitude());
}
}
I am developing an taxi application in android. I need to store retrieve and update location of my cabs and show it on maps using geofire. I have used firebase for authentication.
Need a complete tutorial for android geofire but can't find any
I have also seen SFVehicle example but didn't understand much
Any help would be appreciated!!!
first of all currently there are no complete tutorials on geofire so all you have in your disposal is the official documentation of Geofire go for java and js.And here is a small but maybe helpful stuff--
https://firebase.googleblog.com/2013/09/geofire-location-queries-for-fun-and.html,
https://medium.com/google-cloud/firebase-is-cool-geofire-is-just-awesome-b7f2be5e0f0f#.x78gjws28,
I hope that these could be of some help to you.
I have created a library for Android, which provides geo-based firestore data to find the list of data within a given radius in KM / MILES.
It also gives the faster response in a single query read with the classification of the ADDED and REMOVED data in and from the query with real-time updates.
You can refer Geo-Firestore
It has well-documentation so you can easily develop the same.
here are a few more links
https://firebase.googleblog.com/2014/08/geofire-goes-mobile.html
https://firebase.googleblog.com/2014/06/geofire-20.html
How to save GeoFire coordinates along with other items in Firebase database?
Here is an example code for having a current location of driver
public class MainActivity extends AppCompatActivity implements
OnMapReadyCallback, PermissionsListener {
// Variables needed to initialize a map
private MapboxMap mapboxMap;
private MapView mapView;
// Variables needed to handle location permissions
private PermissionsManager permissionsManager;
// Variables needed to add the location engine
private LocationEngine locationEngine;
private long DEFAULT_INTERVAL_IN_MILLISECONDS = 1000L;
private long DEFAULT_MAX_WAIT_TIME = DEFAULT_INTERVAL_IN_MILLISECONDS *1;
// Variables needed to listen to location updates
private MainActivityLocationCallback callback = new MainActivityLocationCallback(this);
#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, "");
// 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.TRAFFIC_NIGHT,
new Style.OnStyleLoaded() {
#Override
public void onStyleLoaded(#NonNull Style style) {
enableLocationComponent(style);
}
});
}
/**
* Initialize the Maps SDK's LocationComponent
*/
#SuppressWarnings( {"MissingPermission"})
private void enableLocationComponent(#NonNull Style loadedMapStyle) {
// Check if permissions are enabled and if not request
if (PermissionsManager.areLocationPermissionsGranted(this)) {
// Get an instance of the component
LocationComponent locationComponent = mapboxMap.getLocationComponent();
// Set the LocationComponent activation options
LocationComponentActivationOptions locationComponentActivationOptions =
LocationComponentActivationOptions.builder(this, loadedMapStyle)
.useDefaultLocationEngine(false)
.build();
// Activate with the LocationComponentActivationOptions object
locationComponent.activateLocationComponent(locationComponentActivationOptions);
// Enable to make component visible
locationComponent.setLocationComponentEnabled(true);
// Set the component's camera mode
locationComponent.setCameraMode(CameraMode.TRACKING);
// Set the component's render mode
locationComponent.setRenderMode(RenderMode.COMPASS);
initLocationEngine();
} else {
permissionsManager = new PermissionsManager(this);
permissionsManager.requestLocationPermissions(this);
}
}
/**
* Set up the LocationEngine and the parameters for querying the device's location
*/
#SuppressLint("MissingPermission")
private void initLocationEngine() {
locationEngine = LocationEngineProvider.getBestLocationEngine(this);
LocationEngineRequest request = new LocationEngineRequest.Builder(DEFAULT_INTERVAL_IN_MILLISECONDS)
.setPriority(LocationEngineRequest.PRIORITY_HIGH_ACCURACY)
.setMaxWaitTime(DEFAULT_MAX_WAIT_TIME).build();
locationEngine.requestLocationUpdates(request, callback, getMainLooper());
locationEngine.getLastLocation(callback);
}
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
permissionsManager.onRequestPermissionsResult(requestCode, permissions, grantResults);
}
#Override
public void onExplanationNeeded(List<String> permissionsToExplain) {
Toast.makeText(this, "Enable Location", Toast.LENGTH_LONG).show();
}
#Override
public void onPermissionResult(boolean granted) {
if (granted) {
if (mapboxMap.getStyle() != null) {
enableLocationComponent(mapboxMap.getStyle());
}
} else {
Toast.makeText(this, "Permission Not Granted", Toast.LENGTH_LONG).show();
finish();
}
}
private static class MainActivityLocationCallback
implements LocationEngineCallback<LocationEngineResult> {
private final WeakReference<MainActivity> activityWeakReference;
MainActivityLocationCallback(MainActivity activity) {
this.activityWeakReference = new WeakReference<>(activity);
}
/**
* The LocationEngineCallback interface's method which fires when the device's location has changed.
*
* #param result the LocationEngineResult object which has the last known location within it.
*/
#Override
public void onSuccess(LocationEngineResult result) {
MainActivity activity = activityWeakReference.get();
if (activity != null) {
Location location = result.getLastLocation();
if (location == null) {
return;
}
FirebaseDatabase database = FirebaseDatabase.getInstance();
String somi_id2 = "emp_samad";
DatabaseReference myRef3 = database.getReference("current");
GeoFire geoFire = new GeoFire(myRef3);
geoFire.setLocation(somi_id2,new GeoLocation(location.getLatitude(),location.getLongitude()));
Toast.makeText(activity,String.valueOf(location.getLatitude()+"\n"+String.valueOf(location.getLongitude())),Toast.LENGTH_SHORT).show();
// Pass the new location to the Maps SDK's LocationComponent
if (activity.mapboxMap != null && result.getLastLocation() != null) {
activity.mapboxMap.getLocationComponent().forceLocationUpdate(result.getLastLocation());
}
}
}
/**
* The LocationEngineCallback interface's method which fires when the device's location can not be captured
*
* #param exception the exception message
*/
#Override
public void onFailure(#NonNull Exception exception) {
Log.d("LocationChangeActivity", exception.getLocalizedMessage());
MainActivity activity = activityWeakReference.get();
if (activity != null) {
Toast.makeText(activity, exception.getLocalizedMessage(),
Toast.LENGTH_SHORT).show();
}
}
}
#Override
protected void onStart() {
super.onStart();
mapView.onStart();
}
#Override
protected void onResume() {
super.onResume();
mapView.onResume();
}
#Override
protected void onPause() {
super.onPause();
mapView.onPause();
}
#Override
protected void onStop() {
super.onStop();
mapView.onStop();
}
#Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
mapView.onSaveInstanceState(outState);
}
#Override
protected void onDestroy() {
super.onDestroy();
// Prevent leaks
if (locationEngine != null) {
locationEngine.removeLocationUpdates(callback);
}
mapView.onDestroy();
}
#Override
public void onLowMemory() {
super.onLowMemory();
mapView.onLowMemory();
}
}
Now here is the code for showing him on map for realtime
public class MainActivity extends AppCompatActivity
implements
OnMapReadyCallback, PermissionsListener{
private MapView mapView;
private PermissionsManager permissionsManager;
private MapboxMap mapboxMap;
private GeoJsonSource geoJsonSource;
private ValueAnimator animator;
public static double pre_lat,pre_long;
public static Marker marker;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Mapbox.getInstance(this, "*YOUR_KEY*");
setContentView(R.layout.activity_main);
Mapbox.getInstance(this, "");
mapView = findViewById(R.id.mapView);
//fetchData process = new fetchData();
// process.execute();
mapView.onCreate(savedInstanceState);
mapView.getMapAsync(new OnMapReadyCallback() {
#Override
public void onMapReady(#NonNull final MapboxMap mapboxMap) {
MainActivity.this.mapboxMap = mapboxMap;
mapboxMap.setCameraPosition(new CameraPosition.Builder()
.zoom(19)
.target(new
LatLng(24.987029999999997,67.056585))
.build());
mapboxMap.setStyle(Style.DARK,
new Style.OnStyleLoaded() {
#Override
public void onStyleLoaded(#NonNull Style style) {
// enableLocationComponent(style);
// Create an Icon object for the marker to use
FirebaseDatabase database = FirebaseDatabase.getInstance();
String somi_id2 = "emp_samad";
DatabaseReference myRef3 = database.getReference("current");
GeoFire geoFire = new GeoFire(myRef3);
GeoQuery geoQuery = geoFire.queryAtLocation(new GeoLocation(24.987043333333336, 67.05663333333334), 10);
geoFire.getLocation("emp_samad", new LocationCallback() {
#Override
public void onLocationResult(String key, GeoLocation location) {
if (location != null) {
pre_lat = location.latitude;
pre_long = location.longitude;
// Location prevLoc = new Location(location.latitude,location.longitude);
// Location newLoc = ;
// float bearing = prevLoc.bearingTo(newLoc) ;
marker = mapboxMap.addMarker(new MarkerOptions()
.position(new LatLng(pre_lat,pre_long))
.icon(IconFactory.getInstance(MainActivity.this).fromResource(R.drawable.marker)));
System.out.println(String.format("The location for key %s is [%f,%f]", key, location.latitude, location.longitude));
} else {
System.out.println(String.format("There is no location for key %s in GeoFire", key));
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
geoQuery.addGeoQueryDataEventListener(new GeoQueryDataEventListener() {
#Override
public void onDataEntered(DataSnapshot dataSnapshot, GeoLocation location) {
System.out.println(String.format("The location is [%f,%f]", location.latitude, location.longitude));
}
#Override
public void onDataExited(DataSnapshot dataSnapshot) {
}
#Override
public void onDataMoved(DataSnapshot dataSnapshot, GeoLocation location) {
}
#Override
public void onDataChanged(DataSnapshot dataSnapshot, GeoLocation location) {
double lat = pre_lat;
double lon = pre_long;
LatLng pre_latlng = new LatLng(lat,lon);
LatLng washington = new LatLng(location.latitude,location.longitude);
ValueAnimator markerAnimator = ValueAnimator.ofObject(new TypeEvaluator<LatLng>() {
#Override
public LatLng evaluate(float fraction, LatLng startValue, LatLng endValue) {
return new LatLng(startValue.getLatitude() + (endValue.getLatitude() - startValue.getLatitude()) * fraction, startValue.getLongitude() + (endValue.getLongitude() - startValue.getLongitude()) * fraction);
}
}, new LatLng[]{pre_latlng, washington});
markerAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
#Override
public void onAnimationUpdate(ValueAnimator animation) {
if (marker != null) {
marker.setPosition((LatLng) animation.getAnimatedValue());
}
}
});
markerAnimator.setDuration(7500);
//markerAnimator.setRepeatCount(ValueAnimator.INFINITE);
//markerAnimator.setRepeatMode(ValueAnimator.REVERSE);
markerAnimator.setInterpolator(new AccelerateDecelerateInterpolator());
markerAnimator.start();
/* if(marker!=null)
{
//marker.remove();
//marker.setPosition(new LatLng(location.latitude,location.longitude));
}
System.out.println(String.format("The location is [%f,%f]", location.latitude, location.longitude));
*/
}
#Override
public void onGeoQueryReady() {
}
#Override
public void onGeoQueryError(DatabaseError error) {
}
});
}
});
}
});
}
#SuppressWarnings( {"MissingPermission"})
private void enableLocationComponent(#NonNull Style loadedMapStyle) {
// Check if permissions are enabled and if not request
if (PermissionsManager.areLocationPermissionsGranted(this)) {
// Get an instance of the component
LocationComponent locationComponent = mapboxMap.getLocationComponent();
// Activate with options
locationComponent.activateLocationComponent(
LocationComponentActivationOptions.builder(this, loadedMapStyle).build());
// Enable to make component visible
locationComponent.setLocationComponentEnabled(true);
// Set the component's camera mode
locationComponent.setCameraMode(CameraMode.TRACKING);
// Set the component's render mode
locationComponent.setRenderMode(RenderMode.COMPASS);
} else {
permissionsManager = new PermissionsManager(this);
permissionsManager.requestLocationPermissions(this);
}
}
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
permissionsManager.onRequestPermissionsResult(requestCode, permissions, grantResults);
}
#Override
public void onExplanationNeeded(List<String> permissionsToExplain) {
Toast.makeText(this, "Enable Location", Toast.LENGTH_LONG).show();
}
#Override
public void onPermissionResult(boolean granted) {
if (granted) {
mapboxMap.getStyle(new Style.OnStyleLoaded() {
#Override
public void onStyleLoaded(#NonNull Style style) {
// enableLocationComponent(style);
}
});
} else {
Toast.makeText(this, "Permission Not Granted", Toast.LENGTH_LONG).show();
// finish();
}
}
#Override
#SuppressWarnings( {"MissingPermission"})
public void onStart() {
super.onStart();
mapView.onStart();
}
#Override
public void onResume() {
super.onResume();
mapView.onResume();
}
#Override
public void onPause() {
super.onPause();
mapView.onPause();
}
#Override
public void onStop() {
super.onStop();
mapView.onStop();
}
#Override
public void onLowMemory() {
super.onLowMemory();
mapView.onLowMemory();
}
#Override
public void onDestroy() {
super.onDestroy();
mapView.onDestroy();
}
#Override
public void onMapReady(#NonNull MapboxMap mapboxMap)
{
}
}
what you have to use for this is to implement a geofire library
Geofire implementation
implementation 'com.firebase:geofire-android:3.0.0'
I hope that this will help you alot
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 develop an Android app.
I want to stock the gps location and draw a line on the map with these datas, like "draw my course".
What's the best way ?
I designed my map with TileMill.
Where can I stock my data and use it with mapbox?
This is my code :
public class GPSActivity extends Activity{
private LocationManager manager = null;
private MyLocationListener listener;
private TextView textView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textView = (TextView) findViewById(R.id.location);
listener = new MyLocationListener(textView);
manager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
listener = new MyLocationListener(textView);
manager.requestLocationUpdates(LocationManager
.GPS_PROVIDER, 5000, 10,listener);
}
public class MyLocationListener implements LocationListener
{
TextView textView;
public MyLocationListener(TextView textView)
{
this.textView = textView;
}
#Override
public void onLocationChanged(Location location) {
this.textView.setText(location.toString());
}
#Override
public void onStatusChanged(String s, int i, Bundle bundle) {
}
#Override
public void onProviderEnabled(String s) {
}
#Override
public void onProviderDisabled(String s) {
}
}
--> With this code, I have the location. I would like to stock longitude and latitude and use these with mapbox. What's the best way to stock these datas?
I start to design my map on map box : https://a.tiles.mapbox.com/v3/malicia.hh3dgalc/page.html?secure=1#13/48.1169/-1.6803
It will be an interactive map, I want to draw an itinerary with the datas stocked.
Can someone help me?
I have spent many hours looking for a solution to this and need help.
I have a nested AsyncTask in my Android app Activity and I would like to allow the user to rotate his phone during it's processing without starting a new AsyncTask. I tried to use onRetainNonConfigurationInstance() and getLastNonConfigurationInstance().
I am able to retain the task; however after rotation it does not save the result from onPostExecute() to the outer class variable. Of course, I tried getters and setters. When I dump the variable in onPostExecute, that it is OK. But when I try to access to the variable from onClick listener then it is null.
Maybe the code will make the problem clear for you.
public class MainActivity extends BaseActivity {
private String possibleResults = null;
private Object task = null;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.task = getLastNonConfigurationInstance();
setContentView(R.layout.menu);
if ((savedInstanceState != null)
&& (savedInstanceState.containsKey("possibleResults"))) {
this.possibleResults = savedInstanceState
.getString("possibleResults");
}
if (this.possibleResults == null) {
if (this.task != null) {
if (this.task instanceof PossibleResultWebService) {
((PossibleResultWebService) this.task).attach();
}
} else {
this.task = new PossibleResultWebService();
((PossibleResultWebService) this.task).execute(this.matchToken);
}
}
Button button;
button = (Button) findViewById(R.id.menu_resultButton);
button.setOnClickListener(resultListener);
}
#Override
protected void onResume() {
super.onResume();
}
OnClickListener resultListener = new OnClickListener() {
#Override
public void onClick(View v) {
Spinner s = (Spinner) findViewById(R.id.menu_heatSpinner);
int heatNo = s.getSelectedItemPosition() + 1;
Intent myIntent = new Intent(MainActivity.this,
ResultActivity.class);
myIntent.putExtra("matchToken", MainActivity.this.matchToken);
myIntent.putExtra("heatNo", String.valueOf(heatNo));
myIntent.putExtra("possibleResults",
MainActivity.this.possibleResults);
MainActivity.this.startActivityForResult(myIntent, ADD_RESULT);
}
};
private class PossibleResultWebService extends AsyncTask<String, Integer, Integer> {
private ProgressDialog pd;
private InputStream is;
private boolean finished = false;
private String possibleResults = null;
public boolean isFinished() {
return finished;
}
public String getPossibleResults() {
return possibleResults;
}
#Override
protected Integer doInBackground(String... params) {
// quite long code
}
public void attach() {
if (this.finished == false) {
pd = ProgressDialog.show(MainActivity.this, "Please wait...",
"Loading data...", true, false);
}
}
public void detach() {
pd.dismiss();
}
#Override
protected void onPreExecute() {
pd = ProgressDialog.show(MainActivity.this, "Please wait...",
"Loading data...", true, false);
}
#Override
protected void onPostExecute(Integer result) {
possibleResults = convertStreamToString(is);
MainActivity.this.possibleResults = possibleResults;
pd.dismiss();
this.finished = true;
}
}
#Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
if (this.possibleResults != null) {
outState.putString("possibleResults", this.possibleResults);
}
}
#Override
public Object onRetainNonConfigurationInstance() {
if (this.task instanceof PossibleResultWebService) {
((PossibleResultWebService) this.task).detach();
}
return (this.task);
}
}
It is because you are creating the OnClickListener each time you instantiate the Activity (so each time you are getting a fresh, new, OuterClass.this reference), however you are saving the AsyncTask between Activity instantiations and keeping a reference to the first instantiated Activity in it by referencing OuterClass.this.
For an example of how to do this right, please see https://github.com/commonsguy/cw-android/tree/master/Rotation/RotationAsync/
You will see he has an attach() and detach() method in his RotationAwareTask to solve this problem.
To confirm that the OuterClass.this reference inside the AsyncTask will always point to the first instantiated Activity if you keep it between screen orientation changes (using onRetainNonConfigurationInstance) then you can use a static counter that gets incremented each time by the default constructor and keep an instance level variable that gets set to the count on each creation, then print that.