1

Firstly, unfourtanetly my English is not too good, but I hope you can understand what is my problem:) So, I am new here and new in Android too. I have two phones: Motorola Defy (with Cyanogenmond- Android 4.4.2) and a Sony Xperia J (Android 4.1.2 - not rooted). I've created an app which can connect the phone with a Lego Mindstorm NXT via bluetooth. First time, it worked perfectly on Xperia J. It connected to NXT and when I had turned off the NXT, the phone tried to reconnect. It seemed that working, but I closed the app and reopen it some times. After that, Xperia J couldn't connect to NXT, but I don't know why? I tried to delete all of the storage datas (because of the SharedPreferences), but also didn't worked. Then I restarted the phone and it seemed like it perfectly connect again. I thought I coded something wrong, but on the other phone there is no problem. Could somebody help me what can be the problem? (I'm a student, so maybe if somebody knows better idea how can I reconnect to NXT, then please tell me:D)


MainActivity:

public class MainActivity extends ActionBarActivity {

private Handler handler = new Handler() {
    @Override
    public void handleMessage(Message msg) {
        switch(msg.what) {
            case BTCommunicator.DATA_RECEIVED:
                byte[] readBuf = (byte[]) msg.obj;
                String readMessage = new String(readBuf, 0, msg.arg1);
                break;
            case BTCommunicator.CONNECTION_SUCCESSFULL:
                Toast.makeText(MainActivity.this, "Successful connection", Toast.LENGTH_LONG).show();
                BTCommunicator.getInstance().start();
                break;
            case BTCommunicator.CONNECTION_FAILED:
                Toast.makeText(MainActivity.this, "Connection failed", Toast.LENGTH_SHORT).show();
                try {
                    Thread.sleep(2000);
                } catch (Exception ex) {}
                BTCommunicator.getInstance().cancel();
                connectToDevice();
                break;
            case BTCommunicator.CONNECTION_CLOSED:
                Toast.makeText(MainActivity.this, "Connection closed", Toast.LENGTH_SHORT).show();
                BTCommunicator.getInstance().cancel();
                connectToDevice();
                break;
        }
    }
};
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
}

@Override
protected void onPause() {
    BTCommunicator.getInstance().cancel();
    super.onPause();
}

public void allConnection(View v) {
    connectToDevice();
}

public void connectToDevice() {
    SharedPreferences sharedPreferences = PreferenceManager
            .getDefaultSharedPreferences(this);
   String btAddress = sharedPreferences.getString(DeviceFounder.KEYBTADDRESS, "");
    String selectedUUID = sharedPreferences.getString(DeviceFounder.KEYUUID, "");


    Set<BluetoothDevice> pairedDevices = BTCommunicator.getInstance().getBluetoothAdapter().getBondedDevices();
    boolean deviceFound = false;
    for(BluetoothDevice device : pairedDevices) {
        if(device.getAddress().equals(btAddress)) {
            new BTConnectAsyncTask(
                     this, handler, device, selectedUUID).execute();
            deviceFound = true;
        }
    }

    if(!deviceFound) {
        Toast.makeText(this, "Device is not paired: " + btAddress, Toast.LENGTH_LONG).show();
    }
}

public void showDeviceFounder(View v) {
    startActivity(new Intent(this, DeviceFounder.class));
}

}


DeviceFounder class

public class DeviceFounder extends Activity {

private DeviceListAdapter listAdapter;
public static final String KEYBTADDRESS = "BTADDRESS"; //BT MAC-cím
public static final String KEYUUID = "UUID";
public static final String UUIDVALUE = "00001101-0000-1000-8000-00805F9B34FB";
public static String KEYBTNAME = "BTNAME";

private final BroadcastReceiver foundReceiver = new BroadcastReceiver() {
    @Override
    public void onReceive(Context context, Intent intent) {
        String action = intent.getAction();
        //Ha talált új eszközt, beteszi
        if (BluetoothDevice.ACTION_FOUND.equals(action)) {
            //Le akarjuk tölteni az adatokat
            BluetoothDevice device =
                    intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
            listAdapter.addDevice(device);
            listAdapter.notifyDataSetChanged();
        }
    }
};

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_device_founder);

    IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
    registerReceiver(foundReceiver, filter);

    BTCommunicator.getInstance().getBluetoothAdapter().startDiscovery();

    ListView listView = (ListView)findViewById(R.id.listView1);
    listAdapter = new DeviceListAdapter();
    listView.setAdapter(listAdapter);

    listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
        public void onItemClick(AdapterView<?> a, View v, int position, long id) {
            sendSelectedUUID(position);
        }
    });
}

@Override
protected void onDestroy() {
    super.onDestroy();
    unregisterReceiver(foundReceiver);
    BTCommunicator.getInstance().cancel();
}

