¿Tu modo de búsqueda de Bluetooth es así? ¿Qué significa la búsqueda por Bluetooth?
[cpp] ver copia simple
private void updateContent(int bluetoothState, boolean scanState) {
if (numberOfPairedDevices == 0) {
preferenciaScreen.removePreference(mPairedDevicesCategory);
if (scanState == true) {
mActivityStarted = false
startScanning();
} else.....
}.
private void startScanning() {
if (!mAvailableDevicesCategoryIsPresent) {
getPreferenceScreen() .addPreference(mAvailableDevicesCategory);
mLocalAdapter.startScanning(true);
}
De hecho, los procesos de búsqueda y apertura de Bluetooth son estructuralmente los mismos. Utilice LocalBluetoothAdapter.java para realizar la transición a BluetoothAdapter.java y luego saltar a AdapterService.java. Una cosa a tener en cuenta es que durante esta transición, el método startScanning() se convierte en el método startDiscovery(). Consulte el siguiente código: paquetes/aplicaciones/. Settings/src/com /android/settings/bluetooth/LocalBluetoothAdapter.java
[java] ver copia simple
void startScanning(fuerza booleana) {
if ( !mAdapter.isDiscovering( )) {
if (!force) {
// La frecuencia de escaneo no debe exceder SCAN_ EXPIRATION_MS,
// A menos que sea forzado
if (mLastScan + SCAN_EXPIRATION_MS > System.currentTimeMillis()) {
return
}
// Si estamos jugando; música, a menos que sea forzada; de lo contrario, no escanee.
A2dpProfile a2dp = mProfileManager.getA2dpProfile();
if (a2dp ! startDiscovery()) {
mLastScan = System.currentTimeMillis(); >
}
Si (a2dp !
}
La ruta en BluetoothAdapter.java es /frameworks/base/ core/java/android/bluetooth / Parte de BluetoothAdapter.java
[java] ver copia simple
public boolean startDiscovery() {
............ ............
Servicio AdapterService = getService();
Si (servicio == nulo) devuelve falso
devolver service.startDiscovery();
}
Si (servicio == nulo) devuelve falso.
Este código de servicio está escrito para comprender AdapterService. Va desde el marco hasta el paquete de software.
La siguiente ruta del código es, naturalmente, paquetes/apps/Bluetooth/src/com/. android/bluetooth/ btservice/AdapterService.java,
[java] ver copia simple
boolean startDiscovery() {
enforceCallingOrSelfPermission( BLUETOOTH_ADMIN_PERM,
"Necesita permiso de ADMIN DE BLUETOOTH");
return startDiscoveryNative();
}
Esto es básicamente lo mismo que activar Bluetooth Things y el El proceso anterior omitió un pequeño paso, es muy simple y no lo escribiré. Creo que todos pueden adivinar cómo proceder a continuación, JNI debería estar disponible,
Ruta: /packages/apps/ Bluetooth. /jni/com_android_bluetooth_btservice_AdapterService.cpp
[cpp] ver copia simple
estático jboolean startDiscoveryNative(JNIEnv* env, jobject obj) {
ALOGV ( "%s:",__FUNCTION__);
resultado jbooleano = JNI_FALSE;
if(!sBluetoothInterface) devuelve resultado
int ret = sBluetoothInterface- > start_discovery();
resultado = (ret == BT_STATUS_SUCCESS) ?JNI_TRUE : JNI_FALSE;
devolver resultado; Se necesita pensar un poco, pero ya hemos hablado sobre cómo encontrarlo en el artículo anterior Android - Bluetooth (2. Abra Bluetooth, preste atención al archivo android.mk, busque el archivo de encabezado y luego busque el archivo). implementación del archivo C correspondiente. En otras palabras, ahora para revisar, ya hemos visto el proceso de código de apertura y búsqueda de Bluetooth. Lo que salta son las configuraciones una por una. Se inicia la interfaz de configuración, las transiciones de LocalBluetoothAdapter.java y se transfieren al marco (BluetoothAdapter.java). Vuelva a AdapterService.java en el paquete y luego fuera de JNI. El proceso es así. Creo que todos deberían estar familiarizados con saltos de funciones similares (como emparejar Bluetooth, apagar Bluetooth, detener el escaneo, etc.) y luego, para funciones similares en el futuro, simplemente escriba el nombre de la función y menciónelo. De un solo golpe, lo que se debe tener en cuenta aquí es start_discovery() Para implementar la búsqueda de código, preste atención al archivo mk, no es complicado.
El resumen ha terminado, continúe mirando la ruta del código: /external/bluetooth/bluedroid/btif/src/bluetooth.c
[cpp] view Plaincopy
static int start_discovery( void)
{
/* control de cordura */
if (interface_ready() == FALSE)
return BT_STATUS_NOT_READY
return btif_dm_start_discovery( );
}
El siguiente código se puede encontrar saltando directamente a la ruta externa/bluetooth/bluedroid/btif/src/btif_dm. c
Este código es un poco excesivo, pero la cantidad de información que contiene también es muy grande, así que lo guardé y lo publiqué junto con los comentarios. La implementación de la búsqueda Bluetooth no se deja en manos de los fabricantes. para implementar como la apertura de Bluetooth. Está bien, mire cuidadosamente esos #if y #else. Todos son restablecimientos de algunas condiciones de consulta #if (BLE_INCLUDED == TRUE) Esta debería ser la preparación de Google para Bluetooth 4.0 LE. y también se anunció en la conferencia Google I/O de este año. Es una prueba de que la versión Bluetooth 4.0 de bajo consumo será compatible pronto. En cuanto al significado de las cadenas en el código, consulte external/bluetooth/bluedroid/bta/. Incluye/bta_api.h aquí, un archivo de encabezado y la definición de la mayoría de cadenas y estructuras. Todo está aquí, más o menos, con algunas notas.
[cpp] ver copia simple
bt_status_t btif_dm_start_discovery(void)
{
tBTA_DM_INQ inq_params
tBTA_SERVICE_ MASK servicios = 0;
BTIF_TRACE_EVENT1("%s", __FUNCTION__);
/* TODO: ¿Necesitamos procesar varias consultas al mismo tiempo? */
/ * Establecer parámetros de consulta y llamar a API */
#if (BLE_INCLUDED == TRUE)
inq_params.mode = BTA_DM_GENERAL_INQUIRY|BTA_BLE_GENERAL_INQUIRY <; /p>
#else
inq_params.mode = BTA_DM_GENERAL_INQUIRY;
#endif
inq_params.duration = BTIF_DM_DEFAULT_INQ_MAX_DURATION; p> p>
inq_params.max_resps = BTIF_DM_DEFAULT_INQ_MAX_RESULTS;
inq_params.report_dup = TRUE;
inq_params.filter_type = BTA_DM_GENERAL_INQUIRY; /p >
inq_params.duration = BTIF_DM_DEFAULT_INQ_MAX_DURATION; <
inq_params.max_resps = BTIF_DM_DEFAULT_INQ_MAX_RESULTS;
#endifilter_type = BTA_DM_INQ_CLR;
/* TODO:
p>/* Se habilita a VERDADERO una vez que se recibe la consulta del nivel de ocupación */
/* Se habilita a VERDADERO una vez que se recibe la consulta del nivel de ocupación */
b
btif_dm_inquiry_in_progress = FALSE;
/* Buscar dispositivos cercanos*/
BTA_DmSearch(&inq_params, services, bte_search_ devices_evt
return); BT_STATUS_SUCCESS;
}
Parece que el método BTA_DmSearch() va a buscar, pero lo que realmente hace el trabajo principal es bte_search_devices_evt. Entonces, echemos un vistazo a esta función primero.
[cpp] ver copia simple
static void bte_search_devices_evt(evento tBTA_DM_SEARCH_EVT, tBTA_DM_SEARCH *p_data) {
UINT16 param_len = 0
if (p_data)
param_len += sizeof(tBTA_DM_SEARCH);
/* Asignar búfer para guardar el puntero (copia profunda).
El puntero apuntará al final de tBTA_DM_SEARCH*/
switch (evento)
{
caso BTA_DM_INQ_RES_EVVT:
{ p>
if (p_ data->inq_res.p_eir)
param_len += HCI_EXT_INQ_RESPONSE_LEN
}
break; > case BTA_DM_DISC_RES_EVVT :
{
p_search_data = (tBTA_DM_SEARCH *)p_param
/* Actualización de nombre remoto*/
if ( strlen(( const char *) p_search_data->disc_res.bd_name))
{
bt_property_t properties[1]
bt_bdaddr_t bdaddr
;bt_status _t estado;
propiedades[0].type = BT_PROPERTY_BDNAME;
propiedades[0].val = p_search_data->disc_res.bd_name; > propiedades[ 0].len = strlen((char *)p_search_data->disc_res.bd_name
bdcpy(bdaddr.address, p_search_data->disc_res.bd_addr
); status = btif_storage_set_remote_device_property (&bdaddr, &properties[0]);
ASSERTC(status == BT_STATUS_SUCCESS, "Error al guardar las propiedades del dispositivo remoto", estado
HAL_CBACK(bt_hal_cbacks, remote_device_properties_cb); ,
estado, &bdaddr, 1.properties);
}
/* TODO: ¿Servicio? */
}
break;
Un breve fragmento de registro, el siguiente texto se escribe en la función anterior, incluso si la función escrita anteriormente no lo hace. existir, debe estar cerca también.
05-30 13:52:14.890 1578 2612 D bt-btif : bte_search_devices_evt event=BTA_DM_INQ_RES_EVT param_len=524
05-30 13:52:14.890 1578 2612 D bt-btif : search_devices_copy_cb: event=BTA_DM_INQ_RES_EVT
05-30 13:52:14.890 1578 2584 I bt-btif : btif_dm_search_devices_evt event=BTA_DM_INQ_RES_EVT
05-30 13:52:14.890 15 78 2584 D bt-btif: btif_dm_search_devices_evt() ec:89:f5:ba:fb:03 device_type = 0x1
Por supuesto, tenemos que regresar y mirar BTA_DmSearch() para ver su implementación. y más La mayoría de ellos deben usarse para enviar mensajes. El código está en /external/bluetooth/bluedroid/bta/dm/bta_dm_api.
[c]. Proceso específico de esta función. Tendrás que mirar las herramientas y ¡echemos un vistazo al método! Todavía está bien.
[cpp] ver copia simple
void BTA_DmSearch(tBTA_DM_INQ *p_dm_inq, tBTA_SERVICE_MASK servicios, tBTA_DM_SEARCH_CBACK *p_cback)
{ tBTA_DM_API_SEARCH *p_msg
if ( (p_msg = (tBTA_DM_API_SEARCH *) GKI_getbuf(sizeof(tBTA_DM_API_SEARCH)) != NULL)
{
memset(p_msg, 0, sizeof(tBTA_DM_API_SEARCH)); p> p_msg->hdr.event = BTA_DM_API_SEARCH_EVT;
memcpy(& amp;p_msg->inq_params, p_dm_inq, sizeof(tBTA_DM_INQ));
p_msg->
p_msg->p_cback = p_cback;
p_msg->rs_res = BTA_DM_RS_NONE
bta_sys_sendmsg(p_msg> }
}
Después de observar los métodos anteriores, debemos regresar y ver el código a través de JNI para regresar y ver el método de devolución de llamada de JNI
[cpp] ver vista simple p>[cpp] ver copia simple
method_deviceFoundCallback = env->GetMethodID(jniCallbackClass, "deviceFoundCallback", "([B)V"
método deviceFoundCallback final); Ingresará /packages/apps/Bluetooth/src/com/android/bluetooth/btservice/RemoteDevices.
[java] ver copia simple
void deviceFoundCallback(byte[] dirección) {
// Las propiedades del dispositivo están registradas: podemos enviar intents
// Las propiedades del dispositivo están registradas.
dispositivo Bluetooth dispositivo = getDevice(dirección);
debugLog("deviceFoundCallback: La dirección remota es:" + dispositivo
Propiedades del dispositivo deviceProp = getDeviceProperties( dispositivo);
if (deviceProp == null) {
errorLog("Las propiedades del dispositivo son nulas para el dispositivo:" + return; /p>
}
Intención intención = nueva Intent(BluetoothDevice.ACTION_FOUND);
intent.putExtra( BluetoothDevice.EXTRA_DEVICE, dispositivo); intent.putExtra(BluetoothDevice.EXTRA_CLASS,
new BluetoothClass(Integer.valueOf( deviceProp.mBluetoothClass));
intent.putExtra(BluetoothDevice.EXTRA_RSSI, deviceProp.mRssi); p>
p>
intent.putExtra( BluetoothDevice.EXTRA_NAME, deviceProp.mName);
mAdapterService.sendBroadcast(intención, mAdapterService.BLUETOOTH_PERM); /p> p>
En este momento, enviará una transmisión a la interfaz, y la capa de aplicación recibirá la transmisión a través de este identificador y la mostrará, que se puede encontrar en el constructor de BluetoothEventManager.java.
[ java] ver copia simple
addHandler (BluetoothDevice.ACTION_FOUND, new DeviceFoundHandler());
BroadcastReceiver final privado mBroadcastReceiver = new BroadcastReceiver () { p>
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction()
Dispositivo BluetoothDevice; = intención
.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
Controlador controlador = mHandlerMap.get(acción); /p>
controlador.onReceive(contexto, intención, dispositivo);
}
}
}
};
aquí El controlador corresponde a DeviceFoundHand
ler, que es el código publicado a continuación.
[java] ver copia simple
clase privada DeviceFoundHandler implementa Handler {
public void onReceive(Contexto contexto, Intención intención,
BluetoothDevice dispositivo) {
........................
// TODO Obtener el UUID. Deberían funcionar en dispositivos 2.1.
// Saltamos esto por ahora porque hay un problema de bluez en el que no podemos obtener el UUID ni siquiera para dispositivos 2.1.
CachedBluetoothDevice cachedDevice = mDeviceManager.findDevice(dispositivo);
if (cachedDevice == null) {
cachedDevice = mDeviceManager.addDevice(mLocalAdapter, mProfileManager, dispositivo );
Log.d(TAG, "DeviceFoundHandler creó un nuevo CachedBluetoothDevice:"
+ cachedDevice
// Vuelve a llamar a la interfaz de usuario para crear); un nuevo dispositivo Preferencias
despachoDeviceAdded(cachedDevice);
}
................... ..
}
}
despachoDeviceAdded() en la declaración if distribuye el mensaje a la interfaz, y el procesamiento final del mensaje está aquí, ya estoy configurando la aplicación en el programa
/packages/apps/Settings/src/com/ android/settings/bluetooth/DeviceListPreferenceFragment.java
[java] ver copia simple
public void onDeviceAdded( CachedBluetoothDevice cachedDevice) {
if (mDevicePreferenceMap.get(cachedDevice) ! = null) {
return
} p>
// Impide la actualización cuando una de las informaciones de estado se muestra en la lista
if (mLocalAdapter. getBluetoothState() != BluetoothAdapter.STATE_ON) return
if; (mFilter.matches(cachedDevice. getDevice())){
createDevicePreference(cachedDevice)
}
}
El último La rama en el código anterior se completa cuando se muestra la interfaz, comenzando desde la interfaz de configuración, luego yendo a la interfaz de configuración para mostrar la búsqueda y terminando con Bluetooth. El siguiente código ya no está escrito. cosas después del final.