I'm pretty new to Android. Right now I'm trying to make a two-player Pong game using the Bluetooth API. I've more or less tried to copy the BluetoothChat tutorial on the Android website, but I still get an error where the socket immediately disconnects after I switch over to the ConnectedThread. Would anyone have any idea why this is?
I have each of the three types of threads as a private class on a screen of a menu. ConnectThread is split into reading and writing, and is placed inside the screen of the game.
public abstract class FindScreen extends EngineView {
private GUIFactory guiFact;
private TextButton backButton;
private ScrollingList buttonList;
public ConnectThread connectThread;
private BluetoothAdapter adapter;
public FindScreen(Context c, AndroidView aView) {
super(c, aView, 1);
adapter = BluetoothAdapter.getDefaultAdapter();
guiFact = new GUIFactory(new Vector2d(EngineConstants.CENTER_X,
EngineConstants.CENTER_Y), 8, 8, EngineConstants.VIRTUAL_W,
EngineConstants.VIRTUAL_H, EngineConstants.VIRTUAL_W / 32);
GUITask backTask = new GUITask() {
public void execute() {
goBack();
}
};
backButton = guiFact.newGradientTextButton(1, 6, 7, 7, backTask, "Back");
this.add(backButton, 0);
buttonList = guiFact.newScrollingList(1,1,7,6);
this.add(buttonList, 0);
}
#Override
public boolean onTouchEvent(MotionEvent e) {
backButton.executeIfContained(e.getX(), e.getY());
buttonList.executeIfContained(e.getX(), e.getY());
return true;
}
public void onIn() {
// Register for broadcasts when a device is discovered
IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
context.registerReceiver(receiver, filter);
// Register for broadcasts when discovery has finished
filter = new IntentFilter(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
context.registerReceiver(receiver, filter);
buttonList.clearButtons();
if(!adapter.startDiscovery()) { // if discovery doesn't start successfully, leave the screen
goBack();
}
}
public void onOut() {
if (adapter.isDiscovering()) {
adapter.cancelDiscovery();
}
context.unregisterReceiver(receiver);
if (connectThread != null) {
connectThread.cancel();
}
}
/**
* Return to the previous screen, the menu screen
*/
public abstract void goBack();
/**
* Do something after we've connected
* #param socket
*/
public abstract void connected(BluetoothSocket socket);
/**
* Broadcast receiver;
* Listens for discovered devices
* When discovery is finished, changes the list of discovered devices
* When discoverability is changed, changes text
*/
private final BroadcastReceiver receiver = new BroadcastReceiver() {
#Override
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 (device.getBondState() != BluetoothDevice.BOND_BONDED) {
buttonList.addButton(device.getName(), new ConnectTask(device.getAddress()));
// }
// doDiscovery();
}
}
};
private class ConnectTask extends GUITask {
private String address;
public ConnectTask(String addr) {
address = addr;
}
#Override
public void execute() {
BluetoothDevice device = adapter.getRemoteDevice(address);
if (connectThread != null) {
connectThread.cancel();
}
connectThread = new ConnectThread(device);
connectThread.start();
}
}
private class ConnectThread extends Thread {
private final BluetoothSocket socket;
private final BluetoothDevice device;
public ConnectThread(BluetoothDevice dev) {
// Use a temporary object that is later assigned to mmSocket,
// because mmSocket is final
BluetoothSocket tmp = null;
device = dev;
// 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(EngineConstants.MY_UUID);
} catch (IOException e) { }
socket = tmp;
}
public void run() {
// Cancel discovery because it will slow down the connection
if (adapter.isDiscovering()) {
adapter.cancelDiscovery();
}
try {
// Connect the device through the socket. This will block
// until it succeeds or throws an exception
socket.connect();
} catch (IOException connectException) {
// Unable to connect; close the socket and get out
try {
socket.close();
} catch (IOException closeException) { }
return;
}
// Do work to manage the connection (in a separate thread)
connected(socket);
}
/** Will cancel an in-progress connection, and close the socket */
public void cancel() {
try {
socket.close();
} catch (IOException e) { }
}
}
public abstract class HostScreen extends EngineView {
private GUIFactory guiFact;
private TextButton backButton;
private TextLabel waitText;
private BluetoothAdapter adapter;
public AcceptThread acceptThread;
private static final int DISCOVERY_LENGTH = 300;
public HostScreen(Context c, AndroidView aView) {
super(c, aView, 1);
adapter = BluetoothAdapter.getDefaultAdapter();
guiFact = new GUIFactory(new Vector2d(EngineConstants.CENTER_X,
EngineConstants.CENTER_Y), 8, 8, EngineConstants.VIRTUAL_W,
EngineConstants.VIRTUAL_H, EngineConstants.VIRTUAL_W / 32);
GUITask backTask = new GUITask() {
public void execute() {
goBack();
}
};
backButton = guiFact.newGradientTextButton(1, 6, 7, 7, backTask, "Back");
this.add(backButton, 0);
waitText = guiFact.newLabel(2, 3, 6, 4, Color.WHITE, "...");
this.add(waitText, 0);
}
public void onIn() {
if (adapter.getScanMode() != BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE) {
Intent discoverableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
discoverableIntent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, DISCOVERY_LENGTH);
((Activity) context).startActivityForResult(discoverableIntent, EngineConstants.REQUEST_DISCOVERABLE);
}
if (!adapter.isEnabled()) {
Intent enableIntent = new Intent(
BluetoothAdapter.ACTION_REQUEST_ENABLE);
context.startActivity(enableIntent);
}
}
public void onOut() {
if (acceptThread != null) {
acceptThread.cancel();
}
}
public void discoverableAccepted() {
if (acceptThread != null) {
acceptThread.cancel();
}
acceptThread = new AcceptThread();
acceptThread.start();
}
public void discoverableDeclined() {
goBack();
}
/**
* Do something after we've connected
* #param socket
*/
public abstract void connected(BluetoothSocket socket);
#Override
public boolean onTouchEvent(MotionEvent e) {
backButton.executeIfContained(e.getX(), e.getY());
return true;
}
/**
* Return to the previous screen, the menu screen
*/
public abstract void goBack();
private class AcceptThread extends Thread {
private final BluetoothServerSocket serverSocket;
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 = adapter.listenUsingRfcommWithServiceRecord(EngineConstants.NAME, EngineConstants.MY_UUID);
} catch (IOException e) { }
serverSocket = tmp;
}
public void run() {
BluetoothSocket socket = null;
// Keep listening until exception occurs or a socket is returned
while (true) {
try {
socket = serverSocket.accept();
} catch (IOException e) {
break;
}
// If a connection was accepted
if (socket != null) {
// Do work to manage the connection (in a separate thread)
connected(socket);
try {
serverSocket.close();
} catch (IOException e) {
android.util.Log.d("Accept thread", "Could not close serverSocket");
}
break;
}
}
}
/** Will cancel the listening socket, and cause the thread to finish */
public void cancel() {
try {
serverSocket.close();
} catch (IOException e) { }
}
}
}
public class GameScreen extends EngineView {
public ConnectedThread connectedThread;
public ConnectedWriteThread writeThread;
private PacketHandler handler;
private final static int N_LAYERS = 4;
// layer 0 = walls
// layer 1 = puck
// layer 2 = paddles
// layer 3 = GUI
public Paddle enemyPaddle, playerPaddle;
public Puck puck;
private GUIFactory guiFact;
private TextLabel playerLabel, enemyLabel;
public int playerScore = 0, enemyScore = 0;
private boolean isHeld;
private float startX, startTouchX, moveToX;
private final static float MIN_X = Paddle.RADIUS, MAX_X = EngineConstants.VIRTUAL_W - MIN_X;
public float myPaddlePrevPosX;
public boolean enemyScoreChanged = false;
private final static long PACKET_RATE = 200;
private long packetTime = 0;
public GameScreen(Context c, final AndroidView aView) {
super(c, aView, N_LAYERS);
enemyPaddle = new Paddle(new Vector2d(EngineConstants.CENTER_X, EngineConstants.VIRTUAL_H/8f), 255, 255, 100, 100);
playerPaddle = new Paddle(new Vector2d(EngineConstants.CENTER_X, EngineConstants.VIRTUAL_H*7f/8f), 255, 100, 255, 100);
puck = new Puck();
this.add(enemyPaddle, 2);
this.add(playerPaddle, 2);
this.add(puck, 1);
guiFact = new GUIFactory(new Vector2d(EngineConstants.CENTER_X, EngineConstants.CENTER_Y), 8, 10, EngineConstants.VIRTUAL_W, EngineConstants.VIRTUAL_H, 0);
playerLabel = guiFact.newLabel(2, 4, 3, 5, Color.rgb(100, 150, 100), "0");
enemyLabel = guiFact.newLabel(7, 3, 8, 4, Color.rgb(150, 100, 100), "0");
this.add(playerLabel, 3);
this.add(enemyLabel, 3);
this.constraints.add(new BoxConstraint(puck, false, false, 0 + Puck.RADIUS));
this.constraints.add(new BoxConstraint(puck, false, true, EngineConstants.VIRTUAL_W - Puck.RADIUS));
myPaddlePrevPosX = playerPaddle.pos.x;
}
public void onOut() {
if (connectedThread != null) {
connectedThread.cancel();
}
if (writeThread != null) {
writeThread.cancel();
}
}
public void update(long interval) {
super.update(interval);
EngineFunctions.collide(playerPaddle, puck);
EngineFunctions.collide(enemyPaddle, puck);
if (puck.pos.y < 0) {
score(true);
} else if (puck.pos.y > EngineConstants.VIRTUAL_H) {
score(false);
}
packetTime += interval;
if (packetTime > PACKET_RATE) {
// android.util.Log.d("fillQueue", "called");
packetTime = 0;
writeThread.fillQueue();
}
}
private void score(boolean isPlayer) {
if (isPlayer) {
playerScore++;
playerLabel.setText(String.valueOf(playerScore));
} else {
enemyScore++;
enemyLabel.setText(String.valueOf(enemyScore));
enemyScoreChanged = true;
}
puck.pos.x = EngineConstants.CENTER_X;
puck.pos.y = EngineConstants.CENTER_Y;
puck.prevPos.x = EngineConstants.CENTER_X;
puck.prevPos.y = EngineConstants.CENTER_Y;
}
#Override
public boolean onTouchEvent(MotionEvent e) {
switch(e.getAction()) {
case MotionEvent.ACTION_DOWN:
if (playerPaddle.touching(e.getX(), e.getY())) {
isHeld = true;
startX = playerPaddle.pos.x;
startTouchX = e.getX();
}
break;
case MotionEvent.ACTION_MOVE:
if (isHeld) {
myPaddlePrevPosX = playerPaddle.pos.x;
moveToX = startX + (e.getX() - startTouchX);
if (moveToX < MIN_X) {
moveToX = MIN_X;
} else if (moveToX > MAX_X) {
moveToX = MAX_X;
}
playerPaddle.pos.x = moveToX;
playerPaddle.prevPos.x = moveToX;
}
break;
case MotionEvent.ACTION_UP:
isHeld = false;
break;
}
return true;
}
public void startNewConnectedThread(BluetoothSocket soc, boolean isServer) {
if (connectedThread != null) {
connectedThread.cancel();
}
connectedThread = new ConnectedThread(soc, handler);
connectedThread.start();
if (writeThread != null) {
writeThread.cancel();
}
writeThread = new ConnectedWriteThread(soc, handler, isServer);
writeThread.start();
}
public void setHandler(PacketHandler h) {
handler = h;
}
public class ConnectedThread extends Thread {
private final BluetoothSocket socket;
private final InputStream inStream;
private final BufferedReader in;
private PacketHandler handler;
public ConnectedThread(BluetoothSocket soc, PacketHandler pHandler) {
socket = soc;
handler = pHandler;
InputStream tmpIn = null;
// Get the input and output streams, using temp objects because
// member streams are final
try {
tmpIn = socket.getInputStream();
} catch (IOException e) {
}
inStream = tmpIn;
in = new BufferedReader(new InputStreamReader(inStream));
}
public void run() {
/*
// Keep listening to the InputStream until an exception occurs
android.util.Log.d("connectedThread", "started");
String str;
try {
inStream.read();
inStream.read();
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
android.util.Log.d("connectedThread", "normal read is fine");
while (true) {
try {
// Read from the InputStream
str = in.readLine();
byte type = Byte.valueOf(str);
android.util.Log.d("connectedThread", "read");
handler.handlePacket(in, type);
} catch (IOException e) {
break;
}
}*/
for (int i = 0; i < 20; i++) {
try {
String str = in.readLine();
android.util.Log.d("read", str + " ");
} catch (IOException e) {
// TODO Auto-generated catch block
android.util.Log.d("io exception", e.getMessage() + " " + e.getLocalizedMessage() + " " + e.getCause());
}
}
while (true) {
}
}
/* Call this from the main Activity to shutdown the connection */
public void cancel() {
try {
socket.close();
} catch (IOException e) { }
}
}
public class ConnectedWriteThread extends Thread {
public ConcurrentLinkedQueue<String> que;
private final BluetoothSocket socket;
private final OutputStream outStream;
private final BufferedWriter out;
private PacketHandler handler;
private boolean isServ;
public ConnectedWriteThread(BluetoothSocket soc, PacketHandler pHandler, boolean isServer) {
socket = soc;
handler = pHandler;
isServ = isServer;
OutputStream tmpOut = null;
que = new ConcurrentLinkedQueue<String>();
// Get the input and output streams, using temp objects because
// member streams are final
try {
tmpOut = socket.getOutputStream();
} catch (IOException e) { }
outStream = tmpOut;
out = new BufferedWriter(new OutputStreamWriter(outStream));
}
public void run() {
// Keep listening to the InputStream until an exception occurs
android.util.Log.d("connectedThread", "started");
/*
try {
if (isServ) {
out.write(String.valueOf(EngineConstants.PACKET_SYNC) + '\n');
out.write(String.valueOf(0) + '\n');
}
} catch (IOException e1) {
android.util.Log.d("connectedThread", "io exception " + e1.getMessage() + " " + e1.getLocalizedMessage() + " " + e1.getCause());
}
//android.util.Log.d("connectedThread", "sent initial packet");
while (true) {
if (!que.isEmpty()) {
try {
out.write(que.poll());
out.flush();
// android.util.Log.d("connectedThread", "sent packet");
} catch (IOException e) {
android.util.Log.d("write thread", "io exception " + e.getMessage());
}
}
}*/
try {
outStream.write(3);
out.write("343567\n");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
while (true) {
}
}
public void fillQueue() {
// android.util.Log.d("fillQueue", "in method");
handler.queuePacket(que);
}
/* Call this from the main Activity to send data to the remote device */
public void write(String str) {
try {
out.write(str);
} catch (IOException e) { }
}
/* Call this from the main Activity to shutdown the connection */
public void cancel() {
try {
socket.close();
} catch (IOException e) { }
}
}
Try to use reflection:
try {
BluetoothDevice mDevice = mBluetoothAdapter.getRemoteDevice("MAC of remote device");
Method m = mDevice.getClass().getMethod("createRfcommSocket",
new Class[] { int.class });
mSocket = (BluetoothSocket) m.invoke(mDevice, Integer.valueOf(1));
mSocket.connect();
} catch (NoSuchMethodException e) {
} catch (SecurityException e) {
} catch (IllegalArgumentException e) {
} catch (IllegalAccessException e) {
} catch (InvocationTargetException e) {
} catch (Exception e) {}
And after some time in your thread
mInStream = mSocket.getInputStream();
mOutStream = mSocket.getOutputStream();
mInStream is InputStream() and mOutStream is OutputStream().
I came across this problem when used bluetooth connection on HTC device.
Related
I'm trying to get working a Service that hosts a server, and whenever it receives data from it's one client it sends the data off to another server. Both of which are connected by a tcp socket that remains open indefinitely. I'm having trouble implementing single tcp sockets that both read and write correctly.
I'm receiving XML from both ends, and they're well defined. Some processing is done on the xml received and it needs to be added to a queue that handles it's order.
Ideally the connection going in either direction should remain open indefinitely.
But so far I'm seeing the Sockets just keep closing both this Service and the ServerCode are getting closed sockets and I'm not sure why.
Is there a way to establish connections to my two endpoints and keep the sockets open indefinitely?
public class routing extends Service {
private static final String TAG = "[RoutingService]";
private final IBinder mBinder = new RoutingBinder();
private final ScheduledThreadPoolExecutor mRoutingThreadPool = new ScheduledThreadPoolExecutor(2);
private boolean running = false;
private URI serverAddress;
private URI clientAddress;
private Thread serverServiceThread = new ClientService();
private Thread clientServiceThread = new ServerService();
private PriorityBlockingQueue<String> clientQueue;
private PriorityBlockingQueue<String> serverQueue;
public void setClientAddress(URI testServer) {
this.serverAddress = testServer;
this.mRoutingThreadPool.remove(clientServiceThread);
this.mRoutingThreadPool.scheduleWithFixedDelay(clientServiceThread, 0, 100, TimeUnit.MILLISECONDS);
}
public URI getServerAddress() {
return serverAddress;
}
public void setServerAddress(URI testServer) {
startRunning();
this.serverAddress = testServer;
this.mRoutingThreadPool.remove(serverServiceThread);
this.mRoutingThreadPool.scheduleWithFixedDelay(serverServiceThread, 0, 100, TimeUnit.MILLISECONDS);
}
public void startRunning() {
running = true;
}
public void stopRunning() {
running = false;
}
#Override
public void onCreate() {
super.onCreate();
serverQueue = new PriorityBlockingQueue<>();
clientQueue = new PriorityBlockingQueue<>();
}
#Override
public void onDestroy() {
stopRunning();
super.onDestroy();
}
#Nullable
#Override
public IBinder onBind(Intent intent) {
return mBinder;
}
#Override
public int onStartCommand(#Nullable Intent intent, int flags, int startId) {
clientAddress = URI.create("127.0.0.1:8054");
serverAddress = URI.create("192.168.2.1:7087");
startRunning();
setClientAddress(clientAddress);
setServerAddress(serverAddress);
return Service.START_STICKY;
}
public class RoutingBinder extends Binder {
public routing getService() {
return routing.this;
}
}
class ClientService extends Thread {
private Socket socket;
private Runnable ClientReader = new Runnable() {
#Override
public void run() {
if (socket != null && socket.isConnected()) {
try (InputStreamReader sr = new InputStreamReader(socket.getInputStream())) {
StringBuilder xml = new StringBuilder();
char[] buffer = new char[8192];
String content = "";
int read;
while ((read = sr.read(buffer, 0, buffer.length)) != -1) {
serverQueue.add(new String(buffer));
}
} catch (IOException e) {
Log.e("clientReader", "Error in testReading Thread.", e);
}
}
}
};
private Runnable ClientWriter = new Runnable() {
#Override
public void run() {
if (socket != null && socket.isConnected()) {
while (serverQueue != null && !serverQueue.isEmpty()) {
try (OutputStream os = socket.getOutputStream()) {
String xml = serverQueue.poll();
os.write(xml.getBytes());
os.flush();
} catch (IOException e) {
Log.e("clientWriter", "Error in testReading Thread.", e);
}
}
}
}
};
#Override
public void run() {
try (ServerSocket server = new ServerSocket(clientAddress.getPort())) {
try (Socket socket = server.accept()) {
socket.setSoTimeout(0);
Log.d("SOCKET", String.format("Local Port: %s. Remote Port: %s", socket.getLocalPort(), socket.getPort()));
this.socket = socket;
//Make the Threads
Thread reader = new Thread(ClientReader);
Thread writer = new Thread(ClientWriter);
//Start the Threads
reader.start();
writer.start();
//Start the Server
startRunning();
//Join on the Threads so this driver thread will wait until they finish.
reader.join();
writer.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
} catch (IOException e) {
e.printStackTrace();
}
stopRunning();
}
}
class ServerService extends Thread {
private Socket socket;
private Runnable ServerReader = new Runnable() {
#Override
public void run() {
if (socket != null && !socket.isClosed()) {
try (InputStreamReader sr = new InputStreamReader(socket.getInputStream())) {
StringBuilder xml = new StringBuilder();
char[] buffer = new char[8192];
String content = "";
int read;
while ((read = sr.read(buffer, 0, buffer.length)) != -1) {
clientQueue.add(new String(buffer));
}
} catch (IOException e) {
Log.e("ServerReader", "Error in testReading Thread.", e);
}
}
}
};
private Runnable ServerWriter = new Runnable() {
#Override
public void run() {
if (socket != null && socket.isConnected()) {
try (OutputStream os = socket.getOutputStream()) {
while (clientQueue != null && !clientQueue.isEmpty()) {
String xml = clientQueue.poll();
os.write(xml.getBytes());
os.flush();
}
} catch (IOException e) {
Log.e("ServerWriter", "Error in testReading Thread.", e);
}
}
}
};
#Override
public void run() {
if (running) { //Service will keep spinning unti the testService ends the loop
try (Socket socket = new Socket(serverAddress.getHost(), serverAddress.getPort())) {
socket.setSoTimeout(0);
Log.d("SOCKET", String.format("Local test Port: %s. Remote test Port: %s", socket.getLocalPort(), socket.getPort()));
this.socket = socket;
//Make the Threads
final Thread writer = new Thread(ServerWriter);
final Thread reader = new Thread(ServerReader);
//Start the Threads
writer.start();
reader.start();
//Join on the Threads so this driver thread will wait until they finish.
writer.join();
reader.join();
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
Closing the input or output stream of a socket closes the other stream and the socket.
I want to call non static method in my Activity A from Activity B
like
class A extend Activity(){ public void c(){}}
class B extend Activity(){ A.C(); }
How I could do this in android Activity help me.
public class Voice extends Activity {
TextView resultTEXT ;
MediaPlayer mp;
ImageView view;
private BluetoothAdapter btAdapter = null;
private BluetoothSocket btSocket = null;
int page;
// SPP UUID service
private static final UUID BTMODULEUUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");
// String for MAC address
private static String address;
private static String status;
BluetoothDevice device;
private ConnectedThread mConnectedThread;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_voice);
//get the stored mac address of the device
SharedPreferences shared = getSharedPreferences("BtAddress", MODE_PRIVATE);
address = (shared.getString("btAddress", ""));
status = (shared.getString("connect", ""));
btAdapter = BluetoothAdapter.getDefaultAdapter();
//create device and set the MAC address
device = btAdapter.getRemoteDevice(address);
checkBTState();
if(status=="true")
{
new CountDownTimer(1000, 10000) {
public void onTick(long millisUntilFinished) {
}
public void onFinish() {
mp = MediaPlayer.create(Voice.this, R.drawable.onload);
mp.setLooping(false);
mp.start();
}
}.start();
}
view=(ImageView)findViewById(R.id.imageButton);
view.setOnTouchListener(new View.OnTouchListener() {
Handler handler = new Handler();
int numberOfTaps = 0;
long lastTapTimeMs = 0;
long touchDownMs = 0;
#Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_UP:
touchDownMs = System.currentTimeMillis();
break;
case MotionEvent.ACTION_DOWN:
handler.removeCallbacksAndMessages(null);
if ((System.currentTimeMillis() - touchDownMs) > ViewConfiguration.getTapTimeout()) {
//it was not a tap
numberOfTaps = 0;
lastTapTimeMs = 0;
break;
}
if (numberOfTaps > 0
&& (System.currentTimeMillis() - lastTapTimeMs) < ViewConfiguration.getDoubleTapTimeout()) {
numberOfTaps += 1;
} else {
numberOfTaps = 1;
}
lastTapTimeMs = System.currentTimeMillis();
if (numberOfTaps == 2) {
handler.postDelayed(new Runnable() {
#Override
public void run() {
//handle double tap
Toast.makeText(Voice.this, "Help", Toast.LENGTH_LONG).show();
mp = MediaPlayer.create(Voice.this, R.drawable.help);
mp.setLooping(false);
mp.start();
}
}, ViewConfiguration.getDoubleTapTimeout());
}
else if(numberOfTaps== 1)
{
handler.postDelayed(new Runnable() {
#Override
public void run() {
Toast.makeText(Voice.this, "proceed",Toast.LENGTH_LONG).show();
Intent intent=new Intent(Voice.this,ChangeSpeed.class);
startActivity(intent);
}
}, ViewConfiguration.getTapTimeout());
}
}
return true;
}
});
}
public void onActivityResult(int request_result, int result_code, Intent i)
{
super.onActivityResult(result_code, result_code, i);
switch (result_code)
{
case 100: if(result_code == RESULT_OK && i != null)
{
ArrayList<String> result = i.getStringArrayListExtra(RecognizerIntent.EXTRA_RESULTS);
resultTEXT.setText(result.get(0));
}
break;
}
}
#Override
public void onResume() {
super.onResume();
try
{
btSocket = createBluetoothSocket(device);
}
catch (IOException e)
{
Toast.makeText(getBaseContext(), "Socket creation failed", Toast.LENGTH_LONG).show();
}
// Establish the Bluetooth socket connection.
try
{
btSocket.connect();
}
catch (IOException e)
{
try
{
btSocket.close();
}
catch (IOException e2)
{
Log.e("",""+e2);
}
}
mConnectedThread = new ConnectedThread(btSocket);
mConnectedThread.start();
// send a character when resuming.beginning transmission to check device is connected
//If it is not an exception will be thrown in the write method and finish() will be called
mConnectedThread.write("x");
}
private BluetoothSocket createBluetoothSocket(BluetoothDevice device) throws IOException {
return device.createRfcommSocketToServiceRecord(BTMODULEUUID);
}
#Override
public void onPause()
{
super.onPause();
try
{
// Bluetooth sockets close when leaving activity
btSocket.close();
} catch (IOException e2)
{
Log.e("",""+e2);
}
}
/*
//Checks that the Android device Bluetooth is available turned on if off automatically
*/
private void checkBTState()
{
if(btAdapter==null)
{
Toast.makeText(getBaseContext(), "Device does not support bluetooth", Toast.LENGTH_LONG).show();
} else
{
if (btAdapter.isEnabled())
{
}
else
{
Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableBtIntent, 1);
}
}
}
private class ConnectedThread extends Thread {
// private final InputStream mmInStream;
private final OutputStream mmOutStream;
//creation of the connect thread
public ConnectedThread(BluetoothSocket socket)
{
// InputStream tmpIn = null;
OutputStream tmpOut = null;
try
{
//Create I/O streams for connection
// tmpIn = socket.getInputStream();
tmpOut = socket.getOutputStream();
}
catch (IOException e)
{
}
//mmInStream = tmpIn;
mmOutStream = tmpOut;
}
//write method
public void write(String input)
{
byte[] msgBuffer = input.getBytes();
//converts entered String into bytes
try
{
mmOutStream.write(msgBuffer);
} catch (IOException e)
{
//if you cannot write, close the application
Toast.makeText(getBaseContext(), "Connection Failure", Toast.LENGTH_LONG).show();
finish();
}
}
}
/*
method to on the Fan
*/
public void functionFanOn()
{
mConnectedThread.write("1");
// Send "1" via Bluetooth
Toast.makeText(getBaseContext(), "Turn on Fan", Toast.LENGTH_SHORT).show();
Log.e("", "On");
}
functionFanOn() is the method that I want to call in B
You have a problem with the structure of your code. The function in Activity A, which establishes a connection to the Arduino, should be move in another class. Lets say an Utils class.
Refactoring your common code to an new class, so that you can manager it by single instance
This lib EventBus may solve your issue
Another Way is Create Seprate class and use all method of seprate class
class Utils
{
public void c(Context context)
{
//put your code
}
}
And Activity class Like this
class MyActivity extends Activity
{
public void onCreate(Bundle b)
{
super.onCreate(b);
setContentView(R.layout.main);
//method calling
Utils utils=new utils();
utils.c(MyActivity.this);
}
}
Please read my sample code
Is this one activity class like this and contain c(); method
class A extend Activity
{
public void c()
{
}
}
And This is your Second activity class
class B extend Activity
{
A a=new A();
a.c();
}
i hope this help you
i use these codes but Bluetooth socket never created.
i have two phones, SAMSUNG galaxy S5 and Huwaii. i run server code on Huwaii and client code in galaxy but state string in both is "waiting", that means never can create Bluetooth socket, these codes are exactly copied from GOOGLE android Tutriol and I don't know what wrong is.
myClientCode is this :
public class BluetoothActivity extends Activity implements OnItemClickListener {
protected static final int SUCCESS_CONNECT = 0;
public static final int MESSAGE_READ = 1;
TextView state;
BluetoothAdapter btadaptor;
ListView list;
ArrayAdapter<String> array;
Set<BluetoothDevice> btarray;
ArrayList<String> pairedDevices;
ArrayList<BluetoothDevice> devices;
IntentFilter filter;
BroadcastReceiver receiver;
Handler mHandler = new Handler() {
#Override
public void handleMessage(Message msg) {
// TODO Auto-generated method stub
super.handleMessage(msg);
switch (msg.what) {
case SUCCESS_CONNECT:
//Do something
ConnectedThread connectedThread = new ConnectedThread((BluetoothSocket) msg.obj);
Toast.makeText(getApplicationContext(), "connected", 0).show();
String s = "SSSSSS";
connectedThread.write(s.getBytes());
break;
case MESSAGE_READ:
byte[] readbuf = (byte[]) msg.obj;
String string = new String(readbuf);
Toast.makeText(getApplicationContext(), "sus message", 0).show();
break;
}
}
};
public static final UUID MY_UUID = UUID.fromString("0efe5656-27d7-11e6-b67b-9e71128cae77");
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
init();
if (btadaptor == null)
Toast.makeText(getApplicationContext(), "bluetooth not supported", Toast.LENGTH_SHORT).show();
else
{
if ( !btadaptor.enable())
{
startbt();
}
getPairedDevice();
startActivity();
}
}
private void startActivity() {
btadaptor.cancelDiscovery();
btadaptor.startDiscovery();
}
private void getPairedDevice() {
btarray = btadaptor.getBondedDevices();
if (btarray.size() > 0)
{
for (BluetoothDevice bt: btarray)
{
pairedDevices.add(bt.getName());
// Toast.makeText(getApplicationContext(), bt.getName(), 0).show();
}
}
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == 1)
if (resultCode == RESULT_CANCELED)
{
Toast.makeText(getApplicationContext(), "you need to turn on the bluetooth to continue", Toast.LENGTH_SHORT);
finish();
}
super.onActivityResult(requestCode, resultCode, data);
}
private void init() {
state = (TextView) findViewById(R.id.textView1);
state.setText("waitingforlist");
list = (ListView) findViewById(R.id.listView);
list.setOnItemClickListener(this);
array = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1);
list.setAdapter(array);
btadaptor = BluetoothAdapter.getDefaultAdapter();
pairedDevices = new ArrayList<String>();
filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
devices = new ArrayList<BluetoothDevice>();
receiver = new BroadcastReceiver() {
#Override
public void onReceive(Context contex, Intent intent) {
String action = intent.getAction();
if (BluetoothDevice.ACTION_FOUND.equals(action))
{
BluetoothDevice bt = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
devices.add(bt);
String s = "";
for (int a = 0; a < pairedDevices.size(); a++) {
if (bt.getName().equals(pairedDevices.get(a))) {
s = "(PAIRED)";
}
}
array.add(bt.getName() + s + "\n" + bt.getAddress());
}
}
};
registerReceiver(receiver, filter);
}
#Override
protected void onPause() {
unregisterReceiver(receiver);
super.onPause();
}
protected void startbt() {
Intent intent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(intent, 1);
}
#Override
public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, long arg3) {
if (btadaptor.isDiscovering()) {
btadaptor.cancelDiscovery();
}
Toast.makeText(getApplicationContext(), array.getItem(arg2), 0).show();
if (array.getItem(arg2).contains("PAIRED")) {
// Toast.makeText(getApplicationContext(), "OK", 0).show();
BluetoothDevice selectedDevice = devices.get(arg2);
Toast.makeText(getApplicationContext(), selectedDevice.getAddress(), 0).show();
ConnectThread connectThread = new ConnectThread(selectedDevice);
state.setText("CreatedThread");
connectThread.start();
}
else
Toast.makeText(getApplicationContext(), "Device is not Paried", 0).show();
}
public 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;
state.setText(device.getName());
}
#Override
public void run() {
// Cancel discovery because it will slow down the connection
// btadaptor.cancelDiscovery();
// state.setText("DONE RUN2");
try {
// Connect the device through the socket. This will block
// until it succeeds or throws an exception
state.setText("waiting");
mmSocket.connect();
state.setText("connected");
}
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) {}
}
}
*/
///////////////////////
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;
}
#Override
public void run() {
byte[] buffer; // buffer store for the stream
int bytes; // bytes returned from read()
// Keep listening to the InputStream until an exception occurs
while (true) {
try {
buffer = new byte[1024];
// 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) {}
}
}
}
myServerCode is this :
public class BluetoothActivity extends Activity {
protected static final int SUCCESS_CONNECT = 0;
public static final int MESSAGE_READ = 1;
Button bt;
BluetoothAdapter btadaptor;
TextView state;
Handler mHandler = new Handler() {
#Override
public void handleMessage(Message msg) {
// TODO Auto-generated method stub
super.handleMessage(msg);
switch (msg.what) {
case SUCCESS_CONNECT:
//Do something
ConnectedThread connectedThread = new ConnectedThread((BluetoothSocket) msg.obj);
Toast.makeText(getApplicationContext(), "connected", 0).show();
String s = "SSSSSS";
connectedThread.write(s.getBytes());
break;
case MESSAGE_READ:
byte[] readbuf = (byte[]) msg.obj;
String string = new String(readbuf);
Toast.makeText(getApplicationContext(), "sus message", 0).show();
break;
}
}
};
public static final UUID MY_UUID = UUID.fromString("0efe5656-27d7-11e6-b67b-9e71128cae77");
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
init();
if (btadaptor == null)
Toast.makeText(getApplicationContext(), "bluetooth not supported", Toast.LENGTH_SHORT).show();
else
{
if ( !btadaptor.enable())
{
startbt();
}
startActivity();
startDiscovering();
OnClickListener temp = new OnClickListener() {
#Override
public void onClick(View arg0) {
AcceptThread acceptThread = new AcceptThread();
state.setText("THreadCreAted");
acceptThread.start();
}
};
bt.setOnClickListener(temp);
}
}
private void startActivity() {
btadaptor.cancelDiscovery();
btadaptor.startDiscovery();
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == 1)
if (resultCode == RESULT_CANCELED)
{
Toast.makeText(getApplicationContext(), "you need to turn on the bluetooth to continue", Toast.LENGTH_SHORT);
}
super.onActivityResult(requestCode, resultCode, data);
}
private void init() {
bt = (Button) findViewById(R.id.button1);
state = (TextView) findViewById(R.id.textView1);
state.setText("START");
btadaptor = BluetoothAdapter.getDefaultAdapter();
}
private void startDiscovering() {
Intent discoverableIntent = new
Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
discoverableIntent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 300);
startActivity(discoverableIntent);
state.setText("StartDiscovering");
}
protected void startbt() {
Intent intent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(intent, 1);
}
private class AcceptThread extends Thread {
private final BluetoothServerSocket mmServerSocket;
public AcceptThread() {
btadaptor.cancelDiscovery();
// 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 = btadaptor.listenUsingRfcommWithServiceRecord("MYAPP", MY_UUID);
}
catch (IOException e) {}
mmServerSocket = tmp;
}
#Override
public void run() {
state.setText("runStart");
BluetoothSocket socket = null;
// Keep listening until exception occurs or a socket is returned
while (true) {
try {
state.setText("WAIITING");
state.setText("WAIITING2");
socket = mmServerSocket.accept();
state.setText("ConnectionREquesRECIEVED");
}
catch (IOException e) {
break;
}
// If a connection was accepted
if (socket != null) {
state.setText("ACCEPTED");
// Do work to manage the connection (in a separate thread)
// manageConnectedSocket(socket);
try {
mmServerSocket.close();
}
catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
break;
}
}
}
/** Will cancel the listening socket, and cause the thread to finish */
public void cancel() {
try {
mmServerSocket.close();
}
catch (IOException e) {}
}
}
private void manageConnectedSocket(BluetoothSocket mmSocket2) {
}
///////////////////////
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;
}
#Override
public void run() {
byte[] buffer; // buffer store for the stream
int bytes; // bytes returned from read()
// Keep listening to the InputStream until an exception occurs
while (true) {
try {
buffer = new byte[1024];
// 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) {}
}
}
}
is any body know whats wrong ?
or can anybody show me very simple code (both server and client) Bluetooth socket just for connection and sending message ?
I wanted to start with the basics of bluetooth connection and make a simple app capable of scanning, pairing and connecting.
I'm struggling with the last concept, i followed a lot of tutorials but I couldn't make it. I don't know if you can help me but here is my code.
ublic class MainActivity extends Activity {
private final String TAG = "Debugging";
private final static int REQUEST_CODE_ENABLE_BLUETOOTH = 0;
protected static final int SUCCESS_CONNECT = 0;
protected static final int MESSAGE_READ = 1;
public static final UUID MY_UUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");
BluetoothAdapter btAdapter;
ArrayList<String> arrayListpaired;
ArrayAdapter<String> listAdapter,adapter;
ListView listView,listViewPaired;
Set<BluetoothDevice> deviceArray;
ArrayList<String> pairedDevices;
IntentFilter filter;
BroadcastReceiver receiver;
BluetoothDevice bdDevice;
ArrayList<BluetoothDevice> arrayListBluetoothDevices = null;
ArrayList<BluetoothDevice> arrayListPairedBluetoothDevices;
ListItemClicked listItemClicked;
ListItemClickedonPaired listItemClickedonPaired;
String tag = "debugging";
Handler mHandler= new Handler() {
public void handleMessage(Message msg){
super.handleMessage(msg);
switch(msg.what){
case SUCCESS_CONNECT:
ConnectedThread connectedThread = new ConnectedThread((BluetoothSocket)msg.obj);
Toast.makeText(getApplicationContext(),"Connect",Toast.LENGTH_LONG).show();
String s= "Succesfully connected";
connectedThread.write(s.getBytes());
Log.i(tag, "connected");
break;
case MESSAGE_READ:
byte[] readbuff=(byte[])msg.obj;
String string= readbuff.toString();
Toast.makeText(getApplicationContext(), string,Toast.LENGTH_SHORT).show();
break;
}
}
};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btAdapter = BluetoothAdapter.getDefaultAdapter();
arrayListBluetoothDevices = new ArrayList<BluetoothDevice>();
arrayListpaired = new ArrayList<String>();
arrayListPairedBluetoothDevices = new ArrayList<BluetoothDevice>();
adapter= new ArrayAdapter<String>(MainActivity.this, android.R.layout.simple_list_item_1, arrayListpaired);
listItemClickedonPaired = new ListItemClickedonPaired();
listViewPaired = (ListView) findViewById(R.id.listView3);
listItemClicked = new ListItemClicked();
listView = (ListView) findViewById(R.id.listView2);
listAdapter = new ArrayAdapter<String>(MainActivity.this, android.R.layout.simple_list_item_activated_1);
listView.setAdapter(listAdapter);
listAdapter.notifyDataSetChanged();
listViewPaired.setAdapter(adapter);
setupMessageButton1();
setupMessageButton2();
setupMessageButton3();
setupMessageButton4();
setupMessageButton5();
init();
getPairedDevices();
}
private void init() {
listView.setOnItemClickListener(listItemClicked);
listViewPaired.setOnItemClickListener(listItemClickedonPaired);
filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
receiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
String Action = intent.getAction();
if (BluetoothDevice.ACTION_FOUND.equals(Action)) {
Toast.makeText(getApplicationContext(), "One Device Found", Toast.LENGTH_SHORT).show();
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
if (arrayListBluetoothDevices.size() < 1) // this checks if the size of bluetooth device is 0,then add the
{ // device to the arraylist.
listAdapter.add(device.getName() + "\n" + device.getAddress());
arrayListBluetoothDevices.add(device);
listAdapter.notifyDataSetChanged();
}
else
{
boolean flag = true; // flag to indicate that particular device is already in the arlist or not
for (int i = 0; i < arrayListBluetoothDevices.size(); i++) {
if (device.getAddress().equals(arrayListBluetoothDevices.get(i).getAddress())) {
flag = false;
}
}
if (flag == true) {
listAdapter.add(device.getName() + "\n" + device.getAddress());
arrayListBluetoothDevices.add(device);
listAdapter.notifyDataSetChanged();
}
}
}
}
};
registerReceiver(receiver, filter);
}
private void createBond(BluetoothDevice btDevice){
try
{
Method method = btDevice.getClass().getMethod("createBond", (Class[]) null);
method.invoke(btDevice, (Object[]) null);
}
catch (Exception e)
{
e.printStackTrace();
}
}
private void unpairDevice(BluetoothDevice device) {
try {
Method method = device.getClass().getMethod("removeBond", (Class[]) null);
method.invoke(device, (Object[]) null);
} catch (Exception e) {
e.printStackTrace();
}
}
private void getPairedDevices() {
Set<BluetoothDevice> pairedDevice = btAdapter.getBondedDevices();
if(pairedDevice.size()>0)
{
for(BluetoothDevice device : pairedDevice)
{
arrayListpaired.add(device.getName()+"\n"+device.getAddress());
arrayListPairedBluetoothDevices.add(device);
}
}
adapter.notifyDataSetChanged();
}
public class ListItemClicked implements OnItemClickListener {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
// TODO Auto-generated method stub
bdDevice = arrayListBluetoothDevices.get(position);
Log.i("Log", "The device : " + bdDevice.toString());
getPairedDevices();
createBond(bdDevice);
adapter.notifyDataSetChanged();
Log.i("Log", "The bond is created: with" + bdDevice.toString());
}
}
private class ConnectThread extends Thread {
private final BluetoothSocket mmSocket;
private final BluetoothDevice mmDevice;
public ConnectThread(BluetoothDevice device) {
BluetoothSocket tmp = null;
mmDevice = device;
try {
tmp = device.createRfcommSocketToServiceRecord(MY_UUID);
} catch (IOException e) { }
mmSocket = tmp;
}
public void run() {
btAdapter.cancelDiscovery();
try {
mmSocket.connect();
} catch (IOException connectException) {
try {
mmSocket.close();
} catch (IOException closeException) { }
return;
}
mHandler.obtainMessage(SUCCESS_CONNECT, mmSocket).sendToTarget();
}
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; // 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
buffer = new byte[1024];
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) { }
}
}
#Override
protected void onDestroy() {
super.onDestroy();
btAdapter.cancelDiscovery();
unregisterReceiver(receiver);
}
class ListItemClickedonPaired implements OnItemClickListener
{
#Override
public void onItemClick(AdapterView<?> parent, View view, int position,long id) {
bdDevice = arrayListPairedBluetoothDevices.get(position);
unpairDevice(bdDevice);
//arrayListPairedBluetoothDevices.clear();
}
}
private void makeDiscoverable() {
Intent discoverableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
discoverableIntent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 150);
startActivity(discoverableIntent);
}
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == RESULT_CANCELED) {
Toast.makeText(MainActivity.this, "Bluetooth must be enabled to start scanning", Toast.LENGTH_SHORT).show();
} else
{
Toast.makeText(MainActivity.this, "Click on TURN_OFF to disable bluetooth", Toast.LENGTH_LONG).show();
}
}
private void setupMessageButton1() {
//1.get a reference for my button
Button messageButton = (Button) findViewById(R.id.button1);
//2. Set the click to run my code
messageButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
listAdapter.clear();
arrayListBluetoothDevices.clear();
btAdapter.startDiscovery();
}
});
}
private void setupMessageButton2() {
//1.get a reference to the button.
Button messageButton = (Button) findViewById(R.id.button2);
//2. set the click listener to run my code.
messageButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (btAdapter.isEnabled()) {
listAdapter.clear();
btAdapter.disable();
} else
{
Toast.makeText(MainActivity.this, "Dont worry it's already off", Toast.LENGTH_SHORT).show();
}
}
});
}
private void setupMessageButton3() {
//1.get a reference for my button
Button messageButton = (Button) findViewById(R.id.button3);
//2. Set the click to run my code
messageButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
finish();
}
});
}
private void setupMessageButton4() {
//1.get a reference for my button
Button messageButton = (Button) findViewById(R.id.button4);
//2. Set the click to run my code
messageButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
btAdapter.enable();
}
});
}
private void setupMessageButton5() {
//1.get a reference for my button
Button messageButton = (Button) findViewById(R.id.button5);
//2. Set the click to run my code
messageButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
makeDiscoverable();
}
});
}
}
Concerning the log i have that message :
"D/BluetoothUtils﹕ isSocketAllowedBySecurityPolicy start : device null"
"W/BluetoothAdapter﹕ getBluetoothService() called with no BluetoothManagerCallback"
"D/BluetoothSocket﹕ connect(), SocketState: INIT, mPfd: {ParcelFileDescriptor: FileDescriptor[75]} "
public class ListItemClicked implements OnItemClickListener {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
// TODO Auto-generated method stub
bdDevice = arrayListBluetoothDevices.get(position);
Log.i("Log", "The device : " + bdDevice.toString());
createBond(bdDevice);
adapter.notifyDataSetChanged();
ConnectThread connect = new ConnectThread(bdDevice);
connect.start();
}
}
For the connection, i use the ConnectThread found in Bluetooth APi developer Website:
private class ConnectThread extends Thread {
private final BluetoothSocket mmSocket;
private final BluetoothDevice mmDevice;
public ConnectThread(BluetoothDevice device) {
BluetoothSocket tmp = null;
mmDevice = device;
try {
tmp = device.createRfcommSocketToServiceRecord(MY_UUID);
} catch (IOException e) { }
mmSocket = tmp;
}
public void run() {
btAdapter.cancelDiscovery();
try {
mmSocket.connect();
} catch (IOException connectException) {
try {
mmSocket.close();
} catch (IOException closeException) { }
return;
}
mHandler.obtainMessage(SUCCESS_CONNECT, mmSocket).sendToTarget();
}
public void cancel() {
try {
mmSocket.close();
} catch (IOException e) { }
}
}
it's ok i found the solution, i had the problem with the phone i'm using, he is not supporting SPP.
Thank you anyway
I'm trying to get two android phones to connect via bluetooth. I'm following the instructions here from the android online howto's, and I'm following pretty closely.
http://developer.android.com/guide/topics/connectivity/bluetooth.html
I can get bluetooth to connect once, but I have to restart the android device or the app itself in order to get it to connect a second time. This is not a problem during development because with each edit of the code the android studio program re-loads the app. It starts it and restarts it, so that during testing I can connect over and over. During actual use I have to restart the android phone or go to the applications manager option under settings and physically stop that app.
From the code below I can connect if I call these lines:
generateDefaultAdapter();
startDiscovery();
startThreadAccept();
startThreadConnect();
How do I get it so that the bluetooth connection can be initiated over and over again? I see the message 'unable to connect' from the inner class 'ConnectThread' and an IO error from a 'printStackTrace()' from that part of the code. The second time I try, I seem to be able to call the method 'stopConnection()' and then the lines above (starting with 'generateDefaultAdapter()') but I find I cannot connect.
package org.test;
//some import statements here...
public class Bluetooth {
public boolean mDebug = true;
public BluetoothAdapter mBluetoothAdapter;
public UUID mUUID = UUID.fromString(BLUETOOTH_UUID);
public Thread mAcceptThread;
public Thread mConnectThread;
public ConnectedThread mManageConnectionAccept;
public ConnectedThread mManageConnectionConnect;
public APDuellingBluetooth() {
}
public void generateDefaultAdapter() {
mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
if (mBluetoothAdapter == null) {
// Device does not support Bluetooth
}
if (mBluetoothAdapter != null && !mBluetoothAdapter.isEnabled() ) {
Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
(mDialogDuel.getActivity()).startActivityForResult(enableBtIntent, INTENT_ACTIVITY_BLUETOOTH_REQUEST_ENABLE);
}
}
public void cancelDiscovery() { if (mBluetoothAdapter != null) mBluetoothAdapter.cancelDiscovery();}
public void startDiscovery() { mBluetoothAdapter.startDiscovery();}
public BluetoothAdapter getBluetoothAdapter() {return mBluetoothAdapter;}
public void stopConnection () {
try {
if (mAcceptThread != null) {
mAcceptThread.interrupt();
//mAcceptThread.join();
mAcceptThread = null;
}
if (mConnectThread != null) {
mConnectThread.interrupt();
//mConnectThread.join();
mConnectThread = null;
}
if (mManageConnectionConnect != null) {
mManageConnectionConnect.cancel();
mManageConnectionConnect.interrupt();
mManageConnectionConnect = null;
}
if (mManageConnectionAccept != null) {
mManageConnectionAccept.cancel();
mManageConnectionAccept.interrupt();
mManageConnectionAccept = null;
}
}
catch(Exception e) {
e.printStackTrace();
}
}
public void startThreadAccept () {
if (mAcceptThread != null && !mAcceptThread.isInterrupted()) {
if (mDebug) System.out.println("server already open");
//return;
mAcceptThread.interrupt();
mAcceptThread = new AcceptThread();
}
else {
mAcceptThread = new AcceptThread();
}
if (mAcceptThread.getState() == Thread.State.NEW ){
//mAcceptThread.getState() == Thread.State.RUNNABLE) {
mAcceptThread.start();
}
}
public void startThreadConnect () {
BluetoothDevice mDevice = mBluetoothAdapter.getRemoteDevice(mChosen.getAddress());
//if (mDebug) System.out.println(mDevice.getAddress() + " -- " + mChosen.getAddress() );
if (mConnectThread != null && !mConnectThread.isInterrupted()) {
if (mDebug) System.out.println("client already open");
//return;
mConnectThread.interrupt();
mConnectThread = new ConnectThread(mDevice);
}
else {
mConnectThread = new ConnectThread(mDevice);
}
if (mConnectThread.getState() == Thread.State.NEW){// ||
//mConnectThread.getState() == Thread.State.RUNNABLE) {
mConnectThread.start();
}
}
public void manageConnectedSocketAccept(BluetoothSocket socket) {
String mTemp = mBluetoothAdapter.getName();
if (mDebug) {
System.out.println("socket accept from " + mTemp);
System.out.println("info accept " + socket.getRemoteDevice().toString());
}
if (mManageConnectionAccept != null && !mManageConnectionAccept.isInterrupted()) {
//mManageConnectionAccept.cancel();
//mManageConnectionAccept.interrupt();
if (mAcceptThread == null) System.out.println(" bad thread accept");
}
else {
mManageConnectionAccept = new ConnectedThread(socket, "accept");
}
if (mManageConnectionAccept.getState() == Thread.State.NEW ){//||
//mManageConnectionAccept.getState() == Thread.State.RUNNABLE) {
mManageConnectionAccept.start();
}
}
public void manageConnectedSocketConnect(BluetoothSocket socket) {
String mTemp = mBluetoothAdapter.getName();
if (mDebug) {
System.out.println("socket connect from " + mTemp);
System.out.println("info connect " + socket.getRemoteDevice().toString());
}
if (mManageConnectionConnect != null && !mManageConnectionConnect.isInterrupted()) {
//mManageConnectionConnect.cancel();
//mManageConnectionConnect.interrupt();
if (mConnectThread == null) System.out.print(" bad thread connect ");
}
else {
mManageConnectionConnect = new ConnectedThread(socket, "connect");
}
if (mManageConnectionConnect.getState() == Thread.State.NEW){// ||
//mManageConnectionConnect.getState() == Thread.State.RUNNABLE) {
mManageConnectionConnect.start();
}
}
public void decodeInput (String mIn, ConnectedThread mSource) {
// do something with info that is returned to me...
}
public void encodeOutput (String mMac1, String mMac2, int mLR1, int mLR2) {
String mTemp = composeOutputString ( mServer, mMac1,mMac2, mLR1, mLR2);
if (mManageConnectionConnect != null && mManageConnectionConnect.isConnected()) {
mManageConnectionConnect.write(mTemp.getBytes());
mManageConnectionConnect.flush();
}
if (mManageConnectionAccept != null && mManageConnectionAccept.isConnected()) {
mManageConnectionAccept.write(mTemp.getBytes());
mManageConnectionAccept.flush();
}
mTemp = composeOutputString ( mClient, mMac1,mMac2, mLR1, mLR2);
if (mManageConnectionConnect != null && mManageConnectionConnect.isConnected()) {
mManageConnectionConnect.write(mTemp.getBytes());
mManageConnectionConnect.flush();
}
if (mManageConnectionAccept != null && mManageConnectionAccept.isConnected()) {
mManageConnectionAccept.write(mTemp.getBytes());
mManageConnectionAccept.flush();
}
}
public String composeOutputString (SocketConnectData mData, String mMac1, String mMac2, int mLR1, int mLR2) {
// make a string here with the data I want to send...
String mTemp = new String();
return mTemp;
}
/////////////////////////////////////////////
private class AcceptThread extends Thread {
private final BluetoothServerSocket mmServerSocket;
private boolean mLoop = true;
public AcceptThread() {
// Use a temporary object that is later assigned to mmServerSocket,
// because mmServerSocket is final
mLoop = true;
BluetoothServerSocket tmp = null;
try {
// MY_UUID is the app's UUID string, also used by the client code
tmp = mBluetoothAdapter.listenUsingRfcommWithServiceRecord(mServiceNameReceive, mUUID );
} catch (IOException e) {
System.out.println("rfcomm problem ");
}
mmServerSocket = tmp;
}
public void run() {
BluetoothSocket socket = null;
// Keep listening until exception occurs or a socket is returned
while (mLoop) {
try {
if (mmServerSocket != null) {
socket = mmServerSocket.accept();
}
} catch (IOException e) {
if (mDebug) System.out.println("rfcomm accept problem");
e.printStackTrace();
break;
}
// If a connection was accepted
if (socket != null && ! isConnectionOpen() ) {
// Do work to manage the connection (in a separate thread)
manageConnectedSocketAccept(socket);
try {
mmServerSocket.close();
}
catch (IOException e) {}
break;
}
}
}
/** Will cancel the listening socket, and cause the thread to finish */
public void cancel() {
try {
mLoop = false;
mmServerSocket.close();
} catch (IOException e) { }
}
}
/////////////////////////////////////////////
private class ConnectThread extends Thread {
//private final BluetoothSocket mmSocket;
private 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;
try {
tmp = device.createRfcommSocketToServiceRecord(mUUID);
if (mDebug) System.out.println("connect -- rf socket to service record " + tmp);
} catch (Exception e) {
System.out.println("exception -- rf socket to service record problem " + tmp);
}
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 (InterruptedException e ) {System.out.println("interrupted exception");}
catch (IOException e) {
// Unable to connect; close the socket and get out
if (mDebug) System.out.println("unable to connect ");
e.printStackTrace(); // <---- I see output from this spot!!
try {
mmSocket.close();
} catch (IOException closeException) {
System.out.println("unable to close connection ");
}
return;
}
// Do work to manage the connection (in a separate thread)
if (mmSocket.isConnected() && ! isConnectionOpen()) {
manageConnectedSocketConnect(mmSocket);
}
}
/** Will cancel an in-progress connection, and close the socket */
public void cancel() {
try {
mmSocket.close();
} catch (IOException e) { }
}
public boolean isConnected() {
return mmSocket.isConnected();
}
}
/////////////////////////////////////////////
private class ConnectedThread extends Thread {
private final BluetoothSocket mmSocket;
private final InputStream mmInStream;
private final OutputStream mmOutStream;
public String mTypeName = "";
private boolean mLoop = true;
public StringWriter writer;
public ConnectedThread(BluetoothSocket socket, String type) {
mTypeName = type;
mLoop = true;
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;
try {
writer = new StringWriter();
}
catch (Exception e) {}
}
public void run() {
byte[] buffer = new byte[1024]; //
int bytes; // bytes returned from read()
String [] mLines ;
// Keep listening to the InputStream until an exception occurs
while (mLoop) {
try {
// Read from the InputStream
bytes = mmInStream.read(buffer);
if (bytes == -1 || bytes == 0) {
if (mDebug) System.out.println("zero read");
return;
}
writer.append(new String(buffer, 0, bytes));
mLines = writer.toString().split("!");
if (mDebug) System.out.println( "lines " +mLines.length);
for (int i = 0; i < mLines.length; i ++ ) {
if (true) {
if (mDebug) System.out.println(" " + mLines[i]);
decodeInput (mLines[i], this);
}
}
} catch (Exception e) {
e.printStackTrace();
if (mDebug) System.out.println("read buffer problem");
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) {
e.printStackTrace();
if (mDebug) System.out.println("bad write");
}
}
/* Call this from the main activity to shutdown the connection */
public void cancel() {
try {
mLoop = false;
mmSocket.close();
mmOutStream.close();
mmInStream.close();
} catch (IOException e) { }
}
public boolean isConnected() {
boolean mIsOpen = false;
try {
mIsOpen = mmSocket.isConnected() ;
} catch (Exception e) {}
return mIsOpen;
}
public void flush() {
try {
mmOutStream.flush();
}
catch (IOException e) {e.printStackTrace();}
}
}
///////////////////////////////////////////////
}
Thanks for your time.
EDIT: this is the error msg:
W/System.err﹕ java.io.IOException: read failed, socket might closed or timeout, read ret: -1
W/System.err﹕ at android.bluetooth.BluetoothSocket.readAll(BluetoothSocket.java:553)
W/System.err﹕ at android.bluetooth.BluetoothSocket.waitSocketSignal(BluetoothSocket.java:530)
W/System.err﹕ at android.bluetooth.BluetoothSocket.connect(BluetoothSocket.java:357)
W/System.err﹕ at org.davidliebman.test.Bluetooth$ConnectThread.run(Bluetooth.java:761)
Try this:
Instead of restarting the app. Turn off the Bluetooth on the Android device and turn it back on after a 5-sec delay. If you could make the connection successfully, it typically a sign that you did not close the connection and socket completely. Log your code. Make sure the closing socket routine is smoothly executed. Check if the IOException you have in your cancel method of your ConnectedThread is not catching any exception:
/* Call this from the main activity to shutdown the connection */
public void cancel() {
try {
// ADD LOG
mLoop = false;
mmSocket.close();
mmOutStream.close();
mmInStream.close();
// ADD LOG
} catch (IOException e) {
// ADD LOG}
}