I have an ESP8266 12F in Soft AP mode(Server) and trying to connect my Android App to it in persistent mode(TCP).
I'm trying with this code and I can send data but not receive the answer an I know that the answer is being sent because I'm sniffing the ESP8266 connection.
The goal is to start a TCP client connection against the ESP8266 and send packets to it depending on what button is pressed in the App and the IoT device can be busy to answer so I can't wait halting the App GUI; that's why I need a persistent connection.
I tried different approaches without success.
package com.coolio.tcptest;
import android.os.AsyncTask;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.TextView;
import java.net.*;
import java.io.*;
public class ClientActivity extends AppCompatActivity {
Socket myClient = new Socket();
Boolean Connected = false;
String serverName;
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_client);
}
public class client extends AsyncTask<Void,Void,Void>
{
String received;
protected Void doInBackground(Void... Params)
{
//String serverName = "10.7.48.108";
int port = 1100;
try {
//updateText.setText("Connecting to " + serverName + " on port " + port);
// Socket client = new Socket(serverName, port);
if(!Connected)
{
//myClient.addListener();
myClient = new Socket(serverName, port);
myClient.setTcpNoDelay(true);
//myClient.on("new message", onNewMessage);
Connected=true;
}
//updateText.setText("Just connected to " + client.getRemoteSocketAddress());
OutputStream outToServer = myClient.getOutputStream();
DataOutputStream out = new DataOutputStream(outToServer);
InputStream inFromServer = myClient.getInputStream();
DataInputStream in = new DataInputStream(inFromServer);
out.writeBytes("Connected!\r\n");
received = in.readUTF();//Stuck here
myClient.close();
}
catch (IOException e)
{
e.printStackTrace();
}
return null;
}
protected void onPostExecute(Void aVoid)
{
//Never reach here
TextView updateText = (TextView) findViewById(R.id.update);
updateText.setText("in post");
TextView receivedText = (TextView) findViewById(R.id.received);
receivedText.setText("Server says: " + received);
}
}
public void onSendClicked(View view)
{
//EditText messageView= (EditText) findViewById(R.id.ip);
//serverName=messageView.getText().toString();
serverName="192.168.4.1";
new client().execute();
}
}
Related
I'm making a smart interphone.
If button(raspberryPi) is pressed, smartphone(app) rings.
So I need to Socket Communication.
Because I don't know socket... , I copied it.
I should use Java (android), I found Java pi4v library.
I have server(RaspberryPi) code, client(Android) code, and button code.
But, they're respective and I don't know how to combine them.
I want to send any signal pi to android using button!
Here is Server code.
import java.io.*;
import java.net.*;
public class JavaSocketServer{
public static void main(String[] args){
try{
int portNumber = 10001;
System.out.println("Start Server...");
ServerSocket aServerSocket = new ServerSocket(portNumber);
System.out.println("Listening at port " + portNumber + ",,,");
while(true){
Socket sock = aServerSocket.accept();
InetAddress clientHost = sock.getLocalAddress();
int clientPort = sock.getPort();
System.out.println("A client connected.");
System.out.println("(host : " + clientHost + ", port : " + clientPort);
ObjectInputStream instream = new ObjectInputStream(sock.getInputStream());
Object obj = instream.readObject();
System.out.println("Input : " + obj);
ObjectOutputStream outstream = new ObjectOutputStream(sock.getOutputStream());
outstream.writeObject(obj + " from Server.");
outstream.flush();
sock.close();
}
} catch(Exception ex){
ex.printStackTrace();
}
}
}
Here is Android Client Code.
package org.techtown.socket;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.Socket;
/**
*
*
* #author Mike
*
*/
public class MainActivity extends AppCompatActivity {
EditText input01;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
input01 = (EditText) findViewById(R.id.input01);
// 버튼 이벤트 처리
Button button01 = (Button) findViewById(R.id.button01);
button01.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
String addr = input01.getText().toString().trim();
ConnectThread thread = new ConnectThread(addr);
thread.start();
}
});
}
/**
* 소켓 연결할 스레드 정의
*/
class ConnectThread extends Thread {
String hostname;
public ConnectThread(String addr) {
hostname = addr;
}
public void run() {
try {
int port = 11001;
Socket sock = new Socket(hostname, port);
ObjectOutputStream outstream = new ObjectOutputStream(sock.getOutputStream());
outstream.writeObject("Hello AndroidTown on Android");
outstream.flush();
ObjectInputStream instream = new ObjectInputStream(sock.getInputStream());
String obj = (String) instream.readObject();
Log.d("MainActivity", "서버에서 받은 메시지 : " + obj);
sock.close();
} catch(Exception ex) {
ex.printStackTrace();
}
}
}
}
Here is Button code.
import com.pi4j.io.gpio.*;
import com.pi4j.io.gpio.event.GpioPinDigitalStateChangeEvent;
import com.pi4j.io.gpio.event.GpioPinListenerDigital;
/**
* This example code demonstrates how to setup a listener
* for GPIO pin state changes on the Raspberry Pi.
*
* #author Robert Savage
*/
public class ListenGpioExample {
public static void main(String args[]) throws InterruptedException {
System.out.println("<--Pi4J--> GPIO Listen Example ... started.");
// create gpio controller
final GpioController gpio = GpioFactory.getInstance();
// provision gpio pin #02 as an input pin with its internal pull down resistor enabled
final GpioPinDigitalInput myButton = gpio.provisionDigitalInputPin(RaspiPin.GPIO_04, PinPullResistance.PULL_DOWN);
// set shutdown state for this input pin
myButton.setShutdownOptions(true);
// create and register gpio pin listener
myButton.addListener(new GpioPinListenerDigital() {
#Override
public void handleGpioPinDigitalStateChangeEvent(GpioPinDigitalStateChangeEvent event) {
// display pin state on console
System.out.println(" --> GPIO PIN STATE CHANGE: " + event.getPin() + " = " + event.getState());
}
});
System.out.println(" ... complete the GPIO #02 circuit and see the listener feedback here in the console.");
// keep program running until user aborts (CTRL-C)
while(true) {
Thread.sleep(500);
}
// stop all GPIO activity/threads by shutting down the GPIO controller
// (this method will forcefully shutdown all GPIO monitoring threads and scheduled tasks)
// gpio.shutdown(); <--- implement this method call if you wish to terminate the Pi4J GPIO
controller
}
}
I have no Idea,,,,
I need your help!
First: I am from austria , so my english is not so good. So I apologize for the mistakes I will make!
This is my first project I try with Android Studio. I am a newbie in programming. I have not much skill in Arduino and Android program language, but I need it for my bachelor project, so I have to learn it!
I worked with a tutorial video, which was in spanish, so I have no clue what that guy was talking about, but I understood the code all in all.
My problem is, when I start the app on my phone, the first screen (paired devices) works fine. But when I press on the paired device...
This following error occurs :
Capturing and displaying logcat messages from application. This
behavior can be disabled in the "Logcat output" section of the
"Debugger" settings page. D/OpenGLRenderer:
ProgramCache.generateProgram: 103079215104 D/AndroidRuntime: Shutting
down VM E/AndroidRuntime: FATAL EXCEPTION: main
Process: bachelor_projekt.bluetoothcontroller, PID: 11061
java.lang.RuntimeException: Unable to resume activity
{bachelor_projekt.bluetoothcontroller/bachelor_projekt.bluetoothcontroller.UserInterface}:
java.lang.IllegalArgumentException: null is not a valid Bluetooth
address
at android.app.ActivityThread.performResumeActivity(ActivityThread.java:3506)
at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:3546)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2795)
at android.app.ActivityThread.-wrap12(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1527)
at android.os.Handler.dispatchMessage(Handler.java:110)
at android.os.Looper.loop(Looper.java:203)
at android.app.ActivityThread.main(ActivityThread.java:6247)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1063)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:924)
Caused by: java.lang.IllegalArgumentException: null is not a valid Bluetooth address
at android.bluetooth.BluetoothDevice.(BluetoothDevice.java:668)
at android.bluetooth.BluetoothAdapter.getRemoteDevice(BluetoothAdapter.java:553)
at bachelor_projekt.bluetoothcontroller.UserInterface.onResume(UserInterface.java:122)
at android.app.Instrumentation.callActivityOnResume(Instrumentation.java:1272)
at android.app.Activity.performResume(Activity.java:6917)
at android.app.ActivityThread.performResumeActivity(ActivityThread.java:3477)
at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:3546)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2795)
at android.app.ActivityThread.-wrap12(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1527)
at android.os.Handler.dispatchMessage(Handler.java:110)
at android.os.Looper.loop(Looper.java:203)
at android.app.ActivityThread.main(ActivityThread.java:6247)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1063)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:924)
I/Process: Sending signal. PID: 11061 SIG: 9 Application terminated.
After that message, the app shuts down :
I divided my app in:
Bluetooth - for the bluetooth connection
Here is the code:
package bachelor_projekt.bluetoothcontroller;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.content.Intent;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
import java.util.List;
import java.util.Set;
public class Bluetooth extends AppCompatActivity {
// Cleaning of the Logcat (Systemlog)
private static final String TAG = "Bluetooth";
// Declaration of ListView
ListView IdList;
// String which will be sended to the main frame
public static String EXTRA_DEVICE_ADDRESS = "device_address";
// Declaration of the fields
private BluetoothAdapter myBluetooth;
private ArrayAdapter<String> myPairedDevicesArray;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_bluetooth);
}
#Override
public void onResume()
{
super.onResume();
//----------------------------
VerificationBT();
// Initialze the array which keeps the bluetooth devices
myPairedDevicesArray=new ArrayAdapter<String>(this, R.layout.device_name);
IdList = findViewById(R.id.idList);
IdList.setAdapter(myPairedDevicesArray);
IdList.setOnItemClickListener(myDeviceClickListener);
// Get local default bluetooth adapter
myBluetooth = BluetoothAdapter.getDefaultAdapter();
// Includes the bluetooth member which is paired with the device
Set<BluetoothDevice> pairedDevices =myBluetooth.getBondedDevices();
// Pair with an already in the array included device.
if (pairedDevices.size()>0)
{
for (BluetoothDevice device : pairedDevices){
myPairedDevicesArray.add(device.getName() + "\n" + device.getAddress());
}
}
}
// Configuration for the "on click" ability for the liste
private AdapterView.OnItemClickListener myDeviceClickListener = new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView av , View v, int arg2, long arg3) {
// Detect the MAC-Adress of the device ( last 17 caracters)
String info = ((TextView) v).getText().toString();
String address = info.substring(info.length() - 17);
// 1 Try to connect if MAC adress is the same
Intent i = new Intent(Bluetooth.this, UserInterface.class);
startActivity(i);
}
};
private void VerificationBT(){
// Checks if the device has bluetooth and if it is activated
myBluetooth=BluetoothAdapter.getDefaultAdapter();
if(myBluetooth==null) {
Toast.makeText(getBaseContext(), "Device doesn't have bluetooth", Toast.LENGTH_SHORT).show();
} else{
if (myBluetooth.isEnabled()) {
Log.d(TAG, "...Bluetooth Avtivated...");
} else{
// Ask the user to activate bluetooth
Intent enableBt = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableBt,1);
}
}
}
}
The second part is the user interface - Here should be the actual project which is just for start (3 Buttons, 1 for LED on, 1 for LED off, 1 for disconnect).
Here is the code:
package bachelor_projekt.bluetoothcontroller;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothSocket;
import android.content.Intent;
import android.os.Handler;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.UUID;
public class UserInterface extends AppCompatActivity {
Button IdLedON, IdLedOFF, IdDisconnect;
TextView IdBuffer;
//-------------------------------------------------
Handler bluetoothIn;
final int handlerState = 0;
private BluetoothAdapter btAdapter = null;
private BluetoothSocket btSocket = null;
private StringBuilder DataStringIN = new StringBuilder();
private ConnectedThread MyConnection;
// Special service - SPP UUID
private static final UUID BTMODULE_UUID = UUID.fromString
("00001101-0000-1000-8000-00211300ACCD"); //805F9B34FB
// String direction of the MAC
private static String address = null;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_user_interface);
// Connection between inferface and variables
IdLedON = (Button) findViewById(R.id.IdLedON);
IdLedOFF = (Button) findViewById(R.id.IdLedOFF);
IdDisconnect = (Button) findViewById(R.id.IdDisconnect);
IdBuffer = findViewById(R.id.IdBuffer);
bluetoothIn = new Handler(){
public void handleMessage(android.os.Message msg){
if (msg.what == handlerState) {
String readMessage = (String) msg.obj;
DataStringIN.append(readMessage);
int endOfLineIndex = DataStringIN.indexOf("#");
if (endOfLineIndex > 0) {
String dataInPrint = DataStringIN.substring(0, endOfLineIndex);
IdBuffer.setText("Data: " + dataInPrint);
DataStringIN.delete(0, DataStringIN.length());
}
}
}
};
btAdapter = BluetoothAdapter.getDefaultAdapter();
VerificationBT();
IdLedON.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
MyConnection.write("1");
}
});
IdLedOFF.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
MyConnection.write("0");
}
});
IdDisconnect.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
if (btSocket != null)
{
try {
btSocket.close();
} catch (IOException e) {
Toast.makeText(getBaseContext(), "Error", Toast.LENGTH_SHORT).show();;}
}
finish();
}
});
}
private BluetoothSocket createBluetoothSocket(BluetoothDevice device) throws IOException
{
// Creates a save Connection for the device
return device.createRfcommSocketToServiceRecord(BTMODULE_UUID);
}
#Override
public void onResume()
{
super.onResume();
// Receives MAC Adress Direction out of DeviceListActivity via intent
Intent intent = getIntent();
// Receives MAC Adress Direction out of DeviceListActivity via EXTRA
address = intent.getStringExtra(Bluetooth.EXTRA_DEVICE_ADDRESS);
// adjust MAC Adress
BluetoothDevice device = btAdapter.getRemoteDevice(address);
try
{
btSocket = createBluetoothSocket(device);
} catch (IOException e) {
Toast.makeText(getBaseContext(), "Error while Connection with device accured ", Toast.LENGTH_SHORT).show();
}
// Creates a connection with bluetooth
try
{
btSocket.connect();
} catch (IOException e){
try{
btSocket.close();
} catch (IOException e2){}
}
MyConnection = new ConnectedThread(btSocket);
MyConnection.start();
}
#Override
public void onPause()
{
super.onPause();
try
{
// If you leave the application there can be no access to the bluetooth adapter
btSocket.close();
} catch (IOException e2){}
}
// Check if bluetooth device is available and connect with it
private void VerificationBT()
{
if (btAdapter == null) {
Toast.makeText(getBaseContext(), "Device doesn't support bluetooth", Toast.LENGTH_LONG);
} else {
Intent enableBt = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableBt, 1);
}
}
// class for making a connection
private class ConnectedThread extends Thread
{
private final InputStream myInStream;
private final OutputStream myOutStream;
public ConnectedThread(BluetoothSocket socket)
{
InputStream tmpIn=null;
OutputStream tmpOut=null;
try
{
tmpIn = socket.getInputStream();
tmpOut = socket.getOutputStream();
} catch (IOException e) {}
myInStream=tmpIn;
myOutStream=tmpOut;
}
public void run()
{
byte[] buffer = new byte[256];
int bytes;
// Device stays in the "try to connect" mode
while(true) {
try {
bytes = myInStream.read(buffer);
String readMessage = new String(buffer, 0, bytes);
} catch (IOException e) {
break;
}
}
}
public void write(String input)
{
try{
myOutStream.write(input.getBytes());
} catch (IOException e)
{
// If it is not possible to send data
Toast.makeText(getBaseContext(), " Connection failed", Toast.LENGTH_LONG).show();
finish();
}
}
}
}
So if you need for information, just tell me.
Hopefully someone of you understands my problem and can help me :)
Best wishes
Semi
Seems like there is an error in the code.
This error:
android.app.ActivityThread.handleResumeActivity
Appeared way too many times which means and activity froze or crashed and then tried to restart but kept on failing so many times it just gave up in the end.
Also, it looks like your using a VM to test the code so try using it with a real device.
If you cant find out the problem try writing the code from the start again or run it through a bug interpreter.
Best of luck,
Paul!
hello im having stuck after i sending data from esp8266
i connected esp8266 with my arduino
this is my arduino code
#include <SoftwareSerial.h>
//#include <OneWire.h>
//#include <DallasTemperature.h>
//#include <stdlib.h>
//#include "Wire.h"
//#define DS3231_I2C_ADDRESS 0x68
//#define ONE_WIRE_BUS 5
//WIFI
#include <SPI.h>
#include <WiFi.h>
// Setup a oneWire instance to communicate with any OneWire devices (not just Maxim/Dallas temperature ICs)
//OneWire oneWire(ONE_WIRE_BUS);
// Pass our oneWire reference to Dallas Temperature.
//DallasTemperature sensors(&oneWire);
int wifiTx = 4;
int wifiRx = 3;
#define DEBUG true
char com;
String data;
SoftwareSerial wifi(wifiTx, wifiRx);
//wifi
char ssid[] = "waifu"; // your network SSID (name)
char pass[] = "chronoangel"; // your network password
//int status = WL_IDLE_STATUS; // the Wifi radio's status
void setup() {
// put your setup code here, to run once:
Wire.begin();
Serial.begin(9600);
wifi.begin(115200);
sensors.begin();
//sekon, menit,jam, day of week, hari, bulan taun
//setDS3231time(0,15,2,1,13,7,16);
//\start_wifi();
esp();
}
void loop() {
test_wifi();
//loop_esp();
}
void esp()
{
sendCommand("AT\r\n",2000,DEBUG);
sendCommand("AT+RST\r\n",2000,DEBUG); // reset module
sendCommand("AT+CWMODE=1\r\n",1000,DEBUG); // configure as access point
sendCommand("AT+CWJAP=\"waifu\",\"chronoangel\"\r\n",3000,DEBUG);
delay(10000);
//Serial.println("\nCek IP");
//sendCommand("AT+CIFSR\r\n",1000,DEBUG); // get ip address
sendCommand("AT+CIPMUX=1\r\n",1000,DEBUG); // configure for multiple connections
Serial.println("\nGet PORT");
sendCommand("AT+CIPSERVER=1,80\r\n",1000,DEBUG); // turn on server on port 80
Serial.println("\nSet IP");
sendCommand("AT+CIPSTA=\"192.168.1.7\"\r\n",1000,DEBUG); // set ip address
sendCommand("AT+CIFSR\r\n",1000,DEBUG); // get ip address
Serial.println("\nServer Ready");
}
void test_wifi()
{
if(wifi.available())
{
char toSend = (char)wifi.read();
Serial.print(toSend);
}
//Read from usb serial to wifi
if(Serial.available())
{
char toSend = (char)Serial.read();
wifi.print(toSend);
}
}
and this is my android studio code
package com.example.chronoangel.myapplication;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.Socket;
import java.net.UnknownHostException;
import android.os.AsyncTask;
import android.app.Activity;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
public class MainActivity extends AppCompatActivity {
TextView textResponse;
EditText editTextAddress, editTextPort;
Button buttonConnect, buttonClear;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
editTextAddress = (EditText) findViewById(R.id.IP);
editTextPort = (EditText) findViewById(R.id.Port);
buttonConnect = (Button) findViewById(R.id.connect);
//buttonClear = (Button)findViewById(R.id.clear);
textResponse = (TextView) findViewById(R.id.textData);
buttonConnect.setOnClickListener(buttonConnectOnClickListener);
}
OnClickListener buttonConnectOnClickListener = new OnClickListener(){
#Override
public void onClick(View arg0) {
MyClientTask myClientTask = new MyClientTask(editTextAddress.getText().toString(), Integer.parseInt(editTextPort.getText().toString()));
myClientTask.execute();
}};
//class to get data from esp8266
public class MyClientTask extends AsyncTask<Void, Void, Void> {
String dstAddress;
int dstPort;
String response = "";
MyClientTask(String addr, int port) {
dstAddress = addr;
dstPort = port;
}
#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);
}
}
}
this is my view of my program :
my problem is similiar to this page :
http://stackoverflow.com/questions/34274774/esp8266-wifi-server-to-android-client
but i think in there didnt have clue either how to reconnected after send a data
the program run after i click connect on android app
in my serial arduino after i send AT+ COMMAND
AT+CIPSEND = 0,2
then i send data "ab" to my android
the data was not send, but if ii send AT+COMMAND
AT+CIPCLOSE=0
the data was send,but i must click connect again to get the data from esp
my question is can we get continous data after click connect ?
how suppose i do with the android to connect again after arduino send a message ?
This is more an advice than an answer, because I think there is no other way than to close the connection everytime.
But i highly recommend to use your own Software for your ESP8266 rather than to use the AT-Commands. They are nice for the start, to connect to a network and so on. But they are limited. Since you're using arduino allready, i would suggest to use the IDE to write some code for your ESP.
You can find a lot of code and help here.
https://create.arduino.cc/projecthub/Metavix/programming-the-esp8266-with-the-arduino-ide-in-3-simple-601c16
And the ESP8266WiFi.h offers a lot of functions that are ready to use.
I want to send a UDP message from PC(server) to my android phone 4.2(client) using WIFI connection. My phone and PC are connected via wireless router. But no message is received from phone to mobile.
I have understood from debugging that the program is waiting at socket.receive(packet);. So, there is no update on the UI.
I want to show message to the UI when server received a message from client and this process will be continue.
I would be grateful, if you could help me. Thank you. I have added necessary permission.
server:
package com.example.abuttontest;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import android.app.Activity;
import android.os.Bundle;
import android.provider.Settings.System;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
public class MainActivity extends Activity
{
private TextView tv;
int i =0;
// String s;
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button button1 = (Button) findViewById(R.id.button1);
tv = (TextView) findViewById(R.id.textView1);
//TextView textMessage = (TextView) findViewById(R.id.textView2);
button1.setOnClickListener(new OnClickListener()
{
#Override
public void onClick(View v)
{
/*cheack ping message*/
//boolean morgan= isOnline();
//String s = String.valueOf(morgan);
tv.setText("kkkkkkkkkk"); // print ping message
Log.d("MyTag#","This is sample log message");
}
});
/* Thread for receiving Data from CLient */
runThread();
}
private void runThread()
{
new Thread()
{
public void run()
{
Log.d("p2p", "1");
while (i++ < 1000)
{
Log.d("p2p", "2");
try {
/////////////////////
//System.out.println("aaa");
byte[] inbuf = new byte[1000]; // default size
DatagramPacket packet = new DatagramPacket(inbuf, inbuf.length);
Log.d("p2p", "3");
DatagramSocket socket = new DatagramSocket(6000);
socket.receive(packet);
Log.d("p2p", "4");
int numBytesReceived = packet.getLength();
//System.out.println(numBytesReceived);
String s = new String(inbuf);
//System.out.println(s);
//System.out.println(inbuf[2]);
socket.close();
Log.d("p2p", "5");
runOnUiThread(new Runnable()
{
#Override
public void run()
{
tv.setText("#" + i);
}
});
Thread.sleep(300);
}
catch (InterruptedException e)
{
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}.start();
}
#Override
public boolean onCreateOptionsMenu(Menu menu)
{
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item)
{
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
if (id == R.id.one)
{
Toast.makeText(getApplicationContext(), "Toast Message ONE", Toast.LENGTH_LONG).show();
}
if (id == R.id.two)
{
Toast.makeText(getApplicationContext(), "Toast Message TWO", Toast.LENGTH_LONG).show();
}
if (id == R.id.action_settings)
{
return true;
}
return super.onOptionsItemSelected(item);
}
}
client:
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
/*packets in the IP layer are called the datagrams */
/*After creating a packet, the process of sending or receiving it involves calling the send or receive method of DatagramSocket. More specifically, you create a packet, then you create a socket. After you create the socket, you call the send method of DatagramSocket to send the datagram packet or use the receive method of DatagramSocket to receive a packet. You can also use the same DatagramSocket to send and receive multiple packets, each going to different destinations and coming from different sources.*/
public class client
{
public static void main(String args[])
{
System.out.println("from client");
try{
//InetAddress ipaddress = InetAddress.getByName("localhost");
// InetAddress ipaddress = InetAddress.getByName("192.168.0.103");
// while(true)
// {
InetAddress ipaddress = InetAddress.getByName("192.168.0.102");
int port = 6000;
//byte[] buffer = new byte[1024]; // empty byte array
String msg ="hello goooooooogle"; // send this message to the server
byte [] b_array = msg.getBytes();
//on SERVER side DatagramSocket able to receive packets on 8080 port
DatagramPacket packet = new DatagramPacket(b_array, b_array.length, ipaddress, port);// DatagramPacket(byte[], byte_length, InetAddress, port_number)
DatagramSocket socket = new DatagramSocket();
socket.send(packet);
socket.close();
// }
}
catch(Exception e)
{
System.out.println(e);
}
}
}
In your MainActivity you have not mentioned the port number which your server has to listen on.
Most of the network socket examples I found for Android were one directional only. I needed a solution for a bi-directional data stream. I eventually learned of the AsyncTask. This example shows how to get data from a socket and send data back to it. Due to the blocking nature of a socket that is receiving data, that blocking needs to run in a thread other than the UI thread.
For the sake of example, this code connects to a webserver. Pressing the "Start AsyncTask" button will open the socket. Once the socket is open, the web server waits for a request. Pressing the "Send Message" button will send a request to the server. Any response from the server will be displayed in the TextView. In the case of http, a web server will disconnect from the client once all the data has been sent. For other TCP data streams, the connection will stay up until one side disconnects.
Screenshot:
AndroidManifest.xml:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.exampleasynctask"
android:versionCode="1"
android:versionName="1.0">
<uses-sdk android:minSdkVersion="8" />
<uses-permission android:name="android.permission.INTERNET" />
<application android:icon="#drawable/icon" android:label="#string/app_name">
<activity android:name=".MainActivity"
android:label="#string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
res\layout\main.xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<Button android:id="#+id/btnStart" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Start AsyncTask"></Button>
<Button android:id="#+id/btnSend" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Send Message"></Button>
<TextView android:id="#+id/textStatus" android:textSize="24sp" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="Status Goes Here" />
</LinearLayout>
src\com.exampleasynctask\MainActivity.java:
package com.exampleasynctask;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.SocketAddress;
import android.app.Activity;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
public class MainActivity extends Activity {
Button btnStart, btnSend;
TextView textStatus;
NetworkTask networktask;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
btnStart = (Button)findViewById(R.id.btnStart);
btnSend = (Button)findViewById(R.id.btnSend);
textStatus = (TextView)findViewById(R.id.textStatus);
btnStart.setOnClickListener(btnStartListener);
btnSend.setOnClickListener(btnSendListener);
networktask = new NetworkTask(); //Create initial instance so SendDataToNetwork doesn't throw an error.
}
private OnClickListener btnStartListener = new OnClickListener() {
public void onClick(View v){
btnStart.setVisibility(View.INVISIBLE);
networktask = new NetworkTask(); //New instance of NetworkTask
networktask.execute();
}
};
private OnClickListener btnSendListener = new OnClickListener() {
public void onClick(View v){
textStatus.setText("Sending Message to AsyncTask.");
networktask.SendDataToNetwork("GET / HTTP/1.1\r\n\r\n");
}
};
public class NetworkTask extends AsyncTask<Void, byte[], Boolean> {
Socket nsocket; //Network Socket
InputStream nis; //Network Input Stream
OutputStream nos; //Network Output Stream
#Override
protected void onPreExecute() {
Log.i("AsyncTask", "onPreExecute");
}
#Override
protected Boolean doInBackground(Void... params) { //This runs on a different thread
boolean result = false;
try {
Log.i("AsyncTask", "doInBackground: Creating socket");
SocketAddress sockaddr = new InetSocketAddress("192.168.1.1", 80);
nsocket = new Socket();
nsocket.connect(sockaddr, 5000); //10 second connection timeout
if (nsocket.isConnected()) {
nis = nsocket.getInputStream();
nos = nsocket.getOutputStream();
Log.i("AsyncTask", "doInBackground: Socket created, streams assigned");
Log.i("AsyncTask", "doInBackground: Waiting for inital data...");
byte[] buffer = new byte[4096];
int read = nis.read(buffer, 0, 4096); //This is blocking
while(read != -1){
byte[] tempdata = new byte[read];
System.arraycopy(buffer, 0, tempdata, 0, read);
publishProgress(tempdata);
Log.i("AsyncTask", "doInBackground: Got some data");
read = nis.read(buffer, 0, 4096); //This is blocking
}
}
} catch (IOException e) {
e.printStackTrace();
Log.i("AsyncTask", "doInBackground: IOException");
result = true;
} catch (Exception e) {
e.printStackTrace();
Log.i("AsyncTask", "doInBackground: Exception");
result = true;
} finally {
try {
nis.close();
nos.close();
nsocket.close();
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
Log.i("AsyncTask", "doInBackground: Finished");
}
return result;
}
public void SendDataToNetwork(String cmd) { //You run this from the main thread.
try {
if (nsocket.isConnected()) {
Log.i("AsyncTask", "SendDataToNetwork: Writing received message to socket");
nos.write(cmd.getBytes());
} else {
Log.i("AsyncTask", "SendDataToNetwork: Cannot send message. Socket is closed");
}
} catch (Exception e) {
Log.i("AsyncTask", "SendDataToNetwork: Message send failed. Caught an exception");
}
}
#Override
protected void onProgressUpdate(byte[]... values) {
if (values.length > 0) {
Log.i("AsyncTask", "onProgressUpdate: " + values[0].length + " bytes received.");
textStatus.setText(new String(values[0]));
}
}
#Override
protected void onCancelled() {
Log.i("AsyncTask", "Cancelled.");
btnStart.setVisibility(View.VISIBLE);
}
#Override
protected void onPostExecute(Boolean result) {
if (result) {
Log.i("AsyncTask", "onPostExecute: Completed with an Error.");
textStatus.setText("There was a connection error.");
} else {
Log.i("AsyncTask", "onPostExecute: Completed.");
}
btnStart.setVisibility(View.VISIBLE);
}
}
#Override
protected void onDestroy() {
super.onDestroy();
networktask.cancel(true); //In case the task is currently running
}
}
The SendDataToNetwork task runs in the main ui thread, meaning it will crash a Honeycomb or higher app due to NetworkOnMainThreadException Fatal exception. Here's what my SendDataToNetwork looks like to avoid this issue:
public boolean sendDataToNetwork(final byte[] cmd) {
if (_nsocket.isConnected()) {
Log.i(TAG, "SendDataToNetwork: Writing received message to socket");
new Thread(new Runnable() {
public void run() {
try {
_nos.write(cmd);
} catch (Exception e) {
e.printStackTrace();
Log.i(TAG, "SendDataToNetwork: Message send failed. Caught an exception");
}
}
}).start();
return true;
}
Log.i(TAG, "SendDataToNetwork: Cannot send message. Socket is closed");
return false;
}
Your SendDataToNetwork does not run on the same thread as doInBackground(). There is a possibility that SendDataToNetwork would start sending data before socket is ready.
To avoid all this just use SendDataToNetwork to save data and signal to background thread that data is ready to be sent.
Since there is possibility that user can press button multiple times, while the old data is still being sent, you should have synchronized Queue inside NetworkTask. Then:
Background thread sets up the socket connection and then goes to sleep (via wait()).
On button press, SendDataToNetwork adds data to queue and wakes up the background thread (via notify()).
When background thread wakes up, it first checks the finish flag. If set, it closes connections and exits. If not it reads data from Queue, sends it to network and goes back to sleep.
You should have finish() method which sets a finish flag (atomic variable, like boolean) and wakes the background thread. This is a way to gracefully exit the background thread.
Take a look at how thread synchronization is done: http://www.jchq.net/tutorial/07_03Tut.htm
More interactive example
Similar to the OP's, but you can control host, port and message + there is a popup error notification if the connection failed.
Usage 1:
get Android and a Linux desktop on a LAN
find the IP of the desktop with ifconfig
run netcat -l 12345 on a terminal
on Android, fill in the IP of the desktop
click contact server
on the terminal, type the reply, and hit Ctrl + D
it appears on the output: section
Usage 2:
hostname google.com
port 80
Message: "GET / HTTP/1.1\r\nHost: google.com\r\n\r\n"
Note that some HTTP servers won't close after the reply expecting further requests, and the application will hang until they timeout. Such servers expect you to parse the Content-Width header and close yourself.
If the connection fails, an alert message is shown to the user on a dialog.
Code
Add to AndroidManifest.xml:
<uses-permission android:name="android.permission.INTERNET" />
And the main activity is:
import android.app.Activity;
import android.app.AlertDialog;
import android.app.IntentService;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.ScrollView;
import android.widget.TextView;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
public class Main extends Activity {
final static String TAG = "AndroidCheatSocket";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
final LinearLayout linearLayout = new LinearLayout(this);
linearLayout.setOrientation(LinearLayout.VERTICAL);
TextView textView;
final String defaultHostname = "192.168.0.";
textView = new TextView(this);
textView.setText("hostname / IP:");
linearLayout.addView(textView);
final EditText hostnameEditText = new EditText(this);
hostnameEditText.setText(defaultHostname);
hostnameEditText.setSingleLine(true);
linearLayout.addView(hostnameEditText);
textView = new TextView(this);
textView.setText("port:");
linearLayout.addView(textView);
final EditText portEditText = new EditText(this);
portEditText.setText("12345");
portEditText.setSingleLine(true);
linearLayout.addView(portEditText);
textView = new TextView(this);
textView.setText("data to send:");
linearLayout.addView(textView);
final EditText dataEditText = new EditText(this);
dataEditText.setText(String.format("GET / HTTP/1.1\r\nHost: %s\r\n\r\n", defaultHostname));
linearLayout.addView(dataEditText);
final TextView replyTextView = new TextView(this);
final ScrollView replyTextScrollView = new ScrollView(this);
replyTextScrollView.addView(replyTextView);
final Button button = new Button(this);
button.setText("contact server");
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
button.setEnabled(false);
new MyAsyncTask(Main.this, replyTextView, button).execute(
hostnameEditText.getText().toString(),
portEditText.getText().toString(),
dataEditText.getText().toString());
}
});
linearLayout.addView(button);
textView = new TextView(this);
textView.setText("output:");
linearLayout.addView(textView);
linearLayout.addView(replyTextScrollView);
this.setContentView(linearLayout);
}
private class MyAsyncTask extends AsyncTask<String, Void, String> {
Activity activity;
Button button;
TextView textView;
IOException ioException;
MyAsyncTask(Activity activity, TextView textView, Button button) {
super();
this.activity = activity;
this.textView = textView;
this.button = button;
this.ioException = null;
}
#Override
protected String doInBackground(String... params) {
StringBuilder sb = new StringBuilder();
try {
Socket socket = new Socket(
params[0],
Integer.parseInt(params[1]));
OutputStream out = socket.getOutputStream();
out.write(params[2].getBytes());
InputStream in = socket.getInputStream();
byte buf[] = new byte[1024];
int nbytes;
while ((nbytes = in.read(buf)) != -1) {
sb.append(new String(buf, 0, nbytes));
}
socket.close();
} catch(IOException e) {
this.ioException = e;
return "error";
}
return sb.toString();
}
#Override
protected void onPostExecute(String result) {
if (this.ioException != null) {
new AlertDialog.Builder(this.activity)
.setTitle("An error occurrsed")
.setMessage(this.ioException.toString())
.setIcon(android.R.drawable.ic_dialog_alert)
.show();
} else {
this.textView.setText(result);
}
this.button.setEnabled(true);
}
}
}
On GitHub with build boilerplate.
I've also posted an Android server example at: https://stackoverflow.com/a/35745834/895245
Tested on Android 5.1.1, Sony Xperia 3 D6643.