private void sendSelectedUUID(final int aSelectPosition) {
    BluetoothDevice device = (BluetoothDevice) listAdapter.getItem(aSelectPosition);

    SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this);
    SharedPreferences.Editor editor = sharedPreferences.edit();
    editor.putString(KEYBTADDRESS, device.getAddress());
    editor.putString(KEYUUID, UUIDVALUE);
    editor.putString(KEYBTNAME, device.getName());
    editor.commit();
    finish();
}

}

The BTConnectAsyncTask just call this:

 try {
        UUID serviceUuid = UUID.fromString(selectedUUID);
        BTCommunicator.getInstance().connect(device, serviceUuid, handlerStatus);
        return "OK";
    } catch (Exception e) {
        return ("Error: "+e.getMessage());
    }

And lastly the BTCommunicator class:

'public class BTCommunicator extends Thread {
public static final int DATA_RECEIVED = 0;
public static final int CONNECTION_SUCCESSFULL = 1;
public static final int CONNECTION_FAILED = 2;
public static final int CONNECTION_CLOSED = 3;

//Ez reprezentálja a fizikai BlueTooth adaptert. Ezt használva
//tudod felfedni a többi eszközt MAC-kel és BlueToothServerSocket
//segítségével figyelni a bejövő kommunikációt!
private BluetoothAdapter bluetoothAdapter = null;
//Ezen keresztül engedi a rendszer, hogy egy app kommunikáljon egy
//másik appal. Input- és OutputStreamen keresztül.
private InputStream inStream = null;
private OutputStream outStream = null;
private Handler msgHandler = null;
private static boolean enabled = false;
public static  BluetoothSocket clientSocket = null;

//statikus példány kérése
private static BTCommunicator instance = null;

public static BTCommunicator getInstance() {
    if(instance == null) {
        instance = new BTCommunicator();
    }
    return instance;
}

protected BTCommunicator() {
    bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
}

public BluetoothAdapter getBluetoothAdapter() {
    return bluetoothAdapter;
}

public void connect(BluetoothDevice device, UUID uuid, Handler
        handler)
{
    bluetoothAdapter.cancelDiscovery();
    msgHandler = handler;
    enabled = true;

    try {
        clientSocket = device.createRfcommSocketToServiceRecord(uuid);
        clientSocket.connect();
        inStream = clientSocket.getInputStream();
        outStream = clientSocket.getOutputStream();
        handler.obtainMessage(CONNECTION_SUCCESSFULL,
                "").sendToTarget();
    } catch (Exception e) {
        Log.e("BTCommunicator", e.getMessage());
        try {
            handler.obtainMessage(CONNECTION_FAILED, e.getMessage
                    ()).sendToTarget();
            clientSocket.close();
           // BTCommunicator.getInstance().cancel();
            //BTCommunicator.getInstance().connect(device, uuid, handler);
        } catch (IOException closeException) { }
    }
}

public void run() {
    byte[] buffer = new byte[1024];
    int bytes;

    while (enabled) {
        try {
            bytes = inStream.read(buffer);
            msgHandler.obtainMessage(DATA_RECEIVED, bytes, -1,
                    buffer).sendToTarget();
        } catch (IOException e) {
            msgHandler.obtainMessage(CONNECTION_CLOSED,
                    "").sendToTarget();

            try {
                clientSocket.close();
            } catch (IOException e2) { }
            break;
        }
    }
}

public void write(byte[] bytes) {
    try {
        if(outStream != null) {
            outStream.write(bytes);
        }
    } catch (IOException e) {
        Log.e("BTCOMM", e.getMessage());
    }
}

public void cancel() {
    enabled = false;

    if (bluetoothAdapter != null)
        bluetoothAdapter.cancelDiscovery();

    if (msgHandler != null)
        /*msgHandler.obtainMessage(CONNECTION_CLOSED,
                "").sendToTarget();*/

    if (outStream != null) {
        try {
            outStream.close();
            outStream = null;
        } catch (Exception e) {
        }
    }

    if (inStream != null) {
        try {
            inStream.close();
            inStream = null;
        } catch (Exception e) {
        }
    }

    if (clientSocket != null) {
        try {
            clientSocket.close();
            clientSocket = null;
        } catch (IOException e) {
        }
    }

    instance = null;
}

} `

Joci Ivanics
  • 31
  • 1
  • 3

1 Answers1

0

Ok, the problem is solved:) I should call the whole cancel function in the BTCommunicator catch block, because Android 4.1.2 won't close the streams if I close the program. I don't know why, maybe a bug in the OS? XD Because it was only caused before Android version 4.4.2.

Joci Ivanics
  • 31
  • 1
  • 3