Upgrade Bluetooth pairing dialogs for ICS.

* Change Bluetooth pairing dialogs to match ICS wireframes.
* Default to numeric soft keyboard for PIN entry, and add checkbox
  to allow user to switch to alphanumeric keyboard if necessary.
* Move all Bluetooth advanced settings into action bar menu.
* Toggle visibility by touching "My device" entry in devices list.

Change-Id: Ic2377eb4364f41d215181cb1e3933997c9db9106
This commit is contained in:
Jake Hamby
2011-07-12 11:05:46 -07:00
parent aa5b531b0b
commit ca9812a852
16 changed files with 621 additions and 440 deletions

View File

@@ -227,21 +227,6 @@
android:resource="@id/bluetooth_settings" />
</activity>
<activity android:name="Settings$AdvancedBluetoothSettingsActivity"
android:label="@string/bluetooth_advanced_settings_label"
android:targetActivity="Settings">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<action android:name="android.settings.ADVANCED_BLUETOOTH_SETTINGS" />
<category android:name="android.intent.category.VOICE_LAUNCH" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
<meta-data android:name="com.android.settings.FRAGMENT_CLASS"
android:value="com.android.settings.bluetooth.AdvancedBluetoothSettings" />
<meta-data android:name="com.android.settings.TOP_LEVEL_HEADER_ID"
android:resource="@id/bluetooth_settings" />
</activity>
<activity android:name=".bluetooth.DevicePickerActivity"
android:theme="@android:style/Theme.Holo.DialogWhenLarge"
android:label="@string/device_picker"

View File

@@ -0,0 +1,44 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
/*
** Copyright 2011, The Android Open Source Project
**
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
** You may obtain a copy of the License at
**
** http://www.apache.org/licenses/LICENSE-2.0
**
** Unless required by applicable law or agreed to in writing, software
** distributed under the License is distributed on an "AS IS" BASIS,
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
** See the License for the specific language governing permissions and
** limitations under the License.
*/
-->
<ScrollView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_height="match_parent"
android:layout_width="match_parent">
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_height="match_parent"
android:layout_width="match_parent"
android:orientation="vertical">
<TextView
android:id="@+id/message"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="20dip"
android:layout_marginRight="20dip"
android:layout_marginTop="20dip"
android:layout_marginBottom="20dip"
android:gravity="center_vertical"
android:textAppearance="?android:attr/textAppearanceMedium" />
</LinearLayout>
</ScrollView>

View File

