Ciao a tutti.

Ho scritto una semplice applicazione di testo per Android per testare la connessione Bluetooth.

Il codice dell'Activity e' questo:

codice:
public class TesterBluethoot extends Activity {
	
	volatile TextView tv;
    ScrollView sv;
    
    private Handler mHandler = new Handler();
    private Handler mHandlerConnect = new Handler();
    
    private int State = -1;
    private int ConnectState = -1;
    
    private static final int MENU_STATE_CONNECTION = 1;
    private static final int MENU_STATE_SEND = 2;
    private int menuState = MENU_STATE_CONNECTION;
    
    private BluetoothAdapter mBluetoothAdapter;
    private BluetoothDevice remoteDeviceSelected;
    private BluetoothSocket mySocket;
    private InputStream mmInStream;
    private OutputStream mmOutStream;
    
    List remoteDevices = new ArrayList();
    
    private static final UUID MY_UUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");

    private static final int START_CONNECTION = 1;
    private static final int SEND_MSG = 2;
    
    private String toPrint;
    // private ConnectThread myConnection;
    
    private byte[] bufferRead = new byte[1024];
    private boolean clearScreen = false;
    
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        
        tv = new TextView(this);  
    	sv = new ScrollView(this);
    	
    	tv.setTextSize(20);
    	tv.setVerticalScrollBarEnabled(true);
        
    	mHandler.postDelayed(mUpdateTimeTask, 300);
    	mHandlerConnect.postDelayed(mConnectSocket, 150); 
    	
    	tv.append("Start Activity! \n");
	    setContentView(tv);
	    
