Red de conocimiento informático - Problemas con los teléfonos móviles - ¿Tu modo de búsqueda de Bluetooth es así? ¿Qué significa la búsqueda por Bluetooth?

¿Tu modo de búsqueda de Bluetooth es así? ¿Qué significa la búsqueda por Bluetooth?

Continuando con el capítulo anterior, active Bluetooth y continúe observando el proceso de búsqueda de Bluetooth. Hay dos condiciones para activar la búsqueda de Bluetooth. Una es comenzar la búsqueda directamente después de activar Bluetooth en la interfaz de configuración de Bluetooth. Active Bluetooth en la interfaz de configuración de Bluetooth. La búsqueda se activará después del cambio y puede haber otros métodos de activación, pero al final llegará a StartScanning() de BluetoothSettngs.java y comenzará el punto de partida de nuestro análisis. desde aquí.

[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:

{

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>

intent.putExtra( BluetoothDevice.EXTRA_NAME, deviceProp.mName);

mAdapterService.sendBroadcast(intención, mAdapterService.BLUETOOTH_PERM); /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 () {

@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

}

// 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.