Android Bluetooth開発(三)Bluetooth Hid開発
最近のお客様のニーズでは、androidシステムのデバイスが、スキャンガン(Bluetoothキーボードのようなhidプロトコルのみをサポート)に接続し、データを受信して入力ボックスに記入することができます.androidデバイスに接続するためのBluetoothマウスを借りました.
1 Hid概要
HIDデバイス(Hunman Interface Device Profile)、すなわちヒューマンマシンインタラクティブデバイス、よく見られるのはマウス、キーボード、ゲームハンドルなどです.一般的な有線方式は、USBケーブルで機器に接続され、ユーザ入力機器として使用される.Bluetoothテクノロジーでは、HIDデバイスのアクセスはワイヤレスです.
ネット上で資料を調べてhidはandroidから4.0からサポート(おそらくusb hid)を開始しますが、Bluetooth hidはandroid 4から開始する必要があります.2次の図のようにサポートを開始します.
android4.1.2のBluetoothアプリケーションにはhidの関連コードはないがandroid 4.2ソースコードのBluetoothアプリケーションにhidのコードがあります.
2主なコード
hidデバイスの接続手順: Bluetooth をオンにします. inputDeviceprofile を取得スキャン ペア 接続 2.1 Bluetoothをオンにし、ブロードキャスト受信者によってBluetooth関連ステータスをリスニングします.
2.2 inputDeviceprofileを入手する
//4.2以上でHID対応
if (Build.VERSION.SDK_INT >= 17) {
mHidUtil = HidUtil.getInstance(this);
}
BluetoothAdapterオブジェクト呼び出しgetProfileProxy()関数を使用して、プロキシBluetooth入力デバイスプロキシオブジェクトを取得します.
パラメータmListenerはBluetoothProfileを実装する必要があります.ServiceListener().エージェントオブジェクトの取得に成功したか失敗したかは、Listenerにコールバックされます.
接続エージェントサービスが成功すると、onServiceConnected()関数がコールバックされ、失敗するとonServiceDisconnected()関数がコールバックされます.ここでonServiceConnected()のパラメータproxyタイプはBluetoothProfileであり、ここではBluetoothHeadset、BluetoothA 2 dpオブジェクトを取得してもこのコールバック関数を使用するため、パラメータタイプはBluetoothInputDevice、BluetoothHeadset、BluetoothA 2 dpの親に設定されている.ここでは、BluetoothInputDeviceタイプ(BluetoothInputDeviceはBluetoothProfileのサブクラス)に変換することができます.入力デバイスのエージェントオブジェクトを取得すると、接続操作が可能になります.
2.3スキャン(接続ボタンをクリックしてBluetoothデバイスのスキャンを開始)
2.4ペア
ブロードキャスト受信者は、Bluetoothデバイスをスキャンし、必要なBluetoothデバイスをフィルタしてペアリングし、前にペアリングした場合は直接接続します.
HidUtilクラスでのペアリング方法:
2.5接続(ペアリング成功後)
接続する入力デバイスかどうかを判断し、条件を満たしていれば接続します.
HidUtilでの接続方法
BluetoothInputDeviceのconnectメソッドは非表示なので、このメソッドを反射メカニズムで取得して呼び出す必要があります.
2.6接続状態の傍受
ブロードキャスト受信者によって接続ステータスをリスニングします.
2.7接続解除
HidUtilでのdisconnectメソッド
携帯電話の端末が切断された後、再接続すると「マウスのみが再接続要求を開始します.マウスを使用して再接続してください」というメッセージが表示されます.
3受信データ
adb shell
getevent -l
接続に成功すると、次のように表示されます.
could not get driver version for/dev/input/mouse1, Not a typewriter add device 7:/dev/input/event6 name: "Bluetooth Mouse"
これは、Bluetoothマウスが入力デバイスになったことを示します.
左クリック:
/dev/input/event6: EV_MSC MSC_SCAN 00090001 /dev/input/event6: EV_KEY BTN_MOUSE DOWN /dev/input/event6: EV_SYN SYN_REPORT 00000000 /dev/input/event6: EV_MSC MSC_SCAN 00090001 /dev/input/event6: EV_KEY BTN_MOUSE UP /dev/input/event6: EV_SYN SYN_REPORT 00000000
アプリケーションで印刷
03-13 12:08:36.526 I/MainActivity(23670): dispatchTouchEvent ev:MotionEvent { action=ACTION_DOWN, actionButton=0, id[0]=0, x[0]=269.7555, y[0]=543.9628, toolType[0]=TOOL_TYPE_MOUSE, buttonState=BUTTON_PRIMARY, metaState=0, flags=0x0, edgeFlags=0x0, pointerCount=1, historySize=0, eventTime=16788085, downTime=16788085, deviceId=39, source=0x2002 } 03-13 12:08:36.653 I/MainActivity(23670): dispatchTouchEvent ev:MotionEvent { action=ACTION_UP, actionButton=0, id[0]=0, x[0]=269.7555, y[0]=543.9628, toolType[0]=TOOL_TYPE_MOUSE, buttonState=0, metaState=0, flags=0x0, edgeFlags=0x0, pointerCount=1, historySize=0, eventTime=16788216, downTime=16788085, deviceId=39, source=0x2002 }
画面のどこかでクリックしたことを示します.
右クリック:
/dev/input/event6: EV_MSC MSC_SCAN 00090002 /dev/input/event6: EV_KEY BTN_RIGHT DOWN /dev/input/event6: EV_SYN SYN_REPORT 00000000 /dev/input/event6: EV_MSC MSC_SCAN 00090002 /dev/input/event6: EV_KEY BTN_RIGHT UP /dev/input/event6: EV_SYN SYN_REPORT 00000000
03-13 12:09:48.147 I/MainActivity(23670): dispatchKeyEvent event:KeyEvent { action=ACTION_DOWN, keyCode=KEYCODE_BACK, scanCode=0, metaState=0, flags=0x0, hwFlags=0x0, repeatCount=0, eventTime=16859701, downTime=16859701, deviceId=39, source=0x2002 } 03-13 12:09:48.147 I/MainActivity(23670): onKeyDown keyCode=4 03-13 12:09:48.308 I/InputDispatcher( 996): touch process [23670], send to pg 03-13 12:09:48.327 I/MainActivity(23670): dispatchKeyEvent event:KeyEvent { action=ACTION_UP, keyCode=KEYCODE_BACK, scanCode=0, metaState=0, flags=0x0, hwFlags=0x0, repeatCount=0, eventTime=16859870, downTime=16859870, deviceId=39, source=0x2002 } 03-13 12:09:48.327 I/MainActivity(23670): onKeyUp keyCode=4 03-13 12:09:48.337 I/MainActivity(23670): onBackPressed
戻るボタンをクリックすると、プログラムが終了します.
マウスを動かすと、画面上の小さなカーソルが移動し、マウスをスライドさせるとイベントがトリガーされます.
4その他
現在、ほとんどの携帯電話はhidをサポートしており、この機能も開いている.
システム開発を行う場合は、Bluetoothのhidスイッチをオンにすることに注意してください.
ソースコードのpackages/apps/Bluetooth/res/values/config.xmlのprofile_supported_hidをtrueに変更します.
true
demoダウンロードアドレス:http://download.csdn.net/detail/vnanyesheshou/9815127.
私の微信の公衆番号に注目してください.
1 Hid概要
HIDデバイス(Hunman Interface Device Profile)、すなわちヒューマンマシンインタラクティブデバイス、よく見られるのはマウス、キーボード、ゲームハンドルなどです.一般的な有線方式は、USBケーブルで機器に接続され、ユーザ入力機器として使用される.Bluetoothテクノロジーでは、HIDデバイスのアクセスはワイヤレスです.
ネット上で資料を調べてhidはandroidから4.0からサポート(おそらくusb hid)を開始しますが、Bluetooth hidはandroid 4から開始する必要があります.2次の図のようにサポートを開始します.
android4.1.2のBluetoothアプリケーションにはhidの関連コードはないがandroid 4.2ソースコードのBluetoothアプリケーションにhidのコードがあります.
2主なコード
hidデバイスの接続手順:
mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
if (mBluetoothAdapter == null) {
Toast.makeText(this, " ", 0).show();
//
return;
}
//
if (!mBluetoothAdapter.isEnabled()) {
mBluetoothAdapter.enable();
}
//
mBroadcastReceiver = new BlueBroadcastReceiver();
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(BluetoothDevice.ACTION_FOUND);
intentFilter.addAction(BluetoothDevice.ACTION_BOND_STATE_CHANGED);
intentFilter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED);
intentFilter.addAction(BluetoothAdapter.ACTION_DISCOVERY_STARTED);
intentFilter.addAction("android.bluetooth.input.profile.action.CONNECTION_STATE_CHANGED");
this.registerReceiver(mBroadcastReceiver, intentFilter);
2.2 inputDeviceprofileを入手する
//4.2以上でHID対応
if (Build.VERSION.SDK_INT >= 17) {
mHidUtil = HidUtil.getInstance(this);
}
public static HidUtil getInstance(Context context){
if(null == instance){
instance = new HidUtil(context);
}
return instance;
}
private HidUtil(Context context) {
this.context = context;
mBtAdapter = BluetoothAdapter.getDefaultAdapter();
try {
mBtAdapter.getProfileProxy(context,
mListener, INPUT_DEVICE);
} catch (Exception e) {
e.printStackTrace();
}
}
BluetoothAdapterオブジェクト呼び出しgetProfileProxy()関数を使用して、プロキシBluetooth入力デバイスプロキシオブジェクトを取得します.
パラメータmListenerはBluetoothProfileを実装する必要があります.ServiceListener().エージェントオブジェクトの取得に成功したか失敗したかは、Listenerにコールバックされます.
private BluetoothProfile.ServiceListener mListener = new BluetoothProfile.ServiceListener() {
@Override
public void onServiceConnected(int profile, BluetoothProfile proxy) {
Log.i(TAG, "mConnectListener onServiceConnected");
//BluetoothProfile proxy BluetoothInputDevice
try {
if (profile == INPUT_DEVICE) {
mBluetoothProfile = proxy;
}
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public void onServiceDisconnected(int profile) {
Log.i(TAG, "mConnectListener onServiceConnected");
}
};
接続エージェントサービスが成功すると、onServiceConnected()関数がコールバックされ、失敗するとonServiceDisconnected()関数がコールバックされます.ここでonServiceConnected()のパラメータproxyタイプはBluetoothProfileであり、ここではBluetoothHeadset、BluetoothA 2 dpオブジェクトを取得してもこのコールバック関数を使用するため、パラメータタイプはBluetoothInputDevice、BluetoothHeadset、BluetoothA 2 dpの親に設定されている.ここでは、BluetoothInputDeviceタイプ(BluetoothInputDeviceはBluetoothProfileのサブクラス)に変換することができます.入力デバイスのエージェントオブジェクトを取得すると、接続操作が可能になります.
2.3スキャン(接続ボタンをクリックしてBluetoothデバイスのスキャンを開始)
mBluetoothAdapter.startDiscovery();
2.4ペア
ブロードキャスト受信者は、Bluetoothデバイスをスキャンし、必要なBluetoothデバイスをフィルタしてペアリングし、前にペアリングした場合は直接接続します.
if(action.equals(BluetoothDevice.ACTION_FOUND)){
// BluetoothDevice
final BluetoothDevice device = (BluetoothDevice) intent
.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
if (device == null) return;
String btname = device.getName();
String address = device.getAddress();
Log.i(TAG, "bluetooth name:"+btname+",address:"+address);
if((address != null&& address.equals(HID_ADDR))||(btname != null && btname.equals(HID_NAME))){
mConnectDevice = device;
mBluetoothAdapter.cancelDiscovery();
if(!mHidUtil.isBonded(device)){
//
mHidUtil.pair(device);
}else {
//
mHidUtil.connect(device);
}
}
}
HidUtilクラスでのペアリング方法:
/**
*
* @param BluetoothDevice
*/
public void pair(BluetoothDevice device) {
Log.i(TAG, "pair device:"+device);
Method createBondMethod;
try {
createBondMethod = BluetoothDevice.class.getMethod("createBond");
createBondMethod.invoke(device);
} catch (Exception e) {
e.printStackTrace();
}
}
2.5接続(ペアリング成功後)
if(action.equals(BluetoothDevice.ACTION_BOND_STATE_CHANGED)){
BluetoothDevice device = intent
.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
String name = device.getName();
String address = device.getAddress();
Log.i(TAG,"name:"+name+",address:"+address+",bondstate:"+device.getBondState());
if((address != null&& address.equals(HID_ADDR))||(name != null && name.equals(HID_NAME))){
if(device.getBondState() == BluetoothDevice.BOND_BONDED)
mHidUtil.connect(device);
}
}
接続する入力デバイスかどうかを判断し、条件を満たしていれば接続します.
HidUtilでの接続方法
/**
*
* @param bluetoothDevice
*/
public void connect(final BluetoothDevice device) {
Log.i(TAG, "connect device:"+device);
try {
// BluetoothInputDevice connect
Method method = mBluetoothProfile.getClass().getMethod("connect",
new Class[] { BluetoothDevice.class });
method.invoke(mBluetoothProfile, device);
} catch (Exception e) {
e.printStackTrace();
}
}
BluetoothInputDeviceのconnectメソッドは非表示なので、このメソッドを反射メカニズムで取得して呼び出す必要があります.
2.6接続状態の傍受
ブロードキャスト受信者によって接続ステータスをリスニングします.
if(action.equals("android.bluetooth.input.profile.action.CONNECTION_STATE_CHANGED")){
int state = intent.getIntExtra(BluetoothProfile.EXTRA_STATE,0);
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
Log.i(TAG,"state="+state+",device="+device);
if(state == BluetoothProfile.STATE_CONNECTED){//
Toast.makeText(MainActivity.this, R.string.connnect_success, Toast.LENGTH_SHORT).show();
} else if(state == BluetoothProfile.STATE_DISCONNECTED){//
Toast.makeText(MainActivity.this, R.string.disconnected, Toast.LENGTH_SHORT).show();
}
}
2.7接続解除
if(mConnectDevice != null)
mHidUtil.disConnect(mConnectDevice);
HidUtilでのdisconnectメソッド
/**
*
* @param BluetoothDevice
*/
public void disConnect(BluetoothDevice device) {
Log.i(TAG, "disConnect device:"+device);
try {
if (device != null) {
Method method = mBluetoothProfile.getClass().getMethod("disconnect",
new Class[] { BluetoothDevice.class });
method.invoke(mBluetoothProfile, device);
}
} catch (Exception e) {
e.printStackTrace();
}
}
携帯電話の端末が切断された後、再接続すると「マウスのみが再接続要求を開始します.マウスを使用して再接続してください」というメッセージが表示されます.
3受信データ
adb shell
getevent -l
接続に成功すると、次のように表示されます.
could not get driver version for/dev/input/mouse1, Not a typewriter add device 7:/dev/input/event6 name: "Bluetooth Mouse"
これは、Bluetoothマウスが入力デバイスになったことを示します.
左クリック:
/dev/input/event6: EV_MSC MSC_SCAN 00090001 /dev/input/event6: EV_KEY BTN_MOUSE DOWN /dev/input/event6: EV_SYN SYN_REPORT 00000000 /dev/input/event6: EV_MSC MSC_SCAN 00090001 /dev/input/event6: EV_KEY BTN_MOUSE UP /dev/input/event6: EV_SYN SYN_REPORT 00000000
アプリケーションで印刷
03-13 12:08:36.526 I/MainActivity(23670): dispatchTouchEvent ev:MotionEvent { action=ACTION_DOWN, actionButton=0, id[0]=0, x[0]=269.7555, y[0]=543.9628, toolType[0]=TOOL_TYPE_MOUSE, buttonState=BUTTON_PRIMARY, metaState=0, flags=0x0, edgeFlags=0x0, pointerCount=1, historySize=0, eventTime=16788085, downTime=16788085, deviceId=39, source=0x2002 } 03-13 12:08:36.653 I/MainActivity(23670): dispatchTouchEvent ev:MotionEvent { action=ACTION_UP, actionButton=0, id[0]=0, x[0]=269.7555, y[0]=543.9628, toolType[0]=TOOL_TYPE_MOUSE, buttonState=0, metaState=0, flags=0x0, edgeFlags=0x0, pointerCount=1, historySize=0, eventTime=16788216, downTime=16788085, deviceId=39, source=0x2002 }
画面のどこかでクリックしたことを示します.
右クリック:
/dev/input/event6: EV_MSC MSC_SCAN 00090002 /dev/input/event6: EV_KEY BTN_RIGHT DOWN /dev/input/event6: EV_SYN SYN_REPORT 00000000 /dev/input/event6: EV_MSC MSC_SCAN 00090002 /dev/input/event6: EV_KEY BTN_RIGHT UP /dev/input/event6: EV_SYN SYN_REPORT 00000000
03-13 12:09:48.147 I/MainActivity(23670): dispatchKeyEvent event:KeyEvent { action=ACTION_DOWN, keyCode=KEYCODE_BACK, scanCode=0, metaState=0, flags=0x0, hwFlags=0x0, repeatCount=0, eventTime=16859701, downTime=16859701, deviceId=39, source=0x2002 } 03-13 12:09:48.147 I/MainActivity(23670): onKeyDown keyCode=4 03-13 12:09:48.308 I/InputDispatcher( 996): touch process [23670], send to pg 03-13 12:09:48.327 I/MainActivity(23670): dispatchKeyEvent event:KeyEvent { action=ACTION_UP, keyCode=KEYCODE_BACK, scanCode=0, metaState=0, flags=0x0, hwFlags=0x0, repeatCount=0, eventTime=16859870, downTime=16859870, deviceId=39, source=0x2002 } 03-13 12:09:48.327 I/MainActivity(23670): onKeyUp keyCode=4 03-13 12:09:48.337 I/MainActivity(23670): onBackPressed
戻るボタンをクリックすると、プログラムが終了します.
マウスを動かすと、画面上の小さなカーソルが移動し、マウスをスライドさせるとイベントがトリガーされます.
4その他
現在、ほとんどの携帯電話はhidをサポートしており、この機能も開いている.
システム開発を行う場合は、Bluetoothのhidスイッチをオンにすることに注意してください.
ソースコードのpackages/apps/Bluetooth/res/values/config.xmlのprofile_supported_hidをtrueに変更します.
demoダウンロードアドレス:http://download.csdn.net/detail/vnanyesheshou/9815127.
私の微信の公衆番号に注目してください.