Requirements 1:android device comes with a keypad with nine keys, at which point the keypad is recognized as HW Keyboard, and the default and soft keyboard cannot coexist, requiring the soft keyboard to coexist with the physical keyboard.
Realize:
On the internet to find others summed up the Android5.1 solution, need to solve the codebase for Android6.0, can be used.
Method One: (This method is not available in Android8.0 codebase) frameworks/base/services/core/java/com/android/server/wm/ Windowmanagerservice.java, if the Showimewithhardkeyboard variable in the Updateshowimewithhardkeyboard () method is directly set to True, You can use both a soft keyboard and a physical keyboard. (originally to read the Setting database field to judge, so you can also directly modify the setting field to implement)
public void updateShowImeWithHardKeyboard() { synchronized (mWindowMap) { final boolean showImeWithHardKeyboard = Settings.Secure.getIntForUser(
mContext.getContentResolver(), Settings.Secure.SHOW_IME_WITH_HARD_KEYBOARD, 0,
mCurrentUserId) == 1;if (mShowImeWithHardKeyboard != showImeWithHardKeyboard) {
mShowImeWithHardKeyboard = showImeWithHardKeyboard;
mH.sendEmptyMessage(H.SEND_NEW_CONFIGURATION);
}
}
}
Method Two: Frameworks/base/core/java/android/inputmethodservice/inputmethodservice.java, modify Onevaluateinputviewshown () Method directly returns True
public boolean onEvaluateInputViewShown() {
Configuration config = getResources().getConfiguration(); //return config.keyboard == Configuration.KEYBOARD_NOKEYS // || config.hardKeyboardHidden == Configuration.HARDKEYBOARDHIDDEN_YES; return true;
}
Method Three: In the external need to modify the appropriate location, directly setting field modification, can be changed back, once and for all.
Settings.Secure.putInt (Mcontext.getcontentresolver (), Settings.Secure.SHOW_IME_WITH_HARD_KEYBOARD, 1); // 1:disabled,0:enabled
Requirement 2: The soft keyboard and the built-in physical keyboard coexist on the basis of the external Bluetooth keyboard. The external Bluetooth keyboard cannot coexist with the soft keyboard at this time.
Analysis: At this time the external keyboard is also considered a physical keyboard, according to the above requirements 1 method modified, so that the Bluetooth keyboard and the soft keyboard is co-exist, so does not meet the requirements. Need to find the location of the Bluetooth keyboard connection, to the front of the 1 changes in the place to cancel out.
That is: When the Bluetooth keyboard is not connected, the setting field is changed to coexist mode so that the soft keyboard and the built-in physical keyboard coexist; After connecting the Bluetooth keyboard, change the setting field to non-coexistence mode so that the soft keyboard does not coexist with the Bluetooth keyboard (the Bluetooth keyboard is coexisting with the built-in physical keyboard).
Implementation: The difficulty of this requirement is to find the right place to modify the setting field, which is the appropriate location: The Bluetooth keyboard connection is successful or disconnected, and Bluetooth is turned off.
Implementing the Analysis Process:
1. Through the Bluetooth Settings section of the settings, you can see that the type of Bluetooth device can be distinguished by an icon when connecting to a Bluetooth keyboard. This makes it possible to differentiate between Bluetooth keyboards and other Bluetooth devices.
In the Packages/apps/settings/src/com/android/settings/bluetooth/bluetoothdevicepreference.java, according to the icon can be seen, different kinds of BT Device can already be differentiated.
private int getBtClassDrawable() {
BluetoothClass btClass = mCachedDevice.getBtClass();
if (btClass != null) {
switch (btClass.getMajorDeviceClass()) {
case BluetoothClass.Device.Major.COMPUTER:
return R.drawable.ic_bt_laptop;
case BluetoothClass.Device.Major.PHONE:
return R.drawable.ic_bt_cellphone;
case BluetoothClass.Device.Major.PERIPHERAL:
return HidProfile.getHidClassDrawable(btClass);
case BluetoothClass.Device.Major.IMAGING:
return R.drawable.ic_bt_imaging;
default:
// unrecognized device class; continue
}
} else {
Log.w(TAG, "mBtClass is null");
}
...
The desired Bluetooth keyboard is available in hidprofile.gethidclassdrawable (Btclass).
Frameworks/base/packages/settingslib/src/com/android/settingslib/bluetooth/hidprofile.java
public static int getHidClassDrawable(BluetoothClass btClass) {
switch (btClass.getDeviceClass()) {
case BluetoothClass.Device.PERIPHERAL_KEYBOARD:
case BluetoothClass.Device.PERIPHERAL_KEYBOARD_POINTING:
return R.drawable.ic_lockscreen_ime;
case BluetoothClass.Device.PERIPHERAL_POINTING:
return R.drawable.ic_bt_pointing_hid;
default:
return R.drawable.ic_bt_misc_hid;
}
}
2. By grasping the system Bluetooth profile log to confirm that the Bluetooth keyboard is disconnected, it will be in the framework of the Bluetooth side is trigger to.
ADB logcat |grep Profile
When connecting/disconnecting the Bluetooth keyboard, you can catch the following log:
[email protected]:~$ adb logcat |grep Profile
12-22 03:55:00.524 1257 1257 I SystemServer: SamplingProfiler Service
12-22 04:29:41.923 3916 4051 D CachedBluetoothDevice: onProfileStateChanged: profile HID newProfileState 0
12-22 06:25:59.666 7284 7284 D CachedBluetoothDevice: onProfileStateChanged: profile HID newProfileState 2
12-22 06:25:59.668 3916 4051 D CachedBluetoothDevice: onProfileStateChanged: profile HID newProfileState 2
12-22 06:26:33.245 7284 7284 D CachedBluetoothDevice: onProfileStateChanged: profile HID newProfileState 0
12-22 06:26:33.245 3916 4051 D CachedBluetoothDevice: onProfileStateChanged: profile HID newProfileState 0
12-22 06:26:45.586 7284 7284 D CachedBluetoothDevice: onProfileStateChanged: profile HID newProfileState 2
12-22 06:26:45.587 3916 4051 D CachedBluetoothDevice: onProfileStateChanged: profile HID newProfileState 2
...
can be positioned to Frameworks/base/packages/settingslib/src/com/android/settingslib/bluetooth/cachedbluetoothdevice.java
As you can see in the Onprofilestatechanged method, Bluetooth connects and disconnects as you go! and to get Bluetooth device type of context also has! This problem solves more than half!
When you add a Bluetooth connection and disconnect the device type in the Onprofilestatechanged method, determine:
if(mBtClass.getMajorDeviceClass() == BluetoothClass.Device.Major.PERIPHERAL
&& (mBtClass.getDeviceClass() == BluetoothClass.Device.PERIPHERAL_KEYBOARD
|| mBtClass.getDeviceClass() == BluetoothClass.Device.PERIPHERAL_KEYBOARD_POINTING)) {
Log.i("Kunkka0", "getMajorDeviceClass = Peripheral & getDeviceClass = KeyBoard");
if(newProfileState == 0) {// Disconnected
Log.i("Kunkka0","SET SHOW_IME_WITH_HARD_KEYBOARD TO 1");
Settings.Secure.putInt(mContext.getContentResolver(), Settings.Secure.SHOW_IME_WITH_HARD_KEYBOARD, 1);
}else {
Log.i("Kunkka0","SET SHOW_IME_WITH_HARD_KEYBOARD TO 0");
Settings.Secure.putInt(mContext.getContentResolver(), Settings.Secure.SHOW_IME_WITH_HARD_KEYBOARD, 0);
}
}else {
Log.i("Kunkka0","getMajorDeviceClass() = "+mBtClass.getMajorDeviceClass()+", getDeviceClass = "+mBtClass.getDeviceClass());
Log.i("Kunkka0","PERIPHERAL = 1280, PERIPHERAL_KEYBOARD = 1344, PERIPHERAL_KEYBOARD_POINTING = 1472");
}
After compiling the image to test, function implementation!
However, when Bluetooth is turned off, the Bluetooth keyboard is not available, but there is no status change here! At this point, turn off Bluetooth, soft keyboard and Bluetooth keyboard can not be used!
3. In order to solve the problem of turning off Bluetooth, then search the Bluetooth switch status Change event:
As you can see in Frameworks/base/packages/settingslib/src/com/android/settingslib/bluetooth/bluetoothcallback.java, there are:
void onBluetoothStateChanged(int bluetoothState);
void onScanningStateChanged(boolean started);
void onDeviceAdded(CachedBluetoothDevice cachedDevice);
void onDeviceDeleted(CachedBluetoothDevice cachedDevice);
void onDeviceBondStateChanged(CachedBluetoothDevice cachedDevice, int bondState);
void onConnectionStateChanged(CachedBluetoothDevice cachedDevice, int state);
View all overloads of this event Class,open implementation-can see:
The following are settings, but we need more than settings, so look at the statusbar below Keyboardui and Systemui.
StatusBar below the Bluetoothcontrollerimpl is more consistent.
Open Frameworks/base/packages/systemui/src/com/android/systemui/statusbar/policy/bluetoothcontrollerimpl.java
In addition to onbluetoothstatechanged there is a updateconnected () method, incredibly can also detect the Bluetooth device connection status!
So we just need to add event detection in onbluetoothstatechanged () and updateconnected () to modify the settings field!
4. Final Solution:
A. In onbluetoothstatechanged (), when Bluetooth is off, make the keyboard coexist, guaranteeing the coexistence of the soft keyboard and the built-in physical keyboard.
@Override
public void onBluetoothStateChanged(int bluetoothState) {
mEnabled = bluetoothState == BluetoothAdapter.STATE_ON;
if(!mEnabled) {
Log.i("Kunkka0","onBluetoothStateChanged: SET SHOW_IME_WITH_HARD_KEYBOARD TO 1");
Settings.Secure.putInt(mContext.getContentResolver(), Settings.Secure.SHOW_IME_WITH_HARD_KEYBOARD, 1);
}
mHandler.sendEmptyMessage(H.MSG_STATE_CHANGED);
}
B. In updateconnected (), when the Bluetooth keyboard is connected, so that the soft and hard keyboard does not coexist, when the Bluetooth keyboard disconnects, the hardware and software disk coexistence.
private void updateConnected() {
...
for (CachedBluetoothDevice device : getDevices()) {
if (device.isConnected()) {
mLastDevice = device;
}
if(device.getBtClass().getMajorDeviceClass() == BluetoothClass.Device.Major.PERIPHERAL
&& (device.getBtClass().getDeviceClass() == BluetoothClass.Device.PERIPHERAL_KEYBOARD
|| device.getBtClass().getDeviceClass() == BluetoothClass.Device.PERIPHERAL_KEYBOARD_POINTING)) {
Log.i("Kunkka0", "getMajorDeviceClass = Peripheral & getDeviceClass = KeyBoard");
if(!device.isConnected()) {// Disconnected
Log.i("Kunkka0","SET SHOW_IME_WITH_HARD_KEYBOARD TO 1");
Settings.Secure.putInt(mContext.getContentResolver(), Settings.Secure.SHOW_IME_WITH_HARD_KEYBOARD, 1);
}else {
Log.i("Kunkka0","SET SHOW_IME_WITH_HARD_KEYBOARD TO 0");
Settings.Secure.putInt(mContext.getContentResolver(), Settings.Secure.SHOW_IME_WITH_HARD_KEYBOARD, 0);
}
}else {
Log.i("Kunkka0","getMajorDeviceClass() = "+device.getBtClass().getMajorDeviceClass()+", getDeviceClass = "+device.getBtClass().getDeviceClass());
Log.i("Kunkka0","PERIPHERAL = 1280, PERIPHERAL_KEYBOARD = 1344, PERIPHERAL_KEYBOARD_POINTING = 1472");
}
}
...
}
Test, verify through!
Android Source Development Note the soft keyboard coexists with the built-in physical keyboard and the external Bluetooth keyboard does not coexist with logic