Android client connecting to server on pc, using Java sockets - java

I want to send a simple string to a server on my desktop PC. Here is what I have on my PC:
public static void main(String[] args) {
System.out.println("Server Started");
Server server = new Server();
server.start();
}
public void start(){
try {
ServerSocket SRVSOCK = new ServerSocket(333);
Socket SOCK = SRVSOCK.accept();
InputStreamReader ir = new InputStreamReader(SOCK.getInputStream());
BufferedReader bf = new BufferedReader(ir);
String MESSAGE = bf.readLine();
System.out.println(MESSAGE);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
For my android tablet I have this in the onCreate():
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Thread tthread = new Thread(new Runnable(){
#Override
public void run() {
Connect();
}});
}
public void Connect(){
try {
Socket SOCK = new Socket("10.0.0.3", 333);
PrintWriter pw = new PrintWriter(SOCK.getOutputStream());
pw.println("FROM ANDROID!");
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
I have seen you can create a new thread which you need (otherwise the app UI freezes), but it still does not send the text to my server, I have added the incoming and outgoing port in my windows firewall, and even tried to turn off the firewall, but still no luck..
The android code is running on a real physical tablet (Nexus 7 2013) and not an emulator.
What is wrong here?
This whats in my log cat when the app is opened
03-24 13:43:59.695: I/ActivityManager(768): START u0 {act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10200000 cmp=com.hashimo.mcpeworldconverter/.MainActivity bnds=[200,1314] [400,1590] (has extras)} from uid 10022 on display 0
03-24 13:43:59.780: I/ActivityManager(768): Start proc com.hashimo.mcpeworldconverter for activity com.hashimo.mcpeworldconverter/.MainActivity: pid=6724 uid=10140 gids={50140, 9997, 1028, 1015, 3003} abi=armeabi-v7a
03-24 13:44:00.338: I/ActivityManager(768): Displayed com.hashimo.mcpeworldconverter/.MainActivity: +592ms

You are declaring a Thread but you forgot to .start() it. So your code is not executed.

Related

Android Studio Error: Can't create handler inside thread that has not called Looper.prepare()

I am trying to run a section of code every X seconds in an AsyncTask Activity and it is crashing before getting into any print statements. I am not sure why it is crashing, but I also posted the error I am getting. Anyone have any ideas? Thank you so much!
public class AppListener extends AsyncTask<String, String, String> {
#Override
protected String doInBackground(String... uri) {
final Handler h = new Handler();
final int delay = 5000; //milliseconds
h.postDelayed(new Runnable() {
public void run() {
try {
String msg_received = null;
System.out.println("LISTENING FOR LAST INSTALLED APP");
System.out.println("TRY");
Socket socket = new Socket("85.190.178.23", 5050);
// Get data sent through socket
DataInputStream DIS = new DataInputStream(socket.getInputStream());
System.out.println("DataInputStream Started");
// read data that got sent
msg_received = DIS.readUTF();
System.out.println("Message from server" + msg_received);
// Might not want to close socket, or only the first string will be sent and none after
socket.close();
}
catch (Exception e) {
System.out.println("Did not receive string");
}
h.postDelayed(this, delay);
}
}, delay);
String msg_received = null;
return msg_received;
}
}
MY ERROR
Caused by: java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
Here is how I got my loop to execute every X seconds without interfering with my GUI if it is helpful to anyone else: instead of having a separate class, I just posted my code in my main activity right when my app starts
public class MainActivity extends FragmentActivity{
private Thread repeatTaskThread;
// called when the activity is first created
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
// Go into loop that is repeated every X seconds
RepeatTask();
}
private void RepeatTask()
{
repeatTaskThread = new Thread()
{
public void run()
{
while (true)
{
//Post your code here that you want repeated every X seconds
// My "try" and "catch" statements from above got inserted here
try
{
// Sleep for 5 seconds
Thread.sleep(5000);
}
catch (Exception e)
{
e.printStackTrace();
}
}
};
};
repeatTaskThread.start();
}
}
Updated: When you're launching AsyncTasks doInBackground, you're launching a background thread. If you want to post AsyncTask's doInBackground with a delay, then you should not use an AsyncTask at all. You should only need to use a Handler with postDelayed, which will create a background thread for you. It looks like in your code, you tried launch a new Thread with a Handler while in AsyncTask's background thread.
Get rid of the AsyncTask altogether, and include this code in your Activity:
final Handler h = new Handler();
final int delay = 5000; //milliseconds
h.postDelayed(new Runnable() {
public void run() {
try {
String msg_received = null;
System.out.println("LISTENING FOR LAST INSTALLED APP");
System.out.println("TRY");
Socket socket = new Socket("85.190.178.23", 5050);
// Get data sent through socket
DataInputStream DIS = new DataInputStream(socket.getInputStream());
System.out.println("DataInputStream Started");
// read data that got sent
msg_received = DIS.readUTF();
System.out.println("Message from server" + msg_received);
// Might not want to close socket, or only the first string will be sent and none after
socket.close();
}
catch (Exception e) {
System.out.println("Did not receive string");
}
h.postDelayed(this, delay);
}
}, delay);
String msg_received = null;
return msg_received;
}

Android bluetooth device in background not as keyboard

I have barcode scanner who should work with my app. It is supposed to run in the background and my app is responding to input coming from the scanner in its own way. However it should not be used as a hardware keyboard and its input not directed to the firstresponder (no text entries i.e.). Currently i'm stuck with it although i know i have done a solution like described before (couple years ago for a company).
The first part of the question is now how to prevent the bluetooth device from being attached as a hardware keyboard? Can i control this behaviour or is it maybe some mode or setting that the bluetooth device must support (if yes is there name for it to check in the specifications)?
I guess if the device is not attached as a bluetooth keyboard i could establish a connection and listen to the bluetooth socket input stream for available bytes and collect them. Currently i cannot establish a connection because
UUID uuid = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");
socket = device.createRfcommSocketToServiceRecord(uuid);
socket.connect();
throws an java.io.IOException with message read failed, socket might closed or timeout, read ret: -1. Any ideas why i cannot connect to the socket, although the device is currently paired to my device?
EDIT:
Because it was asked, the complete connection source code
private void initBluetooth() {
BTAdapter = BluetoothAdapter.getDefaultAdapter();
if (BTAdapter == null) {
Log.e(getClass().getName(), "no BT Adapter");
return;
}
if (!BTAdapter.isEnabled()) {
Intent enableBT = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableBT, REQUEST_BLUETOOTH);
return;
}
listDevices();
}
private void listDevices() {
Set<BluetoothDevice> pairedDevices = BTAdapter.getBondedDevices();
if (pairedDevices.size() > 0) {
for (BluetoothDevice device : pairedDevices) {
Log.d(getClass().getName(), String.format("Device found %s", device.getName()));
if(device.getName().indexOf("Barcode") > 0) {
mmDevice = device;
try {
openBT();
} catch(IOException e) {
Log.e(getClass().getName(), "Failed", e);
}
break;
}
}
}
}
void openBT() throws IOException
{
UUID uuid = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");
mmSocket = mmDevice.createRfcommSocketToServiceRecord(uuid);
//now make the socket connection in separate thread
Thread connectionThread = new Thread(new Runnable() {
#Override
public void run() {
// Always cancel discovery because it will slow down a connection
BTAdapter.cancelDiscovery();
// Make a connection to the BluetoothSocket
try {
// This is a blocking call and will only return on a
// successful connection or an exception
mmSocket.connect();
} catch (IOException e) {
//connection to device failed so close the socket
e.printStackTrace();
try {
mmSocket.close();
} catch (IOException e2) {
e2.printStackTrace();
}
}
}
});
connectionThread.start();
mmInputStream = mmSocket.getInputStream();
}

