1 /* 2 * Copyright (C) 2010 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.settings.bluetooth; 18 19 import android.bluetooth.BluetoothAdapter; 20 import android.content.BroadcastReceiver; 21 import android.content.Context; 22 import android.content.Intent; 23 import android.content.IntentFilter; 24 import android.provider.Settings; 25 import android.widget.CompoundButton; 26 import android.widget.Switch; 27 import android.widget.Toast; 28 29 import com.android.settings.R; 30 import com.android.settings.WirelessSettings; 31 32 /** 33 * BluetoothEnabler is a helper to manage the Bluetooth on/off checkbox 34 * preference. It turns on/off Bluetooth and ensures the summary of the 35 * preference reflects the current state. 36 */ 37 public final class BluetoothEnabler implements CompoundButton.OnCheckedChangeListener { 38 private final Context mContext; 39 private Switch mSwitch; 40 private boolean mValidListener; 41 private final LocalBluetoothAdapter mLocalAdapter; 42 private final IntentFilter mIntentFilter; 43 44 private final BroadcastReceiver mReceiver = new BroadcastReceiver() { 45 @Override 46 public void onReceive(Context context, Intent intent) { 47 // Broadcast receiver is always running on the UI thread here, 48 // so we don't need consider thread synchronization. 49 int state = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, BluetoothAdapter.ERROR); 50 handleStateChanged(state); 51 } 52 }; 53 54 public BluetoothEnabler(Context context, Switch switch_) { 55 mContext = context; 56 mSwitch = switch_; 57 mValidListener = false; 58 59 LocalBluetoothManager manager = LocalBluetoothManager.getInstance(context); 60 if (manager == null) { 61 // Bluetooth is not supported 62 mLocalAdapter = null; 63 mSwitch.setEnabled(false); 64 } else { 65 mLocalAdapter = manager.getBluetoothAdapter(); 66 } 67 mIntentFilter = new IntentFilter(BluetoothAdapter.ACTION_STATE_CHANGED); 68 } 69 70 public void resume() { 71 if (mLocalAdapter == null) { 72 mSwitch.setEnabled(false); 73 return; 74 } 75 76 // Bluetooth state is not sticky, so set it manually 77 handleStateChanged(mLocalAdapter.getBluetoothState()); 78 79 mContext.registerReceiver(mReceiver, mIntentFilter); 80 mSwitch.setOnCheckedChangeListener(this); 81 mValidListener = true; 82 } 83 84 public void pause() { 85 if (mLocalAdapter == null) { 86 return; 87 } 88 89 mContext.unregisterReceiver(mReceiver); 90 mSwitch.setOnCheckedChangeListener(null); 91 mValidListener = false; 92 } 93 94 public void setSwitch(Switch switch_) { 95 if (mSwitch == switch_) return; 96 mSwitch.setOnCheckedChangeListener(null); 97 mSwitch = switch_; 98 mSwitch.setOnCheckedChangeListener(mValidListener ? this : null); 99 100 int bluetoothState = BluetoothAdapter.STATE_OFF; 101 if (mLocalAdapter != null) bluetoothState = mLocalAdapter.getBluetoothState(); 102 boolean isOn = bluetoothState == BluetoothAdapter.STATE_ON; 103 boolean isOff = bluetoothState == BluetoothAdapter.STATE_OFF; 104 setChecked(isOn); 105 mSwitch.setEnabled(isOn || isOff); 106 } 107 108 public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { 109 // Show toast message if Bluetooth is not allowed in airplane mode 110 if (isChecked && 111 !WirelessSettings.isRadioAllowed(mContext, Settings.Global.RADIO_BLUETOOTH)) { 112 Toast.makeText(mContext, R.string.wifi_in_airplane_mode, Toast.LENGTH_SHORT).show(); 113 // Reset switch to off 114 buttonView.setChecked(false); 115 } 116 117 if (mLocalAdapter != null) { 118 mLocalAdapter.setBluetoothEnabled(isChecked); 119 } 120 mSwitch.setEnabled(false); 121 } 122 123 void handleStateChanged(int state) { 124 switch (state) { 125 case BluetoothAdapter.STATE_TURNING_ON: 126 mSwitch.setEnabled(false); 127 break; 128 case BluetoothAdapter.STATE_ON: 129 setChecked(true); 130 mSwitch.setEnabled(true); 131 break; 132 case BluetoothAdapter.STATE_TURNING_OFF: 133 mSwitch.setEnabled(false); 134 break; 135 case BluetoothAdapter.STATE_OFF: 136 setChecked(false); 137 mSwitch.setEnabled(true); 138 break; 139 default: 140 setChecked(false); 141 mSwitch.setEnabled(true); 142 } 143 } 144 145 private void setChecked(boolean isChecked) { 146 if (isChecked != mSwitch.isChecked()) { 147 // set listener to null, so onCheckedChanged won't be called 148 // if the checked status on Switch isn't changed by user click 149 if (mValidListener) { 150 mSwitch.setOnCheckedChangeListener(null); 151 } 152 mSwitch.setChecked(isChecked); 153 if (mValidListener) { 154 mSwitch.setOnCheckedChangeListener(this); 155 } 156 } 157 } 158 } 159