I'm building an app in Android to communicate with Arduino via usb.
In Android, I create a button to send data to the Arduino. The Arduino should then respond to this message and send another message to be treated in the function of the same button. The problem is that when I click on the button the app stops.
My Arduino code:
void setup()
{
Serial.begin(9600);
}
void loop()
{
char c;
int i = 0;
if(Serial.available()){
c=Serial.read();
if (c == '4'){
Serial.write("X:100 Y:10");
}
}
}
Defining a Callback which triggers whenever data is read in Android:
UsbSerialInterface.UsbReadCallback mCallback = new UsbSerialInterface.UsbReadCallback() {
#Override
public void onReceivedData(byte[] arg0) {
String data = null;
try {
data = new String(arg0, "UTF-8");
data.concat("\n");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
};
The button function in Android is:
public void goBefore(View view) {
ssend = "M114"; // send message to update current position
serialPort.write(ssend.getBytes());
String[] current_Pos = data.split(" ");
Do you know what I'm doing wrong?
Related
first of all excuse my english, because i am not good in english. I'm looking for a way to retrieve information in android send from a nodeJS server with socket io. I have the impression that it is a problem of version. my code compiles very well, I do not manage to retrieve the information contained in a JS object.
here is the server code
var app = require('express')();
var http = require('http').Server(app);
var io = require('socket.io')(http);
var data ={"msg": "hello i am the server"};
io.on('connection',function(socket){
console.log('one user connected '+socket.id);
socket.on('message',function(obj){
console.log(obj.text);
socket.emit('take', data);
})
socket.on('disconnect',function(){
console.log('one user disconnected '+socket.id);
})
})
http.listen(3000,function(){
console.log('server listening on port 3000');
})
the information I'm looking for is 'data'
here is the java code I use, I prefer to put the whole code in case the problem is elsewhere
public class MainActivity extends AppCompatActivity {
private Socket socket;
public String ReceiveMsg ="message par defaut ";
{
try {
socket = IO.socket("http://192.168.43.168:3000");
socket.connect();
} catch (URISyntaxException e) {
}
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
EditText editText = (EditText) findViewById(R.id.editText);
TextView textView = (TextView) findViewById(R.id.textView);
Button but = (Button) findViewById(R.id.button);
socket.connect();
String msg = takemsg(editText);
sendMsg(msg);
socket.on("take", handleIncomingMessages);
textView.setText(getAz(ReceiveMsg));
}
public String takemsg(EditText editText){
String msg = "message par defaut ";
msg = editText.getText().toString();
return msg;
}
public void sendMsg(String msg ){
JSONObject obj = new JSONObject();
try{
obj.put("text", msg);
socket.emit("message", obj);
}catch (JSONException e){
}
}
private Emitter.Listener handleIncomingMessages = new Emitter.Listener(){
#Override
public void call(final Object... args){
runOnUiThread(new Runnable() {
#Override
public void run() {
JSONObject data = (JSONObject) args[0];
try {
ReceiveMsg = data.getString("msg");
} catch (JSONException e) {
}
}
});
}
};
}
First I think we need more data.
What are the outputs of the server? Is connecting well?, check if your code in android is running.
If it's not connecting try setting the port with opts
...
try {
IO.Options opts = IO.Options();
opts.port = 3000;
socket = IO.socket("http://192.168.43.168", opts);
socket.connect();
} catch (URISyntaxException e) {
...
check if your service is alive. for services exists some returns that allows to maintain your service working.
https://developer.android.com/reference/android/app/Service.html#START_STICKY
we must put in the manifest
<uses-permission android:name="android.permission.INTERNET" />
to allow the application to use the network
I am trying to communicate between a C# TCP server, and an Android TCP client. I am new to android so used the second part of this tutorial to create the android client:
http://www.myandroidsolutions.com/2012/07/20/android-tcp-connection-tutorial/#.V8uZISgrKUk
Everything works fine, and I can send little text messages between my phone and my computer, however this tutorial requires that the client app have the server IP hard coded into the program, and for obvious reasons this is going to cause issues if I actually wanted to make an app that uses this.
Outside of this tutorial I have added a second EditText ("#id/ipTxt") and a second button ("#id/setIp")
As I don't want to make anybody read through the whole tutorial, here are the important parts summarized:
Main Activity:
public class MyActivity extends Activity
{
private ListView mList;
private ArrayList<String> arrayList;
private MyCustomAdapter mAdapter;
private TCPClient mTcpClient;
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
arrayList = new ArrayList<String>();
final EditText editText = (EditText) findViewById(R.id.editText);
Button send = (Button)findViewById(R.id.send_button);
//relate the listView from java to the one created in xml
mList = (ListView)findViewById(R.id.list);
mAdapter = new MyCustomAdapter(this, arrayList);
mList.setAdapter(mAdapter);
// connect to the server
new connectTask().execute("");
send.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
String message = editText.getText().toString();
//add the text in the arrayList
arrayList.add("c: " + message);
//sends the message to the server
if (mTcpClient != null) {
mTcpClient.sendMessage(message);
}
//refresh the list
mAdapter.notifyDataSetChanged();
editText.setText("");
}
});
}
public class connectTask extends AsyncTask<String,String,TCPClient> {
#Override
protected TCPClient doInBackground(String... message) {
//we create a TCPClient object and
mTcpClient = new TCPClient(new TCPClient.OnMessageReceived() {
#Override
//here the messageReceived method is implemented
public void messageReceived(String message) {
//this method calls the onProgressUpdate
publishProgress(message);
}
});
mTcpClient.run();
return null;
}
#Override
protected void onProgressUpdate(String... values) {
super.onProgressUpdate(values);
//in the arrayList we add the messaged received from server
arrayList.add(values[0]);
// notify the adapter that the data set has changed. This means that new message received
// from server was added to the list
mAdapter.notifyDataSetChanged();
}
}
}
TCPClient class:
public class TCPClient {
private String serverMessage;
public static final String SERVERIP = "192.168.0.102"; //your computer IP address
public static final int SERVERPORT = 4444;
private OnMessageReceived mMessageListener = null;
private boolean mRun = false;
PrintWriter out;
BufferedReader in;
/**
* Constructor of the class. OnMessagedReceived listens for the messages received from server
*/
public TCPClient(OnMessageReceived listener) {
mMessageListener = listener;
}
/**
* Sends the message entered by client to the server
* #param message text entered by client
*/
public void sendMessage(String message){
if (out != null && !out.checkError()) {
out.println(message);
out.flush();
}
}
public void stopClient(){
mRun = false;
}
public void run() {
mRun = true;
try {
//here you must put your computer's IP address.
InetAddress serverAddr = InetAddress.getByName(SERVERIP);
Log.e("TCP Client", "C: Connecting...");
//create a socket to make the connection with the server
Socket socket = new Socket(serverAddr, SERVERPORT);
try {
//send the message to the server
out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())), true);
Log.e("TCP Client", "C: Sent.");
Log.e("TCP Client", "C: Done.");
//receive the message which the server sends back
in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
//in this while the client listens for the messages sent by the server
while (mRun) {
serverMessage = in.readLine();
if (serverMessage != null && mMessageListener != null) {
//call the method messageReceived from MyActivity class
mMessageListener.messageReceived(serverMessage);
}
serverMessage = null;
}
Log.e("RESPONSE FROM SERVER", "S: Received Message: '" + serverMessage + "'");
} catch (Exception e) {
Log.e("TCP", "S: Error", e);
} finally {
//the socket must be closed. It is not possible to reconnect to this socket
// after it is closed, which means a new socket instance has to be created.
socket.close();
}
} catch (Exception e) {
Log.e("TCP", "C: Error", e);
}
}
//Declare the interface. The method messageReceived(String message) will must be implemented in the MyActivity
//class at on asynckTask doInBackground
public interface OnMessageReceived {
public void messageReceived(String message);
}
}
My theory would be to stop the connectTask process every time the "setIp" button is clicked and create a new one, but that seems like a very inefficient way to do it, plus I don't know how I would go about doing that :(
Any Ideas?
Change your SERVERIP and SERVERPORT constants into non-static variables instead, and then initialize them using additional input values to your TCPClient constructor, or as input parameters to AsyncTask.execute() (which will then be passed as input parameters to your doInBackground() method).
Don't call execute() until you have first determined those values, either from your app's stored configuration, or from the user in the UI.
When you do start a new task, save the object to a variable in your main code (which you are not currently doing). To cancel the connection, you can then call the AsyncTask.cancel() method on that variable. Make sure your connectTask.doInBackground() and TCPClient.run() code checks the AsyncTask.isCancelled() method periodically so they can exit as soon as possible when it returns true. This technique is mentioned in the AsyncTask documentation.
After the connectTask object finishes running, you can create a new one with different input values.
I am basically trying to send a message from my android to my server and the server to send back a response to my android app. I followed THIS tutorial.
Just a simple exercise to introduce myself in to SignalR using Azure Web API and Android.
My Complete Server code in C#:
public class TestHub: Hub {
public void SendMessage(string name, string message) {
// Call the broadcastMessage method to update clients.
Clients.All.broadcastMessage(name, message);
}
public void SendClientMessage(CustomType obj) {
Clients.All.broadcastMessage("From Server", "Server got the message bro");
}
public class CustomType {
public string Name;
public int Id;
}
}
Complete Android Java code:
public class MainActivity extends AppCompatActivity {
Handler handler;
TextView statustext;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
handler = new Handler();
statustext = (TextView) findViewById(R.id.status);
Platform.loadPlatformComponent(new AndroidPlatformComponent());
// Change to the IP address and matching port of your SignalR server.
String host = "https://My-Service-name.azure-mobile.net/";
HubConnection connection = new HubConnection(host);
HubProxy hub = connection.createHubProxy("TestHub");
SignalRFuture < Void > awaitConnection = connection.start();
try {
awaitConnection.get();
} catch (InterruptedException e) {
} catch (ExecutionException e) {
}
hub.subscribe(this);
try {
hub.invoke("SendMessage", "Client", "Hello Server!").get();
hub.invoke("SendClientMessage",
new CustomType() {
{
Name = "Android Homie";
Id = 42;
}
}).get();
} catch (InterruptedException e) {
} catch (ExecutionException e) {
}
}
//I have no idea what the following method is for. Just followed the tutorial.. (blindly)
public void UpdateStatus(String status) {
final String fStatus = status;
handler.post(new Runnable() {
#Override
public void run() {
statustext.setText(fStatus);
}
});
}
public class CustomType {
public String Name;
public int Id;
}
}
Problems with this:
1. I get an exception:
java.util.concurrent.ExecutionException:
microsoft.aspnet.signalr.client.transport.NegotiationException: There
was a problem in the negotiation with the server
2. I feel like I haven't properly called the server from the Java code.
Should the URL be:
https://My-Service-name.azure-mobile.net/
or
https://My-Service-name.azure-mobile.net/api/signalr
Can someone clarify these doubts and help me set it up?
i am making an android socket app to communicate with the server for creating accounts, and i noticed i have to do this in AsyncTask sub class, even when i seperate it to another class without UI,but i am terribly confused how can i use AsyncTask on this, is there any one expert here who can help me please?
this is the code:
public class AccountCreator extends Activity {
public AccountCreator(){
super();
}
// for I/O
ObjectInputStream sInput; // to read from the socket
ObjectOutputStream sOutput; // to write on the socket
Socket socket;
public static String LOGTAG="Lifemate";
public String server = "localhost";
public String username = "user";
public String password = "rezapassword" ;
public int port = 1400;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.i(LOGTAG,"oncreate called");
this.start();
}
AccountCreator(String server, int port, String username,String password) {
this.server = "localhost";
this.port = 1400;
this.username = username;
Log.i(LOGTAG,"first accountcreator called");
}
public boolean start() {
// try to connect to the server
//this method returns a value of true or false when called
try {
socket = new Socket(server, port);
}
// if it failed not much I can so
catch(Exception ec) {
// display("Error connectiong to server:" + ec);
Log.i(LOGTAG,"Error connectiong to server:" + ec);
return false;
}
String msg = "Connection accepted " + socket.getInetAddress() + ":" +
socket.getPort();
// display(msg);
Log.i(LOGTAG, msg);
/* Creating both Data Stream */
try
{
sInput = new ObjectInputStream(socket.getInputStream());
sOutput = new ObjectOutputStream(socket.getOutputStream());
}
catch (IOException eIO) {
// display("Exception creating new Input/output Streams: " + eIO);
Log.i(LOGTAG,"Exception creating new Input/output Streams: " +
eIO);
return false;
}
// creates the Thread to listen from the server
// Send our username to the server this is the only message that we
// will send as a String. All other messages will be ChatMessage objects
try
{
sOutput.writeObject(username);
sOutput.writeObject(password);
}
catch (IOException eIO) {
// display("Exception doing login : " + eIO);
Log.i(LOGTAG,"Exception doing login : " + eIO);
disconnect();
return false;
}
// success we inform the caller that it worked
return true;
}
// private void display(String msg) {
// TextView screenprint = (TextView)findViewById(R.id.systemmessages);
// screenprint.setText(msg);
// }
private void disconnect() {
Log.i(LOGTAG,"reached disconnect");
try {
if(sInput != null) sInput.close();
}
catch(Exception e) {} // not much else I can do
try {
if(sOutput != null) sOutput.close();
}
catch(Exception e) {} // not much else I can do
try{
if(socket != null) socket.close();
}
catch(Exception e) {} // not much else I can do
}
public void Begin() {
Log.i(LOGTAG,"it begun");
int portNumber = 1400;
String serverAddress = server;
String userName = username;
String newpassword = password;
AccountCreator accountcreator = new AccountCreator(serverAddress, portNumber,
userName,password);
if(!accountcreator.start())
return;
}
}
i was trying to put whole code in Async, i dont know if was i right, do i need to do that also or just some parts of it?
In brief, AsyncTask contains a few methods which may be helpful:
onPreExecute:
This method is the first block of code executed when calling asyncTask.execute(); (runs on mainUIThread).
doInBackground:
Here you put all the code which may suspend you main UI (causes hang for your application) like internet requests, or any processing which may take a lot of memory and processing. (runs on background thread), contains one parameter taken from the asyncTask.execute(ParameterType parameter);
onPostExecute
Runs after doInBackground(). Its parameter is the return value of the doInBackground function, and mainly you put the changes in UI need to be done after the connection is finished (runs on mainUIThread)
You have to declare another class within the class you have already created.
class SomeName extends Async<Void, String, Void>{
protected void OnPreExecute(){
// starts the task runs on main UI thread
// Can be used to start a progress dialog to show the user progress
}
#Override
protected Void doInBackground(Void... params){
// does what you want it to do in the background
// Connected to the server to check a log-in
return result;
}
protected void OnPostExecute(Void result){
// finishes the task and can provide information back on the main UI thread
// this would be were you would dismiss the progress dialog
}
}
I want to use AsyncTask for receiving ArrayList's(in this case) from Java server. To be sure, that I received something from server I'm trying to display it with Toast.
The Code is following:
public class MainActivity extends Activity {
private DataReceiving dRec;
private DataTransfer dTrans;
private EditText inputData;
private Button sendParametersBtn;
private Button startComputationBtn;
private TextView displayText;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
inputData=(EditText) findViewById(R.id.InputText);
sendParametersBtn=(Button) findViewById(R.id.button1);
startComputationBtn=(Button) findViewById(R.id.button2);
displayText=(TextView) findViewById(R.id.textView1);
sendParametersBtn.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
dRec = new DataReceiving();
dRec.execute();
}
});
private class DataReceiving extends AsyncTask<Void, Void, ArrayList>
{
#Override
protected ArrayList doInBackground(Void... params) {
ArrayList b = new ArrayList();
try {
b = receive();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return b;
}
protected void onPostExecute(ArrayList result) {
super.onPostExecute(result);
Toast toast=Toast.makeText(getApplicationContext(), result.toString(), Toast.LENGTH_SHORT);
toast.show();
}
public ArrayList receive () throws IOException, ClassNotFoundException
{
ServerSocket s= new ServerSocket(8888);
Socket incoming =s.accept();
ObjectInputStream ios = new ObjectInputStream(incoming.getInputStream());
ArrayList b = (ArrayList) ios.readObject();
ios.close();
incoming.close();
s.close();
return b;
}
While clicking the sendParametersBtn nothing happening.
P.S. I can successfully transmit from Android to Server. So its not a connection or permission problem.
Thank you for help
Hi If your getting some thing from server you have to call web server url for fetching data. After data arrives response have some type it will JSON/XML if they are restful services if they are SOAP services they are in envelope. So after response return get that and parse them as per logic.
Look for HTTP get/post (for ping to server and get data )and parsing (JSON/XML).
Figured out! I removed receive method into doInBackground.