ペアリングされたデバイスへの接続を定期的に試行し、接続が成功した場合にアクションを実行するアプリケーションを作成しました。ACTION_ACL_CONNECTED と ACTION_ACL_DISCONNECTED を処理する登録済みの bluetooth broadcastReceiver があります。サービスでは、実行ループで、ペアリングされたデバイスのリストを取得し、それぞれに接続を試みます。接続が成功すると、ACTION_ACL_CONNECTED 通知を受け取り、デバイスが切断される (または範囲外になる) と、ACTION_ACL_DISCONNECTED を受け取ります。すべてうまくいきます。
ヘッドセットの場合、BluetoothHeadset クラスは ACTION_ACL_CONNECTED と ACTION_ACL_DISCONNECTED を発生させるため、プライマリ UUID が 00001108 であるデバイスに接続する必要はありません。
0000110B の単一の UUID を持つ bluetooth スピーカーがあります。一日中範囲内外に出入りする可能性があり、接続するたびに ACTION_ACL_CONNECTED 信号と ACTION_ACL_DISCONNECTED 信号を受け取り、範囲外になるために切断が発生するたびに.
00001105 を使用して別の電話に接続しようとすると、最初の接続は成功し、ACTION_ACL_CONNECTED が発生します。電話を範囲外に出す (または単に Bluetooth をオフにする) と、ACTION_ACL_DISCONNECTED が発生します。ただし、電話が範囲内にあり、Bluetooth がオンになっている場合でも、さらに接続を試みると、「サービスの検出に失敗しました」という結果になります。これは、携帯電話の Bluetooth アダプターを手動またはコードで切り替えるまで続きます。その後、接続/切断を 1 回実行すると、サービス検出の失敗が再び発生します。明らかに、アダプターを切り替えることは満足のいく解決策ではありません。それで、私の質問は、00001105 で複数の接続/切断を行うことができないという点で、00001105 が 00001108 と異なる理由は何ですか?
コードは比較的複雑ですが、次のとおりです (インデントを許してください。カット アンド ペーストはうまく機能しませんでした)。
public class BluetoothListenerService extends Service {
// The BroadcastReceiver that listens for Connected and disconnected blue tooth devices (HSP,HFP and SPP)
public final BroadcastReceiver mBluetoothReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
String devices[]=null;
Intent service_intent;
String action = intent.getAction();
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
if (BluetoothDevice.ACTION_ACL_CONNECTED.equals(action)) {
// Get the BluetoothDevice object from the Intent
String testUUID=null;
try {
Method method = device.getClass().getMethod("getUuids", (Class<?>[]) null);
ParcelUuid[] phoneUuids = (ParcelUuid[]) method.invoke(device, (Object[]) null);
UUID myUUID=phoneUuids[0].getUuid();
testUUID=myUUID.toString().toLowerCase();
Log.i(TAG,"connected to "+device.getName()+ "using "+ testUUID);
} catch (Exception e) {}
return;
} // end ACTION_ACL_CONNECTED
if (BluetoothDevice.ACTION_ACL_DISCONNECTED.equals(action)) {
Log.i(TAG, "disconnected from "+device.getName());
return;
} // end ACTION_ACL_DISCONNECTED
} // end OnReceive
}; // end broadcast receiver definition
BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
@Override
public void onStart(final Intent intent, final int startId) {
super.onStart(intent, startId);
if (mBluetoothAdapter == null) {
Toast.makeText(this," Bluetooth is not available on this device", Toast.LENGTH_LONG).show();
return;
}
Thread t = new Thread("MyService(" + startId + ")") {
@Override
public void run() {
_onStart(intent, startId);
stopSelf();
}
};
t.start();
return;
}
public void _onStart(Intent intent, int startId) {
String devices[]=null;
Log.i(TAG,"Bluetooth Listener Service started on thread "+ Integer.toString(android.os.Process.myTid()));
// Register the Bluetooth BroadcastReceiver
IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_ACL_CONNECTED);
filter.addAction(BluetoothDevice.ACTION_ACL_DISCONNECTED);
try {
this.unregisterReceiver(mBluetoothReceiver);
} catch(IllegalArgumentException ignorable) {}
registerReceiver(mBluetoothReceiver, filter);
// the loop
bRun=true;
while(bRun) {
Set <BluetoothDevice> mySet=mBluetoothAdapter.getBondedDevices();
Iterator <BluetoothDevice> iterator=mySet.iterator();
while(iterator.hasNext()) {
BluetoothDevice setElement=iterator.next();
String testUUID=null;
try { // Get UUID for device
Method method = setElement.getClass().getMethod("getUuids", (Class<?>[]) null);
ParcelUuid[] phoneUuids = (ParcelUuid[]) method.invoke(setElement, (Object[]) null);
UUID myUUID=phoneUuids[0].getUuid();
testUUID=myUUID.toString().toUpperCase();
Log.i(TAG, "device UUID is "+testUUID);
if (testUUID.compareTo(headsetUUID)!=0 && testUUID.compareTo(a2dpUUID)!=0) {
try { // create a socket
BluetoothSocket tmp=null;
tmp=setElement.createInsecureRfcommSocketToServiceRecord(UUID.fromString(testUUID));
mmSocket=tmp;
Log.i(TAG,"connecting using socket "+mmSocket.toString());
Log.i(TAG,"connecting to "+setElement.getName());
try {
if (mBluetoothAdapter.isDiscovering()==true) mBluetoothAdapter.cancelDiscovery();
mmSocket.connect();
Log.i(TAG,"connection to "+setElement.getName()+" was sucessful");
// the connection will be handled by the receiver in ACL_CONNECTED
} catch (Exception e) { // connection failed
String sTest=e.getMessage();
Log.e(TAG,"connection to "+setElement.getName()+" returned "+sTest);
if (sTest!=null) {
try { // closing the socket
Log.i(TAG,"closing socket due to error: "+sTest);
Log.i(TAG,"closing socket "+mmSocket.toString());
if (!mmSocket.equals(null)) {
mmSocket.close();
mmSocket=null;
tmp=null;
}
else {
Log.e(TAG, "socket is null");
}
} catch (Exception e1) { // socket close failed
Log.e(TAG,"closing socket failed");
break;
}
if (sTest.compareTo("Unable to start Service Discovery")==0) {
mBluetoothAdapter.disable();
SystemClock.sleep(3000);
mBluetoothAdapter.enable();
SystemClock.sleep(1000);
}
}
} // end catch connection failed
} catch (Exception e1) {
Log.e(TAG, "socket create failed.");
}
} // end test if headset or not
} catch (Exception e1) {
Log.e(TAG, "find UUID failed.");
} // end find UUID
} // end while iterator.hasnext()
} // end of run loop
}
}