How to receive Digital Input from arduino using UDP in Android? - android

Actually I want to write a program in which whenever a button is pressed on specific digital pin of Arduino, Android receives that signal using UDP and performs tasks accordingly.
This is the Arduino code snippet:
void loop() {
buttonState = digitalRead(12);
if (buttonState == HIGH) {
// ToDo when push button is pressed
}
else {
Udp.beginPacket(Udp.remoteIP(),Udp.remotePort());
Udp.write("anything here");
Udp.endPacket();
}
This is my Android code:
public class Server implements Runnable
{
String serverHostname1, serverHostname2;
DatagramSocket d1;
InetAddress ip, retiip;
DatagramPacket send, rec;
String modifiedSentence;
public static String TAG = "SERVER";
DatagramSocket serverSocket;
public void run() {
Log.d(TAG, "Service Started");
try {
serverSocket = new DatagramSocket(8032);
} catch (SocketException e) {
e.printStackTrace();
}
Log.d(TAG, "Service Started");
byte[] receiveData = new byte[1024];
while (true) {
DatagramPacket receivePacket = new DatagramPacket(receiveData,
receiveData.length);
Log.d(TAG, "Service Started");
try {
serverSocket.receive(receivePacket);
} catch (IOException e) {
e.printStackTrace();
}
String sentence = new String(receivePacket.getData());
System.out.println("RECEIVED: " + sentence);
InetAddress IPAddress = receivePacket.getAddress();
int port = receivePacket.getPort();
Log.d(TAG, "Service Started");
Log.d(TAG, "Received " + sentence);
}
}

Related

Broadcasting on UDP while receiving data

Is there any good option to send broadcast message on UDP port while receiving data from other devices on the same port?
I have this currently:
First I initialize 1 DiagramSocket for both reading and sending:
private void startSocket(){
try {
if(socket == null) {
socket = new DatagramSocket(3040);
socket.setBroadcast(true);
socket.setReuseAddress(true);
}
} catch (Exception e) {
e.printStackTrace();
}
}
In first Thread I have reading/receiving for current socket:
public class Server implements Runnable {
public Server(iBroadcastResponse iBResponse){
BroadcastClass.this.iBResponse = iBResponse;
}
#Override
public void run() {
startSocket();
while (DataHandler.isEmergencyMode.get() ) {
try {
byte[] buf = new byte[256];
DatagramPacket packet = new DatagramPacket(buf, buf.length);
if(socket == null)
return;
socket.receive(packet);
String command = stringFromPacket(packet);
Log.d(TAG, command);
addToBroadcastCalls(command);
if(iBResponse != null)
iBResponse.onResponse();
} catch (Exception e) {
Log.e(TAG, "Server: Error!\n");
}
}
Log.e(TAG, "Stop!");
}
String stringFromPacket(DatagramPacket packet) {
return new String(packet.getData(), 0, packet.getLength());
}
}
If I run this, it works normally, reads receiving data. But if I try to send data in another thread:
socketThread = new Thread(){
#Override
public void run() {
startSocket();
String message = "Message";
byte[] buf = message.getBytes();
DatagramPacket packet = new DatagramPacket(buf, buf.length);
try {
if(!socket.isConnected())
socket.connect(InetAddress.getByName("255.255.255.255"), 3040);
if (socket != null) {
socket.send(packet);
}
Log.d(TAG, "Send: " +message);
} catch (Exception e) {
e.printStackTrace();
}
}
};
socketThread.start();
When .send() is called it stops receiving data from other devices so now it only send message but stops receiving it from other devices.
Is there any good solution to this problem?
This was the solution
https://stackoverflow.com/a/25520279/1088975
I only changed
System.log...
To
Log.w(TAG, "Message...");
And I changed IP to be always "255.255.255.255" instead of
getBroadcastAddress()
which returns broadcast IP for current WIFI, which didn't work on my android devices

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)

Communicating android and windows through socket

I want to make my android app open socket to my windows console app and they communicate with each other. The socket is opened and data is sent and received in windows app, but my android app does not receive the answer which sent by windows. I watch the packets in my android and I saw the packets are coming but I do not know why my app do not receive it!
windows app server class:
class Server
{
private TcpListener tcpListener;
private Thread listenThread;
public Server()
{
Console.WriteLine("\nStarting server...");
this.tcpListener = new TcpListener(IPAddress.Any, 1234);
this.listenThread = new Thread(new ThreadStart(ListenForClients));
this.listenThread.Start();
}
private void ListenForClients()
{
Console.WriteLine("\nWaiting for clients to connect...");
this.tcpListener.Start();
while (true)
{
//blocks until a client has connected to the server
TcpClient client = this.tcpListener.AcceptTcpClient();
//create a thread to handle communication with connected client
Thread clientThread = new Thread(new ParameterizedThreadStart(HandleClientComm));
clientThread.Start(client);
}
}
private void HandleClientComm(object client)
{
Console.WriteLine("\nIncoming from client...");
TcpClient tcpClient = (TcpClient)client;
NetworkStream clientStream = tcpClient.GetStream();
byte[] message = new byte[4096];
int bytesRead;
try
{
while (true)
{
bytesRead = 0;
try
{
//blocks until a client sends a message
bytesRead = clientStream.Read(message, 0, 4096);
}
catch
{
//a socket error has occured
break;
}
if (bytesRead == 0)
{
//the client has disconnected from the server
break;
}
//message has successfully been received
ASCIIEncoding encoder = new ASCIIEncoding();
Console.WriteLine("\nReceived: \n\n" + encoder.GetString(message, 0, bytesRead));
//By FMR
string response = "random responsive: " + new Random().Next(1000).ToString() + "\n";//"\r\n";
//writeData(clientStream, response);
byte[] msg = System.Text.Encoding.ASCII.GetBytes(response);
// Send back a response.
clientStream.Write(msg, 0, msg.Length);
clientStream.Flush();
Console.WriteLine("\nResponed ..." + response);
}
}
catch (Exception ex)
{
Console.WriteLine("\nException while: " + ex.Message);
}
tcpClient.Close();
}
}
my android thread:
Thread thread = new Thread(new Runnable() {
#Override
public void run() {
Socket socket = null;
ServerSocket serverSocket = null;
Boolean bRun = true;
try {
socket = new Socket(ip, port);
if(outputStream == null) {
outputStream = new DataOutputStream(socket.getOutputStream());
}
// become server
serverSocket = new ServerSocket(port);
Log.i(G.TAG, "before serverSocket.accept");
socket = serverSocket.accept();
Log.i(G.TAG, "response recieve: ");
inputStream = new BufferedReader(new InputStreamReader(socket.getInputStream()));
}
catch (Exception e) {
try {
serverSocket.close();
} catch (IOException e1) {
Log.e(G.TAG, "serverSocket.close() e: " + e1.getMessage());
}
try {
socket.close();
} catch (IOException e1) {
Log.e(G.TAG, "socket.close() e: " + e1.getMessage());
}
}
Log.i(G.TAG, "after start recieve: ");
while (bRun) {
try {
Log.i(G.TAG, "while start: ");
String message = inputStream.readLine();
Log.i(G.TAG, "response message: " + message);
if (message != null) {
setListMessage(false, message);
}
}
catch (IOException e) {
bRun = false;
Log.e(G.TAG, "while bRun e: " + e.getMessage());
}
}
}
});
thread.start();
// in another function, my message is sent successfully from android and receive in windows
I found the problem, this line
socket = serverSocket.accept();
made the problem when I comment the line, the android app received the response!
Does anybody know why?

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.

Android UDP socket sends data only once?

I'm pretty new to writing Android apps, and I wanted to write a piece of code that broadcasts the sensor data at a regular interval, say 1 second. Searching open-source codes I managed to write a sender class as below:
public class Sender extends Thread {
private static final String TAG = "Sending";
private static final int PORT = 12346;
private static final int TIMEOUT_MS = 500;
private static final int BUF_SIZE = 1024;
private WifiManager mWifi;
Sender(WifiManager wifi) {
mWifi = wifi;
}
public void run() {
try {
DatagramSocket socket = new DatagramSocket(PORT);
socket.setBroadcast(true);
socket.setSoTimeout(TIMEOUT_MS);
sendData(socket);
socket.close();
Thread.sleep(1000);
}
catch (IOException ioe) {
Log.e(TAG, "Couldn't send data", ioe);
}
catch (InterruptedException ie) {
Log.e(TAG, "Can't sleep", ie);
}
}
private void sendData(DatagramSocket socket) throws IOException {
byte[] buf = new byte[BUF_SIZE];
buf = object.toString().getBytes();
InetAddress addr = InetAddress.getByName("192.168.0.255"); // TO FIX
DatagramPacket packet = new DatagramPacket(buf, buf.length, addr, PORT);
socket.send(packet);
}
public void main(String[] args) {
new Sender(null).start();
while (true) {
}
}
}
And here's how I start it from within the onCreate method:
public void onCreate(Bundle savedInstanceState) {
...
new Sender((WifiManager) getSystemService(Context.WIFI_SERVICE)).start();
...
}
Now, if I open Wireshark on my laptop, I only see one packet sent at the time the app is started instead of every one second.
Could someone please point out where I did wrong? Honestly I'm not that familiar with threads and stuff, so I may just be missing something obvious here...
EDIT
OK, so the run method must be looped. See corrected code in the answer below.
Here's the corrected run method code:
public void run() {
while (true) {
try {
DatagramSocket socket = new DatagramSocket(PORT);
socket.setBroadcast(true);
socket.setSoTimeout(TIMEOUT_MS);
sendData(socket);
socket.close();
Thread.sleep(1000);
}
catch (IOException ioe) {
Log.e(TAG, "Couldn't send data", ioe);
}
catch (InterruptedException ie) {
Log.e(TAG, "Can't sleep", ie);
}
}
}

Categories

Resources