Witajcie.
Mam mały problem z realizacją połączenia Bluetooth na Androidzie. Temat znajduje się trochę niżej, ale ten wątek będzie dotyczyć troszkę innej kwestii. Moja aktywność, w której chcę inicjować połączenie. Znajduje się w niej lista sparowanych i nowych urządzeń. Po kliknięciu chciałbym połączyć się z urządzeniem. Samo nawiązanie połączenia mam zrobione w onClickListenerze podłączonym do listy(działa, serwer wyświetla mi nazwę i adres podłączonego urządzenia) . Pozostaje kwestia jak automatycznie po nawiązaniu połączenia wysłać jakieś słowo na serwer. Kod Aktywności wygląda póki co tak (wersja robocza jeszcze, ale Androida uczę się od 2 tygodni, więc napisałem jak umiałem):
public class MainActivity extends Activity
{
private static final String TAG = "BTD";
private static final boolean D = true;
// Return Intent extra
public static String EXTRA_DEVICE_ADDRESS = "device_address";
// Member fields
private BluetoothAdapter mBtAdapter;
private BluetoothDevice mBtDevice;
private ArrayAdapter<String> mPairedDevicesArrayAdapter;
private ArrayAdapter<String> mNewDevicesArrayAdapter;
private ListView pairedListView, newDevicesListView;
private String address;
public static final int MESSAGE_READ = 2;
private static final UUID MY_UUID = UUID.fromString("00001101-0000-1000-8000-00805f9b34fb");
private BluetoothSocket socket;
private BluetoothDevice connect_device;
private ConnectThread mConnectThread;
private ConnectedThread mConnectedThread;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Set result CANCELED incase the user backs out
setResult(Activity.RESULT_CANCELED);
//Initialize the button to perform device discovery
Button scanButton = (Button) findViewById(R.id.button1);
scanButton.setOnClickListener(new OnClickListener() {
public void onClick(View v)
{
doDiscovery();
}
});
// Initialize array adapters. One for already paired devices and
// one for newly discovered devices
mPairedDevicesArrayAdapter = new ArrayAdapter<String>(this, R.layout.simplerow);
mNewDevicesArrayAdapter = new ArrayAdapter<String>(this, R.layout.simplerow);
// Find and set up the ListView for paired devices
pairedListView = (ListView) findViewById(R.id.listView1);
pairedListView.setAdapter(mPairedDevicesArrayAdapter);
pairedListView.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,
long arg3) {
mBtAdapter.cancelDiscovery();
// Get the device MAC address, which is the last 17 chars in the View
String info = ((TextView) arg1).getText().toString();
address = info.substring(info.length() - 17);
int itemPosition = arg2;
mBtDevice = mBtAdapter.getRemoteDevice(address);
try {
mConnectThread = new ConnectThread(mBtDevice);
} catch (Exception e) {
// TODO: handle exception
}
mConnectThread.start();
BluetoothSocket soc = mConnectThread.getSocket();
String aaaa = "POWITANIE";
byte[] bajty = aaaa.getBytes();
mConnectedThread = new ConnectedThread(soc);
Log.i("soc", "stworzono");
mConnectedThread.start();
Log.i("soc", "wystartowano");
mConnectedThread.write(bajty);
}
});
// Find and set up the ListView for newly discovered devices
newDevicesListView = (ListView) findViewById(R.id.listView2);
newDevicesListView.setAdapter(mNewDevicesArrayAdapter);
newDevicesListView.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,
long arg3) {
mBtAdapter.cancelDiscovery();
//to samo co wyżej będzie
}
});
// Register for broadcasts when a device is discovered
IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
this.registerReceiver(mReceiver, filter);
// Register for broadcasts when discovery has finished
filter = new IntentFilter(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
this.registerReceiver(mReceiver, filter);
// Get the local Bluetooth adapter
mBtAdapter = BluetoothAdapter.getDefaultAdapter();
// Get a set of currently paired devices
Set<BluetoothDevice> pairedDevices = mBtAdapter.getBondedDevices();
// If there are paired devices, add each one to the ArrayAdapter
if (pairedDevices.size() > 0) {
findViewById(R.id.textView1).setVisibility(View.VISIBLE);
for (BluetoothDevice device : pairedDevices) {
mPairedDevicesArrayAdapter.add(device.getName() + "\n" + device.getAddress());
}
} else {
String noDevices = "no devices";
mPairedDevicesArrayAdapter.add(noDevices);
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
//getMenuInflater().inflate(R.menu.bluetooth, menu);
return true;
}
@Override
protected void onResume() {
super.onResume();
}
@Override
protected void onDestroy() {
super.onDestroy();
// Make sure we're not doing discovery anymore
if (mBtAdapter != null) {
mBtAdapter.cancelDiscovery();
}
// Unregister broadcast listeners
this.unregisterReceiver(mReceiver);
}
/**
* Start device discover with the BluetoothAdapter
*/
private void doDiscovery() {
if (D) Log.d(TAG, "doDiscovery()");
// Indicate scanning in the title
setTitle("Scanning... Please wait");
// Turn on sub-title for new devices
findViewById(R.id.textView2).setVisibility(View.VISIBLE);
// If we're already discovering, stop it
if (mBtAdapter.isDiscovering()) {
mBtAdapter.cancelDiscovery();
}
// Request discover from BluetoothAdapter
mBtAdapter.startDiscovery();
}
// The BroadcastReceiver that listens for discovered devices and
// changes the title when discovery is finished
private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
// When discovery finds a device
if (BluetoothDevice.ACTION_FOUND.equals(action)) {
// Get the BluetoothDevice object from the Intent
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
// If it's already paired, skip it, because it's been listed already
if (device.getBondState() != BluetoothDevice.BOND_BONDED) {
mNewDevicesArrayAdapter.add(device.getName() + "\n" + device.getAddress());
}
// When discovery is finished, change the Activity title
} else if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)) {
setProgressBarIndeterminateVisibility(false);
setTitle("Select device");
if (mNewDevicesArrayAdapter.getCount() == 0) {
String noDevices = "none found";
mNewDevicesArrayAdapter.add(noDevices);
}
}
}
};
private class ConnectThread extends Thread {
private final BluetoothSocket mmSocket;
private final BluetoothDevice mmDevice;
public ConnectThread(BluetoothDevice device) {
// Use a temporary object that is later assigned to mmSocket,
// because mmSocket is final
BluetoothSocket tmp = null;
mmDevice = device;
// Get a BluetoothSocket to connect with the given BluetoothDevice
try {
// MY_UUID is the app's UUID string, also used by the server code
tmp = device.createRfcommSocketToServiceRecord(MY_UUID);
} catch (IOException e) { }
mmSocket = tmp;
}
public void run() {
// Cancel discovery because it will slow down the connection
BluetoothAdapter.getDefaultAdapter().cancelDiscovery();
try {
// Connect the device through the socket. This will block
// until it succeeds or throws an exception
mmSocket.connect();
Log.i("CT", "polaczono");
} catch (IOException connectException) {
// Unable to connect; close the socket and get out
Log.i("CT", "NIE polaczono");
try {
mmSocket.close();
} catch (IOException closeException) { }
Log.i("CT", "NIE zamklo socketa");
return;
}
// Do work to manage the connection (in a separate thread)
//manageConnectedSocket(mmSocket);
//Log.i("CT", "przed connectedthread");
//mConnectedThread = new ConnectedThread(mmSocket);
//mConnectedThread.start();
}
public BluetoothSocket getSocket()
{
return mmSocket;
}
/** Will cancel an in-progress connection, and close the socket */
public void cancel() {
try {
mmSocket.close();
} catch (IOException e) { }
}
}
private class ConnectedThread extends Thread {
private final BluetoothSocket mmSocket;
private final InputStream mmInStream;
private final OutputStream mmOutStream;
public ConnectedThread(BluetoothSocket socket) {
mmSocket = socket;
InputStream tmpIn = null;
OutputStream tmpOut = null;
// Get the input and output streams, using temp objects because
// member streams are final
try {
tmpIn = socket.getInputStream();
tmpOut = socket.getOutputStream();
} catch (IOException e) { }
mmInStream = tmpIn;
mmOutStream = tmpOut;
}
public void run() {
byte[] buffer = new byte[1024]; // buffer store for the stream
int bytes; // bytes returned from read()
// Keep listening to the InputStream until an exception occurs
while (true) {
try {
// Read from the InputStream
bytes = mmInStream.read(buffer);
// Send the obtained bytes to the UI activity
//mHandler.obtainMessage(MESSAGE_READ, bytes, -1, buffer)
//.sendToTarget();
} catch (IOException e) {
break;
}
}
}
/* Call this from the main activity to send data to the remote device */
public void write(byte[] bytes) {
try {
mmOutStream.write(bytes);
} catch (IOException e) { }
}
/* Call this from the main activity to shutdown the connection */
public void cancel() {
try {
mmSocket.close();
} catch (IOException e) { }
}
}
}
Jeśli zrobię tak jak powyżej i po prostu wywołam
mConnectedThread.write(bajty);
to nic nie przychodzi i dostaję informację a LogCat'ie mowiącą "Skipped 179 frames" itd. Podejrzewam, że chodzi tu o wątki, ale nie wiem jak się z tym uporać. Proszę o pomoc