Android Sockets - android

I'm programming a simple Bluetooth chat.
When I want to handle sockets to receive and send message I don't know how to use these methods that i've implemented.
I attach my code and if some one know how to help me...
I have methods to create connection with thread, listen and write with socket. But I don't know how to use it on the main (onCreate).
Thank you.
public class messages_activity extends Activity {
private Button send;
private TextView message;
private EditText write;
private BluetoothSocket transferSocket;
private BluetoothAdapter mBluetoothAdapter;
final UUID applicationUUID = UUID.fromString("27012F0C-68AF-4FBF-8DBE-6BBAF7AA432A");
private boolean listening = false;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.messages);
send = (Button) findViewById(R.id.button4);
message = (TextView) findViewById(R.id.textView2);
write = (EditText) findViewById(R.id.editText);
mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
Intent intent = getIntent();
String macAddress = intent.getStringExtra("MacAddress"); //On macAddress I receive the macAddress of the other device that I want to send and receive
BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(macAddress);
startServerSocket(mBluetoothAdapter);
connectToServerSocket(device, applicationUUID);
send.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
sendMessage(transferSocket, write.getText().toString()); //write is a textField when I write what I want to send
}
});
}
//Bluetooth Socket Server Connection
private UUID startServerSocket(BluetoothAdapter bluetooth){
try{
final BluetoothServerSocket btserver = bluetooth.listenUsingRfcommWithServiceRecord(mBluetoothAdapter.getName(), applicationUUID);
Thread acceptThread = new Thread(new Runnable() {
public void run() {
try{
//Block until client connection established
BluetoothSocket serverSocket = btserver.accept();
//Start listening for messages
StringBuilder incoming = new StringBuilder();
listenForMessages(serverSocket, incoming);
//Add a reference to the socket used to send messages
transferSocket = serverSocket;
}catch (IOException e){}
}
});
acceptThread.start();
}catch (IOException e){}
return applicationUUID;
}
//Creating a Bluetooth client socket
private void connectToServerSocket (BluetoothDevice device, UUID uuid){
try {
BluetoothSocket clientSocket = device.createRfcommSocketToServiceRecord(applicationUUID);
//Block until server connection accept
clientSocket.connect();
//Start listening for messages
StringBuilder incoming = new StringBuilder();
listenForMessages(clientSocket, incoming);
//Add a reference to the socket used to send messages
transferSocket = clientSocket;
}catch (IOException e){}
}
private void sendMessage(BluetoothSocket socket, String message) {
OutputStream outStream;
try {
outStream = socket.getOutputStream();
// Add a stop character.
byte[] byteArray = (message + " ").getBytes();
byteArray[byteArray.length - 1] = 0;
outStream.write(byteArray);
outStream.flush();
} catch (IOException e) {
}
}
private void listenForMessages(BluetoothSocket socket, StringBuilder incoming){
listening = true;
int bufferSize = 1024;
byte[] buffer = new byte[bufferSize];
try{
InputStream instream = socket.getInputStream();
int bytesRead = -1;
while(listening){
bytesRead = instream.read(buffer);
if(bytesRead != -1){
String result = "";
while((bytesRead == bufferSize) && (buffer[bufferSize-1] != 0)){
result = result + new String (buffer, 0, bytesRead - 1 );
bytesRead = instream.read(buffer);
}
result = result + new String (buffer, 0, bytesRead - 1 );
incoming.append(result);
message.setText(incoming); //message is a textview to show what I've received
}
socket.close();
}
}catch(IOException e){}
finally {
}
}

I haven't run the code so I don't know if it works.
listenForMessages shows the received message being inserted into the message textview message.setText(incoming);
This should then show on your screen.
If you want a chat, you should be doing something like:
Enter text in send box, click send.
In the onClick method of send.onClickListener, add a line to the messagetext(Chat window) box showing your message being sent:
ME: Hi! How are you?
Then clear the message text box
The onClick method then fires send message as coded.
When a message is received listenForMessage should add the received message to the Chat Window: ID: message.
FRIEND: I'm all snowed in? You?
Now you are ready for another round of messages.

Related

Bluetooth issue

