This question already has answers here:
NetworkOnMainThreadException [duplicate]
(5 answers)
Closed 7 years ago.
On Being a Duplicate: Please note that I have acknowledged other Q&As (Thread UI) but my case is different as I have tried to use the solution but it doesn't work at all instances (as it works for writing but doesn't for reading.
Updated: I know exactly what is going wrong please read the bold My Question part
I'm trying to make an Android Socket Client that connects to a Java server via WiFi.The final client will send and receive commands and logs as there will be a textbox that user can write SQL commands in it and by hitting a button command will be sent from the app to the Desktop server and show the log in another textbox.
so far I have been trying to use This Answer from another question to make that Client, and adding following lines in the TCP client.
Scanner in = new Scanner(socket.getInputStream());//in doInBackground
//also changed send method a little
public String send(String command)
{
if ( connected ){
out.println(command);
out.flush();
String back = in.nextLine().toString();
return back;
}
return "not Connected";
}
The connection is made successfully and the send method does send the command while server receives it.but the String that server writes back throw the mentioned exception in the title despite the fact that I am using the AsyncTask.
My Question
Why Scanner throws this exception while PrintWriter works correctly ?
Main Activity
import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
public class MainActivity extends ActionBarActivity {
EditText serverIP, servMsg;
String ip, serverOut;
Button connectBtn;
TcpClient tcpClient;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
serverIP = (EditText) findViewById(R.id.serverIP);
connectBtn = (Button) findViewById(R.id.connectBtn);
servMsg = (EditText) findViewById(R.id.servMsg);
}
public void onConnectBtn(View view){
try{
ip = serverIP.getText().toString();
tcpClient = new TcpClient();
tcpClient.connect(getApplicationContext(), ip, 8082);
serverOut = tcpClient.send("HELLO FROM cat:123");
servMsg.setText(serverOut);
tcpClient.disconnect(getApplicationContext());
}
catch (Exception e){
Toast.makeText(getApplicationContext(),
"Exception on runnning thread: " + e.getMessage().toString(), Toast.LENGTH_LONG).show();
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.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();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
}
TCP Client
import java.io.IOException;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.Scanner;
import android.content.Context;
import android.os.AsyncTask;
import android.os.Handler;
import android.util.Log;
import android.widget.Toast;
public class TcpClient {
private static final String TAG = TcpClient.class.getSimpleName();
private Socket socket;
private PrintWriter out;
private Scanner in;
private boolean connected;
public TcpClient() {
socket = null;
out = null;
connected = false;
}
public void connect(Context context, String host, int port) {
new ConnectTask(context).execute(host, String.valueOf(port));
}
private class ConnectTask extends AsyncTask<String, Void, Void> {
private Context context;
public ConnectTask(Context context) {
this.context = context;
}
#Override
protected void onPreExecute() {
showToast(context, "Connecting..");
super.onPreExecute();
}
#Override
protected void onPostExecute(Void result) {
if (connected) {
showToast(context, "Connection successful");
}
super.onPostExecute(result);
}
private String host;
private int port;
#Override
protected Void doInBackground(String... params) {
try {
String host = params[0];
int port = Integer.parseInt(params[1]);
socket = new Socket(host, port);
out = new PrintWriter(socket.getOutputStream(), true);
in = new Scanner(socket.getInputStream());
} catch (UnknownHostException e) {
showToast(context, "Don't know about host: " + host + ":" + port);
Log.e(TAG, e.getMessage());
} catch (IOException e) {
showToast(context, "Couldn't get I/O for the connection to: " + host + ":" + port);
Log.e(TAG, e.getMessage());
}
connected = true;
return null;
}
}
public void disconnect(Context context) {
if (connected) {
try {
out.close();
socket.close();
connected = false;
} catch (IOException e) {
showToast(context, "Couldn't get I/O for the connection");
Log.e(TAG, e.getMessage());
}
}
}
/**
* Send command to a Pure Data audio engine.
*/
public String send(String command)
{
if ( connected ){
out.println(command);
out.flush();
String back = in.nextLine().toString();
return back;
}
return "not Connected";
}
private void showToast(final Context context, final String message) {
new Handler(context.getMainLooper()).post(new Runnable() {
#Override
public void run() {
Toast.makeText(context, message, Toast.LENGTH_LONG).show();
}
});
}
}
Also the Layout right now consist of two TextEdits one in which user types IP of the computer(which I checked with correct IPs) and the second one is going to show Server response.
I believe you are not "flushing", which is essentially forcing the buffer to empty out its contents. Please take a look at this working chat server/client code that uses TCP/IP. On a side note, I would recommend not extending ActionBarActivity because it is deprecated (Google says they will move away from it and won't be supporting it soon). Please see 3rd link.
ChatServer.java
ChatClient.java
ActionBar Activity deprecation
Related
Currently, I have a server(python) and client(android). I am trying to send data from an android to server to another Android using socket. The problem is data looks fine in the server, but garbage value is included when an Android get the Data from server. If I varied the size of string, then it sometimes did not receive the data and after additional sendings, the weird garbage value was received. I think it was some kind of buffer related problem, but I could not figure out the exact problem.
This is output from server : outputFromServer
This is output from android : outputFromAndroid
This is server.py. I am getting data from a client and send it to other clients.
import socket
import time
import select
host = 'myIP' # Symbolic name meaning all available interfaces
port = myPortNumber # Arbitrary non-privileged port
server_sock = socket.socket(socket.AF_INET,socket.SOCK_STREAM)#socket.SOCK_STREAM
server_sock.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)#assure reconnect
server_sock.bind((host, port))
server_sock.listen(5)
print(server_sock)
sockets_list = [server_sock]#socket list... multiple clients
clients = {}#socket is the key, user Data will be value
print("Waiting")
def receive_message(client_socket):
try:
data = client_socket.recv(1024)
print("receive Message : " +data.decode('utf-8'))
#return data.decode('utf-8')
return {"data" : data}
except:
return False
while True:
read_sockets, _, exception_sockets = select.select(sockets_list, [], sockets_list)#read, write ,air on
for notified_socket in read_sockets:
if notified_socket == server_sock: #someone just connected
client_socket, client_address = server_sock.accept()
print(client_socket)
print(client_address)
user = receive_message(client_socket)
if user is False:
print("USER FALSE")
continue
sockets_list.append(client_socket)
clients[client_socket] = user
print("ACCEPTED connection")
else:
message = receive_message(notified_socket)
print("IN ELSE : " + message['data'].decode('utf-8'))
if message is False :
sockets_list.remove(notified_socket)
del clients[notified_socket]
continue
user = clients[notified_socket]
#share this message with everyBody
for client_socket in clients:
print("for loop")
if client_socket != notified_socket:
message_to_send = message['data']
client_socket.send(len(message_to_send).to_bytes(2, byteorder='big'))
client_socket.send(message_to_send)
for notified_socket in exception_sockets:
sockets_list.remove(notified_socket)
del clients[notified_socket]
Here is my Android(java) code for client
package com.example.testing;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.Socket;
import java.net.UnknownHostException;
public class ConnectTcp {
private String TAG = "tcp";
private DataOutputStream dos;
private DataInputStream dis;
private Socket socket;
private Thread socketThread;
public ConnectTcp() {
}//connectTcp
void sendMessage(final String message){
socketThread = new Thread() {
public void run(){
try {
if (Thread.interrupted()) { throw new InterruptedException();}
while(!Thread.currentThread().isInterrupted()) {
// ...
try {
socket = new Socket(remoteIP, port);
Log.e(TAG, "success");
}catch (IOException ioe) {
Log.e(TAG,"ERROR");
try {
dos = new DataOutputStream(socket.getOutputStream()); // output
dis = new DataInputStream(socket.getInputStream()); // inpu
dos.writeUTF("CONNECT TO SERVER : "+ message);
} catch (IOException e) {
e.printStackTrace();
}
while(true) {
try {
while (true) {
line = (String) dis.readUTF();
Log.w("------서버에서 받아온 값", "" + line);
}
} catch (Exception e) {
}
}
}
} catch (InterruptedException consumed){
/* Allow thread to exit */
}
}//run
};//Thread
socketThread.start();
}
void sendAdditionalMessage(final String data) throws IOException {
Thread sendMessageThread = new Thread() {
#Override
public void run() {
super.run();
try {
dos = new DataOutputStream(socket.getOutputStream());
dos.writeUTF(data);
} catch (IOException e) {
e.printStackTrace();
}
}
};
sendMessageThread.start();
}
void closeSocket() throws IOException {
socket.shutdownInput();
socket.shutdownOutput();
socket.close();
socketThread.interrupt();
}
}//class
This is MainActivity.java
package com.example.testing;
import androidx.appcompat.app.AppCompatActivity;
import android.content.Intent;
import android.os.Bundle;
import android.os.Looper;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import java.io.IOException;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.Timer;
import java.util.TimerTask;
import java.util.logging.Handler;
import okhttp3.FormBody;
import okhttp3.RequestBody;
public class MainActivity extends AppCompatActivity {
String getData;
TextView textView;
Button bt_connect;
Button bt_disConnect;
TextView tv_hanium;
int data = 10;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
bt_connect = findViewById(R.id.bt_connect);
bt_disConnect = findViewById(R.id.bt_cancel);
Button bt_goToLogin = findViewById(R.id.bt_goToLogin);
final Button bt_send = findViewById(R.id.bt_send);
final ConnectTcp connectTcp = new ConnectTcp();
bt_connect.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
connectTcp.sendMessage("hello world");//connect to server
}
});
bt_disConnect.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
try {
connectTcp.closeSocket();//close socket
} catch (IOException e) {
Log.d("tcp", "fail to close ");
e.printStackTrace();
}
}
});//데이터 전송 중단
bt_send.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
try {
connectTcp.sendAdditionalMessage("150");// send data
} catch (IOException e) {
e.printStackTrace();
}
}
});
bt_goToLogin.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent goToLogin = new Intent(MainActivity.this, LoginActivity.class);
MainActivity.this.startActivity(goToLogin);
}
});
}
}
The Java DataOutput.writeUTF method sends the length of the string it writes. If you don't want to modify the Java side, you have to modify your receive_message Python function to read the length field. Here's a start:
def receive_message(client_socket):
try:
data = client_socket.recv(2)
# TODO: ensure 2 bytes were returned
expected_length = int.from_bytes(data, byteorder="big")
data = client_socket.recv(expected_length)
if len(data) < expected_length:
# TODO: add a loop to read more data from the socket
pass
# TODO: write your own "modified utf-8" decoder - see
# https://docs.oracle.com/javase/8/docs/api/java/io/DataInput.html
print("receive Message : " + data.decode('utf-8'))
Java's DataOutput and DataInput are not really designed for general input/output, and they make integrating with other programming languages difficult as you've discovered. If I were you I would consider migrating to a different protocol, for example one that is based on reading and writing lines of text.
This question already has answers here:
What is a NullPointerException, and how do I fix it?
(12 answers)
Closed 4 years ago.
I'm trying to implement a TCP connection for one of my projects. Following a few tutorials I found an example that is used quite often. I've been trying to make it work but even in a minimalistic project I'm getting an NullPointerException.
The Code for my MainActivity is as following:
package f.l.tcptest;
import android.os.AsyncTask;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
public class MainActivity extends AppCompatActivity {
TcpClient mTcpClient;
Button button;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
new ConnectTask().execute("");
Button button = (Button) findViewById(R.id.button);
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
mTcpClient.sendMessage("testing");
}
});
}
public class ConnectTask extends AsyncTask<String, String, TcpClient> {
#Override
protected void onPreExecute() {
super.onPreExecute();
}
#Override
protected TcpClient doInBackground(String... message) {
//we create a TCPClient object
TcpClient 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);
//response received from server
Log.d("test", "response " + values[0]);
//process server response here....
}
}
}
And for the TCPClient:
package f.l.tcptest;
import android.util.Log;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.InetAddress;
import java.net.Socket;
import static android.content.ContentValues.TAG;
public class TcpClient {
public static final String SERVER_IP = "192.168.1.102"; //server IP address
public static final int SERVER_PORT = 1337;
// message to send to the server
private String mServerMessage;
// sends message received notifications
private OnMessageReceived mMessageListener = null;
// while this is true, the server will continue running
private boolean mRun = false;
// used to send messages
private PrintWriter mBufferOut;
// used to read messages from the server
private BufferedReader mBufferIn;
/**
* 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(final String message) {
Runnable runnable = new Runnable() {
#Override
public void run() {
if (mBufferOut != null) {
Log.d(TAG, "Sending: " + message);
mBufferOut.println(message + "\r\n");
mBufferOut.flush();
}
}
};
Thread thread = new Thread(runnable);
thread.start();
}
/**
* Close the connection and release the members
*/
public void stopClient() {
mRun = false;
if (mBufferOut != null) {
mBufferOut.flush();
mBufferOut.close();
}
mMessageListener = null;
mBufferIn = null;
mBufferOut = null;
mServerMessage = null;
}
public void run() {
mRun = true;
try {
//here you must put your computer's IP address.
InetAddress serverAddr = InetAddress.getByName(SERVER_IP);
Log.e("TCP Client", "C: Connecting...");
//create a socket to make the connection with the server
Socket socket = new Socket(serverAddr, SERVER_PORT);
try {
//sends the message to the server
mBufferOut = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())), true);
//receives the message which the server sends back
mBufferIn = new BufferedReader(new InputStreamReader(socket.getInputStream()));
//in this while the client listens for the messages sent by the server
while (mRun) {
mServerMessage = mBufferIn.readLine();
if (mServerMessage != null && mMessageListener != null) {
//call the method messageReceived from MyActivity class
mMessageListener.messageReceived(mServerMessage);
}
}
Log.e("RESPONSE FROM SERVER", "S: Received Message: '" + mServerMessage + "'");
} 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);
}
}
When i start the app, it connects to the server and maintains the connection. If i press the button to send the test message the app crashes and shows the following:
E/AndroidRuntime: FATAL EXCEPTION: main
Process: f.l.tcptest, PID: 16391
java.lang.NullPointerException: Attempt to invoke virtual method 'void f.l.tcptest.TcpClient.sendMessage(java.lang.String)' on a null object reference
at f.l.tcptest.MainActivity$1.onClick(MainActivity.java:28)
at android.view.View.performClick(View.java:6294)
at android.view.View$PerformClick.run(View.java:24770)
at android.os.Handler.handleCallback(Handler.java:790)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6494)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:807)
You declared the field in your activity, but you never initialize it. Check your AsyncTask's doInBackground method. You are creating a new local field called mTcpClient, you are not accessing the MainActivity's field. This is why you got NullPointException.
Here is the fixed code:
package f.l.tcptest;
import android.os.AsyncTask;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
public class MainActivity extends AppCompatActivity {
TcpClient mTcpClient;
Button button;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
new ConnectTask().execute("");
Button button = (Button) findViewById(R.id.button);
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
mTcpClient.sendMessage("testing");
}
});
}
public class ConnectTask extends AsyncTask<String, String, TcpClient> {
#Override
protected void onPreExecute() {
super.onPreExecute();
}
#Override
protected TcpClient doInBackground(String... message) {
//we create a TCPClient object
// You should use the global one, do not create the local instance if you want to use it on click event
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);
//response received from server
Log.d("test", "response " + values[0]);
//process server response here....
}
}
}
Additional Note for Android:
But this approach is not good. You should follow best practices. Maybe you can use the intent service instead of AsyncTasks and sending message on UI thread.
I'm not familiar with using bluetooth.
Referring to some discussions found on StackOverflow (the link i can not find now), I managed to make a small PC server that sends a string via bluetooth to the Android smartphone.
The problem is the extremely slow transfer. For string like
ACLineStatus: Online
they serve 6550 milliseconds, for a real-time information.
As shown in the log
E/time to execute code: 6452
D/prova: il dispositivo è: DESKTOP-U1VI1GB
D/prova: ACLineStatus: Online
How can I increase the transfer speed?
Here there is the server code (on PC)
package hello;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import javax.bluetooth.*;
import javax.microedition.io.*;
/**
* Class that implements an SPP Server which accepts single line of
* message from an SPP client and sends a single line of response to the client.
*/
//start server
private void startServer() throws IOException {
//Create a UUID for SPP
UUID uuid = new UUID("1101", true);
//Create the servicve url
String connectionString = "btspp://localhost:" + uuid + ";name=Sample SPP Server";
//open server url
StreamConnectionNotifier streamConnNotifier = (StreamConnectionNotifier) Connector.open(connectionString);
//Wait for client connection
System.out.println("\nServer Started. Waiting for clients to connect...");
StreamConnection connection = streamConnNotifier.acceptAndOpen();
RemoteDevice dev = RemoteDevice.getRemoteDevice(connection);
System.out.println("Remote device address: " + dev.getBluetoothAddress());
System.out.println("Remote device name: " + dev.getFriendlyName(true));
//read string from spp client
/* InputStream inStream=connection.openInputStream();
BufferedReader bReader=new BufferedReader(new InputStreamReader(inStream));
String lineRead=bReader.readLine();
System.out.println(lineRead);*/
//send response to spp client
OutputStream outStream = connection.openOutputStream();
PrintWriter pWriter = new PrintWriter(new OutputStreamWriter(outStream));
pWriter.write(SingletonBatteryStatus.getInstance().getBattery() + "\n");
pWriter.flush();
pWriter.close();
streamConnNotifier.close();
}
public void run() {
//display local device address and name
LocalDevice localDevice = null;
try {
localDevice = LocalDevice.getLocalDevice();
System.out.println("Address: " + localDevice.getBluetoothAddress());
System.out.println("Name: " + localDevice.getFriendlyName());
BluetoothSPPServer bluetoothSPPServer = new BluetoothSPPServer();
bluetoothSPPServer.startServer();
} catch (BluetoothStateException e) {
System.out.println("non c'è il bluetooth");
this.interrupt();
// e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
this.interrupt();
}
}
}
Here there is the client code (on Android)
package com.andrea.provabluetooth;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothSocket;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
import android.support.design.widget.FloatingActionButton;
import android.support.design.widget.Snackbar;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.TextView;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.util.UUID;
public class MainActivity extends AppCompatActivity {
private static final int REQUEST_ENABLE_BT = 1;
private BluetoothAdapter btAdapter = null;
private BluetoothSocket btSocket = null;
private OutputStream outStream = null;
private TextView out;
// Well known SPP UUID
private static final UUID MY_UUID =
UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");
// Insert your server's MAC address
private static String address = "3C:F8:62:50:AE:9B";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
.setAction("Action", null).show();
}
});
out = (TextView) findViewById(R.id.textView);
reciveMessage();
}
private void reciveMessage(){
out.setText("Prova Bluetooth\n\n");
btAdapter = BluetoothAdapter.getDefaultAdapter();
CheckBTState();
BluetoothDevice device = btAdapter.getRemoteDevice(address);
// Two things are needed to make a connection:
// A MAC address, which we got above.
// A Service ID or UUID. In this case we are using the
// UUID for SPP.
try {
btSocket = device.createRfcommSocketToServiceRecord(MY_UUID);
} catch (IOException e) {
AlertBox("1Fatal Error", "In onResume() and socket create failed: " + e.getMessage() + ".");
}
// Discovery is resource intensive. Make sure it isn't going on
// when you attempt to connect and pass your message.
btAdapter.cancelDiscovery();
// Establish the connection. This will block until it connects.
try {
btSocket.connect();
out.append("\n...Connessione stabilita e data link aperto...");
} catch (IOException e) {
try {
btSocket.close();
} catch (IOException e2) {
AlertBox("2Fatal Error", "In onResume() and unable to close socket during connection failure" + e2.getMessage() + ".");
}
}
InputStream inStream;
try {
inStream = btSocket.getInputStream();
BufferedReader bReader = new BufferedReader(new InputStreamReader(inStream));
long startTime = System.currentTimeMillis();
String lineRead = bReader.readLine();
long stopTime = System.currentTimeMillis();
Log.e("time to execute code", stopTime - startTime + "");
Log.d("prova", "il dispositivo è: " + device.getName());
out.append("\n\n" + lineRead);
Log.d("prova", lineRead);
} catch (IOException e) {
Log.d("prova", "il dispositivo non è: " + device.getName());
//e.printStackTrace();
}
try {
btSocket.close();
} catch (IOException e2) {
AlertBox("Fatal Error", "In onPause() and failed to close socket." + e2.getMessage() + ".");
}
}
private void CheckBTState() {
// Check for Bluetooth support and then check to make sure it is turned on
// Emulator doesn't support Bluetooth and will return null
if (btAdapter == null) {
AlertBox("5Fatal Error", "Bluetooth Not supported. Aborting.");
} else {
if (btAdapter.isEnabled()) {
out.append("\n...Bluetooth is enabled...");
} else {
//Prompt user to turn on Bluetooth
Intent enableBtIntent = new Intent(btAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);
}
}
}
public void AlertBox(String title, String message) {
new AlertDialog.Builder(this)
.setTitle(title)
.setMessage(message + " Press OK to exit.")
.setPositiveButton("OK", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface arg0, int arg1) {
finish();
}
}).show();
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.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();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
}
Another small question: I did not change UUID, but I got it as it is, as I found it on the code found on another question here on stackoverflow. Can I leave it so or should I change it? If I have to change it, how can I do it?
Thanks for your immense patience
If it can help someone, just do not close the connection: about 6 seconds are to establish the connection. If you do not close the connection, the next post is instantaneous.
I am fairly new to Android, i want to write a telnet client app for my Android. I have written the code using Apache commons library for telnet. Now i am able to connect to telnet server (for that i have used Asyctask concept) and able to read login banner after a long time i don't know what is causing that. I have modified the example given in Apache commons to work with my android code.I have two java codes in my "src" folder (MainActivity.java and TelnetClientExample.java). First, i want to get the login prompt and then i want user to interact with it please help, Thanks in advance :)
I am posting my screen capture of what i am getting.
MainActivity.java
package com.example.telnetapp;
import java.io.BufferedInputStream;
import java.io.InputStream;
import java.io.PrintWriter;
import android.app.Activity;
import android.os.AsyncTask;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
public class MainActivity extends Activity{
public static int port_int_address;
private EditText server,port;
private Button connect;
public static String ip,port_address;
public PrintWriter out;
public static TextView textResponse;
static String response;
public InputStream instr;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
server = (EditText)findViewById(R.id.edittext1);
port = (EditText)findViewById(R.id.edittext2);
connect = (Button)findViewById(R.id.connect);
textResponse = (TextView)findViewById(R.id.response);
connect.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
ip = server.getText().toString();
port_address = port.getText().toString();
port_int_address = Integer.parseInt(port_address);
try{
MyClientTask task = new MyClientTask(ip, port_int_address);
task.execute();
}
catch(Exception e){Toast.makeText(getApplicationContext(), e.toString(), Toast.LENGTH_LONG).show();}
}
});
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
public class MyClientTask extends AsyncTask<Void, Void, Void> {
String dstAddress;
int dstPort;
TelnetClientExample job;
MyClientTask(String inetAddress, int port){
dstAddress = inetAddress;
dstPort = port;
}
#Override
protected Void doInBackground(Void... arg0) {
try {
job = new TelnetClientExample();
job.backgroundjob();
}
catch (Exception e)
{
Toast.makeText(getApplicationContext(), e.toString(), Toast.LENGTH_SHORT).show();
}
return null;
}
#Override
protected void onPostExecute(Void result) {
try {
instr = TelnetClientExample.tc.getInputStream();
byte[] buff = new byte[1024];
int ret_read = 0;
do
{
ret_read = instr.read(buff);
if(ret_read > 0)
{
MainActivity.response += new String(buff, 0, ret_read);
}
}
while (ret_read >= 0);
}
catch (Exception e) {
MainActivity.response += e.toString();
MainActivity.response += "From reading from telnet server ! \n";
}
textResponse.setText(response);
super.onPostExecute(result);
}
}
}
TelnetClientExample.java
package com.example.telnetapp;
import java.io.IOException;
import java.io.InputStream;
import org.apache.commons.net.telnet.TelnetClient;
public class TelnetClientExample {
public String remoteip = MainActivity.ip;
public int remoteport= MainActivity.port_int_address;
public static TelnetClient tc = null;
public void backgroundjob() throws IOException {
tc = new TelnetClient();
try {
tc.connect(remoteip, remoteport);
}
catch (Exception e) {
}
}
public void close_con(){
try {
tc.disconnect();
}
catch (Exception e) {
MainActivity.response += e.toString();
MainActivity.response += "From reading from disconnecting telnet server ! \n";
}
}
}
The problem is in this code snippet . please look into this and help me to get an interactive session.
protected void onPostExecute(Void result) {
try {
instr = TelnetClientExample.tc.getInputStream();
byte[] buff = new byte[1024];
int ret_read = 0;
do
{
ret_read = instr.read(buff);
if(ret_read > 0)
{
MainActivity.response += new String(buff, 0, ret_read);
}
}
while (ret_read >= 0);
}
catch (Exception e) {
MainActivity.response += e.toString();
MainActivity.response += "From reading from telnet server ! \n";
}
textResponse.setText(response);
super.onPostExecute(result);
}
The problem i am getting -
I make a client in Java, and make some test on Eclipse IDE and work perfectly, on localhost, external server, etc.
When I export the code to android, it doesn't work, the server don't receive nothing ...
Class code:
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.Socket;
/**
* Jose Manuel R---- ----
* Java version 2.0
*/
public class ClienteTCP {
private CharSequence TCP_HOST = "localhost";
private int TCP_PORT = 5000;
volatile private CharSequence SSID, PASS, SERVER_IP;
volatile private int SERVER_PORT;
final private String START = "START";
// Constructor vacio
public ClienteTCP( ) {
}
// Constructor con argumentos
public ClienteTCP(CharSequence tcp_host, int tcp_port, CharSequence ssid, CharSequence pass, CharSequence ip, int port) {
this.TCP_HOST = tcp_host;
this.TCP_PORT = tcp_port;
this.SSID = ssid;
this.PASS = pass;
this.SERVER_PORT = port;
this.SERVER_IP = ip;
}
// CONF METHODS
public void setServerTCPConf(CharSequence host, int port) {
setTCP_HOST(host);
setTCP_PORT(port);
}
public void setApConf(CharSequence ssid, CharSequence pass) {
setSSID(ssid);
setPASS(pass);
}
public void setServerConf(CharSequence ip, int port) {
setSERVER_IP(ip);
setSERVER_PORT(port);
}
// PUBLIC METHODS
public String configureMC() {
sendMessage( createMessage("AP="+SSID.toString()+","+PASS.toString().toString()) );
sendMessage( createMessage("SERVER="+SERVER_IP.toString()+","+SERVER_PORT) );
return sendMessage( createMessage(START) );
}
public String sendMessage(String msg) {
String msgRec = null;
Socket s;
try {
s = new Socket(TCP_HOST.toString(), TCP_PORT);
BufferedReader reader = new BufferedReader(new InputStreamReader(s.getInputStream()));
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
writer.write(msg, 0, msg.length());
writer.flush();
msgRec = reader.readLine();
reader.close();
writer.close();
s.close();
} catch (IOException e) {
android.util.Log.d("log", e.getMessage());
// e.printStackTrace();
}
return msgRec;
}
// PRIVATE METHODS
private String createMessage(String msg) {
char _AF = ((char)175);
char _FA = (char)250;
return (_AF+msg+_FA);
}
}
MainActivity:
/*
Jose Manuel adad adsasd
TCP client for Android
v1.2-alpha
*/
import android.os.StrictMode;
import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import java.net.Socket;
public class MainActivity extends ActionBarActivity {
private volatile EditText debugText;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
Button button = (Button) findViewById(R.id.SEND);
EditText ssid = (EditText) findViewById(R.id.textSsid);
EditText pass = (EditText) findViewById(R.id.textPass);
debugText = (EditText) findViewById(R.id.debugText);
debugText.setText("Version 1-alpha");
button.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
// Do something in response to button click
demo();
}
});
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.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();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
private void demo() {
ClienteTCP cliente = new ClienteTCP();
CharSequence cs = cliente.sendMessage("Hola Mundo");
if ( cs != null)
debugText.setText(cs);
else
debugText.setText("ERROR OCURRED");
}
}
I'm sorry due to big code, but I'm going to cry ://///
If you try to connect to "localhost" from the Android device, it will try to connect to a service on the Android device because, on whatever device you are running, that is the "local host".
Since the service is running on your machine, it needs to be referenced via an IP address that is reachable by the Android device. That means that if the phone/tablet/whatever is connected to your local WiFi, any 192.168.*.* (private network) address should connect just fine but if it's on the public Internet (via a cellular network, for example) then it'll require the public IP address of your machine or of another device, such as a firewall, that will forward the port to your machine on your internal network.
Try change TCP_HOST from localhost to 10.0.2.2