[Java for Android App Development] adamhala007:
Hi! I am beginner in Android programming. I would like to learn how to send a string between 2 devices via Bluetooth. I was trying to write a code on the base of page http://developer.android.com/guide/topics/connectivity/bluetooth.html

I got 3 errors. The first one is, that the MainActivity is underlined red in the following row:

public class MainActivity extends Activity {

It says: 'The blank final field mHandler may not have been initialized'

The other 2 errors are shown in the AcceptThread and ConnectThread classes. The following row is underlined red:

manageConnectedSocket(socket);

It says: 'The method manageConnectedSocket(BluetoothSocket) is undefined for the type AcceptThread' and 'The method manageConnectedSocket(BluetoothSocket) is undefined for the type ConnectThread'

Could you please tell me, how to fix the problems and explain me, what were the problems? Thanks in advance.

MainActivity.java:

package com.example.probax8;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Set;
import java.util.UUID;

import android.app.Activity;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothServerSocket;
import android.bluetooth.BluetoothSocket;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.os.Handler;

import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;

public class MainActivity extends Activity {
private static final String TAG = "MainActivity";
private final static int REQUEST_ENABLE_BT = 1;
private BluetoothAdapter mBluetoothAdapter = null;
private ArrayAdapter<String> mNewDevicesArrayAdapter;
private final UUID my_UUID = UUID.fromString("00001802-0000-1000-8000-00805f9b34fb");
protected static final int MESSAGE_READ = 1;
BroadcastReceiver mReceiver;
private final Handler mHandler;
private BluetoothSocket socket;
String address;
TextView tv;
int a = 0;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

//**** Is BlueTooth and enable BT
final BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
if (mBluetoothAdapter == null) {
// Device does not support Bluetooth
}

if (!mBluetoothAdapter.isEnabled()) {
Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);

}

//**** ON/OFF Bluetooth on click

Button btButton = (Button) findViewById(R.id.bBT);
btButton.setOnClickListener( new OnClickListener() {

@Override
public void onClick(View v) {
// TODO Auto-generated method stub
if(!mBluetoothAdapter.isEnabled()){
mBluetoothAdapter.enable();

}
else{
mBluetoothAdapter.disable();

}
}
});

//**** make Bluetooth discoverable

Button discButton = (Button) findViewById(R.id.bDis);
discButton.setOnClickListener( new OnClickListener() {

@Override
public void onClick(View v) {
// TODO Auto-generated method stub
Intent discoverableIntent = new
Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
discoverableIntent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 300);
startActivity(discoverableIntent);
}
});
Button stopDiscButton = (Button) findViewById(R.id.bStopDisc);
stopDiscButton.setOnClickListener( new OnClickListener() {

@Override
public void onClick(View v) {
// TODO Auto-generated method stub
mBluetoothAdapter.startDiscovery();
}
});
Button startDiscButton = (Button) findViewById(R.id.bStartDisc);
startDiscButton.setOnClickListener( new OnClickListener() {

@Override
public void onClick(View v) {
// TODO Auto-generated method stub
mBluetoothAdapter.startDiscovery();
}
});

tv = (TextView) findViewById(R.id.textView1);
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());
tv.setText(device.getName() + "\n" + device.getAddress());

}

}
}
};

//****

mNewDevicesArrayAdapter=new ArrayAdapter<String>(this,android.R.layout.simple_list_item_1,0);
ListView newDevicesListView = (ListView) findViewById(R.id.listView1);
newDevicesListView.setAdapter(mNewDevicesArrayAdapter);
mNewDevicesArrayAdapter.notifyDataSetChanged();
// newDevicesListView.setOnItemClickListener(mDeviceClickListener);

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
mNewDevicesArrayAdapter.add(device.getName() + "\n" + device.getAddress());

}
}

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

filter = new IntentFilter(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
this.registerReceiver(mReceiver, filter);

newDevicesListView.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,
long arg3) {
// TODO Auto-generated method stub

// mBluetoothAdapter.cancelDiscovery();
final String info = ((TextView) arg1).getText().toString();

//get the device address when click the device item
address = info.substring(info.length()-17);
a = 1;
Log.e(TAG, address);
//connect the device when item is click
BluetoothDevice connect_device = mBluetoothAdapter.getRemoteDevice(address);

try {
socket = connect_device.createRfcommSocketToServiceRecord(my_UUID);
socket.connect();

} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

}

});//************new_devices_list end

if(a==1){
Toast.makeText(this, address,Toast.LENGTH_LONG).show();
}
Button unregButton = (Button) findViewById(R.id.bUnreg);
unregButton.setOnClickListener( new OnClickListener() {

@Override
public void onClick(View v) {
// TODO Auto-generated method stub
unregisterReceiver(mReceiver);
}
});
//**************
class AcceptThread extends Thread {
private final BluetoothServerSocket mmServerSocket;

public AcceptThread() {
// Use a temporary object that is later assigned to mmServerSocket,
// because mmServerSocket is final
BluetoothServerSocket tmp = null;
try {
// MY_UUID is the app's UUID string, also used by the client code
tmp = mBluetoothAdapter.listenUsingRfcommWithServiceRecord("MainActivity", my_UUID);
} catch (IOException e) { }
mmServerSocket = tmp;
}

public void run() {
BluetoothSocket socket = null;
// Keep listening until exception occurs or a socket is returned
while (true) {
try {
socket = mmServerSocket.accept();
} catch (IOException e) {
break;
}
// If a connection was accepted
if (socket != null) {
// Do work to manage the connection (in a separate thread)
manageConnectedSocket(socket);

mmServerSocket.close();

}
}
}

/** Will cancel the listening socket, and cause the thread to finish */
public void cancel() {
try {
mmServerSocket.close();
} catch (IOException e) { }
}
}

//***********
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
mBluetoothAdapter.cancelDiscovery();

try {
// Connect the device through the socket. This will block
// until it succeeds or throws an exception
mmSocket.connect();
} catch (IOException connectException) {
// Unable to connect; close the socket and get out
try {
mmSocket.close();
} catch (IOException closeException) { }
return;
}

// Do work to manage the connection (in a separate thread)
manageConnectedSocket(mmSocket);
}

/** Will cancel an in-progress connection, and close the socket */
public void cancel() {
try {
mmSocket.close();
} catch (IOException e) { }
}
}
//**********

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(MainActivity.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) { }
}
}
}

}

activity_main.xml:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="${relativePackage}.${activityClass}" >

<TextView
android:id="@+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/hello_world" />

<Button
android:id="@+id/bBT"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_below="@+id/textView1"
android:text="Bluetooth" />

<Button
android:id="@+id/bDis"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_below="@+id/bBT"
android:text="Disc 300s" />

<ListView
android:id="@+id/listView1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_below="@+id/bDis" >
</ListView>

<Button
android:id="@+id/bRetry"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBaseline="@+id/bBT"
android:layout_alignBottom="@+id/bBT"
android:layout_toRightOf="@+id/bBT"
android:text="Retry" />

<Button
android:id="@+id/bUnreg"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBottom="@+id/bRetry"
android:layout_toRightOf="@+id/bRetry"
android:text="Unregister" />

<Button
android:id="@+id/bStopDisc"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/bRetry"
android:layout_toRightOf="@+id/bDis"
android:text="StopDisc" />

<Button
android:id="@+id/bStartDisc"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/bUnreg"
android:layout_toRightOf="@+id/bStopDisc"
android:text="StartDisc" />

</RelativeLayout>