Reputation: 294
I have already searched for lots of similar questions, but didn't had any luck. PLEASE do not mark this as a duplicate if it's not one. Feel free to help me change the title if needed, though.
I have an application which displays a GPS retrieving activity (formatted as a dialog) on top of the regular activity. My code is supposed to format the dialog to responsively change its buttons according to the action flow. When it starts, the visibility of those 2 buttons is programatically set to gone (already tried to set at the activity layout, no difference at all), then a method is called to look for GPS positioning. If no location is retrieved, the dialog should (and does) set the buttons as visible. The dialog asks the user to try again or proceed without a location established. If I choose to proceed, the dialog omits one of the 2 buttons and change the text of the visible one. If I choose to try retrieving the location again, the dialog SHOULD omit both buttons again, but that isn't happening. The most crazy thing is that when I press the "try again" button (which remains displayed) a second time, after this glitch, the buttons are omitted. Why is that happening?
Here is my code:
private Location mLastLocation;
private Location location;
// boolean flag to toggle periodic location updates
private boolean mRequestingLocationUpdates = false;
// UI elements
private TextView mainMsg;
Chronometer c;
private int count = 0;
private boolean proceed = false;
private Button button1, button2;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.dialog_location_retriever);
button1 = (Button) findViewById(R.id.btn_loc_1);
button1.setVisibility(View.GONE);
button2 = (Button) findViewById(R.id.btn_loc_2);
button2.setVisibility(View.GONE);
c = (Chronometer) findViewById(R.id.crono);
c.setOnChronometerTickListener(new Chronometer.OnChronometerTickListener() {
@Override
public void onChronometerTick(Chronometer chronometer) {
if (c.getText().equals("00:05")) {
c.stop();
stopLocationUpdates();
proceed = false;
mainMsg.setText("Try again?");
button1.setVisibility(View.VISIBLE); // This is where they first become visible, here the code works for me.
button2.setVisibility(View.VISIBLE);
button2.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mRequestingLocationUpdates = false;
proceed = true;
count = 0;
button1.setVisibility(View.GONE);
button2.setVisibility(View.GONE);
/* Here the code gets crazy! Those couple lines above won't work.
I press button2 one time and the two button's fail to disappear.
Chronometer goes to 0 and starts again. The app will try to find a location again.
If I press button2 a second time, while the chronometer is still counting,
then the buttons disappear and the chronometer resets and start over, as originally intended.
ANOTHER INFO: if I remove the three lines above the button methods, it will work, but the app won't function as intended.*/
togglePeriodicLocationUpdates(); // This code calls a method to control whether the app will start looking for a location or shut the location services.
}
});
button1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mainMsg.setText("Continue without a defined location.");
button1.setVisibility(View.GONE); // Here the code works no matter what...
button2.setText("Continue");
button2.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
finish();
}
});
}
});
}
}
});
mainMsg = (TextView) findViewById(R.id.mainMsg);
// Check availability of google play services
if (checkPlayServices()) {
buildGoogleApiClient();
createLocationRequest();
}
new Timer().schedule(new TimerTask() { // This launches the location finder on timer, so that the user doesn't need to press anything to begin location retrieval
@Override
public void run() {
runOnUiThread(new Thread(new Runnable() {
@Override
public void run() {
togglePeriodicLocationUpdates();
}
}));
}
}, 2000);
}
private void togglePeriodicLocationUpdates() {
if (!mRequestingLocationUpdates) { // Begin search cycle
// Changing the button text
if (count == 0) {
mainMsg.setText("Getting location...");
c.setBase(SystemClock.elapsedRealtime());
}
mRequestingLocationUpdates = true;
// Starting the location updates
startLocationUpdates();
c.start();
Log.d(TAG, "Periodic location updates started!");
} else { // End search cycle
mRequestingLocationUpdates = false;
if (count == -1) {
c.stop();
}
// Stopping the location updates
stopLocationUpdates();
if (proceed & count > 0) {
togglePeriodicLocationUpdates();
}
Log.d(TAG, "Periodic location updates stopped!");
}
}
@Override
public void onLocationChanged(Location location) { // Listener for locations get by the google play location service
if (mLastLocation == null) mLastLocation = location; // checks if first time
try {
if (location.getLatitude() != mLastLocation.getLatitude() &
location.getLongitude() != mLastLocation.getLongitude()) {
/* Seems the location API can the last known location instead of the ACTUAL location.
I didn't like that too much, so I verify if the freshly-collected location is the same as the "last known".
If the location is new.......*/
c.stop(); // Halt the chronometer
stopLocationUpdates(); // Halt location services
// Assign the new location
mLastLocation = location;
this.location = location;
Toast.makeText(getApplicationContext(), "Location changed!", Toast.LENGTH_SHORT).show();
double latitude = location.getLatitude();
double longitude = location.getLongitude();
mRequestingLocationUpdates = false;
// This is supposed to be the last snippet of location code to run...
} else {
// This should run if the location found is not an actual update on your position.
// For your information, this runs in cycles, half dozen or so if the (GPRS) signal is poor.
mainMsg.setText("Text to keep user entertained...");
if (!proceed) {
proceed = !proceed;
}
count++; // Variable to count the number of cycles run
togglePeriodicLocationUpdates(); // Call the toggle function again to run another cycle
// Running those cycles seemed to help my GPS to find a location, instead of just leaving it on all the time.
}
} catch (NullPointerException e) {
c.stop();
e.printStackTrace();
}
}
My layouts:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center_vertical|center_horizontal"
android:orientation="vertical"
tools:context="br.com.gerpaudit.activity.LocationRetrieverActivity"
android:paddingTop="20sp"
android:paddingBottom="20sp">
<TextView
android:id="@+id/mainMsg"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textStyle="bold"
android:text="O aplicativo irá buscar sua localização, aguarde."
android:gravity="center_vertical|center_horizontal"/>
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:text="Tempo decorrido: "
android:id="@+id/textView"
android:textStyle="bold"
android:textSize="25sp"/>
<Chronometer
android:id="@+id/crono"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:allowUndo="false"
android:textSize="25sp"
android:textStyle="bold"
/>
</LinearLayout>
<LinearLayout
android:id="@+id/loc_btn_layout"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical|center_horizontal"
android:paddingLeft="5dp"
android:paddingRight="5dp">
<Button
android:id="@+id/btn_loc_1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#FFF"
android:background="@drawable/bg_voltar"
android:text="Não"
android:layout_weight="1"
android:layout_marginLeft="5dp"
android:layout_marginRight="5dp"
android:visibility="visible"/>
<Button
android:id="@+id/btn_loc_2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#FFF"
android:background="@drawable/bg_voltar"
android:text="Sim"
android:layout_weight="1"
android:layout_marginLeft="5dp"
android:layout_marginRight="5dp"
android:visibility="visible"/>
</LinearLayout>
Upvotes: 0
Views: 1360
Reputation: 294
Turns out I needed to reset the Chronometer BEFORE changing the state of those views. The odd thing is that I verified the state of the buttons, and their visibility showed as "8", i.e., "View.GONE", but still showing. Now that I added a line to reset the Chronometer before setting them to GONE, it works. Don't ask me why.
Upvotes: 0
Reputation: 3693
Try to remove
button2.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mRequestingLocationUpdates = false;
proceed = true;
count = 0;
button1.setVisibility(View.GONE);
button2.setVisibility(View.GONE);
/* Here the code gets crazy! Those couple lines above won't work.
I press button2 one time and the two button's fail to disappear.
Chronometer goes to 0 and starts again. The app will try to find a location again.
If I press button2 a second time, while the chronometer is still counting,
then the buttons disappear and the chronometer resets and start over, as originally intended.
ANOTHER INFO: if I remove the three lines above the button methods, it will work, but the app won't function as intended.*/
togglePeriodicLocationUpdates(); // This code calls a method to control whether the app will start looking for a location or shut the location services.
}
});
button1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mainMsg.setText("Continue without a defined location.");
button1.setVisibility(View.GONE); // Here the code works no matter what...
button2.setText("Continue");
button2.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
finish();
}
});
}
});
out of the if (c.getText().equals("00:05"))
statement and place them after
button1 = (Button) findViewById(R.id.btn_loc_1);
button1.setVisibility(View.GONE);
button2 = (Button) findViewById(R.id.btn_loc_2);
button2.setVisibility(View.GONE);
Upvotes: 1