How to pass information to a string outside a method? - java

I'm new to the Java language and have become a little stuck, I'm trying to pass a location to the String Bob. I need to pass a string from onLocationChanged method, to the String url which outside of the method. I have created a global variable, but the String bob does not hold any data.
Any help would be much appreciated.
public class MainActivity extends AppCompatActivity {
String bob = "";
LocationManager locationManager;
LocationListener locationListener;
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, locationListener);}
}
}
TextView tempTextView;
TextView dateTextView;
TextView weatherDescTextView;
TextView cityTextView;
ImageView weatherImageView;
#RequiresApi(api = Build.VERSION_CODES.N)
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tempTextView = (TextView) findViewById(R.id.tempTextView);
dateTextView = (TextView) findViewById(R.id.dateTextView);
weatherDescTextView = (TextView) findViewById(R.id.weatherDescTextView);
cityTextView = (TextView) findViewById(R.id.cityTextView);
weatherImageView = (ImageView) findViewById(R.id.weatherImageView);
dateTextView.setText(getCurrentDate());
// location
locationManager = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE);
locationListener = new LocationListener() {
#Override
public void onLocationChanged(Location location) {
// Log.i("Location", location.toString());
Geocoder geocoder = new Geocoder(getApplicationContext(), Locale.getDefault());
try {
List<Address> listAddresses = geocoder.getFromLocation(location.getLatitude(), location.getLongitude(), 1);
if (listAddresses != null && listAddresses.size() > 0) {
//Log.i("PlaceInfo", listAddresses.get(0).toString());
if (listAddresses.get(0).getLocality() != null)
{
bob += listAddresses.get(0).getLocality() + " ";
}
Log.i("hello", bob.toString());
}
} catch (IOException e) {
e.printStackTrace();
}
}
#Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
#Override
public void onProviderEnabled(String provider ) {
}
#Override
public void onProviderDisabled(String provider) {
}
};
String url = "http://api.openweathermap.org/data/2.5/weather?q=" +bob+ "&units=metric&appid=xxxx";

i'm new to the Java language
My best piece of advice to you right now is to stop, put Android down, and go learn Java (or hell, get started with Kotlin) before trying to learn Android as well as you go. Android is complicated enough as is without trying to learn the language as well.
Anyway, as to your actual problem:
I'm trying to pass a location to the String 'Bob'. I need to pass a string from 'onLocationChanged' method, to the String 'url' which outside of the method... I have created a 'global' variable, but the String 'bob' does not hold any data.
You're problem is that that onLocationChanged method is a callback that actually doesn't get invoked until much later than the point at which you are trying to set the URL variable (assuming you actually register the callback, which your code does not show).
In other words, you are providing a hook in to the system that says, "when you have the location, let me know", meanwhile your code continues. When system lets you know the location is back (your callback is invoked) it's up to you to use the new value do something with it (in your case, I assume, make a network request).
So you would move your logic to right after the line where you update bob.
Hope that helps.

