I'm in need to move a Bluetooth activity (BTHandler) that handles all my Bluetooth connection into a Service so that I can use multiple activities without loosing the connection. How would I go about doing that?
Thanks
BTHandler
public class BTHandler {
public static final int STATE_NONE = 0; // we're doing nothing
public static final int STATE_CONNECTING = 2; // now initiating an outgoing connection
public static final int STATE_CONNECTED = 3; // now connected to a remote device
final ArrayList<String> devices = new ArrayList();
private final Handler mHandler;
private BluetoothAdapter mAdapter;
private BluetoothDevice device;
private ConnectThread mConnectThread;
private ConnectedThread mConnectedThread;
private BluetoothSocket socket;
private String status;
private int mState;
private boolean connectionStatus = false;
public BTHandler(Context context, Handler handler) { // Konstruktor
mAdapter = BluetoothAdapter.getDefaultAdapter();
mHandler = handler;
}
public void write(String s) {
mConnectedThread.sendRawCommand(s);
Log.v("write", "write");
}
/*
public void write(byte[] bytes) {
try {
mmOutStream.write(bytes);
} catch (IOException e) {
}
}
*/
public void connect(String deviceAddress) {
mConnectThread = new ConnectThread(deviceAddress);
mConnectThread.start();
}
private void guiHandler(int what, int arg1, String obj) {
Message msg = mHandler.obtainMessage();
msg.what = what;
msg.obj = obj;
msg.arg1 = arg1;
msg.sendToTarget();
}
private class ConnectThread extends Thread {
BluetoothSocket tmp = null;
private BluetoothSocket mmSocket;
public ConnectThread(String deviceAddress) {
mAdapter = BluetoothAdapter.getDefaultAdapter();
device = mAdapter.getRemoteDevice(deviceAddress);
BluetoothAdapter mAdapter = BluetoothAdapter.getDefaultAdapter();
BluetoothDevice device = mAdapter.getRemoteDevice(deviceAddress);
UUID uuid = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");
try {
tmp = device.createRfcommSocketToServiceRecord(uuid);
//socket.connect();
//Log.v("connect", "connect");
} catch (IOException e) {
//e.printStackTrace();
//Log.v("exception", "e");
}
mmSocket = tmp;
}
public void run() {
// Cancel discovery because it will slow down the connection
mAdapter.cancelDiscovery();
byte[] buffer = new byte[1024]; // buffer store for the stream
int bytes;
try {
// Connect the device through the socket. This will block
// until it succeeds or throws an exception
mmSocket.connect();
Log.v("connect", "connect");
} catch (IOException connectException) {
// Unable to connect; close the socket and get out
try {
mmSocket.close();
Log.v("close", "close");
} catch (IOException closeException) {
}
guiHandler(Constants.TOAST, Constants.SHORT, "Connection Failed");
return;
}
guiHandler(Constants.CONNECTION_STATUS, Constants.STATE_CONNECTED, "");
mConnectedThread = new ConnectedThread(mmSocket);
mConnectedThread.start();
}
}
private class ConnectedThread extends Thread {
private final BluetoothSocket mmSocket;
private final InputStream mmInStream;
private final OutputStream mmOutStream;
private ObdMultiCommand multiCommand;
public ConnectedThread(BluetoothSocket socket) {
connectionStatus = true;
mmSocket = socket;
InputStream tmpIn = null;
OutputStream tmpOut = null;
try {
tmpIn = socket.getInputStream();
tmpOut = socket.getOutputStream();
} catch (IOException e) {
}
mmInStream = tmpIn;
mmOutStream = tmpOut;
try {
//RPMCommand engineRpmCommand = new RPMCommand();
//SpeedCommand speedCommand = new SpeedCommand();
ModuleVoltageCommand voltageCommand = new ModuleVoltageCommand();
while (!Thread.currentThread().isInterrupted()) {
//engineRpmCommand.run(mmInStream, mmOutStream); //(socket.getInputStream(), socket.getOutputStream());
//speedCommand.run(mmInStream, mmOutStream); //(socket.getInputStream(), socket.getOutputStream());
voltageCommand.run(socket.getInputStream(), socket.getOutputStream());
// TODO handle commands result
//Log.d("Log", "RPM: " + engineRpmCommand.getFormattedResult());
//Log.d("Log", "Speed: " + speedCommand.getFormattedResult());
Log.v("Log", "Voltage: " + voltageCommand.getFormattedResult());
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void run() {
byte[] buffer = new byte[1024]; // buffer store for the stream
int bytes; // bytes returned from read()
OBDcmds();
// Keep listening to the InputStream until an exception occurs
while (connectionStatus) {
sendMultiCommand();
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
// CALL this to MainActivity
public void sendRawCommand(String command) {
try {
new OdbRawCommand(command);
} catch (Exception e) {
Log.v("sendRawCommand", "e");
}
}
private void OBDcmds() { // execute commands
try {
new EchoOffCommand().run(socket.getInputStream(), socket.getOutputStream());
new LineFeedOffCommand().run(socket.getInputStream(), socket.getOutputStream());
new TimeoutCommand(100).run(socket.getInputStream(), socket.getOutputStream());
new SelectProtocolCommand(ObdProtocols.AUTO).run(socket.getInputStream(), socket.getOutputStream()); //ISO_15765_4_CAN
} catch (Exception e) {
Log.v("OBDcmds", "e");
// handle errors
}
}
/*
// 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) {
}
}
public void sendMultiCommand() {
try {
// RUN some code here
} catch (Exception e) {
}
}
}
}
MyService
public class MyService extends Service {
public MyService() {
}
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onCreate() {
Toast.makeText(this, "The new Service was Created", Toast.LENGTH_LONG).show();
}
#Override
public void onStart(Intent intent, int startId) {
// For time consuming an long tasks you can launch a new thread here...
// Do your Bluetooth Work Here
Toast.makeText(this, " Service Started", Toast.LENGTH_LONG).show();
}
#Override
public void onDestroy() {
Toast.makeText(this, "Service Destroyed", Toast.LENGTH_LONG).show();
}
}
You need to create your variables of the threads and stuff inside the Service.
Related
The idea here is to make a socket connection over the local network, send some data, and close the connection immediately. The only thing that should remain running is the serversocket. So far, everything works as expected except one thing:
When the activity that starts the serversocket gets closed with the back button, and then reopened, the data being sent from the client no longer makes it to the serversocket.
DMActivity:
public class DMActivity extends AppCompatActivity {
String ipAddress;
boolean dmListenRunning = false;
DMListen dmListen = new DMListen();
Thread dmListenThread;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_dm);
if (!(dmListenRunning)) {
dmListenThread = new Thread(dmListen);
dmListenRunning = true;
dmListenThread.start();
}
}
#Override
public void onBackPressed()
{
try {
dmListen.KillThread(true);
dmListenThread.interrupt();
}
catch (Exception e)
{
Log.i("LOG", e.toString());
}
finish();
}
}
DMListen:
public class DMListen implements Runnable {
ServerSocket serverSocket;
boolean started = false;
boolean closeSockets = false;
boolean killed = false;
public void run() {
ReceivePlayerData();
}
public void ReceivePlayerData() {
try {
while (!(Thread.interrupted())) {
if (!(started)) {
int port = 8080;
serverSocket = new ServerSocket(port);
started = true;
}
Socket clientSocket = serverSocket.accept();
DataInputStream dataIn = new DataInputStream(clientSocket.getInputStream());
String name;
int init;
name = dataIn.readUTF();
init = dataIn.readInt();
dataIn.close();
clientSocket.close();
}
}
catch (Exception e) {
Log.i("LOG", e.toString();
}
if(killed)
{
try {
serverSocket.close();
if (Thread.currentThread().isInterrupted())
{
try {
Thread.currentThread().join();
}
catch (Exception e)
{
Log.i("LOG", e.toString());
}
}
}
catch(IOException e)
{
Log.i("LOG", e.toString());
}
}
}
public void KillThread(boolean k)
{
boolean killed = k;
}
}
PlayerActivity:
public class PlayerActivity extends AppCompatActivity {
EditText hostIPBox;
Button submit;
String hostIPString;
InetAddress hostIP;
boolean denied = false;
boolean started = false;
PlayerConnect playerConnect;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_player);
hostIPBox = (EditText) findViewById(R.id.ipaddress);
hostIPBox.setRawInputType(Configuration.KEYBOARD_12KEY);
hostIPBox.setSingleLine();
submit = (Button) findViewById(R.id.submit);
submit.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
hostIPString = hostIPBox.getText().toString();
try {
if (!(hostIPString.equals(""))) {
hostIP = InetAddress.getByName(hostIPString);
if(!(started)) {
playerConnect = new PlayerConnect();
playerConnect.SetHostIP(hostIP);
denied = playerConnect.GetDenied();
started = true;
}
else {
playerConnect.SetHostIP(hostIP);
denied = playerConnect.GetDenied();
}
if (denied)
{
started = false;
}
else
{
new Thread(playerConnect).start();
}
}
}
catch (Exception e) {
Log.e("LOG", e.toString());
}
}
});
}
}
PlayerConnect:
public class PlayerConnect implements Runnable {
InetAddress hostIP;
boolean closeSockets = false;
boolean denied = false;
public void run() {
SendPlayerData(hostIP, playerName, playerInitiative);
}
private void SendPlayerData(InetAddress IP, String name, int init) {
try {
int port = 8080;
Socket socket = new Socket();
socket.connect(new InetSocketAddress(IP, port), 3000);
DataOutputStream output = new DataOutputStream(socket.getOutputStream());
if (socket.isConnected())
{
output.writeUTF(name);
output.writeInt(init);
output.close();
socket.close();
}
if (closeSockets) {
output.close();
socket.close();
closeSockets = false;
}
}
catch (Exception e) {
denied = true;
Log.i("LOG", e.printStackTrace());
}
}
public void SetHostIP(InetAddress host)
{
hostIP = host;
}
public boolean GetDenied()
{
return denied;
}
}
You should use Service to handle socket connection. You won't have problems with Activity lifecycle.
I'm doing an Bluetooth application which I connect any device and do some work. I have lots of activities. I do all connection stuff in the BlutoothConnectionService.java class. In my BondedDevicesActivity I click a device that I would like to connect. Then service works and another activity is opened. Then I click some buttons which opens another activities. In all activity I'm sending some information via bluetooth. Thus whenever I open another activity I use BlutoothConnectionService.java class. Problem is in this class, it always trying to connect to device. I would like that once it is connected, it never tries it again until connection is dead. But I couldn't figure out how to make that. I know there is a method called isConnected() but I don't know where to put it in the service class. Here is my code of service:
public class BluetoothConnectionService {
private static final String TAG = "BluetoothConnectionSrvc";
private static final UUID connectionUUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");
private final BluetoothAdapter bluetoothAdapter;
Context ctx;
private ConnectThread connectThread;
private BluetoothDevice bluetoothDevice;
private UUID deviceUUID;
ProgressDialog progressDialog;
private ConnectedThread connectedThread;
String incomingMessage;
public BluetoothConnectionService(Context context, BluetoothDevice device, UUID uuid) {
bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
ctx = context;
startClient(device, uuid);
}
public void startClient(BluetoothDevice device, UUID uuid) {
Log.d(TAG, "startClient: Started.");
connectThread = new ConnectThread(device, uuid);
connectThread.start();
}
private class ConnectThread extends Thread {
private BluetoothSocket bluetoothSocket;
public ConnectThread(BluetoothDevice device, UUID uuid) {
Log.d(TAG, "ConnectThread: started.");
bluetoothDevice = device;
deviceUUID = uuid;
}
public void run() {
Log.i(TAG, "ConnectThread: Run.");
BluetoothSocket tmp = null;
try {
Log.d(TAG, "ConnectThread: Trying to create RFcommSocket using UUID: " + connectionUUID);
tmp = bluetoothDevice.createRfcommSocketToServiceRecord(deviceUUID);
progressDialog = ProgressDialog.show(ctx, "Cihaza Bağlanılıyor", "Lütfen Bekleyiniz...", true);
} catch (Exception e) {
progressDialog.dismiss();
e.printStackTrace();
Log.e(TAG, "ConnectThread: Couldn't create RFcommSocket" + e.getMessage());
showMessage("Cihaza bağlanılamadı, lütfen bağlantınızı kontrol ederek tekrar deneyiniz.");
AnaEkranActivity.instance.finish();
}
if (tmp != null) {
bluetoothSocket = tmp;
bluetoothAdapter.cancelDiscovery();
try {
bluetoothSocket.connect();
Log.d(TAG, "run: ConnectionThread connected.");
connected(bluetoothSocket);
} catch (Exception e) {
progressDialog.dismiss();
e.printStackTrace();
showMessage("Cihaza bağlanılamadı, lütfen bağlantınızı kontrol ederek tekrar deneyiniz.");
AnaEkranActivity.instance.finish();
try {
bluetoothSocket.close();
Log.d(TAG, "run: Closed Socket.");
} catch (Exception e1) {
e1.printStackTrace();
Log.e(TAG, "ConnectThread: run: Unable to close connection in socket" + e1.getMessage());
}
Log.d(TAG, "run: ConnectThread: Could not connect to UUID: " + connectionUUID);
}
}
}
}
public void connected(BluetoothSocket socket) {
Log.d(TAG, "Connected: Starting.");
connectedThread = new ConnectedThread(socket);
connectedThread.start();
}
private class ConnectedThread extends Thread {
private final BluetoothSocket bluetoothSocket;
private final InputStream inputStream;
private final OutputStream outputStream;
public ConnectedThread(BluetoothSocket socket) {
Log.d(TAG, "ConnectedThread: Starting.");
bluetoothSocket = socket;
InputStream tmpIn = null;
OutputStream tmpOut = null;
try {
progressDialog.dismiss();
} catch (Exception e) {
e.printStackTrace();
}
try {
tmpIn = bluetoothSocket.getInputStream();
tmpOut = bluetoothSocket.getOutputStream();
} catch (Exception e) {
e.printStackTrace();
}
inputStream = tmpIn;
outputStream = tmpOut;
}
public void run() {
byte[] readBuffer = new byte[1024];
int readBytes;
while (true) {
try {
readBytes = inputStream.read(readBuffer);
incomingMessage = new String(readBuffer, 0, readBytes);
Log.d(TAG, "InputStream: " + incomingMessage);
showMessage(incomingMessage);
} catch (Exception e) {
e.printStackTrace();
Log.e(TAG, "read: Error reading from inputStream." + e.getMessage());
showMessage("Connection is dead.");
AnaEkranActivity.instance.finish();
break;
}
}
}
public void write(byte[] writeBytes) {
String text = new String(writeBytes, Charset.defaultCharset());
Log.d(TAG, "write: Writing to outputStream: " + text);
try {
outputStream.write(writeBytes);
} catch (Exception e) {
e.printStackTrace();
Log.e(TAG, "write: Error writing to outputStream." + e.getMessage());
showMessage("Error while writing.");
}
}
}
public void write (byte[] out) {
Log.d(TAG, "write: Write Called.");
connectedThread.write(out);
}
public String read () {
Log.d(TAG, "read: Read Called.");
connectedThread.run();
return incomingMessage;
}
public void showMessage(final String toastMessage) {
AnaEkranActivity.instance.runOnUiThread(new Runnable() {
#Override
public void run() {
Toast.makeText(ctx, toastMessage, Toast.LENGTH_SHORT).show();
}
});
}
}
Any idea ?
In android documentation you will get this answer. There we are using same thing in Bluetooth chatting app. Here is the link Bluetooth chat app
Which gives you information about connection. And this explanation
will help you to solve this problem. Go through once clearly you will get the solution.
I am trying to transmit a continuous stream of data to multiple devices over a portable hotspot connection using sockets.
I am facing two problems:
The message only gets displayed to the client AFTER all the messages are displayed in msg TextView on the server end. So if I use an infinite while(true) loop instead of for(int i = 0; i < 1000; i++), in ServerSocketReplyThread, the message never gets transmitted, and the client eventually crashes
I am unable to connect another client to the server until all the messages have been transmitted to the first client.
How do I structure the code to ensure simultaneous, real-time transmission to multiple clients?
Here's what the code looks like:
I am using an activity called Transmit activity, where I am instantiating the msg Textview, which replays the sent messages, and a server object.
msg = (TextView) findViewById(R.id.server_replayed_messages);
Server server = new Server(this);
The Server class is as follows:
public class Server {
TransmitActivity activity;
ServerSocket serverSocket;
String message = "";
static final int socketServerPORT = 8080;
ArrayList<Socket> socketList = new ArrayList<Socket>();
public Server(TransmitActivity a) {
this.activity = a;
Thread socketServerThread = new Thread(new SocketServerThread());
socketServerThread.start();
}
public int getPort() {
return socketServerPORT;
}
public void onDestroy() {
if (serverSocket != null) {
try {
serverSocket.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
private class SocketServerThread extends Thread {
int count = 0;
#Override
public void run() {
try {
// create ServerSocket using specified port
serverSocket = new ServerSocket(socketServerPORT);
while (true) {
// block the call until connection is created and return
// Socket object
Socket socket = serverSocket.accept();
count++;
message += "#" + count + " from "
+ socket.getInetAddress() + ":"
+ socket.getPort() + "\n";
activity.runOnUiThread(new Runnable() {
#Override
public void run() {
activity.msg.setText(message);
}
});
SocketServerReplyThread socketServerReplyThread =
new SocketServerReplyThread(socket, count);
socketServerReplyThread.run();
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
private class SocketServerReplyThread extends Thread {
private Socket hostThreadSocket;
int cnt;
SocketServerReplyThread(Socket socket, int c) {
hostThreadSocket = socket;
cnt = c;
}
#Override
public void run() {
OutputStream outputStream;
for(int i = 0; i < 1000; i++) {
String msgReply = DateFormat.getDateTimeInstance().format(new Date());
try {
outputStream = hostThreadSocket.getOutputStream();
PrintStream printStream = new PrintStream(outputStream);
printStream.print(msgReply);
printStream.flush();
message += "replayed: " + msgReply + "\n";
activity.runOnUiThread(new Runnable() {
#Override
public void run() {
activity.msg.setText(message);
}
});
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
message += "Something wrong in SocketServerReplyThread! " + e.toString() + "\n";
}
activity.runOnUiThread(new Runnable() {
#Override
public void run() {
activity.msg.setText(message);
}
});
}
}
}
}
On the client side I have a ReceiveActivity, where I am using the following code when a "Connect" button is clicked:
Client myClient = new Client(editTextAddress.getText()
.toString(), Integer.parseInt(editTextPort
.getText().toString()), response);
myClient.execute();
The Client class is as follows:
public class Client extends AsyncTask<Void, Void, Void> {
String dstAddress;
int dstPort;
String response = "";
TextView textResponse;
Client(String addr, int port, TextView textResponse) {
dstAddress = addr;
dstPort = port;
this.textResponse = textResponse;
}
#Override
protected Void doInBackground(Void... arg0) {
Socket socket = null;
try {
socket = new Socket(dstAddress, dstPort);
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(1024);
byte[] buffer = new byte[1024];
int bytesRead;
InputStream inputStream = socket.getInputStream();
/*
* notice: inputStream.read() will block if no data return
*/
while ((bytesRead = inputStream.read(buffer)) != -1) {
byteArrayOutputStream.write(buffer, 0, bytesRead);
response += byteArrayOutputStream.toString("UTF-8");
}
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
response = "UnknownHostException: " + e.toString();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
response = "IOException: " + e.toString();
} finally {
if (socket != null) {
try {
socket.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
return null;
}
#Override
protected void onPostExecute(Void result) {
textResponse.setText(response);
super.onPostExecute(result);
}
}
Any help would be much appreciated.
So i'm making a OBDII Bluetooth app were the user can send commands such as voltage (in this case) and get data from the OBDII. So far i've managed to make a Bluetooth connection with my mobile device to my OBDII adapter work and now I need to send some basic commands and displaying them in Logcat (for the moment).
The problem i'm having is that it doesn't recognize my onClick method?
Could not find method onClick(View) in a parent or ancestor Context
for android:onClick attribute defined on view class
android.support.v7.widget.AppCompatButton with id 'getValue'
I'm sure that i've missed something in my code, but I dont know what.
MainActivity.java
public class MainActivity extends AppCompatActivity {
Button b1;
BluetoothAdapter mAdapter;
FragmentHostCallback mHost;
BTHandler btHandler;
private Handler mHandler = new Handler() {
#Override
public void handleMessage(Message msg) {
switch (msg.what) {
case Constants.MESSAGE_STATE_CHANGE:
switch (msg.arg1) {
case BTHandler.STATE_CONNECTED:
//setContentView(R.layout.activity_connected);
Intent intent = new Intent(MainActivity.this, Connected.class);
startActivity(intent);
Toast.makeText(getApplicationContext(), R.string.title_connected_to, Toast.LENGTH_SHORT).show();
Log.v("Log", "Connected");
break;
case BTHandler.STATE_NONE:
Toast.makeText(getApplicationContext(), R.string.title_not_connected, Toast.LENGTH_SHORT).show();
break;
}
}
}
};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btHandler = new BTHandler(MainActivity.this, mHandler);
b1 = (Button) findViewById(R.id.connect);
mAdapter = BluetoothAdapter.getDefaultAdapter();
//init();
if (mAdapter == null) {
Toast.makeText(getApplicationContext(), R.string.device_not_supported, Toast.LENGTH_LONG).show();
finish();
} else {
if (!mAdapter.isEnabled()) {
Intent intent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(intent, 1);
}
}
//BTHandler btHandler = new BTHandler(MainActivity.this, mHandler);
//btHandler.connect("");
}
public void onClick(View v) {
int id = v.getId();
String sendMessage = ("AT RV");
switch (id) {
case R.id.connect:
onConnect(); //Operation
Log.v("Log", "Pressed onClick");
break;
case R.id.getValue:
btHandler.write(sendMessage);
Log.v("Log", "getValue" + sendMessage);
break;
}
}
BTHandler.java
public class BTHandler {
public static final int STATE_NONE = 0; // we're doing nothing
public static final int STATE_CONNECTING = 2; // now initiating an outgoing connection
public static final int STATE_CONNECTED = 3; // now connected to a remote device
final ArrayList<String> devices = new ArrayList();
private final Handler mHandler;
private BluetoothAdapter mAdapter;
private BluetoothDevice device;
private ConnectThread mConnectThread;
private ConnectedThread mConnectedThread;
private BluetoothSocket socket;
private String status;
private int mState;
private boolean connectionStatus = false;
public BTHandler(Context context, Handler handler) { // Konstruktor
mAdapter = BluetoothAdapter.getDefaultAdapter();
mHandler = handler;
}
public void write(String s) {
mConnectedThread.sendRawCommand(s);
}
/*
public void write(byte[] bytes) {
try {
mmOutStream.write(bytes);
} catch (IOException e) {
}
}
*/
public void connect(String deviceAddress) {
mConnectThread = new ConnectThread(deviceAddress);
mConnectThread.start();
}
private void guiHandler(int what, int arg1, String obj) {
Message msg = mHandler.obtainMessage();
msg.what = what;
msg.obj = obj;
msg.arg1 = arg1;
msg.sendToTarget();
}
private class ConnectThread extends Thread {
BluetoothSocket tmp = null;
private BluetoothSocket mmSocket;
public ConnectThread(String deviceAddress) {
mAdapter = BluetoothAdapter.getDefaultAdapter();
device = mAdapter.getRemoteDevice(deviceAddress);
BluetoothAdapter mAdapter = BluetoothAdapter.getDefaultAdapter();
BluetoothDevice device = mAdapter.getRemoteDevice(deviceAddress);
UUID uuid = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");
try {
tmp = device.createRfcommSocketToServiceRecord(uuid);
//socket.connect();
//Log.v("connect", "connect");
} catch (IOException e) {
//e.printStackTrace();
//Log.v("exception", "e");
}
mmSocket = tmp;
}
public void run() {
// Cancel discovery because it will slow down the connection
mAdapter.cancelDiscovery();
byte[] buffer = new byte[1024]; // buffer store for the stream
int bytes;
try {
// Connect the device through the socket. This will block
// until it succeeds or throws an exception
mmSocket.connect();
Log.v("connect", "connect");
} catch (IOException connectException) {
// Unable to connect; close the socket and get out
try {
mmSocket.close();
Log.v("close", "close");
} catch (IOException closeException) {
}
guiHandler(Constants.TOAST, Constants.SHORT, "Connection Failed");
return;
}
guiHandler(Constants.CONNECTION_STATUS, Constants.STATE_CONNECTED, "");
}
}
private class ConnectedThread extends Thread {
private final BluetoothSocket mmSocket;
private final InputStream mmInStream;
private final OutputStream mmOutStream;
private ObdMultiCommand multiCommand;
public ConnectedThread(BluetoothSocket socket) {
connectionStatus = true;
mmSocket = socket;
InputStream tmpIn = null;
OutputStream tmpOut = null;
try {
tmpIn = socket.getInputStream();
tmpOut = socket.getOutputStream();
} catch (IOException e) {
}
mmInStream = tmpIn;
mmOutStream = tmpOut;
try {
RPMCommand engineRpmCommand = new RPMCommand();
SpeedCommand speedCommand = new SpeedCommand();
ModuleVoltageCommand voltageCommand = new ModuleVoltageCommand();
while (!Thread.currentThread().isInterrupted()) {
engineRpmCommand.run(mmInStream, mmOutStream); //(socket.getInputStream(), socket.getOutputStream());
speedCommand.run(mmInStream, mmOutStream); //(socket.getInputStream(), socket.getOutputStream());
voltageCommand.run(mmInStream, mmOutStream); //(socket.getInputStream(), socket.getOutputStream());
// TODO handle commands result
Log.d("Log", "RPM: " + engineRpmCommand.getFormattedResult());
Log.d("Log", "Speed: " + speedCommand.getFormattedResult());
Log.v("Log", "Voltage: " + speedCommand.getFormattedResult());
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void run() {
byte[] buffer = new byte[1024]; // buffer store for the stream
int bytes; // bytes returned from read()
OBDcmds();
// Keep listening to the InputStream until an exception occurs
while (connectionStatus) {
sendMultiCommand();
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
// CALL this to MainActivity
public void sendRawCommand(String s) {
try {
//new ObdRawCommand();
} catch (Exception e) {
}
}
private void OBDcmds() { // execute commands
try {
new EchoOffCommand().run(socket.getInputStream(), socket.getOutputStream());
new LineFeedOffCommand().run(socket.getInputStream(), socket.getOutputStream());
new TimeoutCommand(125).run(socket.getInputStream(), socket.getOutputStream());
new SelectProtocolCommand(ObdProtocols.AUTO).run(socket.getInputStream(), socket.getOutputStream()); //ISO_15765_4_CAN
} catch (Exception e) {
Log.v("Log", "e");
// handle errors
}
}
/*
// 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) {
}
}
public void sendMultiCommand() {
try {
// RUN some code here
} catch (Exception e) {
}
}
}
}
EDIT:
public class MainActivity extends AppCompatActivity implements View.OnClickListener {...}
#Override
protected void onCreate(Bundle savedInstanceState) {
b1 = (Button) findViewById(R.id.connect);
b1.setOnClickListener(this);
}
Logcat:
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.asabanov.powersupplytool, PID: 26570
java.lang.IllegalStateException: Could not find method onClick(View) in a parent or ancestor Context for android:onClick
attribute defined on view class
android.support.v7.widget.AppCompatButton with id 'getValue'
at android.support.v7.app.AppCompatViewInflater$DeclaredOnClickListener.resolveMethod(AppCompatViewInflater.java:307)
at android.support.v7.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:266)
at android.view.View.performClick(View.java:5226)
at android.view.View$PerformClick.run(View.java:21266)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:168)
at android.app.ActivityThread.main(ActivityThread.java:5845)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:797)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:687)
W/System.err: com.github.pires.obd.exceptions.UnableToConnectException: Error
running 01 42, response: 0142...UNABLETOCONNECT
W/System.err: at java.lang.Class.newInstance(Native Method)
W/System.err: at com.github.pires.obd.commands.ObdCommand.checkForErrors(ObdCommand.java:203)
W/System.err: at com.github.pires.obd.commands.ObdCommand.readResult(ObdCommand.java:123)
W/System.err: at com.github.pires.obd.commands.ObdCommand.run(ObdCommand.java:77)
W/System.err: at com.example.asabanov.powersupplytool.BTHandler$ConnectedThread.(BTHandler.java:151)
W/System.err: at com.example.asabanov.powersupplytool.BTHandler$ConnectThread.run(BTHandler.java:117)
V/Log: e
EDIT:
private void onConnect() {
ArrayList deviceStrs = new ArrayList();
final ArrayList<String> devices = new ArrayList();
BluetoothAdapter mAdapter = BluetoothAdapter.getDefaultAdapter();
Set pairedDevices = mAdapter.getBondedDevices();
if (pairedDevices.size() > 0) {
for (Object device : pairedDevices) {
BluetoothDevice bdevice = (BluetoothDevice) device;
deviceStrs.add(bdevice.getName() + "\n" + bdevice.getAddress());
devices.add(bdevice.getAddress());
}
}
// show list
final AlertDialog.Builder alertDialog = new AlertDialog.Builder(this);
ArrayAdapter adapter = new ArrayAdapter(this, android.R.layout.select_dialog_singlechoice,
deviceStrs.toArray(new String[deviceStrs.size()]));
alertDialog.setSingleChoiceItems(adapter, -1, new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
int position = ((AlertDialog) dialog).getListView().getCheckedItemPosition();
String deviceAddress = devices.get(position);
btHandler.connect(deviceAddress);
//btHandler.write();
}
});
alertDialog.setTitle("Paired devices");
alertDialog.show();
}
You should set an onClickListener for your button.
For that, you need to implement OnClickListener interface as:
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
When you create the button, set its OnClickListener as follows:
b1 = (Button) findViewById(R.id.connect);
b1.setOnClickListener(this);
This should get you to your onClick method, when the button is clicked.
Edit: i see you have two buttons. Just do the same for the other button. Don't forget to declare a member for b2, just like b1.
Button b2;
b2 = (Button)findViewById(R.id.getValue);
b2.setOnClickListener(this);
I try to develop a minimalistic BluetoothChat for Android with Phonegap. The Plugin is based on the Android SDK Example of the BluetoothChat as you can see in the example code.
The native BluetoothChat works fine.
The Problem is, when i call my "write"-Function, the "ConnectedThread" is always null, although the connection is established.
I can't recognize where it is set to null again, after the State was set to 3 (STATE_CONNECTED).
So when i run the program native on android, it works fine and the state during write is always 3, but when i use my phonegap plugin 'r'(ConnectedThread) becomes null :
public void write(byte[] out) {
// Create temporary object
ConnectedThread r;
// Synchronize a copy of the ConnectedThread
synchronized (this) {
Log.i(TAG, "State "+mState);
if (mState != STATE_CONNECTED) return;
Log.i(TAG, "Connected Thread "+mConnectedThread);
r = mConnectedThread;
}
// Perform the write unsynchronized
r.write(out);
}
I used a lot of debug messages, but i was never informed that the state is null again.
Full source code :
PLUGIN.java
public class BluetoothConnection extends CordovaPlugin {
//Android specific tag-messages
private static final String TAG ="BluetoothConnection";
private static final boolean D = true;
// Member-Variables
public BluetoothAdapter mBluetoothAdapter;
public JSONArray mListOfDiscoveredDevices;
public String mConnectedDeviceName;
public ConnectionHandler mConnectionHandler;
// Phonegap-specific actions, which call the function
public String ACTION_ENABLEBLUETOOTH = "enableBluetooth";
public String ACTION_DISABLEBLUETOOTH = "disableBluetooth";
public String ACTION_DISCOVERDECIVES = "discoverDevices";
public String ACTION_STOPDISCOVERDEVICES = "stopDiscoverDevices";
public String ACTION_CREATEBOND = "createBond";
public String ACTION_WRITEMESSAGE = "writeMessage";
// not usable, this moment
public String ACTION_DISCONNECT = "disconnect";
//Message types sent from the ConnectionHandler
public static final int MESSAGE_STATE_CHANGE = 1;
public static final int MESSAGE_READ = 2;
public static final int MESSAGE_WRITE = 3;
public static final int MESSAGE_DEVICE_NAME = 4;
public static final int MESSAGE_TOAST = 5;
public static final String DEVICE_NAME = "device_name";
public static final String TOAST = "toast";
#Override
public boolean execute(String action, JSONArray args,
CallbackContext callbackContext) throws JSONException {
mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
if (mBluetoothAdapter.equals(null)) {
Log.i(TAG, "no adapter was found");
}
mConnectionHandler = new ConnectionHandler(mHandler);
if (action.equals(ACTION_ENABLEBLUETOOTH)) {
enableBluetooth();
}
else if (action.equals(ACTION_DISABLEBLUETOOTH)) {
disableBluetooth();
}
else if (action.equals(ACTION_DISCOVERDECIVES)) {
discoverDevices();
}
else if (action.equals(ACTION_STOPDISCOVERDEVICES)) {
stopDiscovering(callbackContext);
}
else if (action.equals(ACTION_CREATEBOND)) {
try {
BluetoothDevice remoteBtDevice = createBond(args, callbackContext);
connect(remoteBtDevice, callbackContext);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
else if(action.equals(ACTION_WRITEMESSAGE)){
writeMessage(args.getString(0));
}
else if (action.equals(ACTION_DISCONNECT)) {
disconnect();
}
return false;
}
public void enableBluetooth() {
if (!mBluetoothAdapter.equals(null)) {
mBluetoothAdapter.enable();
Log.i(TAG, "bluetooth on");
}
}
public void disableBluetooth() {
if (mBluetoothAdapter.isEnabled()) {
mBluetoothAdapter.disable();
Log.i(TAG, "bluetooth off");
}
}
public void discoverDevices() {
mListOfDiscoveredDevices = new JSONArray();
Log.i("Log", "in the start searching method");
IntentFilter intentFilter = new IntentFilter(
BluetoothDevice.ACTION_FOUND);
cordova.getActivity().registerReceiver(mFoundDevices, intentFilter);
mBluetoothAdapter.startDiscovery();
}
private void stopDiscovering(CallbackContext callbackContext) {
if (mBluetoothAdapter.isDiscovering()) {
mBluetoothAdapter.cancelDiscovery();
}
PluginResult res = new PluginResult(PluginResult.Status.OK,
mListOfDiscoveredDevices);
res.setKeepCallback(true);
callbackContext.sendPluginResult(res);
Log.i("Info", "Stopped discovering Devices !");
}
public BluetoothDevice createBond(JSONArray args, CallbackContext callbackContext) throws Exception {
String macAddress = args.getString(0);
Log.i(TAG, "Connect to MacAddress "+macAddress);
BluetoothDevice btDevice = mBluetoothAdapter.getRemoteDevice(macAddress);
Log.i("Device","Device "+btDevice);
Class class1 = Class.forName("android.bluetooth.BluetoothDevice");
Method createBondMethod = class1.getMethod("createBond");
Boolean returnValue = (Boolean) createBondMethod.invoke(btDevice);
if(btDevice.equals(null))
throw new NullPointerException("Remote BluetoothDevice could not be paired !");
return btDevice;
}
public void removeBond(BluetoothDevice btDevice) throws Exception {
Class btClass = Class.forName("android.bluetooth.BluetoothDevice");
Method removeBondMethod = btClass.getMethod("removeBond");
Boolean returnValue = (Boolean) removeBondMethod.invoke(btDevice);
}
public void connect(BluetoothDevice btDevice, CallbackContext callbackContext) {
if(!btDevice.equals(null)){
mConnectionHandler.connect(btDevice, false);
PluginResult result = new PluginResult(PluginResult.Status.NO_RESULT);
result.setKeepCallback(true);
callbackContext.sendPluginResult(result);
Log.i(TAG, "Status after connecting "+mConnectionHandler.getState());
}
else {
callbackContext.error("Could not connect to "+btDevice.getAddress());
}
}
public void disconnect(){
}
public void writeMessage(String message){
if(mConnectionHandler.getState() != ConnectionHandler.STATE_CONNECTED){
Log.i(TAG, "Could not write to device");
Log.i(TAG, "State "+mConnectionHandler.getState());
}
if(message.length() > 0) {
byte[] send = message.getBytes();
mConnectionHandler.write(send);
Log.i(TAG, "sending "+message);
}
else {
Log.i(TAG, "There is nothing to send.");
}
}
private BroadcastReceiver mFoundDevices = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
Message msg = Message.obtain();
String action = intent.getAction();
if (BluetoothDevice.ACTION_FOUND.equals(action)) {
Toast.makeText(context, "found Device !", Toast.LENGTH_SHORT).show();
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
Log.i("FOUND", "Name " + device.getName() + "-" + device.getAddress());
JSONObject discoveredDevice = new JSONObject();
try {
discoveredDevice.put("name", device.getName());
discoveredDevice.put("adress", device.getAddress());
if (!isJSONInArray(discoveredDevice)) {
mListOfDiscoveredDevices.put(discoveredDevice);
}
} catch (JSONException e) {
e.printStackTrace();
}
}
}
};
private final Handler mHandler = new Handler() {
#Override
public void handleMessage(Message msg) {
switch (msg.what) {
case MESSAGE_STATE_CHANGE:
if(D) Log.i(TAG, "MESSAGE_STATE_CHANGE: " + msg.arg1);
switch (msg.arg1) {
case ConnectionHandler.STATE_CONNECTED:
Log.i(TAG, "ConnectionHandler.STATE_CONNECTED !");
break;
case ConnectionHandler.STATE_CONNECTING:
Log.i(TAG, "ConnectionHandler.STATE_CONNECTING !");
break;
case ConnectionHandler.STATE_LISTEN:
Log.i(TAG, "ConnectionHandler.STATE_LISTEN !");
break;
case ConnectionHandler.STATE_NONE:
Log.i(TAG, "ConnectionHandler.STATE_NONE !");
break;
}
break;
case MESSAGE_WRITE:
byte[] writeBuf = (byte[]) msg.obj;
// construct a string from the buffer
String writeMessage = new String(writeBuf);
Log.i(TAG, "Write "+writeMessage);
break;
case MESSAGE_READ:
byte[] readBuf = (byte[]) msg.obj;
// construct a string from the valid bytes in the buffer
String readMessage = new String(readBuf, 0, msg.arg1);
Log.i(TAG, "Read "+readMessage);
break;
case MESSAGE_DEVICE_NAME:
// save the connected device's name
mConnectedDeviceName = msg.getData().getString(DEVICE_NAME);
Log.i(TAG, mConnectedDeviceName);
break;
case MESSAGE_TOAST:
String message = msg.getData().getString(TOAST);
Log.i(TAG, "Connection lost : " +message);
break;
}
}
};}
CONNECTION-HANDLER
public class ConnectionHandler {
// Debugging
private static final String TAG = "BluetoothChatService";
private static final boolean D = true;
// Name for the SDP record when creating server socket
private static final String NAME_SECURE = "BluetoothChatSecure";
private static final String NAME_INSECURE = "BluetoothChatInsecure";
// Unique UUID for this application
private static final UUID MY_UUID_SECURE =
UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");
private static final UUID MY_UUID_INSECURE =
UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");
// Member fields
private final BluetoothAdapter mAdapter;
private final Handler mHandler;
private AcceptThread mSecureAcceptThread;
private AcceptThread mInsecureAcceptThread;
private ConnectThread mConnectThread;
private ConnectedThread mConnectedThread;
private int mState;
// Constants that indicate the current connection state
public static final int STATE_NONE = 0; // we're doing nothing
public static final int STATE_LISTEN = 1; // now listening for incoming connections
public static final int STATE_CONNECTING = 2; // now initiating an outgoing connection
public static final int STATE_CONNECTED = 3; // now connected to a remote device
public ConnectionHandler(Handler handler) {
mAdapter = BluetoothAdapter.getDefaultAdapter();
mState = STATE_NONE;
mHandler = handler;
}
private synchronized void setState(int state) {
if (D) Log.d(TAG, "setState() " + mState + " -> " + state);
mState = state;
// Give the new state to the Handler so the UI Activity can update
mHandler.obtainMessage(BluetoothConnection.MESSAGE_STATE_CHANGE, state, -1).sendToTarget();
}
public synchronized int getState() {
return mState;
}
public synchronized void start() {
if (D) Log.d(TAG, "start");
// Cancel any thread attempting to make a connection
if (mConnectThread != null) {mConnectThread.cancel(); mConnectThread = null;}
// Cancel any thread currently running a connection
if (mConnectedThread != null) {mConnectedThread.cancel(); mConnectedThread = null;}
setState(STATE_LISTEN);
// Start the thread to listen on a BluetoothServerSocket
if (mSecureAcceptThread == null) {
mSecureAcceptThread = new AcceptThread(true);
mSecureAcceptThread.start();
}
if (mInsecureAcceptThread == null) {
mInsecureAcceptThread = new AcceptThread(false);
mInsecureAcceptThread.start();
}
}
public synchronized void connect(BluetoothDevice device, boolean secure) {
if (D) Log.d(TAG, "connect to: " + device);
// Cancel any thread attempting to make a connection
if (mState == STATE_CONNECTING) {
if (mConnectThread != null) {mConnectThread.cancel(); mConnectThread = null;}
}
// Cancel any thread currently running a connection
if (mConnectedThread != null) {mConnectedThread.cancel(); mConnectedThread = null;}
// Start the thread to connect with the given device
mConnectThread = new ConnectThread(device, secure);
mConnectThread.start();
setState(STATE_CONNECTING);
}
public synchronized void connected(BluetoothSocket socket, BluetoothDevice
device, final String socketType) {
if (D) Log.d(TAG, "connected, Socket Type:" + socketType);
// Cancel the thread that completed the connection
if (mConnectThread != null) {mConnectThread.cancel(); mConnectThread = null;}
// Cancel any thread currently running a connection
if (mConnectedThread != null) {mConnectedThread.cancel(); mConnectedThread = null;}
// Cancel the accept thread because we only want to connect to one device
if (mSecureAcceptThread != null) {
mSecureAcceptThread.cancel();
mSecureAcceptThread = null;
}
if (mInsecureAcceptThread != null) {
mInsecureAcceptThread.cancel();
mInsecureAcceptThread = null;
}
// Start the thread to manage the connection and perform transmissions
mConnectedThread = new ConnectedThread(socket, socketType);
mConnectedThread.start();
// Send the name of the connected device back to the UI Activity
Message msg = mHandler.obtainMessage(BluetoothConnection.MESSAGE_DEVICE_NAME);
Bundle bundle = new Bundle();
bundle.putString(BluetoothConnection.DEVICE_NAME, device.getName());
msg.setData(bundle);
mHandler.sendMessage(msg);
setState(STATE_CONNECTED);
}
public synchronized void stop() {
if (D) Log.d(TAG, "stop");
if (mConnectThread != null) {
mConnectThread.cancel();
mConnectThread = null;
}
if (mConnectedThread != null) {
mConnectedThread.cancel();
mConnectedThread = null;
}
if (mSecureAcceptThread != null) {
mSecureAcceptThread.cancel();
mSecureAcceptThread = null;
}
if (mInsecureAcceptThread != null) {
mInsecureAcceptThread.cancel();
mInsecureAcceptThread = null;
}
setState(STATE_NONE);
}
public void write(byte[] out) {
// Create temporary object
ConnectedThread r;
// Synchronize a copy of the ConnectedThread
synchronized (this) {
Log.i(TAG, "State "+mState);
if (mState != STATE_CONNECTED) return;
Log.i(TAG, "Connected Thread "+mConnectedThread);
r = mConnectedThread;
}
// Perform the write unsynchronized
r.write(out);
}
private void connectionFailed() {
// Send a failure message back to the Activity
Message msg = mHandler.obtainMessage(BluetoothConnection.MESSAGE_TOAST);
Bundle bundle = new Bundle();
bundle.putString(BluetoothConnection.TOAST, "Unable to connect device");
msg.setData(bundle);
mHandler.sendMessage(msg);
// Start the service over to restart listening mode
ConnectionHandler.this.start();
}
private void connectionLost() {
// Send a failure message back to the Activity
Message msg = mHandler.obtainMessage(BluetoothConnection.MESSAGE_TOAST);
Bundle bundle = new Bundle();
bundle.putString(BluetoothConnection.TOAST, "Device connection was lost");
msg.setData(bundle);
mHandler.sendMessage(msg);
// Start the service over to restart listening mode
ConnectionHandler.this.start();
}
private class AcceptThread extends Thread {
// The local server socket
private final BluetoothServerSocket mmServerSocket;
private String mSocketType;
public AcceptThread(boolean secure) {
BluetoothServerSocket tmp = null;
mSocketType = secure ? "Secure":"Insecure";
// Create a new listening server socket
try {
if (secure) {
tmp = mAdapter.listenUsingRfcommWithServiceRecord(NAME_SECURE,
MY_UUID_SECURE);
} else {
tmp = mAdapter.listenUsingInsecureRfcommWithServiceRecord(
NAME_INSECURE, MY_UUID_INSECURE);
}
} catch (IOException e) {
Log.e(TAG, "Socket Type: " + mSocketType + "listen() failed", e);
}
mmServerSocket = tmp;
}
public void run() {
if (D) Log.d(TAG, "Socket Type: " + mSocketType +
"BEGIN mAcceptThread" + this);
setName("AcceptThread" + mSocketType);
BluetoothSocket socket = null;
// Listen to the server socket if we're not connected
while (mState != STATE_CONNECTED) {
try {
// This is a blocking call and will only return on a
// successful connection or an exception
socket = mmServerSocket.accept();
} catch (IOException e) {
Log.e(TAG, "Socket Type: " + mSocketType + "accept() failed", e);
break;
}
// If a connection was accepted
if (socket != null) {
synchronized (ConnectionHandler.this) {
switch (mState) {
case STATE_LISTEN:
case STATE_CONNECTING:
// Situation normal. Start the connected thread.
connected(socket, socket.getRemoteDevice(),
mSocketType);
break;
case STATE_NONE:
case STATE_CONNECTED:
// Either not ready or already connected. Terminate new socket.
try {
socket.close();
} catch (IOException e) {
Log.e(TAG, "Could not close unwanted socket", e);
}
break;
}
}
}
}
if (D) Log.i(TAG, "END mAcceptThread, socket Type: " + mSocketType);
}
public void cancel() {
if (D) Log.d(TAG, "Socket Type" + mSocketType + "cancel " + this);
try {
mmServerSocket.close();
} catch (IOException e) {
Log.e(TAG, "Socket Type" + mSocketType + "close() of server failed", e);
}
}
}
private class ConnectThread extends Thread {
private final BluetoothSocket mmSocket;
private final BluetoothDevice mmDevice;
private String mSocketType;
public ConnectThread(BluetoothDevice device, boolean secure) {
mmDevice = device;
BluetoothSocket tmp = null;
mSocketType = secure ? "Secure" : "Insecure";
// Get a BluetoothSocket for a connection with the
// given BluetoothDevice
try {
if (secure) {
tmp = device.createRfcommSocketToServiceRecord(
MY_UUID_SECURE);
} else {
tmp = device.createInsecureRfcommSocketToServiceRecord(
MY_UUID_INSECURE);
}
} catch (IOException e) {
Log.e(TAG, "Socket Type: " + mSocketType + "create() failed", e);
}
mmSocket = tmp;
}
public void run() {
Log.i(TAG, "BEGIN mConnectThread SocketType:" + mSocketType);
setName("ConnectThread" + mSocketType);
// Always cancel discovery because it will slow down a connection
mAdapter.cancelDiscovery();
// Make a connection to the BluetoothSocket
try {
// This is a blocking call and will only return on a
// successful connection or an exception
mmSocket.connect();
} catch (IOException e) {
// Close the socket
try {
mmSocket.close();
} catch (IOException e2) {
Log.e(TAG, "unable to close() " + mSocketType +
" socket during connection failure", e2);
}
connectionFailed();
return;
}
// Reset the ConnectThread because we're done
synchronized (ConnectionHandler.this) {
mConnectThread = null;
}
// Start the connected thread
connected(mmSocket, mmDevice, mSocketType);
}
public void cancel() {
try {
mmSocket.close();
} catch (IOException e) {
Log.e(TAG, "close() of connect " + mSocketType + " socket failed", e);
}
}
}
private class ConnectedThread extends Thread {
private final BluetoothSocket mmSocket;
private final InputStream mmInStream;
private final OutputStream mmOutStream;
public ConnectedThread(BluetoothSocket socket, String socketType) {
Log.d(TAG, "create ConnectedThread: " + socketType);
mmSocket = socket;
InputStream tmpIn = null;
OutputStream tmpOut = null;
// Get the BluetoothSocket input and output streams
try {
tmpIn = socket.getInputStream();
tmpOut = socket.getOutputStream();
} catch (IOException e) {
Log.e(TAG, "temp sockets not created", e);
}
mmInStream = tmpIn;
mmOutStream = tmpOut;
}
public void run() {
Log.i(TAG, "BEGIN mConnectedThread");
byte[] buffer = new byte[1024];
int bytes;
// Keep listening to the InputStream while connected
while (true) {
try {
// Read from the InputStream
bytes = mmInStream.read(buffer);
// Send the obtained bytes to the UI Activity
mHandler.obtainMessage(BluetoothConnection.MESSAGE_READ, bytes, -1, buffer)
.sendToTarget();
} catch (IOException e) {
Log.e(TAG, "disconnected", e);
connectionLost();
// Start the service over to restart listening mode
ConnectionHandler.this.start();
break;
}
}
}
public void write(byte[] buffer) {
try {
mmOutStream.write(buffer);
// Share the sent message back to the UI Activity
mHandler.obtainMessage(BluetoothConnection.MESSAGE_WRITE, -1, -1, buffer)
.sendToTarget();
} catch (IOException e) {
Log.e(TAG, "Exception during write", e);
}
}
public void cancel() {
try {
mmSocket.close();
} catch (IOException e) {
Log.e(TAG, "close() of connect socket failed", e);
}
}
}}
Thanks !!!
I implemented again in a new project - now it works, don't know why - but it work now.