Bluetooth settings revamp
Added a separate scanning screen. UI changes to not require long-press options. Needs TODOs to be filled by BT team. Bug: 3038327
This commit is contained in:
@@ -19,16 +19,22 @@ package com.android.settings.bluetooth;
|
||||
import com.android.settings.R;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.preference.Preference;
|
||||
import android.util.TypedValue;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.View.OnClickListener;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.LinearLayout;
|
||||
|
||||
/**
|
||||
* BluetoothDevicePreference is the preference type used to display each remote
|
||||
* Bluetooth device in the Bluetooth Settings screen.
|
||||
*/
|
||||
public class BluetoothDevicePreference extends Preference implements CachedBluetoothDevice.Callback {
|
||||
public class BluetoothDevicePreference extends Preference implements
|
||||
CachedBluetoothDevice.Callback, OnClickListener {
|
||||
private static final String TAG = "BluetoothDevicePreference";
|
||||
|
||||
private static int sDimAlpha = Integer.MIN_VALUE;
|
||||
@@ -36,6 +42,9 @@ public class BluetoothDevicePreference extends Preference implements CachedBluet
|
||||
private CachedBluetoothDevice mCachedDevice;
|
||||
private int mAccessibleProfile;
|
||||
|
||||
private ImageView mDeviceSettings;
|
||||
private OnClickListener mOnSettingsClickListener;
|
||||
|
||||
/**
|
||||
* Cached local copy of whether the device is busy. This is only updated
|
||||
* from {@link #onDeviceAttributesChanged(CachedBluetoothDevice)}.
|
||||
@@ -66,6 +75,10 @@ public class BluetoothDevicePreference extends Preference implements CachedBluet
|
||||
return mCachedDevice;
|
||||
}
|
||||
|
||||
public void setOnSettingsClickListener(OnClickListener listener) {
|
||||
mOnSettingsClickListener = listener;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPrepareForRemoval() {
|
||||
super.onPrepareForRemoval();
|
||||
@@ -117,6 +130,34 @@ public class BluetoothDevicePreference extends Preference implements CachedBluet
|
||||
ImageView btClass = (ImageView) view.findViewById(R.id.btClass);
|
||||
btClass.setImageResource(mCachedDevice.getBtClassDrawable());
|
||||
btClass.setAlpha(isEnabled() ? 255 : sDimAlpha);
|
||||
|
||||
mDeviceSettings = (ImageView) view.findViewById(R.id.deviceDetails);
|
||||
if (mOnSettingsClickListener != null) {
|
||||
mDeviceSettings.setOnClickListener(this);
|
||||
mDeviceSettings.setTag(mCachedDevice);
|
||||
} else { // Hide the settings icon and divider
|
||||
mDeviceSettings.setVisibility(View.GONE);
|
||||
ImageView divider = (ImageView) view.findViewById(R.id.divider);
|
||||
if (divider != null) {
|
||||
divider.setVisibility(View.GONE);
|
||||
}
|
||||
}
|
||||
|
||||
LayoutInflater inflater = (LayoutInflater)
|
||||
getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
|
||||
ViewGroup profilesGroup = (ViewGroup) view.findViewById(R.id.profileIcons);
|
||||
for (Drawable icon : mCachedDevice.getProfileIcons()) {
|
||||
inflater.inflate(R.layout.profile_icon_small, profilesGroup, true);
|
||||
ImageView imageView =
|
||||
(ImageView) profilesGroup.getChildAt(profilesGroup.getChildCount() - 1);
|
||||
imageView.setImageDrawable(icon);
|
||||
}
|
||||
}
|
||||
|
||||
public void onClick(View v) {
|
||||
if (v == mDeviceSettings) {
|
||||
if (mOnSettingsClickListener != null) mOnSettingsClickListener.onClick(v);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@@ -0,0 +1,95 @@
|
||||
/*
|
||||
* Copyright (C) 2010 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 com.android.settings.bluetooth.LocalBluetoothProfileManager.Profile;
|
||||
import com.android.settings.R;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.preference.Preference;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.View.OnClickListener;
|
||||
import android.widget.ImageView;
|
||||
|
||||
/**
|
||||
* BluetoothProfilePreference is the preference type used to display each profile for a
|
||||
* particular bluetooth device.
|
||||
*/
|
||||
public class BluetoothProfilePreference extends Preference implements OnClickListener {
|
||||
|
||||
private static final String TAG = "BluetoothProfilePreference";
|
||||
|
||||
private Drawable mProfileDrawable;
|
||||
private boolean mExpanded;
|
||||
private ImageView mProfileExpandView;
|
||||
private Profile mProfile;
|
||||
|
||||
private OnClickListener mOnExpandClickListener;
|
||||
|
||||
public BluetoothProfilePreference(Context context, Profile profile) {
|
||||
super(context);
|
||||
|
||||
mProfile = profile;
|
||||
|
||||
setLayoutResource(R.layout.preference_bluetooth_profile);
|
||||
setExpanded(false);
|
||||
}
|
||||
|
||||
public void setOnExpandClickListener(OnClickListener listener) {
|
||||
mOnExpandClickListener = listener;
|
||||
}
|
||||
|
||||
public void setExpanded(boolean expanded) {
|
||||
mExpanded = expanded;
|
||||
notifyChanged();
|
||||
}
|
||||
|
||||
public boolean isExpanded() {
|
||||
return mExpanded;
|
||||
}
|
||||
|
||||
public void setProfileDrawable(Drawable drawable) {
|
||||
mProfileDrawable = drawable;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onBindView(View view) {
|
||||
super.onBindView(view);
|
||||
|
||||
ImageView btProfile = (ImageView) view.findViewById(R.id.profileIcon);
|
||||
btProfile.setImageDrawable(mProfileDrawable);
|
||||
|
||||
mProfileExpandView = (ImageView) view.findViewById(R.id.profileExpand);
|
||||
mProfileExpandView.setOnClickListener(this);
|
||||
mProfileExpandView.setTag(mProfile);
|
||||
|
||||
mProfileExpandView.setImageResource(mExpanded ? R.drawable.ic_preferences_expanded
|
||||
: R.drawable.ic_preferences_collapsed);
|
||||
}
|
||||
|
||||
public void onClick(View v) {
|
||||
if (v == mProfileExpandView) {
|
||||
if (mOnExpandClickListener != null) {
|
||||
setExpanded(!mExpanded);
|
||||
mOnExpandClickListener.onClick(v);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -16,11 +16,11 @@
|
||||
|
||||
package com.android.settings.bluetooth;
|
||||
|
||||
import com.android.settings.bluetooth.LocalBluetoothProfileManager.Profile;
|
||||
import com.android.settings.ProgressCategory;
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.SettingsPreferenceFragment;
|
||||
import com.android.settings.UserLeaveHintListener;
|
||||
import com.android.settings.bluetooth.LocalBluetoothProfileManager.Profile;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.AlertDialog;
|
||||
@@ -39,6 +39,7 @@ import android.os.Bundle;
|
||||
import android.os.ParcelUuid;
|
||||
import android.preference.CheckBoxPreference;
|
||||
import android.preference.Preference;
|
||||
import android.preference.PreferenceCategory;
|
||||
import android.preference.PreferenceScreen;
|
||||
import android.text.TextUtils;
|
||||
import android.view.ContextMenu;
|
||||
@@ -55,7 +56,7 @@ import java.util.WeakHashMap;
|
||||
* connection management.
|
||||
*/
|
||||
public class BluetoothSettings extends SettingsPreferenceFragment
|
||||
implements LocalBluetoothManager.Callback, UserLeaveHintListener {
|
||||
implements LocalBluetoothManager.Callback, UserLeaveHintListener, View.OnClickListener {
|
||||
|
||||
private static final String TAG = "BluetoothSettings";
|
||||
|
||||
@@ -64,14 +65,18 @@ public class BluetoothSettings extends SettingsPreferenceFragment
|
||||
private static final String KEY_BT_DEVICE_LIST = "bt_device_list";
|
||||
private static final String KEY_BT_NAME = "bt_name";
|
||||
private static final String KEY_BT_SCAN = "bt_scan";
|
||||
private static final String KEY_BT_FIND_NEARBY = "bt_find_nearby";
|
||||
|
||||
private static final int SCREEN_TYPE_SETTINGS = 0;
|
||||
private static final int SCREEN_TYPE_DEVICEPICKER = 1;
|
||||
private static final int SCREEN_TYPE_TETHERING = 2;
|
||||
private static final int SCREEN_TYPE_SCAN = 3;
|
||||
|
||||
public static final String ACTION = "bluetooth_action";
|
||||
public static final String ACTION_LAUNCH_TETHER_PICKER =
|
||||
"com.android.settings.bluetooth.action.LAUNCH_TETHER_PICKER";
|
||||
"com.android.settings.bluetooth.action.LAUNCH_TETHER_PICKER";
|
||||
public static final String ACTION_LAUNCH_SCAN_MODE =
|
||||
"com.android.settings.bluetooth.action.LAUNCH_SCAN_MODE";
|
||||
|
||||
private int mScreenType;
|
||||
private int mFilterType;
|
||||
@@ -88,7 +93,7 @@ public class BluetoothSettings extends SettingsPreferenceFragment
|
||||
|
||||
private BluetoothNamePreference mNamePreference;
|
||||
|
||||
private ProgressCategory mDeviceList;
|
||||
private PreferenceCategory mDeviceList;
|
||||
|
||||
private WeakHashMap<CachedBluetoothDevice, BluetoothDevicePreference> mDevicePreferenceMap =
|
||||
new WeakHashMap<CachedBluetoothDevice, BluetoothDevicePreference>();
|
||||
@@ -96,11 +101,11 @@ public class BluetoothSettings extends SettingsPreferenceFragment
|
||||
private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
// TODO: put this in callback instead of receiving
|
||||
|
||||
if (intent.getAction().equals(BluetoothAdapter.ACTION_STATE_CHANGED)) {
|
||||
onBluetoothStateChanged(mLocalManager.getBluetoothState());
|
||||
} else if (intent.getAction().equals(BluetoothDevice.ACTION_BOND_STATE_CHANGED)) {
|
||||
// TODO: If this is a scanning screen, maybe return on successful pairing
|
||||
|
||||
int bondState = intent
|
||||
.getIntExtra(BluetoothDevice.EXTRA_BOND_STATE, BluetoothDevice.ERROR);
|
||||
if (bondState == BluetoothDevice.BOND_BONDED) {
|
||||
@@ -153,6 +158,8 @@ public class BluetoothSettings extends SettingsPreferenceFragment
|
||||
action = intent.getAction();
|
||||
}
|
||||
|
||||
if (getPreferenceScreen() != null) getPreferenceScreen().removeAll();
|
||||
|
||||
if (action.equals(BluetoothDevicePicker.ACTION_LAUNCH)) {
|
||||
mScreenType = SCREEN_TYPE_DEVICEPICKER;
|
||||
mNeedAuth = intent.getBooleanExtra(BluetoothDevicePicker.EXTRA_NEED_AUTH, false);
|
||||
@@ -168,6 +175,10 @@ public class BluetoothSettings extends SettingsPreferenceFragment
|
||||
mFilterType = BluetoothDevicePicker.FILTER_TYPE_PANU;
|
||||
|
||||
activity.setTitle(activity.getString(R.string.device_picker));
|
||||
addPreferencesFromResource(R.xml.device_picker);
|
||||
} else if (action.equals(ACTION_LAUNCH_SCAN_MODE)) {
|
||||
mScreenType = SCREEN_TYPE_SCAN;
|
||||
|
||||
addPreferencesFromResource(R.xml.device_picker);
|
||||
} else {
|
||||
addPreferencesFromResource(R.xml.bluetooth_settings);
|
||||
@@ -182,10 +193,9 @@ public class BluetoothSettings extends SettingsPreferenceFragment
|
||||
|
||||
mNamePreference = (BluetoothNamePreference) findPreference(KEY_BT_NAME);
|
||||
|
||||
mDeviceList = (ProgressCategory) findPreference(KEY_BT_DEVICE_LIST);
|
||||
}
|
||||
|
||||
mDeviceList = (ProgressCategory) findPreference(KEY_BT_DEVICE_LIST);
|
||||
mDeviceList = (PreferenceCategory) findPreference(KEY_BT_DEVICE_LIST);
|
||||
|
||||
registerForContextMenu(getListView());
|
||||
|
||||
@@ -200,7 +210,9 @@ public class BluetoothSettings extends SettingsPreferenceFragment
|
||||
// bluetooth manager
|
||||
mDevicePreferenceMap.clear();
|
||||
mDeviceList.removeAll();
|
||||
addDevices();
|
||||
if (mScreenType != SCREEN_TYPE_SCAN) {
|
||||
addDevices();
|
||||
}
|
||||
|
||||
if (mScreenType == SCREEN_TYPE_SETTINGS) {
|
||||
mEnabler.resume();
|
||||
@@ -210,8 +222,11 @@ public class BluetoothSettings extends SettingsPreferenceFragment
|
||||
|
||||
mLocalManager.registerCallback(this);
|
||||
|
||||
mDeviceList.setProgress(mLocalManager.getBluetoothAdapter().isDiscovering());
|
||||
mLocalManager.startScanning(false);
|
||||
updateProgressUi(mLocalManager.getBluetoothAdapter().isDiscovering());
|
||||
|
||||
if (mScreenType != SCREEN_TYPE_SETTINGS) {
|
||||
mLocalManager.startScanning(true);
|
||||
}
|
||||
|
||||
IntentFilter intentFilter = new IntentFilter();
|
||||
intentFilter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED);
|
||||
@@ -249,6 +264,13 @@ public class BluetoothSettings extends SettingsPreferenceFragment
|
||||
}
|
||||
}
|
||||
|
||||
public void onClick(View v) {
|
||||
if (v.getTag() instanceof CachedBluetoothDevice) {
|
||||
CachedBluetoothDevice device = (CachedBluetoothDevice) v.getTag();
|
||||
device.onClickedAdvancedOptions(this);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen,
|
||||
Preference preference) {
|
||||
@@ -260,7 +282,7 @@ public class BluetoothSettings extends SettingsPreferenceFragment
|
||||
|
||||
if (preference instanceof BluetoothDevicePreference) {
|
||||
BluetoothDevicePreference btPreference = (BluetoothDevicePreference)preference;
|
||||
if (mScreenType == SCREEN_TYPE_SETTINGS) {
|
||||
if (mScreenType == SCREEN_TYPE_SETTINGS || mScreenType == SCREEN_TYPE_SCAN) {
|
||||
btPreference.getCachedDevice().onClicked();
|
||||
} else if (mScreenType == SCREEN_TYPE_DEVICEPICKER) {
|
||||
CachedBluetoothDevice device = btPreference.getCachedDevice();
|
||||
@@ -312,7 +334,7 @@ public class BluetoothSettings extends SettingsPreferenceFragment
|
||||
CachedBluetoothDevice cachedDevice = getDeviceFromMenuInfo(item.getMenuInfo());
|
||||
if (cachedDevice == null) return false;
|
||||
|
||||
cachedDevice.onContextItemSelected(item);
|
||||
cachedDevice.onContextItemSelected(item, this);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -337,8 +359,11 @@ public class BluetoothSettings extends SettingsPreferenceFragment
|
||||
throw new IllegalStateException("Got onDeviceAdded, but cachedDevice already exists");
|
||||
}
|
||||
|
||||
if (addDevicePreference(cachedDevice)) {
|
||||
createDevicePreference(cachedDevice);
|
||||
if (mScreenType != SCREEN_TYPE_SETTINGS
|
||||
|| cachedDevice.getBondState() == BluetoothDevice.BOND_BONDED) {
|
||||
if (addDevicePreference(cachedDevice)) {
|
||||
createDevicePreference(cachedDevice);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -406,6 +431,9 @@ public class BluetoothSettings extends SettingsPreferenceFragment
|
||||
preference = new BluetoothDevicePreference(
|
||||
getActivity(), cachedDevice, CachedBluetoothDevice.OTHER_PROFILES);
|
||||
}
|
||||
if (mScreenType == SCREEN_TYPE_SETTINGS) {
|
||||
preference.setOnSettingsClickListener(this);
|
||||
}
|
||||
mDeviceList.addPreference(preference);
|
||||
mDevicePreferenceMap.put(cachedDevice, preference);
|
||||
}
|
||||
@@ -418,16 +446,23 @@ public class BluetoothSettings extends SettingsPreferenceFragment
|
||||
}
|
||||
|
||||
public void onScanningStateChanged(boolean started) {
|
||||
mDeviceList.setProgress(started);
|
||||
updateProgressUi(started);
|
||||
}
|
||||
|
||||
private void updateProgressUi(boolean start) {
|
||||
if (mDeviceList instanceof ProgressCategory) {
|
||||
((ProgressCategory) mDeviceList).setProgress(start);
|
||||
}
|
||||
}
|
||||
private void onBluetoothStateChanged(int bluetoothState) {
|
||||
// When bluetooth is enabled (and we are in the activity, which we are),
|
||||
// we should start a scan
|
||||
if (bluetoothState == BluetoothAdapter.STATE_ON) {
|
||||
mLocalManager.startScanning(false);
|
||||
if (mScreenType != SCREEN_TYPE_SETTINGS) {
|
||||
mLocalManager.startScanning(false);
|
||||
}
|
||||
} else if (bluetoothState == BluetoothAdapter.STATE_OFF) {
|
||||
mDeviceList.setProgress(false);
|
||||
updateProgressUi(false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -480,4 +515,22 @@ public class BluetoothSettings extends SettingsPreferenceFragment
|
||||
}
|
||||
getActivity().sendBroadcast(intent);
|
||||
}
|
||||
|
||||
public static class FindNearby extends BluetoothSettings {
|
||||
|
||||
public FindNearby() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActivityCreated(Bundle savedInstanceState) {
|
||||
Bundle args = super.getArguments();
|
||||
if (args == null) {
|
||||
args = new Bundle();
|
||||
setArguments(args);
|
||||
}
|
||||
args.putString(ACTION, ACTION_LAUNCH_SCAN_MODE);
|
||||
super.onActivityCreated(savedInstanceState);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -16,28 +16,31 @@
|
||||
|
||||
package com.android.settings.bluetooth;
|
||||
|
||||
import com.android.settings.R;
|
||||
|
||||
import com.android.settings.SettingsPreferenceFragment;
|
||||
import com.android.settings.bluetooth.LocalBluetoothProfileManager.Profile;
|
||||
|
||||
import android.app.AlertDialog;
|
||||
import android.bluetooth.BluetoothAdapter;
|
||||
import android.bluetooth.BluetoothClass;
|
||||
import android.bluetooth.BluetoothDevice;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
import android.content.res.Resources;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.os.ParcelUuid;
|
||||
import android.os.SystemClock;
|
||||
import android.preference.Preference;
|
||||
import android.preference.PreferenceActivity;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
import android.view.ContextMenu;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.bluetooth.LocalBluetoothProfileManager.Profile;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* CachedBluetoothDevice represents a remote Bluetooth device. It contains
|
||||
@@ -63,6 +66,7 @@ public class CachedBluetoothDevice implements Comparable<CachedBluetoothDevice>
|
||||
private String mName;
|
||||
private short mRssi;
|
||||
private BluetoothClass mBtClass;
|
||||
private Context mContext;
|
||||
|
||||
private List<Profile> mProfiles = new ArrayList<Profile>();
|
||||
|
||||
@@ -138,6 +142,7 @@ public class CachedBluetoothDevice implements Comparable<CachedBluetoothDevice>
|
||||
}
|
||||
|
||||
mDevice = device;
|
||||
mContext = context;
|
||||
|
||||
fillData();
|
||||
}
|
||||
@@ -655,6 +660,20 @@ public class CachedBluetoothDevice implements Comparable<CachedBluetoothDevice>
|
||||
return SettingsBtStatus.getPairingStatusSummary(getBondState());
|
||||
}
|
||||
|
||||
public List<Drawable> getProfileIcons() {
|
||||
ArrayList<Drawable> drawables = new ArrayList<Drawable>();
|
||||
|
||||
for (Profile profile : mProfiles) {
|
||||
LocalBluetoothProfileManager profileManager = LocalBluetoothProfileManager
|
||||
.getProfileManager(mLocalManager, profile);
|
||||
int iconResource = profileManager.getDrawableResource();
|
||||
if (iconResource != 0) {
|
||||
drawables.add(mContext.getResources().getDrawable(iconResource));
|
||||
}
|
||||
}
|
||||
|
||||
return drawables;
|
||||
}
|
||||
/**
|
||||
* We have special summaries when particular profiles are connected. This
|
||||
* checks for those states and returns an applicable summary.
|
||||
@@ -781,7 +800,7 @@ public class CachedBluetoothDevice implements Comparable<CachedBluetoothDevice>
|
||||
*
|
||||
* @param item The item that was clicked.
|
||||
*/
|
||||
public void onContextItemSelected(MenuItem item) {
|
||||
public void onContextItemSelected(MenuItem item, SettingsPreferenceFragment fragment) {
|
||||
switch (item.getItemId()) {
|
||||
case CONTEXT_ITEM_DISCONNECT:
|
||||
disconnect();
|
||||
@@ -796,21 +815,34 @@ public class CachedBluetoothDevice implements Comparable<CachedBluetoothDevice>
|
||||
break;
|
||||
|
||||
case CONTEXT_ITEM_CONNECT_ADVANCED:
|
||||
Intent intent = new Intent();
|
||||
// Need an activity context to open this in our task
|
||||
Context context = mLocalManager.getForegroundActivity();
|
||||
if (context == null) {
|
||||
// Fallback on application context, and open in a new task
|
||||
context = mLocalManager.getContext();
|
||||
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
}
|
||||
intent.setClass(context, ConnectSpecificProfilesActivity.class);
|
||||
intent.putExtra(ConnectSpecificProfilesActivity.EXTRA_DEVICE, mDevice);
|
||||
context.startActivity(intent);
|
||||
onClickedAdvancedOptions(fragment);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public void onClickedAdvancedOptions(SettingsPreferenceFragment fragment) {
|
||||
// TODO: Verify if there really is a case when there's no foreground
|
||||
// activity
|
||||
|
||||
// Intent intent = new Intent();
|
||||
// // Need an activity context to open this in our task
|
||||
// Context context = mLocalManager.getForegroundActivity();
|
||||
// if (context == null) {
|
||||
// // Fallback on application context, and open in a new task
|
||||
// context = mLocalManager.getContext();
|
||||
// intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
// }
|
||||
// intent.setClass(context, ConnectSpecificProfilesActivity.class);
|
||||
// intent.putExtra(ConnectSpecificProfilesActivity.EXTRA_DEVICE,
|
||||
// mDevice);
|
||||
// context.startActivity(intent);
|
||||
Preference pref = new Preference(fragment.getActivity());
|
||||
pref.setTitle(getName());
|
||||
pref.setFragment(DeviceProfilesSettings.class.getName());
|
||||
pref.getExtras().putParcelable(DeviceProfilesSettings.EXTRA_DEVICE, mDevice);
|
||||
((PreferenceActivity) fragment.getActivity()).onPreferenceStartFragment(fragment, pref);
|
||||
}
|
||||
|
||||
public void registerCallback(Callback callback) {
|
||||
synchronized (mCallbacks) {
|
||||
mCallbacks.add(callback);
|
||||
|
@@ -16,31 +16,41 @@
|
||||
|
||||
package com.android.settings.bluetooth;
|
||||
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.SettingsPreferenceFragment;
|
||||
import com.android.settings.bluetooth.LocalBluetoothProfileManager.Profile;
|
||||
|
||||
import android.bluetooth.BluetoothDevice;
|
||||
import android.content.Intent;
|
||||
import android.content.Context;
|
||||
import android.os.Bundle;
|
||||
import android.preference.CheckBoxPreference;
|
||||
import android.preference.EditTextPreference;
|
||||
import android.preference.Preference;
|
||||
import android.preference.PreferenceActivity;
|
||||
import android.preference.PreferenceGroup;
|
||||
import android.preference.PreferenceScreen;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.bluetooth.LocalBluetoothProfileManager.Profile;
|
||||
import java.util.HashMap;
|
||||
|
||||
/**
|
||||
* ConnectSpecificProfilesActivity presents the user with all of the profiles
|
||||
* for a particular device, and allows him to choose which should be connected
|
||||
* (or disconnected).
|
||||
*/
|
||||
public class ConnectSpecificProfilesActivity extends PreferenceActivity
|
||||
implements CachedBluetoothDevice.Callback, Preference.OnPreferenceChangeListener {
|
||||
private static final String TAG = "ConnectSpecificProfilesActivity";
|
||||
public class DeviceProfilesSettings extends SettingsPreferenceFragment
|
||||
implements CachedBluetoothDevice.Callback, Preference.OnPreferenceChangeListener,
|
||||
View.OnClickListener {
|
||||
private static final String TAG = "DeviceProfilesSettings";
|
||||
|
||||
private static final String KEY_ONLINE_MODE = "online_mode";
|
||||
private static final String KEY_TITLE = "title";
|
||||
private static final String KEY_RENAME_DEVICE = "rename_device";
|
||||
private static final String KEY_PROFILE_CONTAINER = "profile_container";
|
||||
private static final String KEY_UNPAIR = "unpair";
|
||||
private static final String KEY_ALLOW_INCOMING = "allow_incoming";
|
||||
|
||||
private static final String AUTO_CONNECT_KEY_SUFFIX = "X";
|
||||
|
||||
public static final String EXTRA_DEVICE = "device";
|
||||
|
||||
@@ -48,27 +58,21 @@ public class ConnectSpecificProfilesActivity extends PreferenceActivity
|
||||
private CachedBluetoothDevice mCachedDevice;
|
||||
|
||||
private PreferenceGroup mProfileContainer;
|
||||
private CheckBoxPreference mOnlineModePreference;
|
||||
|
||||
/**
|
||||
* The current mode of this activity and its checkboxes (either online mode
|
||||
* or offline mode). In online mode, user interactions with the profile
|
||||
* checkboxes will also toggle the profile's connectivity. In offline mode,
|
||||
* they will not, and only the preferred state will be saved for the
|
||||
* profile.
|
||||
*/
|
||||
private boolean mOnlineMode;
|
||||
private CheckBoxPreference mAllowIncomingPref;
|
||||
private EditTextPreference mDeviceNamePref;
|
||||
private HashMap<String,CheckBoxPreference> mAutoConnectPrefs
|
||||
= new HashMap<String,CheckBoxPreference>();
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
BluetoothDevice device;
|
||||
if (savedInstanceState != null) {
|
||||
device = savedInstanceState.getParcelable(EXTRA_DEVICE);
|
||||
} else {
|
||||
Intent intent = getIntent();
|
||||
device = intent.getParcelableExtra(EXTRA_DEVICE);
|
||||
Bundle args = getArguments();
|
||||
device = args.getParcelable(EXTRA_DEVICE);
|
||||
}
|
||||
|
||||
if (device == null) {
|
||||
@@ -76,7 +80,7 @@ public class ConnectSpecificProfilesActivity extends PreferenceActivity
|
||||
finish();
|
||||
}
|
||||
|
||||
mManager = LocalBluetoothManager.getInstance(this);
|
||||
mManager = LocalBluetoothManager.getInstance(getActivity());
|
||||
mCachedDevice = mManager.getCachedDeviceManager().findDevice(device);
|
||||
if (mCachedDevice == null) {
|
||||
Log.w(TAG, "Device not found, cannot connect to it");
|
||||
@@ -84,39 +88,43 @@ public class ConnectSpecificProfilesActivity extends PreferenceActivity
|
||||
}
|
||||
|
||||
addPreferencesFromResource(R.xml.bluetooth_device_advanced);
|
||||
getPreferenceScreen().setOrderingAsAdded(false);
|
||||
|
||||
mProfileContainer = (PreferenceGroup) findPreference(KEY_PROFILE_CONTAINER);
|
||||
mAllowIncomingPref = (CheckBoxPreference) findPreference(KEY_ALLOW_INCOMING);
|
||||
mAllowIncomingPref.setChecked(isIncomingFileTransfersAllowed());
|
||||
|
||||
mDeviceNamePref = (EditTextPreference) findPreference(KEY_RENAME_DEVICE);
|
||||
mDeviceNamePref.setSummary(mCachedDevice.getName());
|
||||
mDeviceNamePref.setText(mCachedDevice.getName());
|
||||
|
||||
// Set the title of the screen
|
||||
findPreference(KEY_TITLE).setTitle(
|
||||
getString(R.string.bluetooth_device_advanced_title, mCachedDevice.getName()));
|
||||
|
||||
// Listen for check/uncheck of the online mode checkbox
|
||||
mOnlineModePreference = (CheckBoxPreference) findPreference(KEY_ONLINE_MODE);
|
||||
mOnlineModePreference.setOnPreferenceChangeListener(this);
|
||||
findPreference(KEY_TITLE).setTitle(getResources()
|
||||
.getString(R.string.bluetooth_device_advanced_title, mCachedDevice.getName()));
|
||||
|
||||
// Add a preference for each profile
|
||||
addPreferencesForProfiles();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onSaveInstanceState(Bundle outState) {
|
||||
public void onSaveInstanceState(Bundle outState) {
|
||||
super.onSaveInstanceState(outState);
|
||||
|
||||
outState.putParcelable(EXTRA_DEVICE, mCachedDevice.getDevice());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResume() {
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
|
||||
mManager.setForegroundActivity(this);
|
||||
mManager.setForegroundActivity(getActivity());
|
||||
mCachedDevice.registerCallback(this);
|
||||
|
||||
refresh();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPause() {
|
||||
public void onPause() {
|
||||
super.onPause();
|
||||
|
||||
mCachedDevice.unregisterCallback(this);
|
||||
@@ -138,18 +146,20 @@ public class ConnectSpecificProfilesActivity extends PreferenceActivity
|
||||
* @return A preference that allows the user to choose whether this profile
|
||||
* will be connected to.
|
||||
*/
|
||||
private CheckBoxPreference createProfilePreference(Profile profile) {
|
||||
CheckBoxPreference pref = new CheckBoxPreference(this);
|
||||
private Preference createProfilePreference(Profile profile) {
|
||||
BluetoothProfilePreference pref = new BluetoothProfilePreference(getActivity(), profile);
|
||||
pref.setKey(profile.toString());
|
||||
pref.setTitle(profile.localizedString);
|
||||
pref.setExpanded(false);
|
||||
pref.setPersistent(false);
|
||||
pref.setOnPreferenceChangeListener(this);
|
||||
pref.setOrder(getProfilePreferenceIndex(profile));
|
||||
pref.setOnExpandClickListener(this);
|
||||
|
||||
LocalBluetoothProfileManager profileManager = LocalBluetoothProfileManager
|
||||
.getProfileManager(mManager, profile);
|
||||
|
||||
/**
|
||||
* Gray out checkbox while connecting and disconnecting
|
||||
* Gray out profile while connecting and disconnecting
|
||||
*/
|
||||
pref.setEnabled(!mCachedDevice.isBusy());
|
||||
|
||||
@@ -158,37 +168,46 @@ public class ConnectSpecificProfilesActivity extends PreferenceActivity
|
||||
return pref;
|
||||
}
|
||||
|
||||
public boolean onPreferenceChange(Preference preference, Object newValue) {
|
||||
@Override
|
||||
public boolean onPreferenceTreeClick(PreferenceScreen screen, Preference preference) {
|
||||
String key = preference.getKey();
|
||||
if (TextUtils.isEmpty(key) || newValue == null) return true;
|
||||
if (preference instanceof BluetoothProfilePreference) {
|
||||
onProfileClicked(preference, Profile.valueOf(key));
|
||||
return true;
|
||||
} else if (key.equals(KEY_UNPAIR)) {
|
||||
unpairDevice();
|
||||
finish();
|
||||
return true;
|
||||
}
|
||||
|
||||
if (key.equals(KEY_ONLINE_MODE)) {
|
||||
onOnlineModeCheckedStateChanged((Boolean) newValue);
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean onPreferenceChange(Preference preference, Object newValue) {
|
||||
if (preference == mAllowIncomingPref) {
|
||||
setIncomingFileTransfersAllowed(mAllowIncomingPref.isChecked());
|
||||
} else if (preference == mDeviceNamePref) {
|
||||
// TODO: Verify and check for error conditions
|
||||
mCachedDevice.setName(mDeviceNamePref.getText());
|
||||
} else {
|
||||
Profile profile = getProfileOf(preference);
|
||||
if (profile == null) return false;
|
||||
onProfileCheckedStateChanged(profile, (Boolean) newValue);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private void onOnlineModeCheckedStateChanged(boolean checked) {
|
||||
setOnlineMode(checked, true);
|
||||
}
|
||||
|
||||
private void onProfileCheckedStateChanged(Profile profile, boolean checked) {
|
||||
private void onProfileClicked(Preference preference, Profile profile) {
|
||||
LocalBluetoothProfileManager profileManager = LocalBluetoothProfileManager
|
||||
.getProfileManager(mManager, profile);
|
||||
profileManager.setPreferred(mCachedDevice.getDevice(), checked);
|
||||
if (mOnlineMode) {
|
||||
if (checked) {
|
||||
mCachedDevice.connect(profile);
|
||||
} else {
|
||||
mCachedDevice.disconnect(profile);
|
||||
}
|
||||
}
|
||||
// TODO: Get the current state and flip it, updating the summary for the preference
|
||||
|
||||
// profileManager.setPreferred(mCachedDevice.getDevice(), checked);
|
||||
//
|
||||
// if (checked) {
|
||||
// mCachedDevice.connect(profile);
|
||||
// } else {
|
||||
// mCachedDevice.disconnect(profile);
|
||||
// }
|
||||
}
|
||||
|
||||
public void onDeviceAttributesChanged(CachedBluetoothDevice cachedDevice) {
|
||||
@@ -196,51 +215,12 @@ public class ConnectSpecificProfilesActivity extends PreferenceActivity
|
||||
}
|
||||
|
||||
private void refresh() {
|
||||
// We are in 'online mode' if we are connected, connecting, or disconnecting
|
||||
setOnlineMode(mCachedDevice.isConnected() || mCachedDevice.isBusy(), false);
|
||||
refreshProfiles();
|
||||
}
|
||||
|
||||
/**
|
||||
* Switches between online/offline mode.
|
||||
*
|
||||
* @param onlineMode Whether to be in online mode, or offline mode.
|
||||
* @param takeAction Whether to take action (i.e., connect or disconnect)
|
||||
* based on the new online mode.
|
||||
*/
|
||||
private void setOnlineMode(boolean onlineMode, boolean takeAction) {
|
||||
mOnlineMode = onlineMode;
|
||||
|
||||
if (takeAction) {
|
||||
if (onlineMode) {
|
||||
mCachedDevice.connect();
|
||||
} else {
|
||||
mCachedDevice.disconnect();
|
||||
}
|
||||
}
|
||||
|
||||
refreshOnlineModePreference();
|
||||
}
|
||||
|
||||
private void refreshOnlineModePreference() {
|
||||
mOnlineModePreference.setChecked(mOnlineMode);
|
||||
|
||||
/* Gray out checkbox while connecting and disconnecting */
|
||||
mOnlineModePreference.setEnabled(!mCachedDevice.isBusy());
|
||||
|
||||
/**
|
||||
* If the device is online, show status. Otherwise, show a summary that
|
||||
* describes what the checkbox does.
|
||||
*/
|
||||
mOnlineModePreference.setSummary(mOnlineMode ?
|
||||
mCachedDevice.getSummary(CachedBluetoothDevice.OTHER_PROFILES)
|
||||
: R.string.bluetooth_device_advanced_online_mode_summary);
|
||||
}
|
||||
|
||||
private void refreshProfiles() {
|
||||
for (Profile profile : mCachedDevice.getConnectableProfiles()) {
|
||||
CheckBoxPreference profilePref =
|
||||
(CheckBoxPreference) findPreference(profile.toString());
|
||||
Preference profilePref = findPreference(profile.toString());
|
||||
if (profilePref == null) {
|
||||
profilePref = createProfilePreference(profile);
|
||||
mProfileContainer.addPreference(profilePref);
|
||||
@@ -250,7 +230,7 @@ public class ConnectSpecificProfilesActivity extends PreferenceActivity
|
||||
}
|
||||
}
|
||||
|
||||
private void refreshProfilePreference(CheckBoxPreference profilePref, Profile profile) {
|
||||
private void refreshProfilePreference(Preference profilePref, Profile profile) {
|
||||
BluetoothDevice device = mCachedDevice.getDevice();
|
||||
LocalBluetoothProfileManager profileManager = LocalBluetoothProfileManager
|
||||
.getProfileManager(mManager, profile);
|
||||
@@ -262,9 +242,9 @@ public class ConnectSpecificProfilesActivity extends PreferenceActivity
|
||||
*/
|
||||
profilePref.setEnabled(!mCachedDevice.isBusy());
|
||||
profilePref.setSummary(getProfileSummary(profileManager, profile, device,
|
||||
connectionStatus, mOnlineMode));
|
||||
|
||||
profilePref.setChecked(profileManager.isPreferred(device));
|
||||
connectionStatus, isDeviceOnline()));
|
||||
// TODO:
|
||||
//profilePref.setChecked(profileManager.isPreferred(device));
|
||||
}
|
||||
|
||||
private Profile getProfileOf(Preference pref) {
|
||||
@@ -307,4 +287,60 @@ public class ConnectSpecificProfilesActivity extends PreferenceActivity
|
||||
}
|
||||
}
|
||||
|
||||
public void onClick(View v) {
|
||||
if (v.getTag() instanceof Profile) {
|
||||
Profile prof = (Profile) v.getTag();
|
||||
CheckBoxPreference autoConnectPref = mAutoConnectPrefs.get(prof.toString());
|
||||
if (autoConnectPref == null) {
|
||||
autoConnectPref = new CheckBoxPreference(getActivity());
|
||||
autoConnectPref.setKey(prof.toString() + AUTO_CONNECT_KEY_SUFFIX);
|
||||
autoConnectPref.setTitle(getCheckBoxTitle(prof));
|
||||
autoConnectPref.setOrder(getProfilePreferenceIndex(prof) + 1);
|
||||
autoConnectPref.setChecked(getAutoConnect(prof));
|
||||
mAutoConnectPrefs.put(prof.name(), autoConnectPref);
|
||||
}
|
||||
BluetoothProfilePreference profilePref =
|
||||
(BluetoothProfilePreference) findPreference(prof.toString());
|
||||
if (profilePref != null) {
|
||||
if (profilePref.isExpanded()) {
|
||||
mProfileContainer.addPreference(autoConnectPref);
|
||||
} else {
|
||||
mProfileContainer.removePreference(autoConnectPref);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private int getProfilePreferenceIndex(Profile prof) {
|
||||
return mProfileContainer.getOrder() + prof.ordinal() * 10;
|
||||
}
|
||||
|
||||
private void unpairDevice() {
|
||||
mCachedDevice.unpair();
|
||||
}
|
||||
|
||||
private boolean isDeviceOnline() {
|
||||
// TODO: Verify
|
||||
return mCachedDevice.isConnected() || mCachedDevice.isBusy();
|
||||
}
|
||||
|
||||
private void setIncomingFileTransfersAllowed(boolean allow) {
|
||||
// TODO:
|
||||
Log.d(TAG, "Set allow incoming = " + allow);
|
||||
}
|
||||
|
||||
private boolean isIncomingFileTransfersAllowed() {
|
||||
// TODO:
|
||||
return true;
|
||||
}
|
||||
|
||||
private String getCheckBoxTitle(Profile prof) {
|
||||
// TODO: Use resources and base it on profile if necessary
|
||||
return "Auto connect";
|
||||
}
|
||||
|
||||
private boolean getAutoConnect(Profile prof) {
|
||||
// TODO: Get the auto connect toggle state for the profile
|
||||
return true;
|
||||
}
|
||||
}
|
@@ -47,7 +47,7 @@ public class LocalBluetoothManager {
|
||||
private static final String SHARED_PREFERENCES_NAME = "bluetooth_settings";
|
||||
|
||||
/** Singleton instance. */
|
||||
private static LocalBluetoothManager INSTANCE;
|
||||
private static LocalBluetoothManager sInstance;
|
||||
private boolean mInitialized;
|
||||
|
||||
private Context mContext;
|
||||
@@ -87,17 +87,17 @@ public class LocalBluetoothManager {
|
||||
|
||||
public static LocalBluetoothManager getInstance(Context context) {
|
||||
synchronized (LocalBluetoothManager.class) {
|
||||
if (INSTANCE == null) {
|
||||
INSTANCE = new LocalBluetoothManager();
|
||||
if (sInstance == null) {
|
||||
sInstance = new LocalBluetoothManager();
|
||||
}
|
||||
|
||||
if (!INSTANCE.init(context)) {
|
||||
if (!sInstance.init(context)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
LocalBluetoothProfileManager.init(INSTANCE);
|
||||
LocalBluetoothProfileManager.init(sInstance);
|
||||
|
||||
return INSTANCE;
|
||||
return sInstance;
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -31,12 +31,10 @@ import android.os.ParcelUuid;
|
||||
import android.util.Log;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* LocalBluetoothProfileManager is an abstract class defining the basic
|
||||
@@ -123,7 +121,8 @@ public abstract class LocalBluetoothProfileManager {
|
||||
}
|
||||
}
|
||||
|
||||
private static LinkedList<ServiceListener> mServiceListeners = new LinkedList<ServiceListener>();
|
||||
private static LinkedList<ServiceListener> mServiceListeners =
|
||||
new LinkedList<ServiceListener>();
|
||||
|
||||
public static void addServiceListener(ServiceListener l) {
|
||||
mServiceListeners.add(l);
|
||||
@@ -221,6 +220,10 @@ public abstract class LocalBluetoothProfileManager {
|
||||
|
||||
public abstract boolean isProfileReady();
|
||||
|
||||
public int getDrawableResource() {
|
||||
return R.drawable.ic_bt_headphones_a2dp;
|
||||
}
|
||||
|
||||
// TODO: int instead of enum
|
||||
public enum Profile {
|
||||
HEADSET(R.string.bluetooth_profile_headset),
|
||||
@@ -347,6 +350,11 @@ public abstract class LocalBluetoothProfileManager {
|
||||
public boolean isProfileReady() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getDrawableResource() {
|
||||
return R.drawable.ic_bt_headphones_a2dp;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -489,6 +497,11 @@ public abstract class LocalBluetoothProfileManager {
|
||||
return SettingsBtStatus.CONNECTION_STATUS_UNKNOWN;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getDrawableResource() {
|
||||
return R.drawable.ic_bt_headset_hfp;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -563,6 +576,12 @@ public abstract class LocalBluetoothProfileManager {
|
||||
return SettingsBtStatus.CONNECTION_STATUS_UNKNOWN;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getDrawableResource() {
|
||||
// TODO:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
private static class HidProfileManager extends LocalBluetoothProfileManager {
|
||||
@@ -645,6 +664,12 @@ public abstract class LocalBluetoothProfileManager {
|
||||
mService.setInputDevicePriority(device, BluetoothInputDevice.PRIORITY_OFF);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getDrawableResource() {
|
||||
// TODO:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
private static class PanProfileManager extends LocalBluetoothProfileManager {
|
||||
@@ -721,5 +746,11 @@ public abstract class LocalBluetoothProfileManager {
|
||||
public void setPreferred(BluetoothDevice device, boolean preferred) {
|
||||
return;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getDrawableResource() {
|
||||
// TODO:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user