	    State = 0;
    	//setContentView(R.layout.main);
    }
    
    public boolean onPrepareOptionsMenu(Menu menu) {
    	super.onPrepareOptionsMenu(menu);
    	switch (menuState) {
    	 case MENU_STATE_CONNECTION:  
    	    menu.add(0, START_CONNECTION, 0, "Start Connection");
    	   break;
    	 case MENU_STATE_SEND:
    		 menu.removeItem(START_CONNECTION);
    		 menu.add(0, SEND_MSG, 0, "Send Message");
      	   break;
    	}
    	return true;
    }
    
    public boolean onOptionsItemSelected(MenuItem item) { 
		   switch (item.getItemId()) { 
		    case START_CONNECTION: 
		    	 State = 2;
		        return true; 
		    case SEND_MSG: 
		    	 ConnectState = 3;
		        return true; 	    
		   } 
		   return false; 
	  }
    
    public void onDestroy() {
    	try {
    	 unregisterReceiver(mReceiver);
    	 if (mySocket != null) mySocket.close();
    	}
    	catch (Exception e) {
    		e.printStackTrace();
    		tv.append("onDestroy error: "+e.toString()+" \n");
    	    setContentView(tv);
    	}
    	super.onDestroy();
    }
    
    private void jbInit() throws Exception {
    	
    	tv.append("BluetoothAdapter.getDefaultAdapter() \n");
	    setContentView(tv);
    	mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
    	if (mBluetoothAdapter == null) {
    		tv.append("Device not support Bluetooth");
		    setContentView(tv);
		    return;
    	}
    	
    	tv.append("mBluetoothAdapter.isEnabled() ? \n");
	    setContentView(tv);
    	if (!mBluetoothAdapter.isEnabled()) {
    	    Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
    	    startActivityForResult(enableBtIntent, BIND_AUTO_CREATE);
    	}
    	
    	tv.append("Bluetooth attivo! \n");
	    setContentView(tv);
	    
	    // Register the BroadcastReceiver
	    IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
	    registerReceiver(mReceiver, filter); // Don't forget to unregister during onDestroy
	    State = 1;
    }
    
    public void findPairedDevices() {
       try {	
    	Set<BluetoothDevice> pairedDevices = mBluetoothAdapter.getBondedDevices();
    	// If there are paired devices
    	if (pairedDevices.size() > 0) {
    	    // Loop through paired devices
    	    for (BluetoothDevice device : pairedDevices) {
    	        // Add the name and address to an array adapter to show in a ListView
    	    	tv.append("Disp trovato: "+device.getName() + " - " + device.getAddress()+ " \n");
    	    }
    	    setContentView(tv);  
    	}
    	else {
    		tv.append("Nessun dispositivo trovato... :( \n");
		    setContentView(tv);  
		    State = -1;
    	}
       }
       catch (Exception e) {
    	      e.printStackTrace();
			  State = -1;
			  tv.append("findDevices exception: "+e.toString());
		      setContentView(tv);  
       }
    }
    
    private boolean findDeviceByName(String name) {
    	
    	if (remoteDevices.size() == 0) return false;
    	
    	for (int i=0; i<remoteDevices.size(); i++) {
    		BluetoothDevice elem = (BluetoothDevice)remoteDevices.get(i);
    		if (elem.getName() != null && elem.getName().equalsIgnoreCase(name)) return true;
    	}
    	
    	return false;
    }
    
    private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();
            if (BluetoothDevice.ACTION_FOUND.equals(action)) {
                BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
                if (!findDeviceByName(device.getName())) {
                	remoteDevices.add(device);
                    tv.append("Disp trovato: "+device.getName() + " - " + device.getAddress()+ " \n");
                    setContentView(tv); 
                }
            }
        }
    };
    
    private boolean searchStringIntoName(String pattern, String name) {
    	
    	String tmp = name;
   	
    	int found = tmp.indexOf(pattern);
    	
    	if (found > -1) return true;
    	
    	return false;
    }
    
    private Runnable mUpdateTimeTask = new Runnable() 
	  {
		  public void run() {
	         
			  switch (State) {
			     case 0: 
				   try {
			    	  jbInit();
				   }
				   catch (Exception e) {
					  e.printStackTrace();
					  State = -1;
					  tv.append("jbInit exception: "+e.toString());
				      setContentView(tv);
				   }
				  break;
				  
			     case 1:
			    	try { 
			    		State = -1;
			    		tv.setText("");
			    		tv.append("Cerco i dispositivi \n");
		                setContentView(tv); 
			    	    mBluetoothAdapter.startDiscovery();
			    	}
			    	catch (Exception e) {
			    		  e.printStackTrace();
						  State = -1;
						  tv.append("startDiscovery exception: "+e.toString());
					      setContentView(tv);	
			    	}
			      break;
			       	 
			     case 2:
			    	  		    	 
			    	 try {
			    	    		 
			    	   mBluetoothAdapter.cancelDiscovery();
			    	   Thread.sleep(500);
			    	
			    	   tv.setText("");
			    	   State = -1;
			    	   ConnectState = 1;
			    	 }
			    	 catch (Exception e) {
			    		 e.printStackTrace();
						 State = -1;
						 tv.append("createRfcommSocketToServiceRecord exception: "+e.toString());
					     setContentView(tv);	
					     try {
			                	mySocket.close();
			             } catch (Exception closeException) { }
			    	 }
			    	 break;
			    	 
			     case 100: 
			    	  tv.append(toPrint);
				      setContentView(tv);	
				      State = -1;
			    	 break;
			    	 
			     case 150: 
			    	  tv.append(toPrint);
				      setContentView(tv);	
				      ConnectState = -1;
				      State = -1;
			    	 break;
			    	 
			     case 200: 
			    	  tv.append(toPrint);
				      setContentView(tv);	
				      State = -1;
			    	 break; 	 
			  }
			  
	         mHandler.postDelayed(mUpdateTimeTask, 300);
	      }
	  };
	  
	  private Runnable mConnectSocket = new Runnable() {
		  int scanned = 0;
		  
		  public void run() {
			  
			 switch (ConnectState) {
			 
			   case 1:
				  boolean found = false; 
				   
				  for (int i=0; i<remoteDevices.size(); i++) {
					  BluetoothDevice tmp = (BluetoothDevice)remoteDevices.get(i);
					  if (tmp != null) {
						  if (tmp.getName() != null && tmp.getName().indexOf("HTC") > -1) {
							  remoteDeviceSelected = tmp;
							  found = true;
						  }
					  }
				  }
				   
				  if (found)  {   
				   try {
			    	    	/* mySocket = remoteDeviceSelected.createRfcommSocketToServiceRecord(MY_UUID);
			    	        mySocket.connect(); */
						    
						    Method m = remoteDeviceSelected.getClass().getMethod("createRfcommSocket", new Class[] {int.class});
						    mySocket = (BluetoothSocket) m.invoke(remoteDeviceSelected, 1);
						    
			    	        mmInStream = mySocket.getInputStream();
			    	        mmOutStream = mySocket.getOutputStream();
			    	        toPrint = "Connection to "+remoteDeviceSelected.getName()+" ok \n";
						    State = 200;		
						    ConnectState = 2;
						    menuState = MENU_STATE_SEND;
			    	    }
			    	    catch (Exception e) {
			    	    	try {
			    	    		if (mySocket != null) mySocket.close();
			    	    		if (mmInStream != null) mmInStream.close();
			    	    		if (mmOutStream != null) mmOutStream.close();
			    	    	}
			    	    	catch (Exception e1) {
			    	    		
			    	    	}
			    	    	toPrint = "unable to connect to "+remoteDeviceSelected.getName()+" \n";
						    toPrint = toPrint + "Reason : " + e.toString()+ "\n";
			    	    	State = 150;
						    scanned++;
						    ConnectState = -1;
			    	    }
				   }
				   else {
					   toPrint = "HTC not found \n";
					   State = 150;
					   ConnectState = -1;
				       State = -1;
				       scanned = 0;
				   }
				   break;
			   	  
			   case 2:
				   try {
		                int bytes = mmInStream.read(bufferRead);
		                if (bytes > 0) {
		                	toPrint = "Letti: "+bytes+ " bytes \n";
		                	State = 200;
		                }
		            } 
				    catch (Exception e) {
				    	toPrint = "Read Error : "+e.toString()+"\n";
	                	State = 150;
	                	ConnectState = -1;
		            }
				   break;
				
			   case 3:
				    try {
				        String provaMsg = "Prova bluethoot";
				    	mmOutStream.write(provaMsg.getBytes());
				    	toPrint = "Messaggio di prova inviato \n";
	                	State = 200;
	                	ConnectState = 2;
				    }
				    catch (Exception e) {
				    	toPrint = "Write Error : "+e.toString()+"\n";
	                	State = 150;
	                	ConnectState = -1;
		            }
				   break;
				   
			  }
			  mHandlerConnect.postDelayed(mConnectSocket, 150); 
		  }
	  };
	  
	  private void printText(String text) {
		  tv.append(text);
      	  setContentView(tv);
	  }
	  
	  
}
Con quest'applicazione banalmente apro la connessione col bluetooth locale, cerco i dispositivi con un bluetooth attivo e poi provo a collegarmi con quello attivo su un HTC con cui faccio le prove.

