I'm trying to build an app that will show me my location in googleMap and will update my location every few seconds.
here is my code:
public class MapsActivity extends FragmentActivity implements
ConnectionCallbacks, OnConnectionFailedListener, LocationListener, OnMapReadyCallback {
protected static final String TAG = "location-updates-sample";
/**
* The desired interval for location updates. Inexact. Updates may be more or less frequent.
*/
public static final long UPDATE_INTERVAL_IN_MILLISECONDS = 10000;
/**
* The fastest rate for active location updates. Exact. Updates will never be more frequent
* than this value.
*/
public static final long FASTEST_UPDATE_INTERVAL_IN_MILLISECONDS =
UPDATE_INTERVAL_IN_MILLISECONDS / 2;
// Keys for storing activity state in the Bundle.
protected final static String REQUESTING_LOCATION_UPDATES_KEY = "requesting-location-updates-key";
protected final static String LOCATION_KEY = "location-key";
protected GoogleApiClient mGoogleApiClient;
protected LocationRequest mLocationRequest;
protected Location mCurrentLocation;
/**
* Tracks the status of the location updates request. Value changes when the user presses the
* Start Updates and Stop Updates buttons.
*/
protected Boolean mRequestingLocationUpdates;
private GoogleMap mMap;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_maps);
SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map);
mapFragment.getMapAsync(this);
mRequestingLocationUpdates = false;
updateValuesFromBundle(savedInstanceState);
buildGoogleApiClient();
}
#Override
public void onMapReady(GoogleMap googleMap) {
mMap = googleMap;
LatLng loc = new LatLng(-34,151);
mMap.addMarker(new MarkerOptions().position(loc).title("my location"));
mMap.moveCamera(CameraUpdateFactory.newLatLng(loc));
startUpdates();
}
private void updateValuesFromBundle(Bundle savedInstanceState) {
Log.i(TAG, "Updating values from bundle");
if (savedInstanceState != null) {
if (savedInstanceState.keySet().contains(REQUESTING_LOCATION_UPDATES_KEY)) {
mRequestingLocationUpdates = savedInstanceState.getBoolean(
REQUESTING_LOCATION_UPDATES_KEY);
}
// Update the value of mCurrentLocation from the Bundle and update the UI to show the
// correct latitude and longitude.
if (savedInstanceState.keySet().contains(LOCATION_KEY)) {
// Since LOCATION_KEY was found in the Bundle, we can be sure that mCurrentLocation
// is not null.
mCurrentLocation = savedInstanceState.getParcelable(LOCATION_KEY);
}
updateUI();
}
}
protected synchronized void buildGoogleApiClient() {
Log.i(TAG, "Building GoogleApiClient");
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API)
.build();
createLocationRequest();
}
protected void createLocationRequest() {
mLocationRequest = new LocationRequest();
mLocationRequest.setInterval(UPDATE_INTERVAL_IN_MILLISECONDS);
mLocationRequest.setFastestInterval(FASTEST_UPDATE_INTERVAL_IN_MILLISECONDS);
mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
}
public void startUpdates() { // start updating location
if (!mRequestingLocationUpdates) {
mRequestingLocationUpdates = true;
LocationServices.FusedLocationApi.requestLocationUpdates(
mGoogleApiClient, mLocationRequest, this);
}
}
public void stopUpdates() { // stop updating location
if (mRequestingLocationUpdates) {
mRequestingLocationUpdates = false;
LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, this);
}
}
/**
* Updates the latitude, the longitude, and the last location time in the UI.
*/
private void updateUI() {
LatLng loc = new LatLng(mCurrentLocation.getLatitude(), mCurrentLocation.getLongitude());
mMap.addMarker(new MarkerOptions().position(loc).title("my location"));
mMap.moveCamera(CameraUpdateFactory.newLatLng(loc));
}
#Override
protected void onStart() {
super.onStart();
mGoogleApiClient.connect();
}
#Override
public void onResume() {
super.onResume();
if (mGoogleApiClient.isConnected() && mRequestingLocationUpdates) {
LocationServices.FusedLocationApi.requestLocationUpdates(
mGoogleApiClient, mLocationRequest, this);
}
}
#Override
protected void onPause() {
super.onPause();
// Stop location updates to save battery, but don't disconnect the GoogleApiClient object.
if (mGoogleApiClient.isConnected()) {
LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, this);
}
}
#Override
protected void onStop() {
mGoogleApiClient.disconnect();
super.onStop();
}
/**
* Runs when a GoogleApiClient object successfully connects.
*/
#Override
public void onConnected(Bundle connectionHint) {
Log.i(TAG, "Connected to GoogleApiClient");
if (mCurrentLocation == null) {
mCurrentLocation = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
updateUI();
}
if (mRequestingLocationUpdates) {
LocationServices.FusedLocationApi.requestLocationUpdates(
mGoogleApiClient, mLocationRequest, this);
}
}
#Override
public void onLocationChanged(Location location) {
mCurrentLocation = location;
updateUI();
Toast.makeText(this, getResources().getString(R.string.location_updated_message),
Toast.LENGTH_SHORT).show();
}
#Override
public void onConnectionSuspended(int cause) {
// The connection to Google Play services was lost for some reason. We call connect() to
// attempt to re-establish the connection.
Log.i(TAG, "Connection suspended");
mGoogleApiClient.connect();
}
#Override
public void onConnectionFailed(ConnectionResult result) {
// Refer to the javadoc for ConnectionResult to see what error codes might be returned in
// onConnectionFailed.
Log.i(TAG, "Connection failed: ConnectionResult.getErrorCode() = " + result.getErrorCode());
}
/**
* Stores activity data in the Bundle.
*/
public void onSaveInstanceState(Bundle savedInstanceState) {
savedInstanceState.putBoolean(REQUESTING_LOCATION_UPDATES_KEY, mRequestingLocationUpdates);
savedInstanceState.putParcelable(LOCATION_KEY, mCurrentLocation);
super.onSaveInstanceState(savedInstanceState);
}
}
This code is a part from a sample code from google but i've changed a few things and added the googleMap, its just crashing after onMapReady().
stacktrace:
java.lang.IllegalStateException: GoogleApiClient is not connected yet.
at com.google.android.gms.common.api.internal.zzh.zzb(Unknown Source)
at com.google.android.gms.common.api.internal.zzl.zzb(Unknown Source)
at com.google.android.gms.common.api.internal.zzj.zzb(Unknown Source)
at com.google.android.gms.location.internal.zzd.requestLocationUpdates(Unknown Source)
at com.idanofek.photomap.MapsActivity.startUpdates(MapsActivity.java:135)
at com.idanofek.photomap.MapsActivity.onMapReady(MapsActivity.java:91)
at com.google.android.gms.maps.SupportMapFragment$zza$1.zza(Unknown Source)
at com.google.android.gms.maps.internal.zzo$zza.onTransact(Unknown Source)
at android.os.Binder.transact(Binder.java:387)
at com.google.android.gms.maps.internal.be.a(SourceFile:82)
at com.google.maps.api.android.lib6.e.fb.run(Unknown Source)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5417)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
Before any operation is executed, the GoogleApiClient must be connect using the 'connect()' method. The client is not considered connected until the onConnected(Bundle) callback has been called.
You should instantiate a client object in your Activity's 'onCreated(Bundle)' method then call connect() on onStart()
You may call startLocationUpdate() from the onConnected() callback
#Override
public void onConnected(Bundle connectionHint) {
...
if (mRequestingLocationUpdates) {
startLocationUpdates();
}
}
protected void startLocationUpdates() {
LocationServices.FusedLocationApi.requestLocationUpdates(
mGoogleApiClient, mLocationRequest, this);
}
Here's a Google Documentation regarding Location Updates: http://developer.android.com/training/location/receive-location-updates.html
Related
I am currently making an application where I need to get the user's location when a button is clicked. I am using this sample and it works great as a sample application. My question is, how would I implement it into my application button's onClick event? I don't need it to refresh often, I just need it so that when the user clicks the button, it gets the user's latitude and longitude and saves them to two variables. What would be the best way to do this? I didn't post my own code because all I have is a button with an onClick event.
Follow these steps to get the location on button click:
Implement LocationListener in your activity like:
public class MainActivity Extends AppCompactActivity implements LocationListener
Then create an Instance For LocationManager, longitude, and latitude as below:
LocationManager locationManager; // create global outside all methods
Double currentLattitude, currentLongitude;
Set click event on your button as below:
btnLocation.setOnClickListner( new View.onClickListner
{
#Override
public void onClick(View v)
{
locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, this);
}
});
Now implement method for LocationListener as below:
#Override
public void onLocationChanged(Location location) {
currentLattitude = location.getLatitude();
currentLongitude = location.getLongitude());
}
#Override
public void onProviderDisabled(String provider) {
Log.d("Latitude","disable");
}
#Override
public void onProviderEnabled(String provider) {
Log.d("Latitude","enable");
}
#Override
public void onStatusChanged(String provider, int status, Bundle extras) {
Log.d("Latitude","status");
}
With this, you can get your location via on click of your button.
Main thing to don't forget is to set permission (in your Manifest) as below:
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission. ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.INTERNET" />
Use fused location API this is the fastest from all others.
public class LocationActivity extends Activity implements
LocationListener,
GoogleApiClient.ConnectionCallbacks,
GoogleApiClient.OnConnectionFailedListener {
private static final String TAG = "LocationActivity";
private static final long INTERVAL = 1000 * 10;
private static final long FASTEST_INTERVAL = 1000 * 5;
Button btnFusedLocation;
TextView tvLocation;
LocationRequest mLocationRequest;
GoogleApiClient mGoogleApiClient;
Location mCurrentLocation;
String mLastUpdateTime;
protected void createLocationRequest() {
mLocationRequest = new LocationRequest();
mLocationRequest.setInterval(INTERVAL);
mLocationRequest.setFastestInterval(FASTEST_INTERVAL);
mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.d(TAG, "onCreate ...............................");
//show error dialog if GoolglePlayServices not available
if (!isGooglePlayServicesAvailable()) {
finish();
}
createLocationRequest();
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addApi(LocationServices.API)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.build();
setContentView(R.layout.activity_main);
tvLocation = (TextView) findViewById(R.id.tvLocation);
btnFusedLocation = (Button) findViewById(R.id.btnShowLocation);
btnFusedLocation.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View arg0) {
updateUI();
}
});
}
#Override
public void onStart() {
super.onStart();
Log.d(TAG, "onStart fired ..............");
mGoogleApiClient.connect();
}
#Override
public void onStop() {
super.onStop();
Log.d(TAG, "onStop fired ..............");
mGoogleApiClient.disconnect();
Log.d(TAG, "isConnected ...............: " + mGoogleApiClient.isConnected());
}
private boolean isGooglePlayServicesAvailable() {
int status = GooglePlayServicesUtil.isGooglePlayServicesAvailable(this);
if (ConnectionResult.SUCCESS == status) {
return true;
} else {
GooglePlayServicesUtil.getErrorDialog(status, this, 0).show();
return false;
}
}
#Override
public void onConnected(Bundle bundle) {
Log.d(TAG, "onConnected - isConnected ...............: " + mGoogleApiClient.isConnected());
startLocationUpdates();
}
protected void startLocationUpdates() {
PendingResult<Status> pendingResult = LocationServices.FusedLocationApi.requestLocationUpdates(
mGoogleApiClient, mLocationRequest, this);
Log.d(TAG, "Location update started ..............: ");
}
#Override
public void onConnectionSuspended(int i) {
}
#Override
public void onConnectionFailed(ConnectionResult connectionResult) {
Log.d(TAG, "Connection failed: " + connectionResult.toString());
}
#Override
public void onLocationChanged(Location location) {
Log.d(TAG, "Firing onLocationChanged..............................................");
mCurrentLocation = location;
mLastUpdateTime = DateFormat.getTimeInstance().format(new Date());
updateUI();
}
private void updateUI() {
Log.d(TAG, "UI update initiated .............");
if (null != mCurrentLocation) {
String lat = String.valueOf(mCurrentLocation.getLatitude());
String lng = String.valueOf(mCurrentLocation.getLongitude());
tvLocation.setText("At Time: " + mLastUpdateTime + "\n" +
"Latitude: " + lat + "\n" +
"Longitude: " + lng + "\n" +
"Accuracy: " + mCurrentLocation.getAccuracy() + "\n" +
"Provider: " + mCurrentLocation.getProvider());
} else {
Log.d(TAG, "location is null ...............");
}
}
#Override
protected void onPause() {
super.onPause();
stopLocationUpdates();
}
protected void stopLocationUpdates() {
LocationServices.FusedLocationApi.removeLocationUpdates(
mGoogleApiClient, this);
Log.d(TAG, "Location update stopped .......................");
}
#Override
public void onResume() {
super.onResume();
if (mGoogleApiClient.isConnected()) {
startLocationUpdates();
Log.d(TAG, "Location update resumed .....................");
}
}
}
LocationListener provides call back for location change through onLocationChanged.
GoogleApiClient.ConnectionCallbacks provides call back for GoogleApiClient onConnected.
GoogleApiClient.OnConnectionFailedListener provides call back for GoogleApiClient onConnectionFailed.
Source: http://javapapers.com/android/android-location-fused-provider/
http://blog.teamtreehouse.com/beginners-guide-location-android
I was following this tutorial and seem to have made a mistake somewhere. I'm not so sure where I went wrong, all I know is its saying it was caused at the part where i make a map
public class MapsActivity extends FragmentActivity implements OnMapReadyCallback, GoogleApiClient.ConnectionCallbacks,
GoogleApiClient.OnConnectionFailedListener, LocationListener {
private GoogleMap mMap;
private GoogleApiClient mGoogleApiClient;
private final static int CONNECTION_FAILURE_RESOLUTION_REQUEST = 9000;
private LocationRequest mLocationRequest;
public static final String TAG = MapsActivity.class.getSimpleName();
#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);
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API)
.build();
// Create the LocationRequest object
mLocationRequest = LocationRequest.create()
.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY)
.setInterval(10 * 1000) // 10 seconds, in milliseconds
.setFastestInterval(1 * 1000); // 1 second, in milliseconds
}
#Override
protected void onResume() {
super.onResume();
setUpMap();
mGoogleApiClient.connect();
}
#Override
protected void onPause() {
super.onPause();
if (mGoogleApiClient.isConnected()) {
LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, this);
mGoogleApiClient.disconnect();
}
}
/**
* Manipulates the map once available.
* This callback is triggered when the map is ready to be used.
* This is where we can add markers or lines, add listeners or move the camera. In this case,
* we just add a marker near Sydney, Australia.
* If Google Play services is not installed on the device, the user will be prompted to install
* it inside the SupportMapFragment. This method will only be triggered once the user has
* installed Google Play services and returned to the app.
*/
#Override
public void onMapReady(GoogleMap googleMap) {
mMap = googleMap;
// Add a marker in Sydney and move the camera
LatLng sydney = new LatLng(-34, 151);
mMap.addMarker(new MarkerOptions().position(sydney).title("Marker in Sydney"));
mMap.moveCamera(CameraUpdateFactory.newLatLng(sydney));
}
#Override
public void onConnected(Bundle bundle) {
Log.i(TAG, "Location services connected.");
Location location = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
if (location == null) {
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
// TODO: Consider calling
// ActivityCompat#requestPermissions
// here to request the missing permissions, and then overriding
// public void onRequestPermissionsResult(int requestCode, String[] permissions,
// int[] grantResults)
// to handle the case where the user grants the permission. See the documentation
// for ActivityCompat#requestPermissions for more details.
return;
}
LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this);
}
else {
handleNewLocation(location);
}
}
#Override
public void onConnectionSuspended(int i) {
Log.i(TAG, "Location services suspended. Please reconnect.");
}
#Override
public void onConnectionFailed(ConnectionResult connectionResult) {
if (connectionResult.hasResolution()) {
try {
// Start an Activity that tries to resolve the error
connectionResult.startResolutionForResult(this, CONNECTION_FAILURE_RESOLUTION_REQUEST);
} catch (IntentSender.SendIntentException e) {
e.printStackTrace();
}
} else {
Log.i(TAG, "Location services connection failed with code " + connectionResult.getErrorCode());
}
}
private void handleNewLocation(Location location) {
Log.d(TAG, location.toString());
double currentLatitude = location.getLatitude();
double currentLongitude = location.getLongitude();
LatLng latLng = new LatLng(currentLatitude, currentLongitude);
MarkerOptions options = new MarkerOptions()
.position(latLng)
.title("I am here!");
mMap.addMarker(options);
mMap.moveCamera(CameraUpdateFactory.newLatLng(latLng));
}
#Override
public void onLocationChanged(Location location) {
handleNewLocation(location);
}
private void setUpMap() {
mMap.addMarker(new MarkerOptions().position(new LatLng(0, 0)).title("Marker"));
}
}
according the the console it says it was caused at the setUpMap(); line in the onResume() method and the setUpMap method. what happens when I try to run the app is an error that causes it to close instantly. also i realize i changed it from setUpMapIfNeeded to SetUpMap because in the tutorial I didnt find any setUpMapIfNeeded() method.
you can either avoid calling setUpMap(); from onResume or check in mMap is not null
private void setUpMap() {
if (mMap != null) {
mMap.addMarker(new MarkerOptions().position(new LatLng(0, 0)).title("Marker"));
}
}
as the name suggests, getMapAsync calls onMapReady in an asynchronous way, and you don't have any assurance that onMapReady was already called before onResume get called
I am making an android app about locating friends on map. So far I have the map up and running, and the fused location also running but from a different class which extends thread so the app will keep listening to location changed throughout its life cycle.
I have a problem when I initialize the map, the problem is either the locationListener will keep working but the map won't load, or the map will load but the locationListener will take a long time to get a new location.
I also have a problem when sending the current location from the Thread activity to the map activity so i animate the camera to a new loaction.
Here is the error i get :
12-22 23:22:38.847 17339-17339/com.example.swampsoftware.blbmonitor
W/dalvikvm: threadid=1: thread exiting with uncaught exception
(group=0x41ee6300) 12-22 23:22:38.852
17339-17339/com.example.swampsoftware.blbmonitor E/AndroidRuntime:
FATAL EXCEPTION: main
java.lang.NullPointerException
at
com.example.swampsoftware.blbmonitor.Maps.gotoLocation(Maps.java:232)
at
com.example.swampsoftware.blbmonitor.GetLocation.onLocationChanged(GetLocation.java:81)
at
com.google.android.gms.location.internal.zzk$zzb.handleMessage(Unknown
Source)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:4898)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at
com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1006)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:773)
at dalvik.system.NativeStart.main(Native Method)
So the problem happens once the method "onLocationChanged" is called.
I believe that this is a thread caused problem, but I don't understand what is the problem nor how to fix it, here is the code i made :
Maps.class :
public class Maps extends FragmentActivity implements OnMapReadyCallback{
private GoogleMap mMap;
private Double locationLat;
private Double locationLng;
private Context context;
private static boolean isVisible;
// Defining parse object
ParseObject locationObject;
//Declaring Tabhost
TabHost tabHost;
public Maps() {
}
public Maps(Context context) {
this.context = context;
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
isVisible = true;
setContentView(R.layout.activity_gpslocation);
// Initialize google map
initMap();
}
// Obtain the SupportMapFragment and get notified when the map is ready to be used.
// Initialize GoogleMap -> mMap
public void initMap() {
if (mMap == null) {
SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
.findFragmentById(R.id.map);
mapFragment.getMapAsync(this);
} else {
Toast.makeText(getApplicationContext(), "Can't start map", Toast.LENGTH_SHORT).show();
}
}
#Override
public void onMapReady(GoogleMap googleMap) {
mMap = googleMap;
}
// Method that saves current location
private void setCurrentLocation(Double lat, Double lng) {
locationLat = lat;
locationLng = lng;
}
// Get method for lng
public Double getLocationLat() {
return locationLat;
}
public Double getLocationLng() {
return locationLng;
}
// Method that animates the camera to a new location
public void gotoLocation(Location location) {
LatLng ll = new LatLng(location.getLatitude(), location.getLongitude());
CameraUpdate update = CameraUpdateFactory.newLatLngZoom(ll, 15);
mMap.animateCamera(update);
}
#Override
protected void onResume() {
super.onResume();
initMap();
isVisible = true;
}
#Override
protected void onPause() {
super.onPause();
isVisible = false;
}
protected void onDestroy() {
super.onDestroy();
isVisible = false;
}
public boolean getIsVisible() {
return isVisible;
}
// Method that is called when map is connected, initializes the locationRequest.
public void onConnected(Bundle bundle) {
}
And this is the Thread class that will keep listening to the new location using fused location :
GetLocation :
public class GetLocation extends Thread implements LocationListener, GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener {
private GoogleApiClient googleApiClient; // Object that is used to connect to google maps API, must be built to use fused location
private LocationRequest locationRequest; //Object that requests a quality of service for location updates from fused location
public Context context;
public volatile boolean isRunning = true; // boolean to stop the thread loop
// Declaring location variables
private Double locationLat;
private Double locationLng;
// Declaring objects
private ParseData parseData;
private Maps maps = new Maps();
/***
* run method for thread
***/
public void run() {
//Initializing objects
parseData = new ParseData();
googleApiClient = new GoogleApiClient.Builder(context)
.addApi(LocationServices.API)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.build();
googleApiClient.connect();
}
public void terminate() {
isRunning = false;
}
// Getters
public Double getLocationLat() {
return locationLat;
}
public Double getLocationLng() {
return locationLng;
}
/***
* Auto-generated methods
***/
#Override
public void onLocationChanged(Location location) {
if (!isRunning) {
googleApiClient.disconnect();
return;
} else if (location != null) {
locationLat = location.getLatitude();
locationLng = location.getLongitude();
parseData.GetLocationParse(locationLat, locationLng);
System.out.println(locationLat + " " + locationLng);
// Check is map is active
if(maps.getIsVisible()) {
System.out.println("Maps is in foreground");
maps.gotoLocation(location);
} else {
System.out.println("Maps isn't running");
}
}
}
#Override
public void onConnected(Bundle bundle) {
locationRequest = locationRequest.create();
locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
locationRequest.setInterval(7000);
locationRequest.setFastestInterval(5000);
LocationServices.FusedLocationApi.requestLocationUpdates(googleApiClient, locationRequest, this);
}
#Override
public void onConnectionSuspended(int i) {
}
#Override
public void onConnectionFailed(ConnectionResult connectionResult) {
}
}
Thank you.
I ask, how to create a script, for android, to get a current location with google maps api v2 for android.
Now my scrpt take the location specifying the cordinates.
I post it my java file:
private GoogleMap mMap;
static final LatLng TutorialsPoint = new LatLng(46.493168,11.3306379);
private GoogleMap googleMap;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.test);
try {
if (googleMap == null) {
googleMap = ((MapFragment) getFragmentManager().
findFragmentById(R.id.map)).getMap();
}
googleMap.setMapType(GoogleMap.MAP_TYPE_TERRAIN);
Marker TP = googleMap.addMarker(new MarkerOptions().
position(TutorialsPoint).title("TutorialsPoint"));
}
catch (Exception e) {
e.printStackTrace();
}
}
In your onCreate() method, type this:
SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
.findFragmentById(R.id.mapfragment);
mapFragment.getMapAsync(this);
Make your Activity implement LocationListener, onMapReadyCallback and GoogleApiClient.ConnectionCallbacks interfaces. In the methods of that interfaces:
onMapReady (from onMapReadyCallbacks):
public void onMapReady(GoogleMap map) {
//mapa is your GoogleMap variable
mapa=map;
}
Doing this, you make sure your map is ready for working.
In onConnected method (from GoogleApiClient.ConnectionCallbacks interface) you get your location:
#Override
public void onConnected(Bundle bundle) {
Location lkn=LocationServices.FusedLocationApi.getLastLocation(
gApiClient);
if(myLocation==null){
myLocation=new Location("");
}
if(lkn!=null){
myLocation.setLatitude(lkn.getLatitude());
myLocation.setLongitude(lkn.getLongitude());
}
LocationServices.FusedLocationApi.requestLocationUpdates(
gApiClient, mLocationRequest, this);
}
And finally, in onLocationChanged (from LocationListener interface):
#Override
public void onLocationChanged(Location location) {
//myLocation is a class variable, type Location
myLocation.setLatitude(location.getLatitude());
myLocation.setLongitude(location.getLongitude());
}
So, every time the phone have a new location you will receive it in that method.
You will need to implement this two methods too:
//call this method in your onCreate()
protected synchronized void buildGoogleApiClient() {
//gApiClient is a class variable, type GoogleApiClient
gApiClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(new GoogleApiClient.OnConnectionFailedListener() {
#Override
public void onConnectionFailed(ConnectionResult connectionResult) {
Log.i("Map", "Conection failed");
}
})
.addApi(LocationServices.API)
.build();
gApiClient.connect();
createLocationRequest();
}
protected void createLocationRequest() {
mLocationRequest = new LocationRequest();
mLocationRequest.setInterval(10000);
mLocationRequest.setFastestInterval(5000);
mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
}
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();
}