Files
app_Settings/src/com/android/settings/bluetooth/BluetoothNameDialogFragment.java
Jake Hamby a9534367b5 Fix IME soft keyboard for Bluetooth rename device dialog.
The soft keyboard should automatically pop up when the user selects
the Bluetooth rename device menu item. Fixed by calling
setSoftInputMode(SOFT_INPUT_STATE_ALWAYS_VISIBLE) on the Window
containing the AlertDialog before showing.

The device name field should also be a single line field, with the
Done button causing the device to be renamed. Set the "singleLine"
attribute in the layout XML to true, and added a
TextView.OnEditorActionListener to set the device name and dismiss
the dialog for EditorInfo.IME_ACTION_DONE.

Bug: 5342542
Bug: 5343354
Change-Id: I550d8e9a59395ad66f8a9c11d29c0f2ef278c196
2012-03-13 20:08:22 -07:00

205 lines
7.6 KiB
Java

/*
* 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.KeyEvent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.WindowManager;
import android.view.inputmethod.EditorInfo;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import com.android.settings.R;
/**
* Dialog fragment for renaming the local Bluetooth device.
*/
public 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;
// This flag is set when the user edits the name (preserved on rotation)
private boolean mDeviceNameEdited;
// Key to save the edited name and edit status for restoring after rotation
private static final String KEY_NAME = "device_name";
private static final String KEY_NAME_EDITED = "device_name_edited";
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() {
LocalBluetoothManager localManager = LocalBluetoothManager.getInstance(getActivity());
mLocalAdapter = localManager.getBluetoothAdapter();
}
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
String deviceName = mLocalAdapter.getName();
if (savedInstanceState != null) {
deviceName = savedInstanceState.getString(KEY_NAME, deviceName);
mDeviceNameEdited = savedInstanceState.getBoolean(KEY_NAME_EDITED, false);
}
mAlertDialog = new AlertDialog.Builder(getActivity())
.setIcon(android.R.drawable.ic_dialog_info)
.setTitle(R.string.bluetooth_rename_device)
.setView(createDialogView(deviceName))
.setPositiveButton(R.string.bluetooth_rename_button,
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
String deviceName = mDeviceNameView.getText().toString();
setDeviceName(deviceName);
}
})
.setNegativeButton(android.R.string.cancel, null)
.create();
mAlertDialog.getWindow().setSoftInputMode(
WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE);
return mAlertDialog;
}
private void setDeviceName(String deviceName) {
Log.d(TAG, "Setting device name to " + deviceName);
mLocalAdapter.setName(deviceName);
}
@Override
public void onSaveInstanceState(Bundle outState) {
outState.putString(KEY_NAME, mDeviceNameView.getText().toString());
outState.putBoolean(KEY_NAME_EDITED, mDeviceNameEdited);
}
private View createDialogView(String deviceName) {
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.setText(deviceName); // set initial value before adding listener
mDeviceNameView.addTextChangedListener(this);
mDeviceNameView.setOnEditorActionListener(new TextView.OnEditorActionListener() {
@Override
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
if (actionId == EditorInfo.IME_ACTION_DONE) {
setDeviceName(v.getText().toString());
mAlertDialog.dismiss();
return true; // action handled
} else {
return false; // not handled
}
}
});
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(mDeviceNameEdited); // Ok button enabled after user edits
}
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();
getActivity().unregisterReceiver(mReceiver);
}
void updateDeviceName() {
if (mLocalAdapter != null && mLocalAdapter.isEnabled()) {
mDeviceNameUpdated = true;
mDeviceNameEdited = false;
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 {
mDeviceNameEdited = true;
if (mOkButton != null) {
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) {
}
}