quello che succede e' questo:

1) quando cerco di connettere il cell su cui eseguo l'Activity a un bluetooth remoto se uso il seguente codice:

codice:
mySocket = remoteDeviceSelected.createRfcommSocketToServiceRecord(MY_UID);
mySocket.connect();
mi da un java.io.IOException Service discovery failed

mentre se utilizzo il seguente:

codice:
Method m = remoteDeviceSelected.getClass().getMethod("createRfcommSocket", new Class[] {int.class});
mySocket = (BluetoothSocket) m.invoke(remoteDeviceSelected, 1);
funziona.
La cosa che non mi piace e' che la prima versione e' quella che ho trovato sul sito Android alla seguente URL: http://developer.android.com/guide/t...bluetooth.html

2) Utilizzo il seguente codice che funziona:

codice:
Method m = remoteDeviceSelected.getClass().getMethod("createRfcommSocket", new Class[] {int.class});
mySocket = (BluetoothSocket) m.invoke(remoteDeviceSelected, 1);
per connettermi al dispositivo remoto.

Ho dei problemi sulla lettura e sulla scrittura.

Quando leggo mi da l'errore java.io.IOException Software caused connection abort mentre quando scrivo mi da un java.io.IOException Transport endpoint is not connected.

Qualcuno mi puo' illuminare?
Grazie

Ciao
Sandro