@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
/*
** Copyright 2008, The Android Open Source Project
** Copyright 2011, The Android Open Source Project
**
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
@@ -30,23 +30,53 @@
<TextView
android:id="@+id/message"
android:layout_width="match_parent"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="20dip"
android:layout_marginRight="20dip"
android:gravity="center_horizontal"
android:layout_marginTop="20dip"
android:layout_marginBottom="20dip"
android:gravity="center_vertical"
android:textAppearance="?android:attr/textAppearanceMedium" />
<EditText
android:id="@+id/text"
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:layout_marginTop="20dip"
android:layout_marginLeft="20dip"
android:layout_marginRight="20dip"
android:inputType="textPassword"
android:singleLine="true" />
<TextView
android:id="@+id/pin_values_hint"
android:text="@string/bluetooth_pin_values_hint"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="20dip"
android:layout_marginRight="20dip"
android:gravity="center_vertical"
android:textAppearance="?android:attr/textAppearanceSmall" />
<CheckBox
android:id="@+id/alphanumeric_pin"
android:text="@string/bluetooth_enable_alphanumeric_pin"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="20dip"
android:layout_marginRight="20dip"
android:gravity="center"
android:textAppearance="?android:attr/textAppearanceSmall" />
<TextView
android:id="@+id/message_below_pin"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="20dip"
android:layout_marginRight="20dip"
android:gravity="center_vertical"
android:textAppearance="?android:attr/textAppearanceMedium" />
</LinearLayout>
</ScrollView>

View File

@@ -334,14 +334,6 @@
<item>Never</item>
</string-array>
<!-- Values for visibility_duration_entries matching constants in BluetoothSettings. Do not translate. -->
<string-array name="bluetooth_visibility_timeout_values" translatable="false">
<item>twomin</item>
<item>fivemin</item>
<item>onehour</item>
<item>never</item>
</string-array>
<!-- Match this with drawable.wifi_signal. --> <skip />
<!-- Wi-Fi settings. The signal strength a Wi-Fi network has. -->
<string-array name="wifi_signal">

View File

@@ -191,14 +191,18 @@
<string name="bluetooth">Bluetooth</string>
<!-- Bluetooth settings screen, check box label when the Bluetooth device can be seen by others -->
<string name="bluetooth_visibility">Discoverable</string>
<!-- Bluetooth settings screen, summary after selecting Discoverable check box -->
<string name="bluetooth_is_discoverable">Discoverable for <xliff:g id="discoverable_time_period">%1$s</xliff:g> seconds\u2026</string>
<!-- Bluetooth settings screen, Discoverable checkbox summary text when Discoverable duration is set to "forever" -->
<string name="bluetooth_is_discoverable_always">Discoverable</string>
<!-- Bluetooth settings screen, summary after selecting Discoverable check box [CHAR LIMIT=50] -->
<string name="bluetooth_is_discoverable">Visible to all nearby Bluetooth devices (<xliff:g id="discoverable_time_period">%1$s</xliff:g>)</string>
<!-- Bluetooth settings screen, summary when Discoverable duration is set to "forever" [CHAR LIMIT=50] -->
<string name="bluetooth_is_discoverable_always">Visible to all nearby Bluetooth devices</string>
<!-- Bluetooth settings screen, summary text when not discoverable and no paired devices [CHAR LIMIT=50] -->
<string name="bluetooth_not_visible_to_other_devices">Not visible to other Bluetooth devices</string>
<!-- Bluetooth settings screen, summary text when not discoverable with paired devices [CHAR LIMIT=50] -->
<string name="bluetooth_only_visible_to_paired_devices">Only visible to paired devices</string>
<!-- Bluetooth settings screen, Discoverable checkbox summary text -->
<string name="bluetooth_not_discoverable">Make device discoverable</string>
<!-- Bluetooth settings screen, option name to pick discoverability timeout duration (a list dialog comes up) -->
<string name="bluetooth_visibility_timeout">Discoverable timeout</string>
<string name="bluetooth_visibility_timeout">Visibility timeout</string>
<!-- Bluetooth settings screen, Discoverable timout list dialog summary text -->
<string name="bluetooth_visibility_timeout_summary">Set how long device will be discoverable</string>
<!-- Bluetooth settings screen, check box label whether or not to allow
@@ -216,8 +220,16 @@
<string name="bluetooth_name_not_set">No name set, using account name</string>
<!-- Bluetooth settings screen, menu item to scan for nearby bluetooth devices -->
<string name="bluetooth_scan_for_devices">Scan for devices</string>
<!-- Bluetooth settings. Message for disconnecting from a bluetooth device -->
<string name="bluetooth_disconnect_blank"><xliff:g id="device_name">%1$s</xliff:g> will be disconnected.</string>
<!-- Bluetooth settings screen, menu item to change this device's Bluetooth name. [CHAR LIMIT=30] -->
<string name="bluetooth_rename_device" product="tablet">Rename tablet</string>
<!-- Bluetooth settings screen, menu item to change this device's Bluetooth name. [CHAR LIMIT=30] -->
<string name="bluetooth_rename_device" product="default">Rename phone</string>
<!-- Bluetooth settings screen, confirmation button for rename device dialog. [CHAR LIMIT=20] -->
<string name="bluetooth_rename_button">Rename</string>
<!-- Bluetooth settings. Dialog title to confirm disconnecting from all profiles of a device. [CHAR LIMIT=30] -->
<string name="bluetooth_disconnect_title">Disconnect?</string>
<!-- Bluetooth settings. Message for disconnecting from all profiles of a bluetooth device. [CHAR LIMIT=NONE] -->
<string name="bluetooth_disconnect_all_profiles">This will end your connection with:&lt;br>&lt;b><xliff:g id="device_name">%1$s</xliff:g>&lt;/b></string>
<!-- Bluetooth settings. Message when connected to a device -->
<string name="bluetooth_connected">Connected</string>
<!-- Bluetooth settings. Message when a device is disconnected -->
@@ -234,8 +246,8 @@
<string name="bluetooth_pairing">Pairing\u2026</string>
<!--Bluetooth settings screen, summary text under individual Bluetooth devices when paired with one -->
<string name="bluetooth_paired">Paired but not connected</string>
<!--Bluetooth settings screen, summary text under individual Bluetooth devices that are hands free or a headset -->
<string name="bluetooth_device">handsfree/headset</string>
<!--Bluetooth settings screen, summary text for Bluetooth device with no name -->
<string name="bluetooth_device">Unnamed Bluetooth device</string>
<!--Bluetooth settings screen, text that appears in heading bar when scanning for devices -->
<string name="progress_scanning">Searching</string>
<!--Bluetooth settings screen, text that appears in heading bar when scanning for devices is finished, indicating that user can tap on a device to pair with it [CHAR LIMIT=20]-->
@@ -248,10 +260,8 @@
<string name="bluetooth_notif_title">Pairing request</string>
<!-- Notification message when a Bluetooth device wants to pair with us -->
<string name="bluetooth_notif_message">Select to pair with <xliff:g id="device_name">%1$s</xliff:g></string>
<!-- Bluetooth settings screen, title of the item to show the list of received files [CHAR LIMIT=30] -->
<string name="bluetooth_show_received_files_title">Show received files</string>
<!-- Bluetooth settings screen, summary of the item to show the list of received files [CHAR LIMIT=50] -->
<string name="bluetooth_show_received_files_summary">Show the list of files received via Bluetooth</string>
<!-- Bluetooth settings screen, menu to show the list of received files [CHAR LIMIT=30] -->
<string name="bluetooth_show_received_files">Show received files</string>
<!-- Strings for BluetoothDevicePicker -->
<string name="device_picker">Bluetooth device picker</string>
@@ -913,24 +923,45 @@
<!--Wireless controls screen, settings summary for the item tot ake you to the bluetooth settings screen -->
<string name="bluetooth_settings_summary">Manage connections, set device name &amp; discoverability</string>
<!-- Title for the dialog to enter PIN. -->
<!-- ======================================================================================= -->
<!-- Note: The opening brackets of HTML style tags are escaped (e.g. "<b>" is "&lt;b>") in -->
<!-- the following resources to enable formatting followed by HTML styling, as described -->
<!-- here: http://developer.android.com/guide/topics/resources/string-resource.html -->
<!-- ======================================================================================= -->
<!-- Title for the dialog to enter PIN. [CHAR LIMIT=40] -->
<string name="bluetooth_pairing_request">Bluetooth pairing request</string>
<!-- Message when bluetooth dialog for pin entry is showing -->
<string name="bluetooth_enter_pin_msg">\nEnter PIN to pair with \u0022<xliff:g id="device_name">%1$s</xliff:g>\u0022. (Try 0000 or 1234.) You may need to enter the same PIN on the Bluetooth device.</string>
<!-- Message when bluetooth dialog for passkey entry is showing -->
<string name="bluetooth_enter_passkey_msg">\nEnter passkey to pair with \u0022<xliff:g id="device_name">%1$s</xliff:g>\u0022.</string>
<!-- Message when bluetooth dialog for confirmation of passkey is showing -->
<string name="bluetooth_confirm_passkey_msg">To pair with \u0022<xliff:g id="device_name">%1$s</xliff:g>\u0022, confirm that it is showing the passkey: <xliff:g id="passkey">%2$s</xliff:g>.</string>
<!-- Message when bluetooth dialog for pin entry is showing. [CHAR LIMIT=NONE] -->
<string name="bluetooth_enter_pin_msg">To pair with:&lt;br>&lt;b><xliff:g id="device_name">%1$s</xliff:g>&lt;/b>&lt;br>&lt;br>Enter the device\'s required PIN:</string>
<!-- Message when bluetooth dialog for passkey entry is showing. [CHAR LIMIT=NONE] -->
<string name="bluetooth_enter_passkey_msg">To pair with:&lt;br>&lt;b><xliff:g id="device_name">%1$s</xliff:g>&lt;/b>&lt;br>&lt;br>Enter the device\'s required passkey:</string>
<!-- Checkbox label for alphanumeric PIN entry (default is numeric PIN). [CHAR LIMIT=50] -->
<string name="bluetooth_enable_alphanumeric_pin">PIN contains letters or symbols</string>
<!-- Bluetooth PIN hint text (below the text entry box). [CHAR LIMIT=30] -->
<string name="bluetooth_pin_values_hint">Usually 0000 or 1234</string>
<!-- Pairing dialog text to remind user to enter the PIN on the other device. [CHAR LIMIT=NONE] -->
<string name="bluetooth_enter_pin_other_device">You may also need to enter this PIN on the other device.</string>
<!-- Pairing dialog text to remind user to enter the passkey on the other device. [CHAR LIMIT=NONE] -->
<string name="bluetooth_enter_passkey_other_device">You may also need to enter this passkey on the other device.</string>
<!-- Message for confirmation of passkey to complete pairing. [CHAR LIMIT=NONE] -->
<string name="bluetooth_confirm_passkey_msg">To pair with:&lt;br>&lt;b><xliff:g id="device_name">%1$s</xliff:g>&lt;/b>&lt;br>&lt;br>Make sure it is showing this passkey:&lt;br>&lt;b><xliff:g id="passkey">%2$s</xliff:g>&lt;/b></string>
<!-- Message when bluetooth incoming pairing request for (2.1 devices) dialog is showing -->
<string name="bluetooth_incoming_pairing_msg"><xliff:g id="device_name">%1$s</xliff:g>\nwants to pair.</string>
<string name="bluetooth_incoming_pairing_msg">From:&lt;br>&lt;b><xliff:g id="device_name">%1$s</xliff:g>&lt;/b>&lt;br>&lt;br>Pair with this device?</string>
<!-- Message when bluetooth dialog when passkey or pin needs to be displayed. -->
<string name="bluetooth_display_passkey_pin_msg">Enter \u0022<xliff:g id="passkey">%2$s</xliff:g>\u0022 on \u0022<xliff:g id="device_name">%1$s</xliff:g>\u0022 to pair followed by return or enter. </string>
<!-- Button text for accepting an incoming pairing request -->
<string name="bluetooth_display_passkey_pin_msg">To pair with:&lt;br>&lt;b><xliff:g id="device_name">%1$s</xliff:g>&lt;/b>&lt;br>&lt;br>Type on it:&lt;br>&lt;b><xliff:g id="passkey">%2$s</xliff:g>&lt;/b>, then Return or Enter.</string>
<!-- Button text for accepting an incoming pairing request. [CHAR LIMIT=20] -->
<string name="bluetooth_pairing_accept">Pair</string>
<!-- Button text for declining an incoming pairing request -->
<string name="bluetooth_pairing_decline">Don\u0027t Pair</string>
<!-- Generic string for remote Bluetooth device -->
<string name="bluetooth_remote_device">bluetooth device</string>
<!-- Button text for declining an incoming pairing request. [CHAR LIMIT=20] -->
<string name="bluetooth_pairing_decline">Cancel</string>
<!-- Title for BT error dialogs. -->
<string name="bluetooth_error_title">Attention</string>
@@ -975,8 +1006,6 @@
<string name="bluetooth_menu_advanced">Advanced</string>
<!-- Bluetooth settings. Title of the advanced bluetooth settings screen [CHAR LIMIT=30]-->
<string name="bluetooth_advanced_titlebar">Advanced Bluetooth</string>
<!-- Bluetooth Advanced settings. Used as a label under the shortcut icon that goes to Bluetooth advanced settings. [CHAR LIMIT=20]-->
<string name="bluetooth_advanced_settings_label">Advanced Bluetooth</string>
<!-- Bluetooth settings. Text displayed when Bluetooth is off and device list is empty [CHAR LIMIT=50]-->
<string name="bluetooth_empty_list_bluetooth_off">To see devices, turn Bluetooth on.</string>

View File

@@ -1,47 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2008 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
android:title="@string/bluetooth_advanced_titlebar">
<com.android.settings.bluetooth.BluetoothNamePreference
android:key="bt_name"
android:title="@string/bluetooth_device_name"
android:summary="@string/bluetooth_name_not_set"
android:dialogTitle="@string/bluetooth_device_name"
android:persistent="false"
android:singleLine="true" />
<CheckBoxPreference
android:key="bt_discoverable"
android:title="@string/bluetooth_visibility"
android:summaryOn="@string/bluetooth_is_discoverable"
android:summaryOff="@string/bluetooth_not_discoverable"
android:persistent="false" />
<ListPreference
android:key="bt_discoverable_timeout"
android:title="@string/bluetooth_visibility_timeout"
android:summary="@string/bluetooth_visibility_timeout_summary"
android:entries="@array/bluetooth_visibility_timeout_entries"
android:entryValues="@array/bluetooth_visibility_timeout_values" />
<Preference
android:key="bt_show_received_files"
android:title="@string/bluetooth_show_received_files_title"
android:summary="@string/bluetooth_show_received_files_summary" />
</PreferenceScreen>

View File

@@ -584,6 +584,5 @@ public class Settings extends PreferenceActivity implements ButtonBarHandler {
public static class DeviceAdminSettingsActivity extends Settings { /* empty */ }
public static class DataUsageSummaryActivity extends Settings { /* empty */ }
public static class AdvancedWifiSettingsActivity extends Settings { /* empty */ }
public static class AdvancedBluetoothSettingsActivity extends Settings { /* empty */ }
public static class TextToSpeechSettingsActivity extends Settings { /* empty */ }
}