I am building an app which connects through bluetooth but the problem is that it is crushing the device when I try to open the activity as the app should transfer the data from arduino to android app and display on it.I am having problem with the default bluetooth device issue when i see it on terminal
Here is the code
public class BlankActivity extends AppCompatActivity {
Button btnOn, btnOff;
TextView txtString, txtStringLength, sensorView0;
Handler bluetoothIn;
final int handlerState = 0; //used to identify handler message
private BluetoothAdapter btAdapter = null;
private BluetoothSocket btSocket = null;
private StringBuilder recDataString = new StringBuilder();
private ConnectedThread mConnectedThread;
// SPP UUID service - this should work for most devices
private static final UUID myUUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");
// String for MAC address
private static String address;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.sensors_layout);
//Link the buttons and textViews to respective views
btnOn = (Button) findViewById(R.id.buttonOn);
btnOff = (Button) findViewById(R.id.buttonOff);
txtString = (TextView) findViewById(R.id.txtString);
txtStringLength = (TextView) findViewById(R.id.testView1);
sensorView0 = (TextView) findViewById(R.id.sensorView0);
bluetoothIn = new Handler() {
public void handleMessage(android.os.Message msg) {
if (msg.what == handlerState) { //if message is what we want
String readMessage = (String) msg.obj; // msg.arg1 = bytes from connect thread
recDataString.append(readMessage); //keep appending to string until ~
int endOfLineIndex = recDataString.indexOf("~"); // determine the end-of-line
if (endOfLineIndex > 0) { // make sure there data before ~
String dataInPrint = recDataString.substring(0, endOfLineIndex); // extract string
//txtString.setText("Data Received = " + dataInPrint);
int dataLength = dataInPrint.length(); //get length of data received
//txtStringLength.setText("String Length = " + String.valueOf(dataLength));
if (recDataString.charAt(0) == '#') //if it starts with # we know it is what we are looking for
{
String sensor0 = recDataString.substring(1, endOfLineIndex); //get sensor value from string between indices 1-5
//String sensor1 = recDataString.substring(6, 10); //same again...
//String sensor2 = recDataString.substring(11, 15);
//String sensor3 = recDataString.substring(16, 20);
sensorView0.setText(" Intensity = " + sensor0 + " Raw "); //update the textviews with sensor values
//sensorView1.setText(" Sensor 1 Voltage = " + sensor1 + "V");
//sensorView2.setText(" Sensor 2 Voltage = " + sensor2 + "V");
//sensorView3.setText(" Sensor 3 Voltage = " + sensor3 + "V");
}
recDataString.delete(0, recDataString.length()); //clear all string data
// strIncom =" ";
dataInPrint = " ";
}
}
}
};
btAdapter = BluetoothAdapter.getDefaultAdapter(); // get Bluetooth adapter
checkBTState();
// Set up onClick listeners for buttons to send 1 or 0 to turn on/off LED
btnOff.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
mConnectedThread.write("0"); // Send "0" via Bluetooth
Toast.makeText(getBaseContext(), "Measurement Off!!!", Toast.LENGTH_SHORT).show();
}
});
btnOn.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
mConnectedThread.write("1"); // Send "1" via Bluetooth
Toast.makeText(getBaseContext(), "Please Wait ", Toast.LENGTH_SHORT).show();
}
});
}
private BluetoothSocket createBluetoothSocket(BluetoothDevice device) throws IOException {
return device.createRfcommSocketToServiceRecord(myUUID);
//creates secure outgoing connecetion with BT device using UUID
}
#Override
public void onResume() {
super.onResume();
//Get MAC address from DeviceListActivity via intent
Intent intent = getIntent();
//Get the MAC address from the DeviceListActivty via EXTRA
address = intent.getStringExtra(MainLayout.EXTRA_ADDRESS);
//create device and set the MAC address //I am having problem here in android monitor
BluetoothDevice device = btAdapter.getRemoteDevice(address);
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) {
//insert code to deal with this
}
}
mConnectedThread = new ConnectedThread(btSocket);
mConnectedThread.start();
//I 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
// I have problem with this line
****mConnectedThread.write("x");**
}**
#Override
public void onPause() {
super.onPause();
try {
//Don't leave Bluetooth sockets open when leaving activity
btSocket.close();
} catch (IOException e2) {
//insert code to deal with this
}
}
//Checks that the Android device Bluetooth is available and prompts to be turned on if off
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);
}
}
}
//create new class for connect thread
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;
}
public void run() {
byte[] buffer = new byte[256];
int bytes;
// Keep looping to listen for received messages
while (true) {
try {
bytes = mmInStream.read(buffer); //read bytes from input buffer
String readMessage = new String(buffer, 0, bytes);
// Send the obtained bytes to the UI Activity via handler
bluetoothIn.obtainMessage(handlerState, bytes, -1, readMessage).sendToTarget();
} catch (IOException e) {
break;
}
}
}
//write method
public void write(String input) {
byte[] msgBuffer = input.getBytes(); //converts entered String into bytes
try {
mmOutStream.write(msgBuffer); //write bytes over BT connection via outstream
} catch (IOException e) {
//if you cannot write, close the application
Toast.makeText(getBaseContext(), "Connection Failure", Toast.LENGTH_LONG).show();
finish();
}
}
}
}
This is the crash code when I am facing when I click the button
at de.zmt.photometerapp.BlankActivity$3.onClick(BlankActivity.java:114)