onLocationChanged is evaluated after you compute String url.
Once you have an understanding of multithreading, you will understand this.
At the moment, your code would be no different if you move String url to the very top of onCreate.
If you want the URL to be properly assigned, move it after Log.i("hello", and even check your logs to make sure it's correct
Personally, I don't suggest Android as the platform from which you learn Java

Related

access the inner class variable to another method

Kindly help. I am not a regular java writer, so I can't solve this:
The getLastLocation() in onCreate method is returning 0.0 for Lat and Lang, while the value is correct withing getLastLocation() method itself. Also, in getLastLocation, AndroidStudio says, the argument Lat and Lang is never used.
Kindly help me correct this puzzle.
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Bundle bundle = new Bundle();
bundle.putDouble ("loclat", 25.4358);
bundle.putDouble("loclang", 81.8463);
Fragment SunFragment = new SunFragment();
SunFragment.setArguments(bundle);
setContentView(R.layout.activity_main);
mFusedLocationClient = LocationServices.getFusedLocationProviderClient(this);
getLastLocation(Lat, Long);
//Value is 0 here
Toast.makeText(getApplicationContext(),Double.toString(Lat), Toast.LENGTH_LONG).show();
SectionsPagerAdapter sectionsPagerAdapter = new SectionsPagerAdapter(this,
getSupportFragmentManager(), Lat, Long);
ViewPager viewPager = findViewById(R.id.view_pager);
viewPager.setAdapter(sectionsPagerAdapter);
TabLayout tabs = findViewById(R.id.tabs);
tabs.setupWithViewPager(viewPager);
}
#SuppressLint("MissingPermission")
public void getLastLocation(double Lat, double Long){
if (checkPermissions()) {
if (isLocationEnabled()) {
mFusedLocationClient.getLastLocation().addOnCompleteListener(
new OnCompleteListener<Location>() {
#Override
public void onComplete(#NonNull Task<Location> task) {
Location location = task.getResult();
if (location == null) {
requestNewLocationData();
} else {
final double Lat = location.getLatitude();
final double Long = location.getLongitude();
// Giving the value here
Toast.makeText(getApplicationContext(),"Long"+ Long, Toast.LENGTH_LONG).show();
}
}
}
);
} else {
Toast.makeText(this, "Turn on location", Toast.LENGTH_LONG).show();
Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
startActivity(intent);
}
} else {
requestPermissions();
}
}
Try to setup ViewPager with Tab after getting data for Lat and Long
private Double Lat;
private Double Long;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mFusedLocationClient = LocationServices.getFusedLocationProviderClient(this);
getLastLocation();
}
private void setupViewPager() {
Toast.makeText(getApplicationContext(),Double.toString(Lat), Toast.LENGTH_LONG).show();
SectionsPagerAdapter sectionsPagerAdapter = new SectionsPagerAdapter(this,
getSupportFragmentManager(), Lat, Long);
ViewPager viewPager = findViewById(R.id.view_pager);
viewPager.setAdapter(sectionsPagerAdapter);
TabLayout tabs = findViewById(R.id.tabs);
tabs.setupWithViewPager(viewPager);
}
#SuppressLint("MissingPermission")
public void getLastLocation(){
if (checkPermissions()) {
if (isLocationEnabled()) {
mFusedLocationClient.getLastLocation().addOnCompleteListener(
new OnCompleteListener<Location>() {
#Override
public void onComplete(#NonNull Task<Location> task) {
Location location = task.getResult();
if (location == null) {
requestNewLocationData();
} else {
Lat = location.getLatitude();
Long = location.getLongitude();
// Giving the value here
Toast.makeText(getApplicationContext(),"Long"+ Long, Toast.LENGTH_LONG).show();
setupViewPager();
}
}
}
);
} else {
Toast.makeText(this, "Turn on location", Toast.LENGTH_LONG).show();
Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
startActivity(intent);
}
} else {
requestPermissions();
}
}
Suggestions: Instead of passing data to fragment you can use callback to communicate between Activity and Fragment. Check this to learn how to communicate between Activity and Fragment
You have a lot of issues here. You cannot do what you're trying to do with things the way they are right now. I'm a bit surprised this actually compiles. Long is a class name. I'd suggest sticking to convention, and use lowercase. So longitude and latitude. Your code is confusing to read.
First, the line:
getLastLocation(Lat, Long);
You're passing a double which is pass by value. You are not modifying the values you passed in. You cannot do this with primitive types. You would need to encapsulate primitives inside an object and pass that object. e.g.
public class Coordinates {
private double longitude;
private double latitude;
// getters and setters
}
I'm not really familiar with Android, but it seems that a similar object already exists, and it's in your code. That's Location. You should use that instead of passing around double.
Second, even if you could pass around primitives like that, you're creating and assigning new variables with these two lines:
final double Lat = location.getLatitude();
final double Long = location.getLongitude();
Finally, you're dealing with an asynchronous call. So assuming you solve the above problems, you're still going to have issues:
mFusedLocationClient.getLastLocation().addOnCompleteListener(
new OnCompleteListener<Location>() { ... });
There is no guarantee that this action will be completed by the time getLastLocation returns, so when you call Toast.makeText in onCreate you're still likely to get 0.
So what can you do?
Well, it seems like you need to retrieve location data before this onCreate method is called and cache it. Then, in this onCreate, you can just assume that it's set.
Alternately, as Mike M. suggests, there's another method you can take advantage of: onComplete

