2010-11-26 49 views
0

我有一個屏幕(活動),它執行以下操作:它具有切換按鈕,切換飛行模式;它通過使用產生新線程的服務來完成。它也有一個按照完全相同的方式完成同樣的事情的按鈕。下面的代碼片段顯示的確沒有什麼特別之處。雖然切換按鈕的所有功能都按預期工作(如果當前電話不處於飛行模式,則飛行模式變爲「開」;如果當前處於飛行模式則變爲「關」),當按鈕被點擊時,飛行模式持續切換(飛機模式從「開」切換到「關」,然後回到「開」,然後切換到「關」......),就好像它落入循環一樣。在互聯網上進行了一些研究後,我懷疑這與Android中針對電話/服務狀態的intent/broadcastReceiver的方式有關;因爲切換按鈕具有兩種狀態,這有效地防止了意圖再次被廣播。它是否正確??如果是這樣,使用按鈕切換飛行模式的正確方法是什麼?(相對於單選按鈕或切換按鈕)?我的代碼連續切換飛行模式

/** Handler for the button. */ 
runToggleAirplaneModeServiceBtn.setOnClickListener(new OnClickListener() { 
@Override 
public void onClick(View v) { 
    startService(new Intent(SleepScheduleController.this, AirplaneModeService.class)); 
} 
}); 
/** Handler for the toggle button. */ 
airplaneModeToggleButton.setOnCheckedChangeListener(new OnCheckedChangeListener() { 
@Override 
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { 
    startService(new Intent(SleepScheduleController.this, AirplaneModeService.class)); 
} 
}); 
/** In the same screen as the toggle button and the button. 
* Need this to update the state of the toggle button once 
* the toggling command is executed. 
*/ 
intentFilter = new IntentFilter("android.intent.action.SERVICE_STATE"); 
receiver = new BroadcastReceiver() { 
    @Override 
    public void onReceive(Context context, Intent intent) { 
     displayAirplaneMode(); 
    }}; 
registerReceiver(receiver, intentFilter); 

private void displayAirplaneMode() { 
    if(airplaneModeToggler.isInAirplaneMode()){ 
     airplaneModeToggleButton.setChecked(true); 
     airplaneModeTextView.setText(R.string.airplane_mode_on); 
    }else{ 
    airplaneModeToggleButton.setChecked(false); 
    airplaneModeTextView.setText(R.string.airplane_mode_off); 
    } 
} 

/** Code snippet in AirplaneModeService*/ 
@Override 
public void onCreate() { 
    airplaneModeToggler = new AirplaneModeToggler(this); 
    Thread mThread = new Thread(null, airplaneModeToggleTask, "AirplaneModeToggleTask"); 
    mThread.start(); 
} 

private Runnable airplaneModeToggleTask = new Runnable() { 
    @Override 
    public void run() { 
     airplaneModeToggler.toggle(null); 
     AirplaneModeService.this.stopSelf(); 
    } 
}; 

/** Code snippet in the Utility class used by AirplaneModeService.*/ 
public Boolean toggleAirplaneMode(Boolean enabling) { 
    boolean _enabling = enabling == null ? !isInAirplaneMode() : enabling.booleanValue(); 
Settings.System.putInt(mContext.getContentResolver(), 
      Settings.System.AIRPLANE_MODE_ON, 
      _enabling ? AIRPLANE_MODE_ON : AIRPLANE_MODE_OFF); 
    Intent intent = new Intent(Intent.ACTION_AIRPLANE_MODE_CHANGED); 
    intent.putExtra("state", _enabling); 
    mContext.sendBroadcast(intent); 
    return _enabling; 
} 
+0

我回到我的代碼,並以編程方式切換飛行模式,它確實開始了同樣的瘋狂循環的事情。如果我使用後臺服務或直接在活動中使用我的實用工具類,它似乎沒有任何區別。當然,如果我沒有註冊意向,這個循環就不會發生;但隨後我的UI將不會更新以反映飛機模式已更改的事實: intentFilter = new IntentFilter(「android.intent.action.SERVICE_STATE」); – mobileTofu 2010-11-26 18:35:31

回答

0

所以我追蹤了這個bug。這是由toggleButton的OnCheckedChangeListener在我的代碼中重新執行命令造成的。說如果以前通過編程方式調用了切換命令,或者通過單擊另一個按鈕,則這些會在toggleButton上導致已檢查的狀態更改,這會隨後執行相同的切換命令,這會導致另一輪檢查狀態更改toggleButton。