View File

@@ -1,96 +0,0 @@
/*
* Copyright (C) 2011 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.settings.bluetooth;
import android.content.Intent;
import android.os.Bundle;
import android.preference.CheckBoxPreference;
import android.preference.ListPreference;
import android.preference.Preference;
import android.preference.PreferenceScreen;
import com.android.settings.R;
import com.android.settings.SettingsPreferenceFragment;
public class AdvancedBluetoothSettings extends SettingsPreferenceFragment
implements Preference.OnPreferenceChangeListener {
private static final String KEY_BT_DISCOVERABLE = "bt_discoverable";
private static final String KEY_BT_DISCOVERABLE_TIMEOUT = "bt_discoverable_timeout";
private static final String KEY_BT_NAME = "bt_name";
private static final String KEY_BT_SHOW_RECEIVED = "bt_show_received_files";
/* Private intent to show the list of received files */
private static final String BTOPP_ACTION_OPEN_RECEIVED_FILES =
"android.btopp.intent.action.OPEN_RECEIVED_FILES";
private BluetoothDiscoverableEnabler mDiscoverableEnabler;
private BluetoothNamePreference mNamePreference;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.bluetooth_advanced_settings);
LocalBluetoothManager localManager = LocalBluetoothManager.getInstance(getActivity());
if (localManager != null) {
LocalBluetoothAdapter localAdapter = localManager.getBluetoothAdapter();
mDiscoverableEnabler = new BluetoothDiscoverableEnabler(getActivity(),
localAdapter,
(CheckBoxPreference) findPreference(KEY_BT_DISCOVERABLE),
(ListPreference) findPreference(KEY_BT_DISCOVERABLE_TIMEOUT));
}
mNamePreference = (BluetoothNamePreference) findPreference(KEY_BT_NAME);
}
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
}
@Override
public void onResume() {
super.onResume();
mDiscoverableEnabler.resume();
mNamePreference.resume();
}
@Override
public void onPause() {
super.onPause();
mNamePreference.pause();
mDiscoverableEnabler.pause();
}
@Override
public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen, Preference preference) {
if (KEY_BT_SHOW_RECEIVED.equals(preference.getKey())) {
Intent intent = new Intent(BTOPP_ACTION_OPEN_RECEIVED_FILES);
getActivity().sendBroadcast(intent);
return true;
}
return super.onPreferenceTreeClick(preferenceScreen, preference);
}
@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
return true;
}
}