Client socket times out when connecting to Server

I have a problem when I try to connect my physical device to my server using sockets. On the server side it does not seem to accept any connection while on the client side the socket times out. Any ideas why this is happening?
I provide my code below
Server Code:
public void run()
{
// TODO Auto-generated method stub
try{
gamePending = false;
pid = 0;
while(pid < 2){
System.out.println("Hello from run loop on game");
Socket tempSocket = server.accept();
System.out.println("Client connected at " + tempSocket.getLocalPort());
PrintWriter tempWriter = new PrintWriter(new BufferedWriter (new OutputStreamWriter(tempSocket.getOutputStream())),true);
tempWriter.println("" + pid);
players[pid] = new Client(tempSocket, pid, this);
players[pid].start();
gamePending = true;
if(pid == 0){sendMsg(pid, "waiting for other player");}
pid++;
}
}
catch(Exception e){
System.out.println("There has been an Error. Game will be Terminated.");
}
//Start new game for the next two players...
new Game();
}
Client Side:
public void run() {
// Connects to the Server....
try {
socket = new Socket("192.168.1.116", 9090);
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
in = new BufferedReader (new InputStreamReader(socket.getInputStream()));
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
try {
out = new PrintWriter(socket.getOutputStream(),true);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
11-16 23:32:11.016: W/System.err(24213): java.net.ConnectException: failed to connect to /192.168.1.116 (port 9090): connect failed: ETIMEDOUT (Connection timed out)
11-16 23:32:11.016: W/System.err(24213): at libcore.io.IoBridge.connect(IoBridge.java:114)
11-16 23:32:11.016: W/System.err(24213): at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:192)
11-16 23:32:11.026: W/System.err(24213): at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:459)
11-16 23:32:11.026: W/System.err(24213): at java.net.Socket.connect(Socket.java:842)
11-16 23:32:11.026: W/System.err(24213): at vatos.locos.spheroknockout.Connection.run(Connection.java:22)
11-16 23:32:11.026: W/System.err(24213): at java.lang.Thread.run(Thread.java:841)
11-16 23:32:11.026: W/System.err(24213): Caused by: libcore.io.ErrnoException: connect failed: ETIMEDOUT (Connection timed out)
}
I can't be sure (because it does not appear in your code) but I think the server is not hosing on the same port (9090). That may be the main problem, but the server or client may also be blocked by a firewall (even if they run on the same machine).