how do i find the high speed from a speedometer application?

I have created a speedometer application, I want it to display the max speed the user has achieved. How do I find the highest speed the user has achieved?
I have already tried to contain the speeds in an array so that I can find the highest speed using the math.max function but the speeds in a variable keep changing how do I store the past speeds to compare and find the highest speed.
my main3activity:
public class Main3Activity extends AppCompatActivity implements android.location.LocationListener {
int arr[];
public int borat;
public float boo;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main3);
LocationManager lm =(LocationManager)this.getSystemService(Context.LOCATION_SERVICE);
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;
}
lm.requestLocationUpdates(LocationManager.GPS_PROVIDER,0,0,this);
this.onLocationChanged(null);
final TextView mTextField=(TextView)this.findViewById(R.id.textView);
new CountDownTimer(11000, 1000) {
public void onTick(long millisUntilFinished) {
mTextField.setText("" + millisUntilFinished / 1000);
}
public void onFinish() {
Intent myIntent = new Intent(Main3Activity.this,
aftergame.class);
startActivity(myIntent);
}
}.start();
}
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
switch (requestCode) {
case 1: {
// If request is cancelled, the result arrays are empty.
if (grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
} else {
// permission denied, boo! Disable the
// functionality that depends on this permission.
}
return;
}
// other 'case' lines to check for other
// permissions this app might request
}
}
public boolean checkLocationPermission()
{
String permission = "android.permission.ACCESS_FINE_LOCATION";
int res = this.checkCallingOrSelfPermission(permission);
return (res == PackageManager.PERMISSION_GRANTED);
}
#Override
public void onLocationChanged(Location location) {
int cpeeda;
int cpeedb;
final int speed;
TextView txt=(TextView)this.findViewById(R.id.st);
if(location==null){
txt.setText("0 m/s");
}else{
float cpeed=location.getSpeed();
float cpeed1=location.getSpeed();
cpeeda=(int)cpeed;
cpeeda=arr[0];
borat= Math.max(0,arr[0]);
txt.setText(cpeeda + " m/s");
}
}
#Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
#Override
public void onProviderEnabled(String provider) {
}
#Override
public void onProviderDisabled(String provider) {
}
}
my activity which displays the high speed:
public class aftergame extends AppCompatActivity {
Button button;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_aftergame);
button = (Button) findViewById(R.id.button2) ;
Main3Activity m=new Main3Activity();
TextView tm=(TextView)this.findViewById(R.id.textView3);
tm.setText(""+m.borat);
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent myIntent = new Intent(aftergame.this,
MainActivity.class);
startActivity(myIntent);
}
});
}
}
Here:
cpeeda=arr[0];
borat= Math.max(0,arr[0]);
That is non-sensical. I guess you meant to assign
arr[0] = cpeeda;
But even that doesn't make much sense. The idea of arrays is that they provide multiple data points. When you only assign a value into the first slot, all the other array slots stay at their initial value (which would be 0 if done right). Btw: your code does not create an array, so arr is null first of all.
In the end, the real answer is two-fold:
you are absolutely overburdening yourself here. Your code implies that you lack a lot of knowledge about basic java. You should spend some days, weeks, to learn Java first, before going for the even more complicated "Java Android"
you don't need an array to just find a max speed!
Simply do something like:
double maxSpeed = 0; // some field of your class, similar to your array
... wherever you determine the current speed:
if (maxSpeed > currentSpeed) {
maxSpeed = currentSpeed;
Yet, when you want to store multiple datapoints, you either should create an array of a fixed size (where you start overwriting older values once you got to that fixed size), or you could use an ArrayList. That one grows dynamically, thus you could just keep adding values to it. (of course, at some point you better stop doing so, otherwise you will run out of memory sooner or later)

FusedLocationProviderClient.removeLocationUpdates always returns failure

I have an activity that extends a base class called LocationAwareActivity all this LocationAwareActivity activity does is creates a location service client
LocationServices.getFusedLocationProviderClient and listens to
location updates.
Source for this activity is here
https://github.com/snijsure/MultiActivity/blob/master/app/src/main/java/com/example/subodhnijsure/multiactivity/LocationAwareActivity.java
And when activity is destroyed it calls removeLocationUpdates . What I am finding is
removeLocationUpdate returns a task that always returns not-successful
More concerning is because location activities is not removed, the activity is not getting being garbage collected.
- So if I start the any activity that inherits from LocationAwareActivity that activity always stays on heap.
So the question is what is the correct way to stop receiving location updates thus allowing activity to be garbage collected.
Entire source for this project can be accessed here - https://github.com/snijsure/MultiActivity
In removeLocationUpdates you should pass locationCallback, current implementation is wrong.
Still, there is chance of memory leak somewhere else. You should try integrating Leakcanary in your app and it can give you reference tree and will tell you which field or listener is causing this memory leak.
You can refer one of my only blog post here
public void stopLocationUpdates() {
if (locationProviderClient != null) {
try {
final Task<Void> voidTask = locationProviderClient.removeLocationUpdates(locationCallback);
if (voidTask.isSuccessful()) {
Log.d(TAG,"StopLocation updates successful! ");
} else {
Log.d(TAG,"StopLocation updates unsuccessful! " + voidTask.toString());
}
}
catch (SecurityException exp) {
Log.d(TAG, " Security exception while removeLocationUpdates");
}
}
}
Hi #Subodh Nijsure Please check below code and paste into your code and after checked it:
final Task<Void> voidTask = locationProviderClient.removeLocationUpdates(locationCallback);
voidTask.addOnCompleteListener(new OnCompleteListener<Void>() {
#Override
public void onComplete(#NonNull Task<Void> task) {
Log.e(TAG, "addOnCompleteListener: "+task.isComplete());
}
});
voidTask.addOnSuccessListener(new OnSuccessListener<Void>() {
#Override
public void onSuccess(Void aVoid) {
Log.e(TAG, "addOnSuccessListener: " );
}
});
voidTask.addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
Log.e(TAG, "addOnFailureListener: ");
}
});
I think voidTask.isSuccessful() this method is not working when you put this listener at that time it working fine and i also see into memory it's release all memory when come to previous Activity.
And when you are redirecting to any activity then please stopLocationUpdates() called once into onPause() and remove from other method like onDestroy(),onStop() because it stop once so why should we call multiple time.
Hope this helps you.
By looking at the code in the repository I discovered some issues in your design that maybe cause the leaking of your Activity.
1) You are using two different LocationCallbacks. One in the start and one in the stop method, but you should actually use the same. So one time instantiating it would be sufficient and would lead probably also to a successful result of your Task when removing the LocationCallback.
2) Since your instantiating the LocationCallback twice with an Anonymous Class you are keeping a non-static reference of an inner class even if you finish the containing class and this causes your Memory Leak. You can read more about this here.
3) IMHO it is better to use a separate manager class for handling your location requests than abstracting an Activity.
That said here is my...
Solution
GpsManager.java
public class GpsManager extends LocationCallback {
private FusedLocationProviderClient client;
private Callback callback;
public interface Callback {
void onLocationResult(LocationResult locationResult);
}
public boolean start(Context context, Callback callback) {
this.callback = callback;
client = LocationServices.getFusedLocationProviderClient(context);
if (!checkLocationPermission(context)) return false;
client.requestLocationUpdates(getLocationRequest(), this, null);
return true;
}
public void stop() {
client.removeLocationUpdates(this);
}
#Override
public void onLocationResult(LocationResult locationResult) {
callback.onLocationResult(locationResult);
}
private boolean checkLocationPermission(Context context) {
int permissionCheck = ContextCompat.checkSelfPermission(
context, android.Manifest.permission.ACCESS_FINE_LOCATION);
return permissionCheck == PackageManager.PERMISSION_GRANTED;
}
private LocationRequest getLocationRequest() {
return LocationRequest.create()
.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY)
.setInterval(30_000L)
.setFastestInterval(20_000L);
}
}
and calling this from your Activity like this
YourActivity.java
public class MapsActivity extends AppCompatActivity implements GpsManager.Callback {
private static final int PERMISSION_REQUEST_FINE_LOCATION = 1;
private GpsManager mGpsManager;
#Override
protected void onCreate(Bundle savedInstanceState) {
...
mGpsManager = new GpsManager(getApplicationContext(), this);
// check if user gave permissions, otherwise ask via dialog
if (!checkPermission()) {
getLocationPermissions();
return;
}
mGpsManager.start();
...
}
#Override
protected void onStop() {
super.onStop();
mGpsManager.stop();
}
#Override
public void onLocationResult(LocationResult locationResult) {
// do something with the locationResult
}
// CHECK PERMISSIONS PART
private boolean checkPermission() {
return isGranted(ActivityCompat.checkSelfPermission(this, ACCESS_FINE_LOCATION)) &&
isGranted(ActivityCompat.checkSelfPermission(this, ACCESS_COARSE_LOCATION));
}
#TargetApi(Build.VERSION_CODES.M)
private void getLocationPermissions() {
requestPermissions(new String[] {Manifest.permission.ACCESS_FINE_LOCATION},
PERMISSION_REQUEST_FINE_LOCATION);
}
#Override
public void onRequestPermissionsResult(int code, #Nullable String permissions[], #Nullable int[] results) {
switch (code) {
case PERMISSION_REQUEST_FINE_LOCATION:
if (isPermissionGranted(results)) {
getLocationRequest();
}
}
}
private boolean isPermissionGranted(int[] results) {
return results != null && results.length > 0 && isGranted(results[0]);
}
private boolean isGranted(int permission) {
return permission == PackageManager.PERMISSION_GRANTED;
}
}
This is just a guess because I didn't try your code but the solution should help you anyways. Please correct me if I'm wrong ;)
The reason why the Task object returns false is in your stopLocationUpdates method, you are again creating a local **LocationCallback** reference and then using this reference to as an argument in locationProviderClient.removeLocationUpdates(cL);
where your local LocationCallBack is never present in the locationProviderClient
So what you have to do is , instead of creating another LocationCallBack object ,you have to pass the same global object which you are instantiating in your startLocationUpdates method
your code should be like this
final Task<Void> voidTask = locationProviderClient.removeLocationUpdates(locationCallback);

