I need to get current location, and after that - do next code. How can i wait while this method has finished? onLocationChanged is called automatically that why i have problem. Do someone has any ideas how to do itmore correct?
I make it very stupid, in OnLocationChanged() i call onResume(), but it is so bad idea.
#Override
public void onLocationChanged(Location location) {
final Location loc = location;
Log.d("myLogs", "OnChange2");
Log.d("myLogs", "2" + loc.getLatitude() + "," + loc.getLongitude());
myLat = loc.getLatitude();
myLong = location.getLongitude();
onResume();
}
You might want to use AsyncTask for that. See Android find GPS location once, show loading dialog for the answers. Basically in onPreExecute you can start dialog( it starts before the doInBackground is called). It means you are waiting till the time you can location and showing the dialog. Then in doInBackground you can get the location. After that finishes onPostExecute is called. You can stop is from inside onPostExecute. You can check if the location is not null and then call some other function from inside onPostExecute also if you want.
This might be one way. You can learn a basic example from AsyncTask Android example . You can also start by reading the documentation here and read How to Get GPS Location Using AsyncTask? .
Some other similar helpful questions:
Wait for current location - GPS - Android Dev
getting location instantly in android
Hope this helps.
I realize the OP has accepted the above answer but I have a feeling the OP wanted a more simple answer.
I am assuming the OP has an android application with an Activity. I declared mine like this:
public class HelloAndroidActivity extends Activity implements LocationListener {
The OP was confused as to how the lifecycle methods worked and when work should be done. My Resume and Pause methods would look like this:
#Override
protected void onPause() {
((LocationManager)getSystemService(Context.LOCATION_SERVICE)).removeUpdates(this);
super.onPause();
}
#Override
protected void onResume() {
((LocationManager)getSystemService(Context.LOCATION_SERVICE)).requestLocationUpdates(LocationManager.GPS_PROVIDER, 5 * 1000, 1, this);
super.onResume();
}
Notice that my onResume asks that I be notified when there are location updates and the onPause method asks that I no longer be notified. You should be careful to not ask for updates at a time interval smaller then you really need or you will drain your battery.
Since the activity implements LocationListener my onLocationChanged method looks like this:
#Override
public void onLocationChanged(Location location) {
// Update the location fields
((EditText)findViewById(R.id.latField)).setText(Double.toString(location.getLatitude()));
((EditText)findViewById(R.id.longField)).setText(Double.toString(location.getLongitude()));
}
This simply takes the new location and updates some text EditText fields that I have in my activity. The only other thing I needed to do was to add the GPS permission to my manifest:
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
So if I were asking how to start out using the location manager and the location service this would be how I would begin. I'm not trying to take anything away from the accepted answer, I just think there was a fundamental misunderstanding about what to do in onResume and in the onLocationMethodChanged methods.
Related
So I followed Google's first Android app sample. If I tapped the send button, it opened up the DisplayMessageActivity. But upon tapped the back button (left arrow) from the DisplayMessageActivity, the onCreate(Bundle savedInstanceState) of the MainActivity got called again. It looks like it created a new instance of MainActivity. I could verify this by setting a bool value in onCreate of MainActivity and it was not retained.
How do you go back to the previous instance of MainActivity (the caller)?
You should have a look at Androids Activity Lifecycle.
If you want to access the state of the activity again, I would suggest to use the method
public void onSaveInstanceState(Bundle outState)
to save the current state.
Retrieve the previously saved values in this method:
public void onRestoreInstanceState(Bundle savedInstanceState)`
An example can be found here
You can call finish() in the onClickListener of the back arrow view. It will finish the DisplayMessageActivity and you will return to the caller activity (MainActivity in your case).
Something like:
backArrow.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
finish();
}
});
It looks like it created a new instance of MainActivity.
Yes, I think, that was quite a normal behavior.
Basically, Android OS would keep only one Activity at once so that free as many memory resources as possible.
You should design your application with understanding about such lifecycle concepts.
You can save some of the states of your Activity in certain manners (Parcelable, Bundle or SharedPreferences, etc.).
I am trying to log installs of my app using Firebase with this simple code below:
firebaseAnalytics.logEvent("foo", bundle);
However, I am not sure where to put this code. Does any one know of an "onInstall" method in the Application class?
Or is there another, easier way to log installs with Firebase?
Thank you!
You could determine if the user launches the application for the first time, and log that event.
public class MyActivity extends Activity {
SharedPreferences prefs = null;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Perhaps set content view here
prefs = getSharedPreferences("com.mycompany.myAppName", MODE_PRIVATE);
}
#Override
protected void onResume() {
super.onResume();
if (prefs.getBoolean("firstrun", true)) {
firebaseAnalytics.logEvent("foo", bundle);
prefs.edit().putBoolean("firstrun", false).commit();
}
}
}
Code referenced from this SO answer.
There's another answer in that same SO question that explained how to differentiate between first run and subsequent upgrades, I'll just link that SO answer here for your reference.
The cleanest method would be to have a remote server that holds a unique ID for each user.
Also, you could theoretically write a file directly on the device. But then, you'd need to get the write permission and it's most definitely not a good idea to create and leave a file on the device.
P.S - To answer the actual question, No, Android doesn't have an onInstall method.
I'm simply trying to write a method that returns Latitude and Longitude. I have an activity with a button and two text fields. The java class I am using extends AppCompatActivity and implements LocationListener When the button is pressed the following method is pressed:
public void startGPS(View view)
{
// Here is the code to handle permissions - you should not need to edit this.
if ( Build.VERSION.SDK_INT >= 23 &&
ContextCompat.checkSelfPermission( this, android.Manifest.permission.ACCESS_FINE_LOCATION ) != PackageManager.PERMISSION_GRANTED &&
ContextCompat.checkSelfPermission( this, android.Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this, new String[] { android.Manifest.permission.ACCESS_FINE_LOCATION, android.Manifest.permission.ACCESS_COARSE_LOCATION }, TAKE_PHOTO_PERMISSION);
}
Location location = locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 5000, 0, this);
}
Later on I try to print out my location in my onLocationChanged method but it was causing the app to crash. I ran it through the debugger and found that the location was always null.
I tried to this solution but it didn't work. Other examples are calling the function in onResume but I really need this to be in startGPS method.
Also, is there a chance that the error is just with my device? I'm running it on a Nexus 7 which doesn't seem to have any problems when I run Google Maps.
If are trying to return the GPS Coordinates after pressing a button that chances are you don't already have an existing GPS location stored. You should be using requestLocationUpdates and not getLastKnownLocation.
locationManager.requestLocationUpdate(LocationManager.NETWORK_PROVIDER, 5000, 0, locationListener)
When you use requestLocationUpdate it will automatically call onLocationChanged for you so you don't need to call it in your code.
You can substitute LocationManager.NETWORK_PROVIDERfor LocationManager.GPS_PROVIDER but as long as you have a WiFi connection you should be able to get coordinates.
If you are trying to use this inside try switching GPS_PROVIDER to NETWORK_PROVIDER; this will work anywhere that the phone has service.
Because Android doesn't track location when no app is requesting it, in order to save battery. GetLastKnownLocation will almost always return null. If you want an assured non-null response, use requestLocationUpdates or requestSingleLocation. Both of those are asynchronous though, so they will call a callback when a location is found (actually figuring out a location can take from a few seconds to a minute or two, depending on the type of location provider, atmospheric conditions, line of sight issues, etc. If using GPS and inside it could actually never occur.)
Working with the Location Manager in Android, nce you first call the requestLocationUpdates, the value you pass it to select the refresh time can be changed?
Let me explain. Here we have what I'm doing (and works perfect):
(...)
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, GPSrefresh, GPSminDistance, locationListener);
(...)
public void onLocationChanged(Location location) {
// Do what you want to do
}
If, after some time, I change the value of GPSrefresh, Is it going to affect to the locationUpdates? Is it always checking the value of GPSrefresh or it just did it the first time it was called?
Thank you very much.
you are passing values to a method requestLocationUpdates of LocationManager calss and then updateing that value..so it will not affect the previous method call..
Like,
String tmp="Mango";
Fruits.add(tmp);
tmp="Apple";
in above only Mango will be added..to add Apple you will have to call Fruits.add(tmp) again,
Same way..IF you cange value of GPSRefresh you will need to call the method requestLocationUpdates again with the new updated parameters.
I have an android app that has various activities.
for example there is a home screen and an update screen.
The home screen is a list activity.
A button on the home screen brings you to the update screen that updates the database from a server. In theory when Returning to teh homescreen after an update, the list should be changed to reflect the update just done.
the code for going to the update screen is as follows:
Button synch = (Button) findViewById(R.id.synchButton);
synch.setOnClickListener(new OnClickListener() {
public void onClick(View viewParam) {
Intent intent = new Intent(HomeScreen.this, SynchScreen.class);
startActivity(intent);
}
});
and the code for returning back to the homescreen after the updates is:
main_menu.setOnClickListener(new OnClickListener() {
public void onClick(View viewParam) {
finish();
}
});
the list is compiled from an async task that runs in onStart, so my understanding is that onStart should run when I return to the homescreen, thus always displaying the most up to date version of the list.
On my Emulator I always get teh updated list, but when I run it on my phone the list is never updated, it just returns to the state of teh screen before I did the update.
any ideas?
thanks
Kevin
Check the Activity lifecycle section of the Android documentation. The code updating the view should probably be moved to onResume, since the Activity might not get killed when launching a new one.
Put the code for starting the Asynctask in onResume. Read the documentation related to activity life cycle.
#Override
public void onResume() {
super.onResume();
Apaptor.refreshListView(Vector);
}