Connect an android application (as client) and an application running on my machine (as server) via socket

I'm trying to create a communication via socket between an android app (it would be as client) and a java application (as server) running on my computer. Although my application is very simple, it crashes on my Android device.
Can anyone help me??? I will report below pieces of code..
SERVER-SIDE
public class Server {
public static void main(String args[]){
try {
ServerSocket ss=new ServerSocket(9090);
Socket client=ss.accept();
System.out.println("A request is arrived");
ObjectOutputStream oos=new ObjectOutputStream(client.getOutputStream());
PrintWriter out=new PrintWriter(oos,true);
out.write("Hello..I'm the Server");
out.flush(); out.close(); client.close();
} catch(Exception e){e.printStackTrace();}
}
}
CLIENT-SIDE
public class ChildActivity extends Activity{
public static final int SERVERPORT = 9090;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_child);
Button b=(Button) findViewById(R.id.button1);
b.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
try {
InetAddress addre=InetAddress.getByName("a.b.c.d"); //ip address got typing command ipconfig in windows
Socket socket=new Socket(addre,9090);
ObjectInputStream in=new ObjectInputStream(socket.getInputStream());
String msg=(String) in.readObject();
Toast.makeText(getBaseContext(), msg, Toast.LENGTH_LONG).show();
in.close();
} catch (Exception e) {e.printStackTrace();}
}
}
});... and so on }}
I've also included following permissions in file Manifest, because my phone is connected on the Internet via wi-fi.
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
Every kind of help is well appreciated... Thanks again.
ps. sorry for my English :P
I'll try to guess your crashlog. You have a android.os.NetworkOnMainThreadException.
This answer should help you https://stackoverflow.com/a/6343299/1173794
You are most propably getting a "No-Network-On-Main-Thread" exception.
Android doesn't permit you to do IO on the main thread because this blocks the UI and can lead to an application not responding screen. You could use an AsyncTask to do the IO in the background.

create persistent connection

In my android application I am trying create persistent connection for downloading images. Here is my code
public class PersActivity extends Activity {
ImageView img;
String imageUrl="http://192.168.1.4/JRec/";
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Button bt3= (Button)findViewById(R.id.download);
bt3.setOnClickListener(getImgListener);
img = (ImageView)findViewById(R.id.image);
}
View.OnClickListener getImgListener = new View.OnClickListener()
{
#Override
public void onClick(View view) {
for (int i = 0; i<4;i++){
downloadFile(i,imageUrl+"images/"+i+".png");
}
}
};
Bitmap bmImg;
void downloadFile(int i, String fileUrl){
URL myFileUrl =null;
try {
myFileUrl= new URL(fileUrl);
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
System.out.println("Opening connection");
HttpURLConnection conn= (HttpURLConnection)myFileUrl.openConnection();
conn.setRequestProperty("Connection", "keep-alive");
conn.setDoInput(true);
conn.connect();
System.out.println("Downloading"+fileUrl);
InputStream is = conn.getInputStream();
bmImg = BitmapFactory.decodeStream(is);
img.setImageBitmap(bmImg);
if (i ==3){
System.out.println("Disconnected");
conn.disconnect();
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
When I start download the file every time it should open connection for download, I want to open connection only one time and when the application end downloading all files the connection must be disconnected. Is there any way to do this.
Thanks anyone who get attention on this.
Http connections are "stateless" so there is no connection to be kept open like say in an SSH connection;
So each image you download will be done in a separate request/connection. (that's also the web browser do it).
Also, why did you put the creation of the URL in a separate try/catch ?
That makes no sense because if you fail to create the URL object, you will get a null pointer when you will try to open the connection.

Categories