Android BluetoothDevice.getName () return null
En algún momento, BluetoothDevice.getName () devuelve null. ¿Cómo puedo arreglarlo? RemoteDeviceName puede ser nulo en el siguiente código. Y necesito distinguir mi dispositivo y otros dispositivos por remoteDeviceName.
BluetoothAdapter.getDefaultAdapter().startLeScan(new LeScanCallback() { @Override public void onLeScan(final BluetoothDevice device, final int rssi, byte[] scanRecord) { String remoteDeviceName = device.getName(); Log.d("Scanning", "scan device " + remoteDeviceName); });
- Error de petición de cadena de volea al pasar cadena con valor nulo como param
- Android onActivityResult. La variable miembro es a veces nula
- GCM devuelve un tipo de mensaje nulo
- Recyclerview se bloquea al eliminar el último elemento. NullPointerException: android.view.ViewGroup $ LayoutParams android.view.View.getLayoutParams ()
- GetActionView () de mi MenuItem return null
- FindViewByID devuelve null para CustomView
- GetActionBar () devuelve null después de la actualización de SDK a 5.0
- Push Notifications usando Urban Dirigible devuelve apID como nulo en el primer lanzamiento
- Error al entregar el resultado ResultInfo {who = null, request = 1, result = -1, data = Intent {(tiene extras)}} a actividad; Java.lang.NullPointerException
- Variable estática null al volver a la aplicación
- Gran cantidad de memoria no recogida de basura
- Orientación de Android zxing: ResultMetaData es null, Get Rotation / Orientation
- MSecurityInputMethodService es nulo en logcat
Finalmente, descubrí la solución:
1.Para el dispositivo conectado:
Leer el nombre del dispositivo de la característica gatt . Org.bluetooth.characteristic.gap.denombre_de_vice del servicio org.bluetooth.service.generic_access .
Dispositivo 2.For no conectado:
/** * Get device name from ble advertised data */ private LeScanCallback mScanCb = new LeScanCallback() { @Override public void onLeScan(final BluetoothDevice device, final int rssi, byte[] scanRecord) { final BleAdvertisedData badata = BleUtil.parseAdertisedData(scanRecord); String deviceName = device.getName(); if( deviceName == null ){ deviceName = badata.getName(); } } ////////////////////// Helper Classes: BleUtil and BleAdvertisedData /////////////// final public class BleUtil { private final static String TAG=BleUtil.class.getSimpleName(); public static BleAdvertisedData parseAdertisedData(byte[] advertisedData) { List<UUID> uuids = new ArrayList<UUID>(); String name = null; if( advertisedData == null ){ return new BleAdvertisedData(uuids, name); } ByteBuffer buffer = ByteBuffer.wrap(advertisedData).order(ByteOrder.LITTLE_ENDIAN); while (buffer.remaining() > 2) { byte length = buffer.get(); if (length == 0) break; byte type = buffer.get(); switch (type) { case 0x02: // Partial list of 16-bit UUIDs case 0x03: // Complete list of 16-bit UUIDs while (length >= 2) { uuids.add(UUID.fromString(String.format( "%08x-0000-1000-8000-00805f9b34fb", buffer.getShort()))); length -= 2; } break; case 0x06: // Partial list of 128-bit UUIDs case 0x07: // Complete list of 128-bit UUIDs while (length >= 16) { long lsb = buffer.getLong(); long msb = buffer.getLong(); uuids.add(new UUID(msb, lsb)); length -= 16; } break; case 0x09: byte[] nameBytes = new byte[length-1]; buffer.get(nameBytes); try { name = new String(nameBytes, "utf-8"); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } break; default: buffer.position(buffer.position() + length - 1); break; } } return new BleAdvertisedData(uuids, name); } } public class BleAdvertisedData { private List<UUID> mUuids; private String mName; public BleAdvertisedData(List<UUID> uuids, String name){ mUuids = uuids; mName = name; } public List<UUID> getUuids(){ return mUuids; } public String getName(){ return mName; } }
BluetoothDevice.getName()
puede devolver null
si no se pudo determinar el nombre. Esto podría ser debido a cualquier número de factores. Independientemente, el nombre es el nombre descriptivo del dispositivo y no debe usarse para distinguirlo de otros dispositivos. En su lugar, utilice la dirección de hardware mediante getAddress()
.
En Marshmallow, utilice ScanRecord.getDeviceName()
para recuperar el nombre local incrustado en el registro de exploración.
BluetoothDevice.getName()
no es fiable si el nombre local se incluye en una respuesta de análisis, en lugar de en el paquete de publicidad inmediata.
He encontrado que si usted consulta para el nombre del dispositivo inmediatamente después de que sea cogido en la exploración puede volver null. Para conseguir alrededor de esto encubro un runnable cada segundo o así en el hilo de la interfaz de usuario un máximo de 3 veces (tan 3 segundos), y el nombre se resuelve generalmente por entonces.
Nota, en el fragmento proporcionado, la clase Runnable
implementa Runnable
, por lo tanto, puedo pasar this
a View.postDelayed(Runnable action, long delayMillis)
private static final int MAX_NAME_CHECKS = 3; private static final int NAME_CHECK_PERIOD = 1000; int nameChecks; @Override public void run() { resolveName(); } /** * Checks for the device name, for a maximum of {@link ViewHolder#MAX_NAME_CHECKS} * as the name may not have been resolved at binding. */ private void resolveName() { if (device != null) { String name = device.getName(); boolean isEmptyName = TextUtils.isEmpty(name); if (isEmptyName) deviceName.setText(R.string.unknown_device); else deviceName.setText(name); // Check later if device name is resolved if (nameChecks++ < MAX_NAME_CHECKS && isEmptyName) itemView.postDelayed(this, NAME_CHECK_PERIOD); } }
- Emulador de Android Ubicación de Mac OSX
- Las imágenes no se cargan en android 5.0 usando la biblioteca picasso