View File

@@ -24,6 +24,7 @@ import android.content.Context;
import android.content.DialogInterface;
import android.graphics.drawable.Drawable;
import android.preference.Preference;
import android.text.Html;
import android.text.TextUtils;
import android.util.Log;
import android.util.TypedValue;
@@ -200,7 +201,8 @@ public final class BluetoothDevicePreference extends Preference implements
if (TextUtils.isEmpty(name)) {
name = context.getString(R.string.bluetooth_device);
}
String message = context.getString(R.string.bluetooth_disconnect_blank, name);
String message = context.getString(R.string.bluetooth_disconnect_all_profiles, name);
String title = context.getString(R.string.bluetooth_disconnect_title);
DialogInterface.OnClickListener disconnectListener = new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
@@ -209,7 +211,7 @@ public final class BluetoothDevicePreference extends Preference implements
};
mDisconnectDialog = Utils.showDisconnectDialog(context,
mDisconnectDialog, disconnectListener, name, message);
mDisconnectDialog, disconnectListener, title, Html.fromHtml(message));
}
private void pair() {
@@ -221,7 +223,6 @@ public final class BluetoothDevicePreference extends Preference implements
private int getConnectionSummary() {
final CachedBluetoothDevice cachedDevice = mCachedDevice;
final BluetoothDevice device = cachedDevice.getDevice();
// if any profiles are connected or busy, return that status
for (LocalBluetoothProfile profile : cachedDevice.getProfiles()) {

View File

@@ -21,11 +21,11 @@ import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.os.Handler;
import android.os.SystemProperties;
import android.preference.CheckBoxPreference;
import android.preference.ListPreference;
import android.preference.Preference;
import android.text.format.DateUtils;
import com.android.settings.R;
@@ -34,7 +34,7 @@ import com.android.settings.R;
* checkbox. It sets/unsets discoverability and keeps track of how much time
* until the the discoverability is automatically turned off.
*/
final class BluetoothDiscoverableEnabler implements Preference.OnPreferenceChangeListener {
final class BluetoothDiscoverableEnabler implements Preference.OnPreferenceClickListener {
private static final String SYSTEM_PROPERTY_DISCOVERABLE_TIMEOUT =
"debug.bt.discoverable_time";
@@ -44,6 +44,10 @@ final class BluetoothDiscoverableEnabler implements Preference.OnPreferenceChang
private static final int DISCOVERABLE_TIMEOUT_ONE_HOUR = 3600;
static final int DISCOVERABLE_TIMEOUT_NEVER = 0;
// Bluetooth advanced settings screen was replaced with action bar items.
// Use the same preference key for discoverable timeout as the old ListPreference.
private static final String KEY_DISCOVERABLE_TIMEOUT = "bt_discoverable_timeout";
private static final String VALUE_DISCOVERABLE_TIMEOUT_TWO_MINUTES = "twomin";
private static final String VALUE_DISCOVERABLE_TIMEOUT_FIVE_MINUTES = "fivemin";
private static final String VALUE_DISCOVERABLE_TIMEOUT_ONE_HOUR = "onehour";
@@ -53,11 +57,17 @@ final class BluetoothDiscoverableEnabler implements Preference.OnPreferenceChang
private final Context mContext;
private final Handler mUiHandler;
private final CheckBoxPreference mCheckBoxPreference;
private final ListPreference mTimeoutListPreference;
private final Preference mDiscoveryPreference;
private final LocalBluetoothAdapter mLocalAdapter;
private final SharedPreferences mSharedPreferences;
private boolean mDiscoverable;
private int mNumberOfPairedDevices;
private int mTimeoutSecs = -1;
private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
@@ -78,21 +88,13 @@ final class BluetoothDiscoverableEnabler implements Preference.OnPreferenceChang
};
BluetoothDiscoverableEnabler(Context context, LocalBluetoothAdapter adapter,
CheckBoxPreference checkBoxPreference, ListPreference timeoutListPreference) {
Preference discoveryPreference) {
mContext = context;
mUiHandler = new Handler();
mCheckBoxPreference = checkBoxPreference;
mTimeoutListPreference = timeoutListPreference;
checkBoxPreference.setPersistent(false);
// we actually want to persist this since can't infer from BT device state
mTimeoutListPreference.setPersistent(true);
mLocalAdapter = adapter;
if (adapter == null) {
// Bluetooth not supported
checkBoxPreference.setEnabled(false);
}
mDiscoveryPreference = discoveryPreference;
mSharedPreferences = discoveryPreference.getSharedPreferences();
discoveryPreference.setPersistent(false);
}
public void resume() {
@@ -102,8 +104,7 @@ final class BluetoothDiscoverableEnabler implements Preference.OnPreferenceChang
IntentFilter filter = new IntentFilter(BluetoothAdapter.ACTION_SCAN_MODE_CHANGED);
mContext.registerReceiver(mReceiver, filter);
mCheckBoxPreference.setOnPreferenceChangeListener(this);
mTimeoutListPreference.setOnPreferenceChangeListener(this);
mDiscoveryPreference.setOnPreferenceClickListener(this);
handleModeChanged(mLocalAdapter.getScanMode());
}
@@ -113,20 +114,14 @@ final class BluetoothDiscoverableEnabler implements Preference.OnPreferenceChang
}
mUiHandler.removeCallbacks(mUpdateCountdownSummaryRunnable);
mCheckBoxPreference.setOnPreferenceChangeListener(null);
mTimeoutListPreference.setOnPreferenceChangeListener(null);
mContext.unregisterReceiver(mReceiver);
mDiscoveryPreference.setOnPreferenceClickListener(null);
}
public boolean onPreferenceChange(Preference preference, Object value) {
if (preference == mCheckBoxPreference) {
// Turn on/off BT discoverability
setEnabled((Boolean) value);
} else if (preference == mTimeoutListPreference) {
mTimeoutListPreference.setValue((String) value);
setEnabled(true);
}
public boolean onPreferenceClick(Preference preference) {
// toggle discoverability
mDiscoverable = !mDiscoverable;
setEnabled(mDiscoverable);
return true;
}
@@ -138,9 +133,8 @@ final class BluetoothDiscoverableEnabler implements Preference.OnPreferenceChang
long endTimestamp = System.currentTimeMillis() + timeout * 1000L;
LocalBluetoothPreferences.persistDiscoverableEndTimestamp(mContext, endTimestamp);
updateCountdownSummary();
mLocalAdapter.setScanMode(BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE, timeout);
updateCountdownSummary();
} else {
mLocalAdapter.setScanMode(BluetoothAdapter.SCAN_MODE_CONNECTABLE);
}
@@ -148,22 +142,51 @@ final class BluetoothDiscoverableEnabler implements Preference.OnPreferenceChang
private void updateTimerDisplay(int timeout) {
if (getDiscoverableTimeout() == DISCOVERABLE_TIMEOUT_NEVER) {
mCheckBoxPreference.setSummaryOn(
mContext.getString(R.string.bluetooth_is_discoverable_always));
mDiscoveryPreference.setSummary(R.string.bluetooth_is_discoverable_always);
} else {
mCheckBoxPreference.setSummaryOn(
mContext.getString(R.string.bluetooth_is_discoverable, timeout));
String textTimeout = DateUtils.formatElapsedTime(timeout);
mDiscoveryPreference.setSummary(mContext.getString(R.string.bluetooth_is_discoverable,
textTimeout));
}
}
void setDiscoverableTimeout(int index) {
String timeoutValue;
switch (index) {
case 0:
default:
mTimeoutSecs = DISCOVERABLE_TIMEOUT_TWO_MINUTES;
timeoutValue = VALUE_DISCOVERABLE_TIMEOUT_TWO_MINUTES;
break;
case 1:
mTimeoutSecs = DISCOVERABLE_TIMEOUT_FIVE_MINUTES;
timeoutValue = VALUE_DISCOVERABLE_TIMEOUT_FIVE_MINUTES;
break;
case 2:
mTimeoutSecs = DISCOVERABLE_TIMEOUT_ONE_HOUR;
timeoutValue = VALUE_DISCOVERABLE_TIMEOUT_ONE_HOUR;
break;
case 3:
mTimeoutSecs = DISCOVERABLE_TIMEOUT_NEVER;
timeoutValue = VALUE_DISCOVERABLE_TIMEOUT_NEVER;
break;
}
mSharedPreferences.edit().putString(KEY_DISCOVERABLE_TIMEOUT, timeoutValue).apply();
setEnabled(true); // enable discovery and reset timer
}
private int getDiscoverableTimeout() {
if (mTimeoutSecs != -1) {
return mTimeoutSecs;
}
int timeout = SystemProperties.getInt(SYSTEM_PROPERTY_DISCOVERABLE_TIMEOUT, -1);
if (timeout < 0) {
String timeoutValue = mTimeoutListPreference.getValue();
if (timeoutValue == null) {
mTimeoutListPreference.setValue(VALUE_DISCOVERABLE_TIMEOUT_TWO_MINUTES);
return DISCOVERABLE_TIMEOUT_TWO_MINUTES;
}
String timeoutValue = mSharedPreferences.getString(KEY_DISCOVERABLE_TIMEOUT,
VALUE_DISCOVERABLE_TIMEOUT_TWO_MINUTES);
if (timeoutValue.equals(VALUE_DISCOVERABLE_TIMEOUT_NEVER)) {
timeout = DISCOVERABLE_TIMEOUT_NEVER;
@@ -175,16 +198,48 @@ final class BluetoothDiscoverableEnabler implements Preference.OnPreferenceChang
timeout = DISCOVERABLE_TIMEOUT_TWO_MINUTES;
}
}
mTimeoutSecs = timeout;
return timeout;
}
private void handleModeChanged(int mode) {
int getDiscoverableTimeoutIndex() {
int timeout = getDiscoverableTimeout();
switch (timeout) {
case DISCOVERABLE_TIMEOUT_TWO_MINUTES:
default:
return 0;
case DISCOVERABLE_TIMEOUT_FIVE_MINUTES:
return 1;
case DISCOVERABLE_TIMEOUT_ONE_HOUR:
return 2;
case DISCOVERABLE_TIMEOUT_NEVER:
return 3;
}
}
void setNumberOfPairedDevices(int pairedDevices) {
mNumberOfPairedDevices = pairedDevices;
setSummaryNotDiscoverable();
}
void handleModeChanged(int mode) {
if (mode == BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE) {
mCheckBoxPreference.setChecked(true);
mDiscoverable = true;
updateCountdownSummary();
} else {
mCheckBoxPreference.setChecked(false);
mDiscoverable = false;
setSummaryNotDiscoverable();
}
}
private void setSummaryNotDiscoverable() {
if (mNumberOfPairedDevices != 0) {
mDiscoveryPreference.setSummary(R.string.bluetooth_only_visible_to_paired_devices);
} else {
mDiscoveryPreference.setSummary(R.string.bluetooth_not_visible_to_other_devices);
}
}
@@ -199,7 +254,7 @@ final class BluetoothDiscoverableEnabler implements Preference.OnPreferenceChang
if (currentTimestamp > endTimestamp) {
// We're still in discoverable mode, but maybe there isn't a timeout.
mCheckBoxPreference.setSummaryOn(null);
updateTimerDisplay(0);
return;
}

View File

@@ -0,0 +1,161 @@
/*
* Copyright (C) 2011 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.settings.bluetooth;
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.DialogFragment;
import android.bluetooth.BluetoothAdapter;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.text.Editable;
import android.text.InputFilter;
import android.text.TextWatcher;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import com.android.settings.R;
/**
* Dialog fragment for renaming the local Bluetooth device.
*/
final class BluetoothNameDialogFragment extends DialogFragment implements TextWatcher {
private static final int BLUETOOTH_NAME_MAX_LENGTH_BYTES = 248;
private AlertDialog mAlertDialog;
private Button mOkButton;
// accessed from inner class (not private to avoid thunks)
static final String TAG = "BluetoothNameDialogFragment";
final LocalBluetoothAdapter mLocalAdapter;
EditText mDeviceNameView;
// This flag is set when the name is updated by code, to distinguish from user changes
private boolean mDeviceNameUpdated;
private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (action.equals(BluetoothAdapter.ACTION_LOCAL_NAME_CHANGED)) {
updateDeviceName();
} else if (action.equals(BluetoothAdapter.ACTION_STATE_CHANGED) &&
(intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, BluetoothAdapter.ERROR) ==
BluetoothAdapter.STATE_ON)) {
updateDeviceName();
}
}
};
public BluetoothNameDialogFragment(LocalBluetoothAdapter adapter) {
mLocalAdapter = adapter;
}
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
mAlertDialog = new AlertDialog.Builder(getActivity())
.setIcon(android.R.drawable.ic_dialog_info)
.setTitle(R.string.bluetooth_rename_device)
.setView(createDialogView())
.setPositiveButton(R.string.bluetooth_rename_button,
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
if (mLocalAdapter != null) {
String deviceName = mDeviceNameView.getText().toString();
Log.d(TAG, "Setting device name to " + deviceName);
mLocalAdapter.setName(deviceName);
}
}
})
.setNegativeButton(android.R.string.cancel, null)
.create();
return mAlertDialog;
}
private View createDialogView() {
final LayoutInflater layoutInflater = (LayoutInflater)getActivity()
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View view = layoutInflater.inflate(R.layout.dialog_edittext, null);
mDeviceNameView = (EditText) view.findViewById(R.id.edittext);
mDeviceNameView.setFilters(new InputFilter[] {
new Utf8ByteLengthFilter(BLUETOOTH_NAME_MAX_LENGTH_BYTES)
});
mDeviceNameView.addTextChangedListener(this);
return view;
}
@Override
public void onDestroy() {
super.onDestroy();
mAlertDialog = null;
mDeviceNameView = null;
mOkButton = null;
}
@Override
public void onResume() {
super.onResume();
if (mOkButton == null) {
mOkButton = mAlertDialog.getButton(DialogInterface.BUTTON_POSITIVE);
mOkButton.setEnabled(false); // Ok button is enabled when the user edits the name
}
IntentFilter filter = new IntentFilter();
filter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED);
filter.addAction(BluetoothAdapter.ACTION_LOCAL_NAME_CHANGED);
getActivity().registerReceiver(mReceiver, filter);
updateDeviceName();
}
@Override
public void onPause() {
super.onPause();
getActivity().unregisterReceiver(mReceiver);
}
void updateDeviceName() {
if (mLocalAdapter != null && mLocalAdapter.isEnabled()) {
mDeviceNameUpdated = true;
mDeviceNameView.setText(mLocalAdapter.getName());
}
}
public void afterTextChanged(Editable s) {
if (mDeviceNameUpdated) {
// Device name changed by code; disable Ok button until edited by user
mDeviceNameUpdated = false;
mOkButton.setEnabled(false);
} else {
mOkButton.setEnabled(s.length() != 0);
}
}
/* Not used */
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
/* Not used */
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
}

