明らかにどこかにあるはずのエラーを見つけるのに苦労しています。おそらく、私が認識していない論理エラーです。
クリックすると、自分の位置を特定する locationManager を開始するボタンがあります。現在地をスキャンしている間、ボタンを無効にしたいです。私はなんとかそれを行うことができました(Yay)が、最初に場所を取得してボタンを2回クリックした後、2回目の場所を受け取るために、ボタンはもう無効になりません. これにより、ボタンを複数回タップできるようになり、場所をリッスンする locationListener がどんどん開始されます。それは、スキャン中にボタンを無効にすることで防止しようとしたことです.
これが私のコードです。説明は次のとおりです。
主な活動:
public class MainActivity extends FragmentActivity {
// Setting layout dependent variables
...
private Button btn_scan;
// Setting several variables
...
// Setting default values
...
private boolean locationReceived = false;
private boolean gsmReceived = false;
private boolean isBusy = false;
private int counter = 0;
private Handler handler;
private Runnable runnable = new Runnable() {
public void run() {
counter ++;
handler.postDelayed(runnable, 1000);
if (locationReceived && gsmReceived) {
// SAVE DATA TO DB HERE! //
displayInformation();
handler.removeCallbacks(runnable);
} else if (counter >= (TIME_TO_WAIT_FOR_RESPONSE+1)) {
displayInformation();
handler.removeCallbacks(runnable);
}
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Application context
context = getApplicationContext();
// Handler
handler = new Handler();
// initializing layout dependent variables
...
btn_scan = (Button) findViewById(R.id.btn_scan);
// Initialize GoogleMap
...
// Get the LocationManager for checking, if providers are enabled
locationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
// Get the PhoneStateListener and telephony service to receive the signal strength
myListener = new MyPhoneStateListener();
tel = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
// Ask for the current location in here.
locationResult = new LocationResult() {
@Override
public void gotLocation(final Location location) {
// If location given, do something with it. If not, return some message.
if (location != null) {
updateGeoData(location);
}
}
};
btn_scan.setOnClickListener(new OnClickListener(){
@Override
public void onClick(View v) {
if (!isBusy) {
toogleButton();
// if GPS is enabled in phone settings
if (!locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER) && !locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER)) {
postGPSAlert();
toogleButton();
} else {
// If GPS enabled, get info
getInformation();
}
}
}
});
}
/*
* wrapper method for getting informations
*/
private void getInformation() {
// start informationfetcher.
runnable.run();
// get geo location, longitude & latitude
getGeoLocation();
// get signal strength and its' other parameters
getSignalStrength();
// get internet connectivity quality string
getConnectivityQuality();
// get internet connectivity type
getConnectivityType();
}
/*
* get signal strength. only starts the listener, which does the rest of the job.
*/
public void getSignalStrength() {
tel.listen(myListener, PhoneStateListener.LISTEN_SIGNAL_STRENGTHS);
}
/*
* get connectivity type and update the variable internetType
*/
private void getConnectivityType() {
... nothing important
}
/*
* Gets internet quality string
*/
private void getConnectivityQuality() {
... nothing important
}
/*
* Gets the geo location
*/
public void getGeoLocation() {
MyLocation myLocation = new MyLocation(context, TIME_TO_WAIT_FOR_RESPONSE);
if (!myLocation.getLocation(locationResult)) {
String message = "To make use of localization, please enable GPS or mobile networking.";
Toast.makeText(context, message, Toast.LENGTH_LONG).show();
}
}
/*
* Updates retrieved GeoData
*/
private void updateGeoData(Location location) {
latitude = location.getLatitude();
longitude = location.getLongitude();
locationReceived = true;
}
/*
* Updates GUI with all received values
*/
private void displayInformation() {
... only updating textViews here
if (gsmReceived) {
... only updating textViews here
}
if (locationReceived) {
... only updating textViews here and moving googleMapCamera to some spot
}
// Post Error messages, if location and/or GSM could not be obtained.
... just Toasting some error messages, if no signal or GPS received.
toogleButton();
}
/*
* Posts an alert saying u gotta enable GPS
*/
private void postGPSAlert() {
// Prompt alert
AlertDialog.Builder alert = new AlertDialog.Builder(MainActivity.this);
// Title and message values
alert.setTitle(getString(R.string.prompt_titleProviderFail));
alert.setMessage(getString(R.string.prompt_messageProviderFail));
// If OK was clicked, redirect to settings to enable GPS
alert.setPositiveButton("Ok", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
startActivity(new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS));
}
});
// If ABORT was clicked, redirect back to activity
alert.setNegativeButton("Abort", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
// Canceled.
}
});
// Show dialog
alert.show();
}
/*
* Method for disabling and enabling the button on pressure/update
*/
private void toogleButton() {
if (btn_scan.isEnabled()) {
isBusy = true;
btn_scan.setText("SCANNING ...");
btn_scan.setEnabled(false);
} else if (!btn_scan.isEnabled()) {
isBusy = false;
btn_scan.setText("SCAN");
btn_scan.setEnabled(true);
}
}
/*
* (non-Javadoc)
* Listener, to listen on signalStrength of your phone. It'll set all the variables declared above and update the info you'll see.
*/
private class MyPhoneStateListener extends PhoneStateListener {
@Override
public void onSignalStrengthsChanged(SignalStrength signalStrength) {
super.onSignalStrengthsChanged(signalStrength);
... just updating some String variables here
gsmReceived = true;
tel.listen(myListener, PhoneStateListener.LISTEN_NONE);
}
}
}
ボタンをクリックするとすぐに、すでに操作が実行されているかどうかを確認し、メソッドtoogleButton()を介してボタンを無効にしています。そのため、ネットワーク、signalStrength、および現在地に関する情報を収集するために、いくつかのメソッドがトリガーされます。通常、自分の位置を収集するのに最も時間がかかりますが、それは重要ではありません。すべての情報が収集された場合、ハンドラー + ランナブルを使用して毎秒 60 秒間チェックしています。その場合、userInterface のdisplayInformation()を介してすべての情報を表示し、toogleButton( )を介してボタンを再度有効にします。また、変数isBusy = trueを設定しています. すべての情報を収集せずに 60 秒が経過した場合でも、(それまで) 収集されたすべての情報を表示し、ボタンをもう一度 (有効な状態に) 押します。
これはすべて、初めて正常に機能します。すべての情報を受け取った後にもう一度ボタンを押すと、ボタンは無効になりませんが、アプリは必要に応じて情報を収集します。ここでの唯一の問題は、ボタンを複数回押して、複数の要求を開始して情報を収集できるようになったことです。それは私が望むものではありません。一つ一つ欲しい。
ここで私が何を間違えたか知っていますか?