In my application i want to do bluetooth chat. I'm facing a problem in threading. In my application my android phone will work as server which has a blocking statement
socket=mServerSocket.accept();
for this purpose i've created a child thread so that it will run separately. But before finishing this child thread main thread goes down giving Force Close and if i use the .join() method it hangs up my UI.
What is the solution to run both threads parallel?
this is my code
main Activity
package com.my.bluechat_2_1;
import android.app.Activity;
import android.bluetooth.BluetoothAdapter;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
public class BlueChat extends Activity {
/** Called when the activity is first created. */
private BlueHandler btHandler=null;
private BluetoothAdapter btAdapter = null;
private Context context=this;
TextView chatWindow=null;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
chatWindow=(TextView)findViewById(R.id.textView1);
doStart();
}
private void doStart(){
Button btnStart=(Button)findViewById(R.id.button1);
btnStart.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View arg0) {
// Get local Bluetooth adapter
btAdapter = BluetoothAdapter.getDefaultAdapter();
// If the adapter is null, then Bluetooth is not supported
if(btAdapter == null)
{
Toast.makeText(context, "Device does not support Bluetooth", Toast.LENGTH_LONG).show();
}
if (!btAdapter.isEnabled()) {
Intent discoverableIntent = new
Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
discoverableIntent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 300);
startActivity(discoverableIntent);
}
chatWindow.append("Waiting for connection...\n");
btHandler=new BlueHandler(context,chatWindow,btAdapter);
Thread acceptThread=new Thread(btHandler);
acceptThread.start();
}
});
}
}
BlueHandler
package com.my.bluechat_2_1;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.UUID;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothServerSocket;
import android.bluetooth.BluetoothSocket;
import android.content.Context;
import android.widget.TextView;
import android.widget.Toast;
public class BlueHandler implements Runnable{
// Name for the SDP record when creating server socket
private static final String SMARTCAM_BT_SERVICE_NAME = "SmartCam";
// Unique UUID for this application
private static final UUID SMARTCAM_BT_SERVICE_UUID = UUID.fromString("95b82690-4c94-11e1-b86c-0800200c9a66");
private BluetoothAdapter btAdapter = null;
private BluetoothServerSocket btServerSocket = null;
private BluetoothSocket btSocket = null;
private InputStream btInputStream=null;
private Context contextObj=null;
private TextView textView;
public BlueHandler(Context contextObj,TextView textView,BluetoothAdapter btAdapter){
this.contextObj=contextObj;
this.btAdapter=btAdapter;
this.textView=textView;
try {
btServerSocket=this.btAdapter.listenUsingRfcommWithServiceRecord(SMARTCAM_BT_SERVICE_NAME, SMARTCAM_BT_SERVICE_UUID);
} catch (IOException e) {
// TODO Auto-generated catch block
Toast.makeText(this.contextObj, "Service not created", Toast.LENGTH_LONG);
}
}
#Override
public void run() {
// TODO Auto-generated method stub
textView.append("Inside child thread.\n");
textView.append(btServerSocket+"\n");
while (true) {
try {
btSocket = btServerSocket.accept();
} catch (IOException e) {
break;
}
// If a connection was accepted
if (btSocket != null) {
// Do work to manage the connection (in a separate thread)
try {
btServerSocket.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
break;
}
}
textView.append("Connected.\n");
try {
btInputStream=btSocket.getInputStream();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
byte[] buffer = new byte[1024]; // buffer store for the stream
String s;
int bytes; // bytes returned from read()
// Keep listening to the InputStream until an exception occurs
while (true) {
try {
// Read from the InputStream
bytes=btInputStream.read(buffer);
s= new String(buffer);
// Send the obtained bytes to the UI Activity
textView.append("received ::" +s+"\n");
} catch (IOException e) {
break;
}
}
}
}
You're probably getting a crash because you're accessing a textView on the worker thread. You'll need to use TextView.post(Runnable) to make that not happen.
In reality you should be using a bindable Service to do this kind of work. You can post back to the UI via broadcast intents or callback methods, That way you don't have to worry about rotation bugs.
Are you performing a long operation in the constructor of your children thread? Each long operation must be done in the run() method.
Related
I have java code that sends strings via ip to a python script. The code works perfectly with the emulator but when I successfully install the app via usb to my phone it does not work. Here is the code:
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;
import java.io.IOException;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.UnknownHostException;
public class MainActivity extends AppCompatActivity {
public String message;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final Button btn_python = findViewById(R.id.python);
final Button btn_movie = findViewById(R.id.movie);
final Button btn_hw = findViewById(R.id.homework);
btn_python.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view1) {
send py = new send();
message = "python";
Log.i("Button", "Button works");
System.out.println("whatever");
py.execute();
}
});
btn_movie.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view2) {
send mov = new send();
message = "movie";
mov.execute();
}
});
btn_hw.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view2) {
send hw = new send();
message = "homework";
hw.execute();
}
});
}
class send extends AsyncTask<Void,Void,Void>{
Socket s;
PrintWriter pw;
#Override
protected Void doInBackground(Void...params) {
System.out.println("whatevernumbertwo");
try {
System.out.println("whatevernumberthree");
s = new Socket("ip address", 7800);
Log.i("Socket", "connects to socket");
pw = new PrintWriter(s.getOutputStream());
Log.i("output stream", "Output stream works");
pw.write(message);
Log.i("write", "Write works");
pw.flush();
Log.i("flush", "Flush works");
pw.close();
s.close();
} catch (UnknownHostException e) {
System.out.println("Fail");
e.printStackTrace();
} catch (IOException e) {
System.out.println("Fail");
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}
}
As I mentioned this works on the emulator but not on the actual device. The proper permissions have also been given. What am I doing wrong? Thanks in advance.
After much digging around, it turned out to be the server's firewall all along. That explains why (apparently) no exception was thrown, and why the code didn't seem to execute; it was executing, it was just getting stuck inside Socket() (during the connect).
Surely Socket() is, in fact, throwing an IOException; it probably just takes a while.
The code works on the emulator because, as it is operating on the same machine, it is behind the firewall.
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!
I am currently building an application that will connect to a device via bluetooth and receive data from it. Currently i am able to connect with the paired devices, but can't seem to find any good resources on how to receive data from that device. I have attached 2 images of the application, the first one; is the main menu. In there you'll see a button that says "connect to TANGO", in which i have put in all the code below. That allows me to connect to any paired devices. Also in the main menu, there's a "Translate" button, and that's were i am trying to receive data in, and view them, but so far i haven't been able to do so.
Here's the code for the "connect to TANGO" connection.java
import android.app.Activity;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ListView;
import android.widget.Toast;
import java.util.ArrayList;
import java.util.Set;
public class connection extends AppCompatActivity {
Button b1,b2,b3,b4;
private BluetoothAdapter BA;
private Set<BluetoothDevice>pairedDevices;
ListView lv;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_connection);
b1 = (Button)findViewById(R.id.button);
b2=(Button)findViewById(R.id.button2);
b3=(Button)findViewById(R.id.button3);
b4=(Button)findViewById(R.id.button4);
BA = BluetoothAdapter.getDefaultAdapter();
lv = (ListView)findViewById(R.id.listView);
}
public void on(View v){
if (!BA.isEnabled()) {
Intent turnOn = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(turnOn, 0);
Toast.makeText(getApplicationContext(), "Turned on",Toast.LENGTH_LONG).show();
} else {
Toast.makeText(getApplicationContext(), "Already on", Toast.LENGTH_LONG).show();
}
}
public void off(View v){
if (BA.disable());
Toast.makeText(getApplicationContext(), "Turned off" ,Toast.LENGTH_LONG).show();
}
public void visible(View v){
Intent getVisible = new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
startActivityForResult(getVisible, 0);
}
public void list(View v){
pairedDevices = BA.getBondedDevices();
ArrayList list = new ArrayList();
for(BluetoothDevice bt : pairedDevices) list.add(bt.getName());
Toast.makeText(getApplicationContext(), "Showing Paired Devices",Toast.LENGTH_SHORT).show();
final ArrayAdapter adapter = new ArrayAdapter(this,android.R.layout.simple_list_item_1, list);
lv.setAdapter(adapter);
}
}
When you have a reference to a paired BluetoothDevice you need to create a socket and listen to it. Simplified example follows:
Create a BluetoothSocket and connect to it:
BluetoothSocket socket = device.createRfcommSocketToServiceRecord(<your-device>.getUuids()[0].getUuid());
socket.connect();
Listen to the socket (Get data from the device)
InputStream inStream = socket.getInputStream();
while (inStream.available() > 0) {
inStream.read(); // <-- data from device
}
Write to the socket (Send data to the device)
OutputStream outStream = socket.getOutputStream();
byte[] bytes = <some-data>
outStream.write(bytes);
For more detailed information, with examples, see the docs
#krekle would this code work.
import android.bluetooth.BluetoothSocket;
import android.os.Handler;
import android.os.Message;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
public class display extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_display);
}
private final BluetoothSocket mmSocket;
private final InputStream mmInStream;
private final OutputStream mmOutStream;
private android.os.Handler mHandler;
public display (BluetoothSocket socket, Handler mHandler) {
mmSocket = socket;
this.mHandler = mHandler;
InputStream tmpIn = null;
OutputStream tmpOut = null;
// Get the input and output streams, using temp objects because
// member streams are final
try {
tmpIn = socket.getInputStream();
tmpOut = socket.getOutputStream();
} catch (IOException e) { }
mmInStream = tmpIn;
mmOutStream = tmpOut;
}
public void run() {
byte[] buffer = new byte[1024]; // buffer store for the stream
int bytes; // bytes returned from read()
// Keep listening to the InputStream until an exception occurs
while (true) {
try {
// Read from the InputStream
bytes = mmInStream.read(buffer);
// Send the obtained bytes to the UI activity
int MESSAGE_READ = 0;
mHandler.obtainMessage(MESSAGE_READ, bytes, -1, buffer)
.sendToTarget();
} catch (IOException e) {
break;
}
}
}
/* Call this from the main activity to send data to the remote device */
public void write(byte[] bytes) {
try {
mmOutStream.write(bytes);
} catch (IOException e) { }
}
/* Call this from the main activity to shutdown the connection */
public void cancel() {
try {
mmSocket.close();
} catch (IOException e) { }
}
}
i only had to change "ConnectThread" to "display" and "Thread" to "AppCompatActivity" just to match with the activities that i already made before.
I'm trying to establish a simple UDP connection between a client program running on an android emulator and a server, on two different systems. The server side is fine, but the client side keeps crashing. Is it a problem with the emulator? Should i redirect the port to make it work?
CLIENT SIDE (on android emulator):
package com.example.clientrecv;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;
import android.os.Bundle;
import android.app.Activity;
import android.util.Log;
import android.widget.Button;
import android.widget.Toast;
public class MainActivity extends Activity
{
public String text;
public int serverport=1234;
public byte[] message=new byte[1000];
public Button b;
public DatagramPacket p;
public DatagramSocket s;
public Toast t;
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
b=(Button) findViewById(R.id.button1);
try {
p = new DatagramPacket(message,message.length);
s = new DatagramSocket(serverport);
try {
s.receive(p);
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
text= new String(message,0,p.getLength());
Log.d("hello","the message:"+text);
s.close();
// TODO Auto-generated method stub
} catch (SocketException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void showmsg()
{
t=Toast.makeText(getApplicationContext(), text, Toast.LENGTH_LONG);
t.show();
}
}
SERVER SIDE: (on pc)
import java.io.*;
import java.net.*;
class serversend
{
public static void main(String args[]) throws Exception
{
String strmsg="Server says hello";
int serverport=1234;
int len=strmsg.length();
System.out.println("starting");
byte[] message=strmsg.getBytes();
try{
InetAddress local=InetAddress.getByName("localhost");
DatagramSocket s=new DatagramSocket();
DatagramPacket p=new DatagramPacket(message,len,local,serverport);
System.out.println("Running");
s.send(p);
System.out.println("Sent");
}catch(Exception e)
{
System.out.println("caught");
}
}
}
There are many example available that can help you to communicate between server and client using UDP
to communicate between these two should add the client port on server side
InetAddress local = InetAddress.getByName("192.168.1.102");
here are the Following Link For Client Server Communication Using UDP
LINK UDP1
Link UDP2
Android after 3.0 version doesn't allow you to implement networking operations within the main UI Thread. You must define a new Thread for that... Here is how you can do it:
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//here you Set up you parameters and launch the thread (e.g):
this.newThread = new Thread(new mThread());
this.newThread.start();
/* Next you define your newThread's run method in wich all networking
operations must take place*/
class mThread implements Runnable {
public void run() {
// Do all networking tasks you need
}
}
I have Created a Service Which in turn Creates a Socket, But as soon as try to read data sent from Server, it hangs ,On the other hand the same code run if i am not using Service but plain Activity ??
import android.app.*;
import android.content.*;
import android.os.*;
import android.util.*;
import java.net.*;
import java.io.*;
import android.widget.*;
public class BackgroundService extends Service
{
private Socket socket=null;
private InputStreamReader in=null;
private String ip;
private String tag="BackgroundService";
public IBinder onBind(Intent p1)
{
// TODO: Implement this method
return null;
}
public void onCreate(){
super.onCreate();
}
public void onStart(Intent i,int id){
super.onStart(i,id);
ip=i.getStringExtra("Ip");
Log.v(tag,"Ip "+i.getStringExtra("Ip"));
try
{
socket = new Socket(ip.trim(), 8888);
new Runnable() {
public void run()
{
// Hangs in this block.....
try
{
in = new InputStreamReader (socket.getInputStream());
BufferedReader bf=new BufferedReader (in);
// Never Reaches this messge
Log.v(tag,"mess:"+bf.readLine() );
}
catch (IOException e)
{
e.printStackTrace();
}
}
}.run();
}
catch (IOException e)
{
e.printStackTrace();
}
}
}
Log.v is the Problem it wont allow you print the value so use System.out.println() and bf.printline will contain the message