View File

@@ -1,143 +0,0 @@
/*
* Copyright (C) 2008 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.settings.bluetooth;
import android.app.AlertDialog;
import android.app.Dialog;
import android.bluetooth.BluetoothAdapter;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
import android.preference.EditTextPreference;
import android.text.Editable;
import android.text.InputFilter;
import android.text.TextWatcher;
import android.util.AttributeSet;
import android.widget.Button;
import android.widget.EditText;
/**
* BluetoothNamePreference is the preference type for editing the device's
* Bluetooth name. It asks the user for a name, and persists it via the
* Bluetooth API.
*/
public final class BluetoothNamePreference extends EditTextPreference implements TextWatcher {
// private static final String TAG = "BluetoothNamePreference";
private static final int BLUETOOTH_NAME_MAX_LENGTH_BYTES = 248;
private final LocalBluetoothAdapter mLocalAdapter;
private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (action.equals(BluetoothAdapter.ACTION_LOCAL_NAME_CHANGED)) {
setSummaryToName();
} else if (action.equals(BluetoothAdapter.ACTION_STATE_CHANGED) &&
(intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, BluetoothAdapter.ERROR) ==
BluetoothAdapter.STATE_ON)) {
setSummaryToName();
}
}
};
public BluetoothNamePreference(Context context, AttributeSet attrs) {
super(context, attrs);
mLocalAdapter = LocalBluetoothManager.getInstance(context).getBluetoothAdapter();
setSummaryToName();
}
public void resume() {
IntentFilter filter = new IntentFilter();
filter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED);
filter.addAction(BluetoothAdapter.ACTION_LOCAL_NAME_CHANGED);
getContext().registerReceiver(mReceiver, filter);
// Make sure the OK button is disabled (if necessary) after rotation
EditText et = getEditText();
if (et != null) {
et.setFilters(new InputFilter[] {
new Utf8ByteLengthFilter(BLUETOOTH_NAME_MAX_LENGTH_BYTES)
});
et.addTextChangedListener(this);
Dialog d = getDialog();
if (d instanceof AlertDialog) {
Button b = ((AlertDialog) d).getButton(AlertDialog.BUTTON_POSITIVE);
b.setEnabled(et.getText().length() > 0);
}
}
}
public void pause() {
EditText et = getEditText();
if (et != null) {
et.removeTextChangedListener(this);
}
getContext().unregisterReceiver(mReceiver);
}
private void setSummaryToName() {
if (mLocalAdapter != null && mLocalAdapter.isEnabled()) {
setSummary(mLocalAdapter.getName());
}
}
@Override
protected boolean persistString(String value) {
// Persist with Bluez instead of shared preferences
if (mLocalAdapter != null) {
mLocalAdapter.setName(value);
}
return true;
}
@Override
protected void onClick() {
super.onClick();
// The dialog should be created by now
EditText et = getEditText();
if (et != null && mLocalAdapter != null) {
et.setText(mLocalAdapter.getName());
}
}
// TextWatcher interface
public void afterTextChanged(Editable s) {
Dialog d = getDialog();
if (d instanceof AlertDialog) {
((AlertDialog) d).getButton(DialogInterface.BUTTON_POSITIVE).setEnabled(s.length() > 0);
}
}
// TextWatcher interface
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
// not used
}
// TextWatcher interface
public void onTextChanged(CharSequence s, int start, int before, int count) {
// not used
}
}