BufferedReader not reading data but shows value in debug mode

I have implemented Socket for a multiplayer game using libGdx.
Client side
private void startClient(String ip, int port) {
SocketHints socketHints = new SocketHints();
// Socket will time our in 4 seconds
socketHints.connectTimeout = 4000;
//create the socket and connect to the server entered in the text box ( x.x.x.x format ) on port 9021
Socket socket = Gdx.net.newClientSocket(Net.Protocol.TCP, ip, port,
socketHints);
try {
System.out.println("JoinScreen.startClient");
// write our entered message to the stream
OutputStream out = socket.getOutputStream();
out.write("testtest shine \n".getBytes());
out.flush();
} catch (IOException e) {
e.printStackTrace();
}
}
Server code
private void startThreadServer() {
new Thread(new Runnable() {
#Override
public void run() {
System.out.println("HotspotHomeScreen.run");
ServerSocketHints serverSocketHint = new ServerSocketHints();
serverSocketHint.acceptTimeout = 0;
ServerSocket serverSocket = Gdx.net.newServerSocket(Net.Protocol.TCP, mPort, serverSocketHint);
String messageStr = null;
while (true) {
// Create a socket
Socket socket = serverSocket.accept(null);
System.out.println("while true");
int value = 0;
BufferedReader buffer = new BufferedReader(new InputStreamReader(socket.getInputStream()));
try {
while ((value = buffer.read()) != -1) {
char c = (char) value;
if (value != 0 && value != 155)
messageStr = messageStr + c;
// Read to the next newline (\n) and display that text on labelMessage
System.out.println("HotspotHomeScreen.run " + buffer.readLine());
System.out.println("test messageStr = " + messageStr);
}
} catch (IOException e) {
e.printStackTrace();
}
System.out.println("testnjnihg test" + messageStr);
System.out.println("HostScreen last line");
}
}
}).start(); // And, start the thread running
}
The BufferedReader is invoked after starting the server on one device,but data cannot read. When I switch to debug mode, after reaching while ((value = buffer.read()) != -1) { the buffer shows all the data I sent in the debugger console,but the execution stops there. Sorry for my bad Language

Android ServerSocket not sending data to client (client c#, server java)

I'm playing around ServerSocket on Android as the server part. I don't understand how it behaves. Here are what I tested :
A1. Instantiates a ServerSocket on Android
A2. ServerSocket sends "hello" to client
A3. Client can read the "hello" and can answer back to ServerSocket
A4. ServerSocket on Android receives the answer from the client
=> That works perfectly
Now I want the client to be the first to send a message to ServerSocket :
B1. Instantiates a ServerSocket on Android
B2. Client sends data to ServerSocket
B3. ServerSocket receives the data from client
B4. IMPOSSIBLE TO REPLY to the client
May that be a possible normal behaviour ?
Thanks
here is the source code
public void startServer()
{
log("startServer");
UUID uuid = UUID.randomUUID();
final String sessionId = uuid.toString().replace("-", "");
log("Session ID = " + sessionId);
Thread t = new Thread(new Runnable() {
#Override
public void run() {
while (stopServer == false) {
ServerSocket serverSocket = null;
try {
serverSocket = new ServerSocket(7777);
final Socket socket = serverSocket.accept();
InputStream inputStream = socket.getInputStream();
String strFromClient = "";
int i = 0;
while (i != -1) {
try {
i = inputStream.read();
if (i != -1)
strFromClient += (char) i;
}catch (Exception e){
break;
}
}
inputStream.close();
OutputStream outputStream = socket.getOutputStream();
String strToClient = "test";
byte[] cArray = strToClient.getBytes();
outputStream.write(cArray);
outputStream.flush();
outputStream.close();
socket.close();
serverSocket.close();
log("end server");
} catch (Exception e) {
//log(e.toString());
}
}
}
});
t.start();
}
Ok I found the solution ! The error was because the C# client was not sending the "-1" value (this is only triggered after closing a stream or stuff like that).
The solution is on the Android side, and the reading of the data from the client is now done as follow :
InputStream inputStream = socket.getInputStream();
String strFromClient = "";
int available = inputStream.available();
Log.d("intelsms", "available from client:" + available);
for (int i=0;i<available;i++){
int c = inputStream.read();
strFromClient+=(char)c;
}
I use the "available()" method in order to know how many bytes are available for reading from the client.
OUF !

I cannot cancel my thread in Android

I am developing an app that communicated with Arduino via bluetooth, however, I dont know why I cannot cancel the thread which responsible for the bluetooth inputstream.
public class mainclass extends Activity{
BluetoothSocket scSocket = AnotherClass.btSocket;
SendReceiveBytes sendReceiveBT;
Thread th;
protected void onCreate(Bundle savedInstanceState) {
.
.
sendReceiveBT = new SendReceiveBytes(scSocket);
th = new Thread(sendReceiveBT);
th.start();
.
.
sendReceiveBT.stop=true;
Log.e(TAG, "Request sent");
.
.
}
}
public class SendReceiveBytes implements Runnable {
public static final int MESSAGE_WRITE = 1;
public static final int MESSAGE_READ = 2;
String readMessage="";
private BluetoothSocket btSocket;
private InputStream btInputStream = null;
private OutputStream btOutputStream = null;
public boolean stop=false;
public boolean stopped=false;
String TAG = "SendReceiveBytes";
public SendReceiveBytes(BluetoothSocket socket) {
btSocket = socket;
try {
btInputStream = btSocket.getInputStream();
btOutputStream = btSocket.getOutputStream();
}
catch (IOException streamError) {
Log.e(TAG, "Error when getting input or output Stream");
}
}
public void run() {
byte[] buffer = new byte[1024]; // buffer store for the stream
int bytes; // bytes returned from read()
// Keep listening to the InputStream until an exception occurs
while (!stop) {
try {
// Read from the InputStream
bytes = btInputStream.read(buffer);
// Send the obtained bytes to the UI activity
byte[] readBuf = (byte[]) buffer;
// construct a string from the valid bytes in the buffer
readMessage = new String(readBuf, 0, bytes);
}
catch (IOException e) {
Log.e(TAG, "Error reading from btInputStream");
break;
}
}
Log.e(TAG, "Quit");
stopped=true;
}
}
In the LogCat, the tag with "Request sent" is shown which means I already set the "stop" to true, however, the tag with "Quit" never show up.
You could try to override the stop()-method, which set stop-flag to true. Also make sure to close your streams.

NFC Pair Bluetooth Connection Android Bidirectional Socket issue

Hi I want to connect two android phones application using Bluetooth and NFC.
I am currently sending the UUID and the MAC over NFC from one device to another;
The issue is that when it comes to opening the sockets I get the following error:
java.io.IOException: Service discovery failed
On the client side of the application:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.bluerec);
JSONObject oneObject = null;
//NFC
Intent intent = getIntent();
Parcelable[] messages = intent.getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES);
NdefMessage message = (NdefMessage)messages[0];
NdefRecord record = message.getRecords()[0];
payload = new String(record.getPayload());
String add = null;
String uuid = null;
try {
oneObject = new JSONObject(payload);
add = oneObject.getString("MAC");
uuid = oneObject.getString("UUID");
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
TextView textView = (TextView) findViewById(R.id.textView);
textView.setText(payload);
UUID uuid2 = UUID.fromString(uuid);
BluetoothAdapter bluetooth = BluetoothAdapter.getDefaultAdapter();
this.bluetooth = bluetooth;
BluetoothDevice device = bluetooth.getRemoteDevice(add);
connectToServerSocket(device, uuid2 );
}
private void connectToServerSocket(BluetoothDevice device, UUID uuid) {
try{
BluetoothSocket clientSocket = device.createRfcommSocketToServiceRecord(uuid);
// Block until server connection accepted.
clientSocket.connect();
// Start listening for messages.
StringBuilder incoming = new StringBuilder();
listenForMessages(clientSocket, incoming);
// Add a reference to the socket used to send messages.
transferSocket = clientSocket;
} catch (IOException e) {
Log.e("BLUETOOTH", "Blueooth client I/O Exception", e);
}
}
And on the Server side:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
//Bluetooth
//NFC
jsonObj = getMacAddress();
payload = jsonObj.toString();
nfcAdapter = NfcAdapter.getDefaultAdapter(this);
String mimeType = "application/com.example.cpayvendingcomm";
byte[] mimeBytes = mimeType.getBytes(Charset.forName("US-ASCII"));
NdefMessage nfcMessage = new NdefMessage(
new NdefRecord[]
{
// Create the NFC payload.
new NdefRecord(
NdefRecord.TNF_MIME_MEDIA,
mimeBytes,
new byte[0],
payload.getBytes()),
// Add the AAR (Android Application Record)
//NdefRecord.createApplicationRecord("com.paad.nfcbeam")
});
nfcAdapter.setNdefPushMessage(nfcMessage, this);
initBluetooth();
}
private static final int ENABLE_BLUETOOTH = 1;
private void initBluetooth() {
if (!bluetooth.isEnabled()) {
// Bluetooth isn't enabled, prompt the user to turn it on.
Intent intent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(intent, ENABLE_BLUETOOTH);
} else {
// Bluetooth is enabled, initialize the UI.
initBluetoothUI();
BluetoothAdapter bluetooth = BluetoothAdapter.getDefaultAdapter();
this.bluetooth = bluetooth;
startServerSocket(bluetooth);
}
}
private void initBluetoothUI() {
// TODO Auto-generated method stub
}
private ArrayList<BluetoothDevice> deviceList =
new ArrayList<BluetoothDevice>();
BroadcastReceiver discoveryResult = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
String remoteDeviceName = intent.getStringExtra(BluetoothDevice.EXTRA_NAME);
BluetoothDevice remoteDevice = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
deviceList.add(remoteDevice);
Log.d(TAG, "Discovered " + remoteDeviceName);
}
};
private BluetoothSocket transferSocket;
private UUID startServerSocket(BluetoothAdapter bluetooth) {
UUID uuid = UUID.fromString("a60f35f0-b93a-11de-8a39-08002009c545");
String name = "bluetoothserver";
try {
final BluetoothServerSocket btserver =
bluetooth.listenUsingRfcommWithServiceRecord(name, uuid);
Thread acceptThread = new Thread(new Runnable() {
public void run() {
try {
// Block until client connection established.
BluetoothSocket serverSocket = btserver.accept();
// Start listening for messages.
StringBuilder incoming = new StringBuilder();
listenForMessages(serverSocket, incoming);
// Add a reference to the socket used to send messages.
transferSocket = serverSocket;
} catch (IOException e) {
Log.e("BLUETOOTH", "Server connection IO Exception", e);
}
}
});
acceptThread.start();
} catch (IOException e) {
Log.e("BLUETOOTH", "Socket listener IO Exception", e);
}
return uuid;
}
// Listener for messages
private boolean listening = false;
private void listenForMessages(BluetoothSocket socket, StringBuilder incoming) {
listening = true;
int bufferSize = 1024;
byte[] buffer = new byte[bufferSize];
try {
InputStream instream = socket.getInputStream();
int bytesRead = -1;
while (listening) {
bytesRead = instream.read(buffer);
if (bytesRead != -1) {
String result = "";
while ((bytesRead == bufferSize) &&
(buffer[bufferSize-1] != 0)){
result = result + new String(buffer, 0, bytesRead - 1);
bytesRead = instream.read(buffer);
}
result = result + new String(buffer, 0, bytesRead - 1);
incoming.append(result);
}
socket.close();
}
} catch (IOException e) {
Log.e(TAG, "Message received failed.", e);
}
finally {
}
}
Passing the Bluetooth address assumes you are connecting without prior pairing of the Bluetooth devices. Depending on whether you want to pair the two devices or not you can implement it two ways:
No Pairing. Use createInsecureRfcommSocketToServiceRecord() instead of createRfcommSocketToServiceRecord() on the client as described in how to create insecure server connection in Android. Use listenUsingInsecureRfcommWithServiceRecord() on the server.
Pairing with Secure Simple Pairing with passing OOB via NFC. It's a more involved process, beyond what you are asking.

Categories

Resources