Android app modulization (classes)

thank you for taking the time to load my post and view my question.
For the longest time I have been creating long android activities just because I didn't quite understand classes and how they worked. Earlier this week, I learned how easy it is to send information between methods. Today, I am struggling to send information between classes. Instead of having one very long page of code to sift through, I want to break it down into chunks, and have the information reference and interact with eachother. This way it is easier to keep my code organized and faster to make changes. I have tried to remove two separate classes from my main thread and created them in the same directory, the code shows no errors so they should execute just fine. However, I am messing up somewhere with the context. I don't fully grasp the concept of context either. I have one class to get my phones location, and another class to upload to my server. Both these classes return null values when trying to be executed. However, when it was all stream-lined on one main activity, there was no null errors. I have been reading context is the issue here.
I have referenced the other classes from my mainthread like this:
LocationClass LocationClass;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.mapfrag);
LocationClass = new LocationClass();
#Override
public void onMapReady(GoogleMap googleMap) {
Map = googleMap;
Map.setOnMapClickListener(this);
Map.setOnMapLongClickListener(this);
Map.setMapType(1);
Map.setOnMarkerClickListener(this);
LocationClass.GETLOCATION();
}
and my location class looks like this:
public class LocationClass extends AppCompatActivity implements
GoogleApiClient.ConnectionCallbacks,
GoogleApiClient.OnConnectionFailedListener {
private final static int PLAY_SERVICES_RESOLUTION_REQUEST = 1000;
private Location mLastLocation;
private GoogleApiClient mGoogleApiClient;
public LatLng reallifelocation;
public static final String userdata = "userdata";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (checkPlayServices()) {
buildGoogleApiClient();
}
check_perms();
}
and then it checks the permissions and does what it has to to get the location. This code is all tested and working from the main thread, I'm just trying to create my own class for it
error:
java.lang.NullPointerException: Attempt to invoke virtual method 'android.content.Context android.content.Context.getApplicationContext()' on a null object reference
at android.content.ContextWrapper.getApplicationContext(ContextWrapper.java:112)
at biz.tanners.geo_x.LocationClass.GETLOCATION(LocationClass.java:49)
where the error sits(LocationClass.java):
public void GETLOCATION() {
if (ActivityCompat.checkSelfPermission(this.getApplicationContext(), android.Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {return;}
final SharedPreferences prefs = getSharedPreferences(userdata, MODE_PRIVATE);
mLastLocation = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
if (mLastLocation != null) {
reallifelocation = new LatLng(mLastLocation.getLatitude(), mLastLocation.getLongitude());
}
//add to prefs or offline db
}
Your error stems from here
if (ActivityCompat.checkSelfPermission(
this.getApplicationContext(),
android.Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
return;
}
Here this probably should correspond to the Context and being another class, the context is different.
A quick fix would be to pass the Activity's context as a parameter to the LocationClass's object. By adding it in the constructor and assigning it to the right variable, which later you could use instead of this.
Hope this helps.

Android - getting current location through Google Map

I am developing an app related to Google map. I have done following steps successfully.
Created API key to access Google Map
Added Google Play Services Library in my app
Added required permissions
Added map in my activity with SupportMapFragment
Added a separate class MyMap.java to manipulate the map
Passed tow parameters to this class - Context of main activity and object of GoogleMap
Turned Wi-Fi and GPS on and ran the app
After this I am getting map with nice look and controls.
MyMap.java
public class MyMap implements ConnectionCallbacks, OnConnectionFailedListener {
private Context context;
private GoogleMap map;
private GoogleApiClient client = null;
public MyMap(Context context, GoogleMap map) {
this.context = context;
this.map = map;
client = new GoogleApiClient.Builder(context)
.addApi(LocationServices.API).addConnectionCallbacks(this)
.addOnConnectionFailedListener(this).build();
}
#Override
public void onConnectionFailed(ConnectionResult arg0) {
// TODO Auto-generated method stub
}
#Override
public void onConnected(Bundle arg0) {
Toast.makeText(context, "Connected", 1).show();
Location mLastLocation = LocationServices.FusedLocationApi
.getLastLocation(client);
if (mLastLocation != null) {
Toast.makeText(
context,
String.valueOf(mLastLocation.getLatitude()) + ","
+ String.valueOf(mLastLocation.getLongitude()), 1)
.show();
}
}
#Override
public void onConnectionSuspended(int arg0) {
// TODO Auto-generated method stub
}
}
Problem
In the above class I want to toast the current location. But it is not toasting anything. At least I need to see a toast saying "connected" on onConnected
event. Is there something wrong in my implementation?
Thanks in advance.
You seemingly never connect your client so it would be a real suprise if onConnected was called :)
You create your client with
client = new GoogleApiClient.Builder(context)
.addApi(LocationServices.API).addConnectionCallbacks(this)
.addOnConnectionFailedListener(this).build();
but for the client to do something you have to add:
client.connect();
getLastLocation() is going to give location only once. To get periodic location updates, you need to override onLocationChanged() method. You can get this Link
Best way that I found is simple implement you activity like so:
public class MapActivity extends Activity implements GoogleMap.OnMyLocationChangeListener
and override method
#Override
public void onMyLocationChange(Location location) {
mMap.addMarker(new MarkerOptions().position(location).icon(
BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_GREEN)));
}
And don't forget about mMap.setMyLocationEnabled(true); and mMap.setOnMyLocationChangeListener(this); in map init method
That's all!
Also, you can check is map available like here:
public boolean checkMapsAvailable() {
int isAvailable = GooglePlayServicesUtil.isGooglePlayServicesAvailable(this);
if (isAvailable == ConnectionResult.SUCCESS) {
return true;
} else if (GooglePlayServicesUtil.isUserRecoverableError(isAvailable)) {
Dialog dialog = GooglePlayServicesUtil.getErrorDialog(isAvailable, this, 9001);
dialog.show();
} else {
Constants.showToast(Constants.ALERT_GOOGLEPLAY_CONNECTION);
}
return false;
}
Hope this helps.

Categories

Resources