• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2011 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.settings.bluetooth;
18 
19 import android.app.AlertDialog;
20 import android.app.Dialog;
21 import android.app.DialogFragment;
22 import android.bluetooth.BluetoothAdapter;
23 import android.content.BroadcastReceiver;
24 import android.content.Context;
25 import android.content.DialogInterface;
26 import android.content.Intent;
27 import android.content.IntentFilter;
28 import android.os.Bundle;
29 import android.text.Editable;
30 import android.text.InputFilter;
31 import android.text.TextWatcher;
32 import android.util.Log;
33 import android.view.LayoutInflater;
34 import android.view.View;
35 import android.widget.Button;
36 import android.widget.EditText;
37 
38 import com.android.settings.R;
39 
40 /**
41  * Dialog fragment for renaming the local Bluetooth device.
42  */
43 public final class BluetoothNameDialogFragment extends DialogFragment implements TextWatcher {
44     private static final int BLUETOOTH_NAME_MAX_LENGTH_BYTES = 248;
45 
46     private AlertDialog mAlertDialog;
47     private Button mOkButton;
48 
49     // accessed from inner class (not private to avoid thunks)
50     static final String TAG = "BluetoothNameDialogFragment";
51     final LocalBluetoothAdapter mLocalAdapter;
52     EditText mDeviceNameView;
53 
54     // This flag is set when the name is updated by code, to distinguish from user changes
55     private boolean mDeviceNameUpdated;
56 
57     // This flag is set when the user edits the name (preserved on rotation)
58     private boolean mDeviceNameEdited;
59 
60     // Key to save the edited name and edit status for restoring after rotation
61     private static final String KEY_NAME = "device_name";
62     private static final String KEY_NAME_EDITED = "device_name_edited";
63 
64     private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
65         @Override
66         public void onReceive(Context context, Intent intent) {
67             String action = intent.getAction();
68             if (action.equals(BluetoothAdapter.ACTION_LOCAL_NAME_CHANGED)) {
69                 updateDeviceName();
70             } else if (action.equals(BluetoothAdapter.ACTION_STATE_CHANGED) &&
71                     (intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, BluetoothAdapter.ERROR) ==
72                             BluetoothAdapter.STATE_ON)) {
73                 updateDeviceName();
74             }
75         }
76     };
77 
BluetoothNameDialogFragment()78     public BluetoothNameDialogFragment() {
79         LocalBluetoothManager localManager = LocalBluetoothManager.getInstance(getActivity());
80         mLocalAdapter = localManager.getBluetoothAdapter();
81     }
82 
83     @Override
onCreateDialog(Bundle savedInstanceState)84     public Dialog onCreateDialog(Bundle savedInstanceState) {
85         String deviceName = mLocalAdapter.getName();
86         if (savedInstanceState != null) {
87             deviceName = savedInstanceState.getString(KEY_NAME, deviceName);
88             mDeviceNameEdited = savedInstanceState.getBoolean(KEY_NAME_EDITED, false);
89         }
90         mAlertDialog = new AlertDialog.Builder(getActivity())
91                 .setIcon(android.R.drawable.ic_dialog_info)
92                 .setTitle(R.string.bluetooth_rename_device)
93                 .setView(createDialogView(deviceName))
94                 .setPositiveButton(R.string.bluetooth_rename_button,
95                         new DialogInterface.OnClickListener() {
96                             public void onClick(DialogInterface dialog, int which) {
97                                 if (mLocalAdapter != null) {
98                                     String deviceName = mDeviceNameView.getText().toString();
99                                     Log.d(TAG, "Setting device name to " + deviceName);
100                                     mLocalAdapter.setName(deviceName);
101                                 }
102                             }
103                         })
104                 .setNegativeButton(android.R.string.cancel, null)
105                 .create();
106 
107         return mAlertDialog;
108     }
109 
110     @Override
onSaveInstanceState(Bundle outState)111     public void onSaveInstanceState(Bundle outState) {
112         outState.putString(KEY_NAME, mDeviceNameView.getText().toString());
113         outState.putBoolean(KEY_NAME_EDITED, mDeviceNameEdited);
114     }
115 
createDialogView(String deviceName)116     private View createDialogView(String deviceName) {
117         final LayoutInflater layoutInflater = (LayoutInflater)getActivity()
118             .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
119         View view = layoutInflater.inflate(R.layout.dialog_edittext, null);
120         mDeviceNameView = (EditText) view.findViewById(R.id.edittext);
121         mDeviceNameView.setFilters(new InputFilter[] {
122                 new Utf8ByteLengthFilter(BLUETOOTH_NAME_MAX_LENGTH_BYTES)
123         });
124         mDeviceNameView.setText(deviceName);    // set initial value before adding listener
125         mDeviceNameView.addTextChangedListener(this);
126         return view;
127     }
128 
129     @Override
onDestroy()130     public void onDestroy() {
131         super.onDestroy();
132         mAlertDialog = null;
133         mDeviceNameView = null;
134         mOkButton = null;
135     }
136 
137     @Override
onResume()138     public void onResume() {
139         super.onResume();
140         if (mOkButton == null) {
141             mOkButton = mAlertDialog.getButton(DialogInterface.BUTTON_POSITIVE);
142             mOkButton.setEnabled(mDeviceNameEdited);    // Ok button enabled after user edits
143         }
144         IntentFilter filter = new IntentFilter();
145         filter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED);
146         filter.addAction(BluetoothAdapter.ACTION_LOCAL_NAME_CHANGED);
147         getActivity().registerReceiver(mReceiver, filter);
148     }
149 
150     @Override
onPause()151     public void onPause() {
152         super.onPause();
153         getActivity().unregisterReceiver(mReceiver);
154     }
155 
updateDeviceName()156     void updateDeviceName() {
157         if (mLocalAdapter != null && mLocalAdapter.isEnabled()) {
158             mDeviceNameUpdated = true;
159             mDeviceNameEdited = false;
160             mDeviceNameView.setText(mLocalAdapter.getName());
161         }
162     }
163 
afterTextChanged(Editable s)164     public void afterTextChanged(Editable s) {
165         if (mDeviceNameUpdated) {
166             // Device name changed by code; disable Ok button until edited by user
167             mDeviceNameUpdated = false;
168             mOkButton.setEnabled(false);
169         } else {
170             mDeviceNameEdited = true;
171             if (mOkButton != null) {
172                 mOkButton.setEnabled(s.length() != 0);
173             }
174         }
175     }
176 
177     /* Not used */
beforeTextChanged(CharSequence s, int start, int count, int after)178     public void beforeTextChanged(CharSequence s, int start, int count, int after) {
179     }
180 
181     /* Not used */
onTextChanged(CharSequence s, int start, int before, int count)182     public void onTextChanged(CharSequence s, int start, int before, int count) {
183     }
184 }
185