2 * Copyright (C) 2009 The Android Open Source Project
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 package com.android.settings.bluetooth;
19 import android.app.Activity;
20 import android.app.AlertDialog;
21 import android.bluetooth.BluetoothAdapter;
22 import android.bluetooth.BluetoothDevice;
23 import android.content.BroadcastReceiver;
24 import android.content.Context;
25 import android.content.DialogInterface;
26 import android.content.Intent;
27 import android.content.IntentFilter;
28 import android.os.Bundle;
29 import android.util.Log;
31 import com.android.settings.R;
32 import com.android.settingslib.bluetooth.BluetoothDiscoverableTimeoutReceiver;
33 import com.android.settingslib.bluetooth.LocalBluetoothAdapter;
34 import com.android.settingslib.bluetooth.LocalBluetoothManager;
37 * RequestPermissionActivity asks the user whether to enable discovery. This is
38 * usually started by an application wanted to start bluetooth and or discovery
40 public class RequestPermissionActivity extends Activity implements
41 DialogInterface.OnClickListener {
42 // Command line to test this
43 // adb shell am start -a android.bluetooth.adapter.action.REQUEST_ENABLE
44 // adb shell am start -a android.bluetooth.adapter.action.REQUEST_DISCOVERABLE
46 private static final String TAG = "RequestPermissionActivity";
48 private static final int MAX_DISCOVERABLE_TIMEOUT = 3600; // 1 hr
50 // Non-error return code: BT is starting or has started successfully. Used
51 // by this Activity and RequestPermissionHelperActivity
52 /* package */ static final int RESULT_BT_STARTING_OR_STARTED = -1000;
54 private static final int REQUEST_CODE_START_BT = 1;
56 private LocalBluetoothAdapter mLocalAdapter;
58 private int mTimeout = BluetoothDiscoverableEnabler.DEFAULT_DISCOVERABLE_TIMEOUT;
61 * True if bluetooth wasn't enabled and RequestPermissionHelperActivity was
62 * started to ask the user and start bt.
64 * If/when that activity returns successfully, display please wait msg then
65 * go away when bt has started and discovery mode has been enabled.
67 private boolean mNeededToEnableBluetooth;
69 // True if requesting BT to be turned on
70 // False if requesting BT to be turned on + discoverable mode
71 private boolean mEnableOnly;
73 private boolean mUserConfirmed;
75 private AlertDialog mDialog;
77 private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
80 public void onReceive(Context context, Intent intent) {
84 if (mNeededToEnableBluetooth
85 && BluetoothAdapter.ACTION_STATE_CHANGED.equals(intent.getAction())) {
86 int state = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, BluetoothDevice.ERROR);
87 if (state == BluetoothAdapter.STATE_ON) {
97 protected void onCreate(Bundle savedInstanceState) {
98 super.onCreate(savedInstanceState);
100 // Note: initializes mLocalAdapter and returns true on error
106 int btState = mLocalAdapter.getState();
109 case BluetoothAdapter.STATE_OFF:
110 case BluetoothAdapter.STATE_TURNING_OFF:
111 case BluetoothAdapter.STATE_TURNING_ON:
113 * Strictly speaking STATE_TURNING_ON belong with STATE_ON;
114 * however, BT may not be ready when the user clicks yes and we
115 * would fail to turn on discovery mode. By kicking this to the
116 * RequestPermissionHelperActivity, this class will handle that
117 * case via the broadcast receiver.
121 * Start the helper activity to:
122 * 1) ask the user about enabling bt AND discovery
123 * 2) enable BT upon confirmation
125 registerReceiver(mReceiver,
126 new IntentFilter(BluetoothAdapter.ACTION_STATE_CHANGED));
127 Intent intent = new Intent();
128 intent.setClass(this, RequestPermissionHelperActivity.class);
130 intent.setAction(RequestPermissionHelperActivity.ACTION_INTERNAL_REQUEST_BT_ON);
132 intent.setAction(RequestPermissionHelperActivity.
133 ACTION_INTERNAL_REQUEST_BT_ON_AND_DISCOVERABLE);
134 intent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, mTimeout);
136 startActivityForResult(intent, REQUEST_CODE_START_BT);
137 mNeededToEnableBluetooth = true;
139 case BluetoothAdapter.STATE_ON:
141 // Nothing to do. Already enabled.
144 // Ask the user about enabling discovery mode
149 Log.e(TAG, "Unknown adapter state: " + btState);
153 private void createDialog() {
154 AlertDialog.Builder builder = new AlertDialog.Builder(this);
156 if (mNeededToEnableBluetooth) {
157 // RequestPermissionHelperActivity has gotten confirmation from user
159 builder.setMessage(getString(R.string.bluetooth_turning_on));
160 builder.setCancelable(false);
162 // Ask the user whether to turn on discovery mode or not
163 // For lasting discoverable mode there is a different message
164 if (mTimeout == BluetoothDiscoverableEnabler.DISCOVERABLE_TIMEOUT_NEVER) {
166 getString(R.string.bluetooth_ask_lasting_discovery));
169 getString(R.string.bluetooth_ask_discovery, mTimeout));
171 builder.setPositiveButton(getString(R.string.allow), this);
172 builder.setNegativeButton(getString(R.string.deny), this);
175 mDialog = builder.create();
178 if (getResources().getBoolean(R.bool.auto_confirm_bluetooth_activation_dialog) == true) {
179 // dismiss dialog immediately if settings say so
180 onClick(null, DialogInterface.BUTTON_POSITIVE);
185 protected void onActivityResult(int requestCode, int resultCode, Intent data) {
186 if (requestCode != REQUEST_CODE_START_BT) {
187 Log.e(TAG, "Unexpected onActivityResult " + requestCode + ' ' + resultCode);
188 setResult(RESULT_CANCELED);
192 if (resultCode != RESULT_BT_STARTING_OR_STARTED) {
193 setResult(resultCode);
198 // Back from RequestPermissionHelperActivity. User confirmed to enable
199 // BT and discoverable mode.
200 mUserConfirmed = true;
202 if (mLocalAdapter.getBluetoothState() == BluetoothAdapter.STATE_ON) {
205 // If BT is not up yet, show "Turning on Bluetooth..."
210 public void onClick(DialogInterface dialog, int which) {
212 case DialogInterface.BUTTON_POSITIVE:
216 case DialogInterface.BUTTON_NEGATIVE:
217 setResult(RESULT_CANCELED);
223 private void proceedAndFinish() {
228 returnCode = RESULT_OK;
229 } else if (mLocalAdapter.setScanMode(
230 BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE, mTimeout)) {
231 // If already in discoverable mode, this will extend the timeout.
232 long endTime = System.currentTimeMillis() + (long) mTimeout * 1000;
233 LocalBluetoothPreferences.persistDiscoverableEndTimestamp(
236 BluetoothDiscoverableTimeoutReceiver.setDiscoverableAlarm(this, endTime);
238 returnCode = mTimeout;
239 // Activity.RESULT_FIRST_USER should be 1
240 if (returnCode < RESULT_FIRST_USER) {
241 returnCode = RESULT_FIRST_USER;
244 returnCode = RESULT_CANCELED;
247 if (mDialog != null) {
251 setResult(returnCode);
256 * Parse the received Intent and initialize mLocalBluetoothAdapter.
257 * @return true if an error occurred; false otherwise
259 private boolean parseIntent() {
260 Intent intent = getIntent();
261 if (intent != null && intent.getAction().equals(BluetoothAdapter.ACTION_REQUEST_ENABLE)) {
263 } else if (intent != null
264 && intent.getAction().equals(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE)) {
265 mTimeout = intent.getIntExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION,
266 BluetoothDiscoverableEnabler.DEFAULT_DISCOVERABLE_TIMEOUT);
268 Log.d(TAG, "Setting Bluetooth Discoverable Timeout = " + mTimeout);
270 if (mTimeout < 1 || mTimeout > MAX_DISCOVERABLE_TIMEOUT) {
271 mTimeout = BluetoothDiscoverableEnabler.DEFAULT_DISCOVERABLE_TIMEOUT;
274 Log.e(TAG, "Error: this activity may be started only with intent "
275 + BluetoothAdapter.ACTION_REQUEST_ENABLE + " or "
276 + BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
277 setResult(RESULT_CANCELED);
281 LocalBluetoothManager manager = Utils.getLocalBtManager(this);
282 if (manager == null) {
283 Log.e(TAG, "Error: there's a problem starting Bluetooth");
284 setResult(RESULT_CANCELED);
287 mLocalAdapter = manager.getBluetoothAdapter();
293 protected void onDestroy() {
295 if (mNeededToEnableBluetooth) {
296 unregisterReceiver(mReceiver);
301 public void onBackPressed() {
302 setResult(RESULT_CANCELED);
303 super.onBackPressed();