View File

@@ -24,13 +24,17 @@ import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.text.Editable;
import android.text.Html;
import android.text.InputFilter;
import android.text.InputType;
import android.text.Spanned;
import android.text.TextWatcher;
import android.text.InputFilter.LengthFilter;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.EditText;
import android.widget.TextView;
@@ -42,8 +46,8 @@ import com.android.settings.R;
* BluetoothPairingDialog asks the user to enter a PIN / Passkey / simple confirmation
* for pairing with a remote Bluetooth device. It is an activity that appears as a dialog.
*/
public final class BluetoothPairingDialog extends AlertActivity implements DialogInterface.OnClickListener,
TextWatcher {
public final class BluetoothPairingDialog extends AlertActivity implements
CompoundButton.OnCheckedChangeListener, DialogInterface.OnClickListener, TextWatcher {
private static final String TAG = "BluetoothPairingDialog";
private static final int BLUETOOTH_PIN_MAX_LENGTH = 16;
@@ -156,7 +160,7 @@ public final class BluetoothPairingDialog extends AlertActivity implements Dialo
final AlertController.AlertParams p = mAlertParams;
p.mIconId = android.R.drawable.ic_dialog_info;
p.mTitle = getString(R.string.bluetooth_pairing_request);
p.mView = createView(deviceManager);
p.mView = createPinEntryView(deviceManager.getName(mDevice));
p.mPositiveButtonText = getString(android.R.string.ok);
p.mPositiveButtonListener = this;
p.mNegativeButtonText = getString(android.R.string.cancel);
@@ -167,56 +171,78 @@ public final class BluetoothPairingDialog extends AlertActivity implements Dialo
mOkButton.setEnabled(false);
}
private View createView(CachedBluetoothDeviceManager deviceManager) {
private View createPinEntryView(String deviceName) {
View view = getLayoutInflater().inflate(R.layout.bluetooth_pin_entry, null);
String name = deviceManager.getName(mDevice);
TextView messageView = (TextView) view.findViewById(R.id.message);
TextView messageView2 = (TextView) view.findViewById(R.id.message_below_pin);
CheckBox alphanumericPin = (CheckBox) view.findViewById(R.id.alphanumeric_pin);
mPairingView = (EditText) view.findViewById(R.id.text);
mPairingView.addTextChangedListener(this);
alphanumericPin.setOnCheckedChangeListener(this);
int messageId1;
int messageId2;
int maxLength;
switch (mType) {
case BluetoothDevice.PAIRING_VARIANT_PIN:
messageView.setText(getString(R.string.bluetooth_enter_pin_msg, name));
// Maximum of 16 characters in a PIN adb sync
mPairingView.setFilters(new InputFilter[] {
new LengthFilter(BLUETOOTH_PIN_MAX_LENGTH) });
messageId1 = R.string.bluetooth_enter_pin_msg;
messageId2 = R.string.bluetooth_enter_pin_other_device;
// Maximum of 16 characters in a PIN
maxLength = BLUETOOTH_PIN_MAX_LENGTH;
break;
case BluetoothDevice.PAIRING_VARIANT_PASSKEY:
messageView.setText(getString(R.string.bluetooth_enter_passkey_msg, name));
messageId1 = R.string.bluetooth_enter_passkey_msg;
messageId2 = R.string.bluetooth_enter_passkey_other_device;
// Maximum of 6 digits for passkey
mPairingView.setInputType(InputType.TYPE_CLASS_NUMBER |
InputType.TYPE_NUMBER_FLAG_SIGNED);
mPairingView.setFilters(new InputFilter[] {
new LengthFilter(BLUETOOTH_PASSKEY_MAX_LENGTH)});
maxLength = BLUETOOTH_PASSKEY_MAX_LENGTH;
alphanumericPin.setVisibility(View.GONE);
break;
default:
Log.e(TAG, "Incorrect pairing type for createPinEntryView: " + mType);
return null;
}
// Format the message string, then parse HTML style tags
String messageText = getString(messageId1, deviceName);
messageView.setText(Html.fromHtml(messageText));
messageView2.setText(messageId2);
mPairingView.setInputType(InputType.TYPE_CLASS_NUMBER);
mPairingView.setFilters(new InputFilter[] {
new LengthFilter(maxLength) });
return view;
}
private View createView(CachedBluetoothDeviceManager deviceManager) {
View view = getLayoutInflater().inflate(R.layout.bluetooth_pin_confirm, null);
String name = deviceManager.getName(mDevice);
TextView messageView = (TextView) view.findViewById(R.id.message);
String messageText; // formatted string containing HTML style tags
switch (mType) {
case BluetoothDevice.PAIRING_VARIANT_PASSKEY_CONFIRMATION:
mPairingView.setVisibility(View.GONE);
messageView.setText(getString(R.string.bluetooth_confirm_passkey_msg, name,
mPairingKey));
messageText = getString(R.string.bluetooth_confirm_passkey_msg,
name, mPairingKey);
break;
case BluetoothDevice.PAIRING_VARIANT_CONSENT:
mPairingView.setVisibility(View.GONE);
messageView.setText(getString(R.string.bluetooth_incoming_pairing_msg, name));
case BluetoothDevice.PAIRING_VARIANT_OOB_CONSENT:
messageText = getString(R.string.bluetooth_incoming_pairing_msg, name);
break;
case BluetoothDevice.PAIRING_VARIANT_DISPLAY_PASSKEY:
case BluetoothDevice.PAIRING_VARIANT_DISPLAY_PIN:
mPairingView.setVisibility(View.GONE);
messageView.setText(getString(R.string.bluetooth_display_passkey_pin_msg, name,
mPairingKey));
break;
case BluetoothDevice.PAIRING_VARIANT_OOB_CONSENT:
mPairingView.setVisibility(View.GONE);
messageView.setText(getString(R.string.bluetooth_incoming_pairing_msg, name));
messageText = getString(R.string.bluetooth_display_passkey_pin_msg, name,
mPairingKey);
break;
default:
Log.e(TAG, "Incorrect pairing type received, not creating view");
return null;
}
messageView.setText(Html.fromHtml(messageText));
return view;
}
@@ -317,7 +343,11 @@ public final class BluetoothPairingDialog extends AlertActivity implements Dialo
public void onClick(DialogInterface dialog, int which) {
switch (which) {
case BUTTON_POSITIVE:
onPair(mPairingView.getText().toString());
if (mPairingView != null) {
onPair(mPairingView.getText().toString());
} else {
onPair(null);
}
break;
case BUTTON_NEGATIVE:
@@ -335,4 +365,12 @@ public final class BluetoothPairingDialog extends AlertActivity implements Dialo
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
// change input type for soft keyboard to numeric or alphanumeric
if (isChecked) {
mPairingView.setInputType(InputType.TYPE_CLASS_TEXT);
} else {
mPairingView.setInputType(InputType.TYPE_CLASS_NUMBER);
}
}
}

View File

@@ -20,6 +20,10 @@ import android.app.ActionBar;
import android.app.Activity;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.preference.Preference;
import android.preference.PreferenceActivity;
@@ -48,16 +52,48 @@ public final class BluetoothSettings extends DeviceListPreferenceFragment {
private static final String TAG = "BluetoothSettings";
private static final int MENU_ID_SCAN = Menu.FIRST;
private static final int MENU_ID_ADVANCED = Menu.FIRST + 1;
private static final int MENU_ID_RENAME_DEVICE = Menu.FIRST + 1;
private static final int MENU_ID_VISIBILITY_TIMEOUT = Menu.FIRST + 2;
private static final int MENU_ID_SHOW_RECEIVED = Menu.FIRST + 3;
/* Private intent to show the list of received files */
private static final String BTOPP_ACTION_OPEN_RECEIVED_FILES =
"android.btopp.intent.action.OPEN_RECEIVED_FILES";
private BluetoothEnabler mBluetoothEnabler;
private BluetoothDiscoverableEnabler mDiscoverableEnabler;
private PreferenceGroup mPairedDevicesCategory;
private PreferenceGroup mAvailableDevicesCategory;
private boolean mAvailableDevicesCategoryIsPresent;
private View mView;
private TextView mEmptyView;
// accessed from inner class (not private to avoid thunks)
Preference mMyDevicePreference;
private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (action.equals(BluetoothAdapter.ACTION_LOCAL_NAME_CHANGED) ||
(action.equals(BluetoothAdapter.ACTION_STATE_CHANGED) &&
(intent.getIntExtra(BluetoothAdapter.EXTRA_STATE,
BluetoothAdapter.ERROR) == BluetoothAdapter.STATE_ON))) {
updateDeviceName();
}
}
private void updateDeviceName() {
if (mLocalAdapter != null && mLocalAdapter.isEnabled() && mMyDevicePreference != null) {
mMyDevicePreference.setTitle(mLocalAdapter.getName());
}
}
};
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
@@ -106,15 +142,26 @@ public final class BluetoothSettings extends DeviceListPreferenceFragment {
super.onResume();
mBluetoothEnabler.resume();
updateContent(mLocalAdapter.getBluetoothState());
if (mDiscoverableEnabler != null) {
mDiscoverableEnabler.resume();
}
IntentFilter filter = new IntentFilter();
filter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED);
filter.addAction(BluetoothAdapter.ACTION_LOCAL_NAME_CHANGED);
getActivity().registerReceiver(mReceiver, filter);
}
@Override
public void onPause() {
super.onPause();
mBluetoothEnabler.pause();
getActivity().unregisterReceiver(mReceiver);
if (mDiscoverableEnabler != null) {
mDiscoverableEnabler.pause();
}
}
@Override
@@ -124,12 +171,14 @@ public final class BluetoothSettings extends DeviceListPreferenceFragment {
int textId = isDiscovering ? R.string.bluetooth_searching_for_devices :
R.string.bluetooth_search_for_devices;
menu.add(Menu.NONE, MENU_ID_SCAN, 0, textId)
//.setIcon(R.drawable.ic_menu_scan_network)
.setEnabled(bluetoothIsEnabled && !isDiscovering)
.setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);
menu.add(Menu.NONE, MENU_ID_ADVANCED, 0, R.string.bluetooth_menu_advanced)
//.setIcon(android.R.drawable.ic_menu_manage)
menu.add(Menu.NONE, MENU_ID_RENAME_DEVICE, 0, R.string.bluetooth_rename_device)
.setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);
menu.add(Menu.NONE, MENU_ID_VISIBILITY_TIMEOUT, 0, R.string.bluetooth_visibility_timeout)
.setShowAsAction(MenuItem.SHOW_AS_ACTION_NEVER);
menu.add(Menu.NONE, MENU_ID_SHOW_RECEIVED, 0, R.string.bluetooth_show_received_files)
.setShowAsAction(MenuItem.SHOW_AS_ACTION_NEVER);
}
@Override
@@ -140,16 +189,20 @@ public final class BluetoothSettings extends DeviceListPreferenceFragment {
startScanning();
}
return true;
case MENU_ID_ADVANCED:
if (getActivity() instanceof PreferenceActivity) {
((PreferenceActivity) getActivity()).startPreferencePanel(
AdvancedBluetoothSettings.class.getCanonicalName(),
null,
R.string.bluetooth_advanced_titlebar, null,
this, 0);
} else {
startFragment(this, AdvancedBluetoothSettings.class.getCanonicalName(), -1, null);
}
case MENU_ID_RENAME_DEVICE:
new BluetoothNameDialogFragment(mLocalAdapter).show(
getFragmentManager(), "rename device");
return true;
case MENU_ID_VISIBILITY_TIMEOUT:
new BluetoothVisibilityTimeoutFragment(mDiscoverableEnabler).show(
getFragmentManager(), "visibility timeout");
return true;
case MENU_ID_SHOW_RECEIVED:
Intent intent = new Intent(BTOPP_ACTION_OPEN_RECEIVED_FILES);
getActivity().sendBroadcast(intent);
return true;
}
return super.onOptionsItemSelected(item);
@@ -195,9 +248,15 @@ public final class BluetoothSettings extends DeviceListPreferenceFragment {
if (mLocalAdapter != null) {
mMyDevicePreference.setTitle(mLocalAdapter.getName());
}
mMyDevicePreference.setPersistent(false);
mMyDevicePreference.setEnabled(true);
preferenceScreen.addPreference(mMyDevicePreference);
if (mDiscoverableEnabler == null) {
mDiscoverableEnabler = new BluetoothDiscoverableEnabler(getActivity(),
mLocalAdapter, mMyDevicePreference);
}
// Paired devices category
if (mPairedDevicesCategory == null) {
mPairedDevicesCategory = new PreferenceCategory(getActivity());
@@ -209,6 +268,8 @@ public final class BluetoothSettings extends DeviceListPreferenceFragment {
BluetoothDeviceFilter.BONDED_DEVICE_FILTER);
int numberOfPairedDevices = mPairedDevicesCategory.getPreferenceCount();
mDiscoverableEnabler.setNumberOfPairedDevices(numberOfPairedDevices);
// Available devices category
if (mAvailableDevicesCategory == null) {
mAvailableDevicesCategory = new ProgressCategory(getActivity(), null);
@@ -291,10 +352,6 @@ public final class BluetoothSettings extends DeviceListPreferenceFragment {
}
};
private Preference mMyDevicePreference;
private PreferenceGroup mPairedDevicesCategory;
/**
* Add a listener, which enables the advanced settings icon.
* @param preference the newly added preference

View File

@@ -0,0 +1,68 @@
/*
* Copyright (C) 2011 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.settings.bluetooth;
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.DialogFragment;
import android.bluetooth.BluetoothAdapter;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.text.Editable;
import android.text.InputFilter;
import android.text.TextWatcher;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import com.android.internal.app.AlertController;
import com.android.settings.R;
/**
* Dialog fragment for setting the discoverability timeout.
*/
final class BluetoothVisibilityTimeoutFragment extends DialogFragment
implements DialogInterface.OnClickListener {
private final BluetoothDiscoverableEnabler mDiscoverableEnabler;
public BluetoothVisibilityTimeoutFragment(BluetoothDiscoverableEnabler enabler) {
mDiscoverableEnabler = enabler;
}
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
return new AlertDialog.Builder(getActivity())
.setIcon(android.R.drawable.ic_dialog_info)
.setTitle(R.string.bluetooth_visibility_timeout)
.setSingleChoiceItems(R.array.bluetooth_visibility_timeout_entries,
mDiscoverableEnabler.getDiscoverableTimeoutIndex(), this)
.setNegativeButton(android.R.string.cancel, null)
.create();
}
public void onClick(DialogInterface dialog, int which) {
mDiscoverableEnabler.setDiscoverableTimeout(which);
dismiss();
}
}

View File

@@ -257,6 +257,14 @@ final class CachedBluetoothDevice implements Comparable<CachedBluetoothDevice> {
return true;
}
/**
* Return true if user initiated pairing on this device. The message text is
* slightly different for local vs. remote initiated pairing dialogs.
*/
boolean isUserInitiatedPairing() {
return mConnectAfterPairing;
}
void unpair() {
disconnect();