通過藍牙HID將安卓手機模擬成鼠標和鍵盤


一直以來就有一種想法,就是自己寫一個APP將安卓手機模擬成鼠標/鍵盤,應急的時候可以用來代替鼠標/鍵盤。之前也在國內外的網站上找了各種方案,但是這些方案不是很好,直到谷歌發布的API28后終於有了很好的解決方案。為了實現這個想法也走了不少彎路,也許方法不對吧,但看到最終完美運行的APP,心中還是很有成就感的。經測試裝了此APP的手機能與幾乎所有安卓手機、WIN10筆記本電腦連接並操作,蘋果設備需要IOS13及以上版本才能支持藍牙鼠標/鍵盤。蘋果系統下鼠標功能正常,鍵盤輸入文字沒問題,但是其它功能鍵(如:Win,Menu,PageUp/Down,上下左右鍵...)則沒什么作用。

BluetoothHidDevice
android.bluetooth.BluetoothHidDevice是完成任務的核心類。通過它將我們的應用注冊成具有HID特征的藍牙設備,並傳送HID設備的報告描述符。如果我們的報告描述符沒有問題,那么我們的設備就會成功模擬想要的HID設備。

碼磚思路

  1. 首先將我們的應用注冊為HID設備;
BluetoothAdapter.getDefaultAdapter().getProfileProxy(context, mProfileServiceListener,BluetoothProfile.HID_DEVICE);

public static BluetoothProfile.ServiceListener mProfileServiceListener = new BluetoothProfile.ServiceListener() {
    @Override
    public void onServiceDisconnected(int profile) { }
    @SuppressLint("NewApi") @Override
    public void onServiceConnected(int profile, BluetoothProfile proxy) {
        bluetoothProfile = proxy;
        if (profile == BluetoothProfile.HID_DEVICE) {
            HidDevice = (BluetoothHidDevice) proxy;
            HidConsts.HidDevice = HidDevice;
            BluetoothHidDeviceAppSdpSettings sdp = new BluetoothHidDeviceAppSdpSettings(HidConsts.NAME, HidConsts.DESCRIPTION, HidConsts.PROVIDER,BluetoothHidDevice.SUBCLASS1_COMBO, HidConsts.Descriptor);
            HidDevice.registerApp(sdp, null, null, Executors.newCachedThreadPool(), mCallback);
        }
    }
};
public static final BluetoothHidDevice.Callback mCallback = new BluetoothHidDevice.Callback() {
    @Override
    public void onAppStatusChanged(BluetoothDevice pluggedDevice, boolean registered) { }
    @Override
    public void onConnectionStateChanged(BluetoothDevice device, int state) {
        if(state == BluetoothProfile.STATE_DISCONNECTED){
            HidUitls.IsConnected(false);
            if(connectionStateChangeListener != null){
                connectionStateChangeListener.onDisConnected();
            }
        }else if(state == BluetoothProfile.STATE_CONNECTED){
            HidUitls.IsConnected(true);
            if(connectionStateChangeListener != null){
                connectionStateChangeListener.onConnected();
            }
        }else if(state == BluetoothProfile.STATE_CONNECTING){
            if(connectionStateChangeListener != null){
                connectionStateChangeListener.onConnecting();
            }
        }
    }
};
  1. 然后判斷想要連接的藍牙設備有沒有配對過(雙方都要配對好),如果沒有配對則需要建立配對;
public static boolean Pair(String deviceAddress){
    if(BluetoothAdapter.checkBluetoothAddress(deviceAddress)){
        try {
            mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
            if(BtDevice == null){
                BtDevice = mBluetoothAdapter.getRemoteDevice(deviceAddress);
            }
            if(BtDevice.getBondState() == BluetoothDevice.BOND_NONE){
                BtDevice.createBond();
                return false;
            }else if(BtDevice.getBondState() == BluetoothDevice.BOND_BONDED){
                return true;
            }else if(BtDevice.getBondState() == BluetoothDevice.BOND_BONDING){
                return false;
            }
        }catch (Exception ex){ ex.printStackTrace(); }
    }
    return false;
}
  1. 配對完成后獲取藍牙設備的MAC地址,用MAC地址連接目標設備;
public static boolean Connect(String deviceAddress){
    if(TextUtils.isEmpty(deviceAddress)){return false;}
    mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
    if(BtDevice == null){
        BtDevice = mBluetoothAdapter.getRemoteDevice(deviceAddress);
    }
    boolean ret = HidDevice.connect(BtDevice);
    return ret;
}

IOS13相關設置
安裝了HidDroid后的安卓機要控制蘋果手機需要做如下設置,在蘋果手機上找到:設置->輔助功能->觸控->輔助觸控->設備,選擇已經配對並連接的安卓手機,設置成功后屏幕上出現一個白色的球,這個球就是鼠標指針。
IOS13相關設置
代碼運行效果
https://player.youku.com/embed/XNDYyMTAxNTcwNA==

在鼠標鍵盤的基礎上新增多媒體控制功能,媒體控制包含7個功能,分別是:上一首、下一首、音量+、音量-,停止播放、播放/暫停、靜音。在實現HID媒體播放的過程中發現,安卓對報告描述符的兼容性非常好,只要看上去正確的描述符運行起來基本沒有問題,而win10就沒有那么好的兼容性了,從理論上分析正確的描述符不一定能在win10下工作。經過了不知多少次的嘗試后終於能夠編寫出兼容win10的描述符。還有,既然能兼容安卓,那么智能電視的媒體控制自然是不在話下的。
下面看看效果:
媒體控制界面
win10下媒體控制效果
ios13媒體控制效果
[ios13媒體控制效果]

說明:在win10下用Media Player播放視頻,上一首、下一首功能是后退/快進,用音樂播放器時才是切歌。如果手機上沒有安裝音樂播放器則切歌/播放/暫停/停止功能不起作用,只能調節音量。

就在實現了媒體控制的功能后,偶然在微軟的網站上看到了顯示器亮度調節相關的HID描述符,果斷決定試試。看看微軟官網怎么描述顯示器亮度調節的:https://docs.microsoft.com/zh-cn/windows-hardware/drivers/hid/display-brightness-control

可以看出這里用了2bit來表示,我們在實現媒體控制的時候用來7個按鈕分別對應7個bit,要將亮度控制集成進來就需要9個bit,顯然超過一個字節。糾結半天將媒體控制的停止功能去掉,因為播放/暫停可以實現類似的功能。看到這里你也許會問,報告描述符一個Main Item不能超過8個Control?比如給他9個Control,然后再用7個Bit的Padding填充?這些我都試了,在安卓里雖然不能調節屏幕亮度,其它功能是不受影響的,但是到win10所有功能都受影響了。最后的結論是,暫時將所有Control控制在一個字節內,超過一個字節的Control再慢慢研究。
多媒體控制界面
win10亮度調節
[win10亮度調節]
最后再強調下,這個亮度調節目前只有微軟的win8/win10支持,而且是移動設備(使用電池供電的設備),如果找到Mac和Linux的亮度調節Usage再做兼容。
最近家里新添了小度X8智能屏音響,用HidDroid連接小度X8也是沒有問題的,意外的是發現調節屏幕亮暗的功能在小度X8的DuerOS下也能得到支持,音量調節也是可以的。

完整源碼下載地址

《通過藍牙HID將安卓手機模擬成鼠標和鍵盤》源碼

《通過藍牙HID將安卓手機模擬成鼠標和鍵盤》(媒體控制+win8/10屏幕亮度)+《通過藍牙讓安卓手機成為PC游戲方向盤手柄-支持旋轉輪胎》兩份源碼打包下載


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM