我正在开发Android BLE应用程序。我在某些Android设备中面临的问题是,当我使用writeCharacteristic()方法在特征中写入数据时,它返回false并且不写入。 你知道为什么它会返回虚假的情况吗? 使用我的BQ Aquaris U Plus它不会发生,只是成功写入并返回true。但是对于我的华为Y6,它发生了很多次。也许7/10个案例它会返回false。 这是我的代码,是如此之大,但可以提供帮助:
public class ServicioFirmadoNuevo extends Service{
private static final long NUMEROS_DE_RETRYS = Constantes.NUMEROS_DE_RETRYS;
private ServiceConnection serviceConn;
private ArrayList<byte[]> arrayDatosPartidos;
private Handler handler;
private BluetoothGatt mGatt;
private final IBinder mBinder = new ServicioFirmadoNuevo.LocalBinder();
private android.bluetooth.BluetoothDevice mBluetoothDevice;
private byte[] byteFinal;
private ArrayList<byte[]> datosAJuntar;
private int numeroDeParticionesDeDatos;
private boolean esperandoDesconexion = false;
private boolean protocoloLectura = false;
private boolean comunicacionTerminada = false;
private boolean retry = true;
private int contadorRetrys = 0;
private int iteracionesLectura = 0;
private String idMotivo;
private int vecesOnChanged = 0;
private int nSerie;
private Intent intentError = new Intent("errorFirmado");
public ServicioFirmadoNuevo(){}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
return START_STICKY;
}
public void onStartCommand2(Intent intent, BluetoothDevice device, String motivoCodigo, String motivoLetra, int nserie) {
Log.i("INICIOSERVICIOFIRMADO", "TRUE");
mGatt = null;
handler = new Handler();
datosAJuntar = new ArrayList<byte[]>();
contadorRetrys = 0;
Log.d("pruebitas", motivoCodigo+motivoLetra);
mBluetoothDevice = device;
nSerie = nserie;
Log.d("NSERIEAFIRMAR", nserie+"");
/*if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
if (device.getBondState() == BluetoothDevice.BOND_NONE){
Log.d("BOUNDING??? ", device.createBond()+"");
}
}
final String motCod = motivoCodigo;
new android.os.Handler().postDelayed(
new Runnable() {
public void run() {
conectaConEsteMotivo(motCod);
}
},
4000);*/
conectaConEsteMotivo(motivoCodigo);
}
public void setServiceConn(ServiceConnection serviceConn) {
this.serviceConn = serviceConn;
}
public class LocalBinder extends Binder {
public ServicioFirmadoNuevo getServiceInstance(){
return ServicioFirmadoNuevo.this;
}
}
public void conectaConEsteMotivo(String idmotivo){
handler.postDelayed(timeOutFirmado, 10000);
handler.postDelayed(runnableCodeTimeOutConversacion, 9000);
this.idMotivo = idmotivo;
if (mGatt == null) {
Log.e("mGATT", "IS NULL");
try {
Handler mHandler = new Handler(getApplicationContext().getMainLooper());
mHandler.post(new Runnable() {
@Override
public void run() {
Log.e("TRY", "1");
if (mBluetoothDevice!=null){
/*if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
Log.d("BOUNDING??? ", mBluetoothDevice.createBond()+"");
}*/
Log.d("mBluetoothDevice", "mBluetoothDevice.connectGatt called...");
mGatt = mBluetoothDevice.connectGatt(getApplicationContext(), false, gattCallback);
/*new Handler().postDelayed(
new Runnable() {
public void run() {
Log.d("mBluetoothDevice", "mBluetoothDevice.connectGatt called...");
mGatt = mBluetoothDevice.connectGatt(getApplicationContext(), false, gattCallback);
}
},
1000);*/
}
}
});
}catch (Throwable e){
e.printStackTrace();
if (mGatt != null){
mGatt.disconnect();
mGatt.close();
}
if (!retry){
Log.e("ERROR","ERROR");
//presenter.escribirEnToast("Problema Null Pointer en método : conectaConEsteMotivo(String a) ");
//presenter.pararServicioFirmado();
}
}
} else {
Log.i("MGATTISNOTNULL","MGATT NO ES NULL");
}
}
private Runnable runnableCodeTimeOutConversacion = new Runnable() {
@Override
public void run() {
//contadorRetrys = (int) NUMEROS_DE_RETRYS;
if (!esperandoDesconexion){
Log.e("TIMEOUTCONVERSACION", "TRUE");
if(mGatt != null){
mGatt.disconnect();
mGatt.close();
}
//presenter.escribirEnToast("TIMEOUT Conversación");
//presenter.setServicioEnEjecucion(false);
//presenter.pararServicioFirmado();
retrySameMotivo();
}
}
};
private final BluetoothGattCallback gattCallback = new BluetoothGattCallback() {
@Override
public void onConnectionStateChange(final BluetoothGatt gatt, int status, int newState) {
Log.i("onConnectionStateChange", "Status: " + status);
switch (newState) {
case BluetoothProfile.STATE_CONNECTED:
Log.i("gattCallback", "STATE_CONNECTED");
boolean discover_services = gatt.discoverServices();
if (discover_services) {
Log.i("Hadescubiertoservicios", "TRUE");
} else {
Log.i("Hadescubiertoservicios", "FALSE");
}
break;
case BluetoothProfile.STATE_DISCONNECTED:
Log.e("gattCallback", "STATE_DISCONNECTED STATUS: "+ status);
//gatt.disconnect();
//gatt.close();
//mGatt.disconnect();
//mGatt.close();
if(esperandoDesconexion){
if (mGatt != null){
mGatt.disconnect();
mGatt.close();
}
//presenter.setServicioEnEjecucion(false);
//presenter.pararServicioYReiniciar();
sendBroadcast(intentError);
}
else {
if (idMotivo == null){
Log.e("ERRORIDMOTIVONULL", " IDMOTIVO ES NULL");
gatt.disconnect();
gatt.close();
if (mGatt != null){
mGatt.disconnect();
mGatt.close();
}
//presenter.escribirEnToast("IDMOTIVO ES NULL");
esperandoDesconexion = true;
sendBroadcast(intentError);
}else {
if(contadorRetrys < NUMEROS_DE_RETRYS ){
retrySameMotivo();
}else {
Log.e("LimiteRetrysSuperado", " Ya se han hecho suficientes retrys y no se ha logrado firmar");
gatt.disconnect();
gatt.close();
if (mGatt != null){
mGatt.disconnect();
mGatt.close();
}
Log.e("retrys", "Límite Retrys alcanzado.");
//presenter.setServicioEnEjecucion(false);
//presenter.pararServicioYReiniciar();
esperandoDesconexion = true;
sendBroadcast(intentError);
}
}
}
break;
default:
Log.e("gattCallback", "STATE_OTHER");
}
}
@Override
public void onServicesDiscovered(final BluetoothGatt gatt, int status) {
Log.i("onServicesDiscovered", "enter");
List<BluetoothGattService> services = gatt.getServices();
if (services.size() == 0) {
Log.i("ServiciosDeLaBaliza=0","el sice de los servicios entontrados es = 0 :"+ services.toString());
}
Log.i("onServicesDiscovered", services.toString());
//Muestreo de Servicios con sus respectivas Characteristics
for (BluetoothGattService servicio : services) {
Log.i("Service", servicio.getUuid().toString());
for (BluetoothGattCharacteristic characteristic : servicio.getCharacteristics()) {
Log.i("Char", characteristic.getUuid().toString());
}
}
Log.d("PASAMITADonSERVICEDISCD","-----");
try {
BluetoothGattCharacteristic characteristic = gatt.getServices().get(2).getCharacteristics().get(0);//todo: CAMBIAR get 2 por su uuid
Log.d("CHARACTERISTIC -->", characteristic!= null ? "NO ES NULL": "ES NULL");
//habilitar notificaciones
gatt.setCharacteristicNotification(characteristic, true);
BluetoothGattDescriptor desc = characteristic.getDescriptors().get(0);
desc.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE);
gatt.writeDescriptor(desc);
}catch (Exception e){
sendBroadcast(intentError);
e.printStackTrace();
Log.e("ERRORDESCUBRIENDO", "TRUE");
}
}
@Override
public void onCharacteristicRead(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
Log.e("ENTRA EN LEERCHAR", characteristic.getValue()[0]+"");
protocolo(gatt, characteristic);
}
//Cuando se escribe una caracteristica lanza esto
@Override
public void onCharacteristicWrite(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
Log.e("ENTRAONWRITE", "STATUS: "+status);
if (status == BluetoothGatt.GATT_SUCCESS) {
handler.postDelayed(runnableCodeTimeOutTransmisiones, 1000);
Log.i("ESCRIBIR","OK");
Log.i("bytesescritos", characteristic.getValue().length+""+ "////////"+ new String(characteristic.getValue(), Charset.forName("UTF-8")));
Log.i("1stEscrito", (char) characteristic.getValue()[0] + "");
if(new String(characteristic.getValue(), Charset.forName("UTF-8")).equals(Constantes.PM_END_ACK+"")){
characteristic.setValue(Constantes.PM_END_COM+"");
boolean porcentaje;
porcentaje = gatt.writeCharacteristic(characteristic);
Log.w("LOQUEESCRIBO: ", BateriaDeMetodosUtiles.bytesToHex(characteristic.getValue())+ " : "+porcentaje);
Log.w("ESCPORCENT", porcentaje+"");
}else {
if (new String(characteristic.getValue(), Charset.forName("UTF-8")).equals(Constantes.PM_END_COM + "")) {
byteFinal = BateriaDeMetodosUtiles.juntarBytesDeUnArrayListDeBytes(datosAJuntar);
Log.e("FINALBYTE", new String(byteFinal, Charset.forName("UTF-8")));
Log.e("FINALBYTEHEX", BateriaDeMetodosUtiles.bytesToHex(byteFinal));
protocoloLectura = false;
iteracionesLectura = 0;
esperandoDesconexion = true;
Log.e("VamosASalirDelProcess", "Deberíamos salir de la conexión al haber escrito esto: " + new String(characteristic.getValue(), Charset.forName("UTF-8")));
Intent intentBD = new Intent("fichajeCompletado");
Log.d("PRUEBABYTEEE", BateriaDeMetodosUtiles.bytesToHex(byteFinal));
intentBD.putExtra("byteFinal", byteFinal);
sendBroadcast(intentBD);
//presenter.pararServicioEscaneo();
}
}
if (vecesOnChanged == 2){
gatt.readCharacteristic(characteristic);
}
vecesOnChanged = 0;
} else {
Log.e("ESCRIBIRERROR","ERROR Lo que intentaste escribir era : "+characteristic.getValue() + "O en otras palabras: "+ BateriaDeMetodosUtiles.bytesToHex(characteristic.getValue())+" STATUS = "+status);
gatt.disconnect();
gatt.close();
if (mGatt != null){
mGatt.disconnect();
mGatt.close();
}
//presenter.escribirEnToast("ERROR ESCRIBIENDO");
Log.e("ERROR","ESCRIBIENDO");
sendBroadcast(intentError);
}
}
@Override
public void onDescriptorWrite(BluetoothGatt gatt, BluetoothGattDescriptor descriptor, int status) {
Log.i("onDescriptorWrite","enter");
byte[] paraLaBaliza ;//= BateriaDeMetodosUtiles.creacionDeRespuestaParaLaBaliza(idMotivo);
//nuevoMETODOO//////////
BaseDeDatos mBaseDeDatos = Room.databaseBuilder(getApplicationContext(), BaseDeDatos.class, Constantes.nombreBaseDeDatos).fallbackToDestructiveMigration().allowMainThreadQueries().build();
ControlHoras controlHoras = mBaseDeDatos.controlHorasDao().seleccionarTodasControlHoras();
paraLaBaliza = BateriaDeMetodosUtiles.creacionDeRespuestaParaBaliza2(idMotivo, controlHoras.getHoraPasada(), controlHoras.getHash(), controlHoras.getUpTimePasada(), nSerie);
Log.d("QUEENVIOBALIZA", ""+idMotivo);
//presenter.setFHDispositivo(BateriaDeMetodosUtiles.obtenerFH(paraLaBaliza)); LO HAGO CUANDO FICHO
Log.e("DatosQueRecibeBaliza", BateriaDeMetodosUtiles.bytesToHex(paraLaBaliza));
for (int i = 0; i < paraLaBaliza.length; i++){
Log.d("paraLabaliza", i+ " "+paraLaBaliza[i]);
}
ArrayList<byte[]> tmp = BateriaDeMetodosUtiles.particionDeBytes(paraLaBaliza);
arrayDatosPartidos = BateriaDeMetodosUtiles.creacionBytesDelProtocoloTam20(tmp);
Log.i("LENGTHESCRITURA", arrayDatosPartidos.get(0).length+"IS LEN");
numeroDeParticionesDeDatos = arrayDatosPartidos.size();
Log.i("DESCRIPTORWRITE","YES");
descriptor.getCharacteristic().setValue(Constantes.PM_START+"");
if ( gatt.writeCharacteristic( descriptor.getCharacteristic()) ) {
Log.i("ESCRIBECHARINONDESCRIPT","TRUE");
} else {
Log.i("ESCRIBECHARINONDESCRIPT","FALSE");
}
}
@Override
public void onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) {
Log.i("onCharacteristicChanger", "enter");
vecesOnChanged++;
char charrr = (char) characteristic.getValue()[0];
Log.e("QUEESCHANGE1st", charrr+"");
if (vecesOnChanged == 2 && charrr == '$'){
Log.e("RESTAONCHANGE","TRUE");
vecesOnChanged --;
}
byte[] valorCambiado = characteristic.getValue();
Log.i("CHANGED", "TRUE");
Log.i("itera", iteracionesLectura+"");
Log.i("VALORCHANGED",new String(characteristic.getValue(), Charset.forName("UTF-8")));
Log.i("VALORCHANGEDLEN",characteristic.getValue().length+"");
if ((!protocoloLectura) || (protocoloLectura && (valorCambiado[0] != Constantes.PM_ACK))) {
Log.d("C_PROTOCOLO_ON_CHANGED", "TRUE");
protocolo(gatt, characteristic);
}
}
};
private void protocolo(final BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) {
Log.w("ENTRAPROTOCOLO", "TRUE");
try {
handler.removeCallbacks(runnableCodeTimeOutTransmisiones);
}catch (NullPointerException e) {
e.printStackTrace();
}
byte[] valorLeido = characteristic.getValue();
Log.i("Lectura: ", new String(characteristic.getValue(), Charset.forName("UTF-8")));
String resultadoLegible = "";
for (int i = 0; i < valorLeido.length; i++) {
resultadoLegible += valorLeido[i] +"";
//Log.i("Legible", resultadoLegible);
}
String valorEnHex = BateriaDeMetodosUtiles.bytesToHex(valorLeido);
Log.i("VALORREADED:",resultadoLegible);
Log.i("VALORHEX", valorEnHex);
Log.i("ValorString", new String (characteristic.getValue(),Charset.forName("UTF-8")));
Log.i("VALORLENGTH:",""+characteristic.getValue().length);
if (iteracionesLectura <= numeroDeParticionesDeDatos) {// es menor o igual porque la primera vez lees solo para empezar la comunicacion, si no sería menor estrícto
if(valorLeido[0] == Constantes.PM_ACK) {
if (iteracionesLectura == numeroDeParticionesDeDatos) {
Log.i("ESCRIBODESPEDIDA","TRUE");
characteristic.setValue(Constantes.PM_END+"");
} else {
Log.i("LENGTHESCRITURA", arrayDatosPartidos.get(iteracionesLectura).length+"IS LEN");
characteristic.setValue(arrayDatosPartidos.get(iteracionesLectura));
}
Log.e("LENGTHCHARESCRI", characteristic.getValue().length+"");
boolean porcentaje;
porcentaje = gatt.writeCharacteristic(characteristic);
Log.w("LOQUEESCRIBO: ", BateriaDeMetodosUtiles.bytesToHex(characteristic.getValue())+ " : "+porcentaje);
iteracionesLectura++;
}else {
Log.e("ERRORHEADER","no me ha devuelto un +");
//gatt.disconnect();
//gatt.close();
//mGatt = null;
iteracionesLectura = 0;
sendBroadcast(intentError);
}
} else {
protocoloLectura = true;
if(!comunicacionTerminada){
if(valorLeido[0] != Constantes.PM_END_ACK){
if (valorLeido[0] == Constantes.PM_START) {
characteristic.setValue(Constantes.PM_ACK+"");
boolean porcentaje;
porcentaje = gatt.writeCharacteristic(characteristic);
Log.w("LOQUEESCRIBO: ", BateriaDeMetodosUtiles.bytesToHex(characteristic.getValue())+ " : "+porcentaje);
}else if (valorLeido[0] == Constantes.PM_END){
characteristic.setValue(Constantes.PM_END_ACK+"");
boolean porcentaje;
porcentaje = gatt.writeCharacteristic(characteristic);
Log.w("LOQUEESCRIBO: ", BateriaDeMetodosUtiles.bytesToHex(characteristic.getValue())+ " : "+porcentaje);
} else {
if (valorLeido[1] > 0 && valorLeido[1] <= 18) {
datosAJuntar.add(BateriaDeMetodosUtiles.addByteAlArrayFinal(valorLeido));//almaceno en un arrayList todos los datos que leo para después juntarlo.
characteristic.setValue(Constantes.PM_ACK+"");
boolean porcentaje;
porcentaje = gatt.writeCharacteristic(characteristic);
Log.w("LOQUEESCRIBO: ", BateriaDeMetodosUtiles.bytesToHex(characteristic.getValue())+ " : "+porcentaje);
}
}
}
}else {
//presenter.escribirEnToast("Valor leído en el Value de la Característica: " + new String(characteristic.getValue(), Charset.forName("UTF-8")));
//gatt.disconnect();
//gatt.close();
//mGatt = null;
iteracionesLectura = 0;
retry = false;
Log.i("Comunicacion terminada", "TRUE");
}
}
}
private void retrySameMotivo() {
contadorRetrys++;
Log.e("RetryMOTIVOSAME", "TRUE");
//mGatt = null;
try {
mGatt.disconnect();
mGatt.close();
conectaConEsteMotivoRetry(idMotivo);
}catch (NullPointerException e){
e.printStackTrace();
sendBroadcast(intentError);
}
}
public void conectaConEsteMotivoRetry(String idmotivo){
this.idMotivo = idmotivo;
handler.removeCallbacks(runnableCodeTimeOutConversacion);
//handler.postDelayed(timeOutFirmado, 10000);
if (mGatt != null) {
try{
//myTimerProtocolo = null;
handler.removeCallbacks(runnableCodeTimeOutTransmisiones);
Log.d("mBluetoothDevice", "mBluetoothDevice.connectGatt called in the retry...");
/*if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
Log.d("BOUNDING??? ", mBluetoothDevice.createBond()+"");
}*/
mGatt = mBluetoothDevice.connectGatt(getApplicationContext(), false, gattCallback);
//stopScan();// will stop after first device detection
}catch (NullPointerException e){
e.printStackTrace();
}
} else {
Log.i("MGATTISNULL","MGATT ES NULL");
}
}
private Runnable runnableCodeTimeOutTransmisiones = new Runnable() {
@Override
public void run() {
if (!esperandoDesconexion) {
//contadorRetrys = (int) NUMEROS_DE_RETRYS;
try {
Log.e("TIMERPROTOCOLO", "TRUE");
if(mGatt!= null){
mGatt.disconnect();
mGatt.close();
}
if (!retry){
Log.e("TIMEOUT","TRANSMISIONES");
// presenter.escribirEnToast("TIMEOUT Transmisiones");
sendBroadcast(intentError);
}/*else {
retrySameMotivo();
}*/
}catch (NullPointerException e){
e.printStackTrace();
}
}
}
};
private Runnable timeOutFirmado = new Runnable() {
@Override
public void run() {
try {
Log.e("TIMEOUTGLOBALMAXFIRMADO", "TRUE");
//presenter.escribirEnToast("TIMEOUT Global FIRMANDO");
//PRUEBA LISTASCAN
sendBroadcast(intentError);
mGatt.disconnect();
mGatt.close();
}catch (Exception e){
e.printStackTrace();
try {
Log.e("HACER DESCONAMANO","TRUE");
mGatt.disconnect();
mGatt.close();
}catch (Exception exc){
exc.printStackTrace();
}
}
}
};
@Nullable
@Override
public IBinder onBind(Intent intent) {
return mBinder;
}
@Override
public boolean onUnbind(Intent intent) {
try{
mGatt.disconnect();
mGatt.close();
Log.e("UNBINDFirmado", "UNBIND");
//presenter.lanzarServicioFirmado();
try {
handler.removeCallbacks(runnableCodeTimeOutTransmisiones);
handler.removeCallbacks(runnableCodeTimeOutConversacion);
handler.removeCallbacks(timeOutFirmado);
/*if (presenter.getErrorFirmando() && presenter.getNumeroIntentosFirmar() <= 2){
presenter.setNumeroIntentosFirmar(presenter.getNumeroIntentosFirmar() + 1);
presenter.setFlagScanDevice(true);
presenter.escribirEnToast("Reintento...");
presenter.connectToDeviceServicio(presenter.getActualDevice(), presenter.getNserieString());
}else {
presenter.setNumeroIntentosFirmar(0);
//presenter.desaparecerBotonesMotivos();
presenter.setVisibilityMensajeDespuesDeFirmar(View.VISIBLE);
presenter.setVisibilityBotonAceptarDespuesDeFirmar(View.VISIBLE);
presenter.setIconFirmadoEstado(R.drawable.check_gif);
if(presenter.getTextDespuesFirmado().equals("Ha ocurrido un problema con su fichaje, vuelva a intentarlo.")){
presenter.setVisibilityBotonReintentar(View.VISIBLE);
}
}*/
}catch (NullPointerException e){
Log.e("ERROR IN UNBIND", "A NULLPOINT");
e.printStackTrace();
}
}catch (Exception e){
e.printStackTrace();
}
return super.onUnbind(intent);
}
}
答案 0 :(得分:1)
它可能返回false,因为在BLE中你可以一次执行一个操作。如果您同时执行多次写入,则它只执行最后一次写入。
所以,你必须等到一个人写,然后你可以写另一个。