For the past couple of days, I have been working on establishing a client-server socket over Bluetooth with an android server and a windows PC socket so I can send information over from the computer that can be used on an app for Oculus Gear VR (app would be on the android). I am having a big issue with the Bluetooth server socket on the android side. It doesn't help that my experience with android studio is encompassed within like 4 days. I figured out how to create a regular server socket on an android app that waits for a connection from the client
`public class MyServer {
BluetoothDevice device;
Thread m_objThread;
ServerSocket m_server;
String m_strMessage;
DataDisplay m_dataDisplay;
Object m_connected;
public MyServer()
{
}
public void setEventListener(DataDisplay dataDisplay)
{
m_dataDisplay = dataDisplay;
}
public void startListening()
{
m_objThread = new Thread(new Runnable() {
public void run() {
try {
m_server = new ServerSocket(2001);
Socket connectedSocket = m_server.accept();
Message clientmessage = Message.obtain();
ObjectInputStream ois = new ObjectInputStream(connectedSocket.getInputStream());
String strMessage = (String) ois.readObject();
clientmessage.obj = strMessage;
mHandler.sendMessage(clientmessage);
ObjectOutputStream oos = new ObjectOutputStream(connectedSocket.getOutputStream());
oos.writeObject("Hi..");
ois.close();
oos.close();
m_server.close();
} catch (Exception e) {
Message msg3 = Message.obtain();
msg3.obj = e.getMessage();
mHandler.sendMessage(msg3);
}
}
});
m_objThread.start();
}
Handler mHandler = new Handler() {
#Override
public void handleMessage(Message status)
{
m_dataDisplay.Display(status.obj.toString());
}
};
`
But I am not completely sure how to change this to a Bluetooth server socket in order to create a Bluetooth socket. Any help is appreciated, I am relatively new to coding and have only used c++ on visual studio so I am having a lot of trouble with android studio. Thanks!
You should create one thread for accepting a connection and another- for sending and receiving the data. When device is connected, you stop 'connect thread' and start 'transfer' thread. There is a gread example from google- https://github.com/googlesamples/android-BluetoothChat
Related
I try to send a UDP packet from my mobile to a PC – IP 192.168.1.113, at the PC I use “Packet sender”with UDP server port 55777.
But it does not work, I have sent UDP packet from a VBA script in Excel to the Packet sender and it works, I can also send through
UDP apps I have downloaded to the mobile, to the “Packet sender”.
I use:
Android Studio 3.5
SDK platform 8.1
Mobile: Samsung S9+
I have added the INTERNET permission to the manifest:
I send the packet from a new thread since the main thread does not allow to send packages, the below code is the first step before I continue, need to make this to work first though.
public class MainActivity extends AppCompatActivity {
private Handler mainHandler = new Handler();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
public void startThread(View view) {
ExampleRunnable runnable = new ExampleRunnable(10);
new Thread(runnable).start();
}
class ExampleRunnable implements Runnable {
#Override
public void run() {
DatagramSocket ds = null;
String message = "Hello";
try{
ds = new DatagramSocket();
InetAddress serverAddr = InetAddress.getByName("192.168.1.113");
DatagramPacket dp;
dp = new DatagramPacket(message.getBytes(), message.length(), serverAddr, 55777);
ds.send(dp);
} catch (IOException e) {
e.printStackTrace();
} finally {
if (ds != null) {
ds.close();
}
}
}
}
}
There is several things to be confirmed before answering the question. You can provide stack trace or any error if there is any. In your case, If there is no programming error, You should check your firewall once. Add new firewall rule for the incoming connection request on port 55777.
hope your having a nice day . im building a Video Call application using XMPP and Jingle and direct ByteStream from phone to phone . in order to do so i noticed i need a stun server to get public ip and port of android devices and send them to the other party , im getting the public ip like this
InetAddress address = Inet4Address.getByName("stun.l.google.com");
MessageHeader sendMH = new
MessageHeader(MessageHeader.MessageHeaderType.BindingRequest);
ChangeRequest changeRequest = new ChangeRequest();
sendMH.addMessageAttribute(changeRequest);
byte[] data = sendMH.getBytes();
DatagramSocket s = new DatagramSocket(null);
localPort = s.getLocalPort();
s.setReuseAddress(true);
// s.bind(address);
DatagramPacket p = new DatagramPacket(data,
data.length,address,19302);
s.send(p);
DatagramPacket rp;
rp = new DatagramPacket(new byte[32], 32);
s.receive(rp);
MessageHeader receiveMH = new MessageHeader(MessageHeader.MessageHeaderType.BindingResponse);
// System.out.println(receiveMH.getTransactionID().toString() + "Size:"
// + receiveMH.getTransactionID().length);
receiveMH.parseAttributes(rp.getData());
MappedAddress ma = (MappedAddress) receiveMH
.getMessageAttribute(MessageAttribute.MessageAttributeType.MappedAddress);
ip = ma.getAddress().toString();
port = ma.getPort();
Log.i("XMPP-Stabler",ma.getAddress().toString()+" "+ma.getPort());
s.close();
}catch (Exception e){
e.printStackTrace();
}
then i send the result to the other party and open up a SocketServer on this client using given port , but still i can not connect to this ServerSocket over internet , or probably i am doing some thing wrong ? can you please help me how should i use STUN or TURN results ? thanks
and here is my connecting side of Jingle just in case
otherTransport = (JingleS5BTransport)
jingle.getContents().get(0).getTransport();
ArrayList<JingleContent> contents = new ArrayList<>();
contents.add(content);
session = (JingleS5BTransportSession) JingleS5BTransportManager.getInstanceFor(connection).transportSession(new JingleSession(connection.getUser(),responderFullId,role,sessionId,contents) {
#Override
public XMPPConnection getConnection() {
return connection;
}
#Override
public void onTransportMethodFailed(String namespace) {
Log.i("XMPP-Stabler","transport method failed "+namespace);
}
});
session.setTheirProposal(otherTransport);
session.initiateOutgoingSession(new JingleTransportInitiationCallback() {
#Override
public void onSessionInitiated(BytestreamSession bytestreamSession) {
Log.i("XMPP-Stabler","ON SESSION INITIATED 2!");
Socks5BytestreamSession session = (Socks5BytestreamSession) bytestreamSession;
}
#Override
public void onException(Exception e) {
e.printStackTrace();
}
});
I'm new to android development so please be gentle :p I'm having trouble sending UDP packets from my android phone to my anrdiuno (with WiFi shield). I can send and recieve packets to or from the arduino using the TCP/UDP Terminal app from the Play Store, with no problems. For an easy beginners task I would like to send just one packet to my arduino (which is on my local network at address 192.168.0.101 and listens on port 5000), when I press a button, a message is then displayed saying that data has been sent. My current android code is below:
//CALLED WHEN USER PRESSES BUTTON
public void sendMessage(View view){
runUdpClient();
// Create the text view
TextView textView = new TextView(this);
textView.setTextSize(40);
textView.setText("MESSAGE SENT");
// Set the text view as the activity layout
setContentView(textView);
}
private void runUdpClient() {
try{
String msg = "Hello";
byte[] msgBytes = (msg.getBytes());
String serverHostname1 = new String ("192.168.0.101");
InetAddress ip = InetAddress.getByName(serverHostname1);
//SEND ON PORT 5000
DatagramSocket socket = new DatagramSocket(5000);
socket.setBroadcast(true);
DatagramPacket packet = new DatagramPacket(msgBytes,msgBytes.length, ip, 5000);
//packet.setAddress(ip);
//packet.setPort(5000);
socket.send(packet);
socket.close();
}catch(Exception e){
e.printStackTrace();
}
}
I have debugged the code and found that an exception is thrown when socket.send(packet) is called, (although i do not know how to view this expection). After stepping through the send function, this exception was thrown:
IllegalArgumentException("Packet address mismatch with connected address");
Please could someone help me with this please? Thank you ever so much for any help given :)
found a solution to this problem. If anyone else gets this problem the solution is to call the udp packet send function from inside a thread as such:
public void sendMessage(View view){
final EditText editMessage = (EditText) findViewById(R.id.edit_message);
final String message = editMessage.getText().toString();
new Thread(new Runnable(){
#Override
public void run() {
try {
runUdpClient(message);
} catch (Exception ex) {
ex.printStackTrace();
}
}
}).start();
}
Found out that most communications need to be done inside a thread. Peace.
I want to implement socket connection between 2 deceives , client keep sending GPS data to the server and I need both of it run in new thread , the client send first one data then keep show error like this
03-18 16:35:11.805: E/Client run:(8163): java.net.ConnectException: failed to connect to /192.168.2.103 (port 5678): connect failed: ECONNREFUSED (Connection refused)
here is the client code
public class Send implements Runnable{
private boolean Connect = true;
public void Connect(){
Connect = true;
}
public void Disconnect(){
Connect = false;
}
#Override
public void run() {
// TODO Auto-generated method stub
while(Connect){
try {
SocketClient = new Socket("192.168.2.103", 5678);
ObjectOutputStream oos = new ObjectOutputStream(SocketClient.getOutputStream());
oos.writeDouble(GPSinfo[2]);
//ObjectInputStream ois = new ObjectInputStream(SocketClient.getInputStream());
//ois.readInt();
oos.close();
//ois.close();
} catch (Exception e) {
Log.e("Client run: ", e.toString());
}
}
}
}
here is server code
public class Receive implements Runnable{
private boolean CanReceive = true;
private double Data;
public void Connect(){
CanReceive = true;
}
public void Disconnect(){
CanReceive = false;
}
#Override
public void run() {
// TODO Auto-generated method stub
while(CanReceive){
try {
SocketServer = new ServerSocket(5678);
Socket connectedSocket = SocketServer.accept();
ObjectInputStream ois = new ObjectInputStream(connectedSocket.getInputStream());
Data = ois.readDouble();
DataText.setText("" + Data);
//ObjectOutputStream oos = new ObjectOutputStream(connectedSocket.getOutputStream());
//oos.writeInt(1);
//ois.close();
//oos.close();
} catch (Exception e) {
Log.e("Server run: ", e.toString());
}
}
}
}
by the way , the both code is inner class , and INTERNET permission is added.
It's obvious it's not a router-firewall related problem as you are under the same net, so there are only a few possibilities:
There's nothing listening on that port on that IP on the server-side
There's a local firewall on the server-side that is blocking that connection attempt
You are not using WIFI so you're not under the same net.
You should make sure you can open that service some ther way, that would help you debugging where the culprit is. If you've already done this, I'd suggest using some debugging tool to trace TCP packets (I don't know either what kind of operating system you use on the destination machine; if it's some linux distribution, tcpdump might help, in Win environments WireShark works just good).
This isn't a 'data transfer error'. This is a 'connection refused' error. It means the server you want to transfer the data to or from isn't running at the IP:port you specified.
Try killing the adb service before you begin the connection. I had a similar problem and killing the adb service before the connection resolved the issue.
I had the same error. I simply used ServerSocket and it worked well.
ServerSocket socket = new ServerSocket(8888);
I am beginner in android programming. Am trying to broadcast messages on WiFiDirect using the following code:
public class FileTransferService extends IntentService {
public static final String host= "255.255.255.255";
InetAddress broadcastAddress = InetAddress.getByName(host);// Exception: Unknown host exception
int port = 8888;
protected void onHandleIntent(Intent intent) {
Log.d(WiFiDirectActivity.TAG,"m in 1");
Context context = getApplicationContext();
DatagramSocket socket;
try {
socket = new DatagramSocket(port);
socket.setBroadcast(true);
socket.connect(broadcastAddress, port);
String message = "Hello";
byte[] buffer = message.getBytes();
DatagramPacket packet = new DatagramPacket(
buffer, buffer.length, broadcastAddress, port);
socket.send(packet); // <----- Causes a SocketException
} catch (IOException e) {
Log.d(WiFiDirectActivity.TAG, e.getMessage(), e);
}
}
}
It shows me unknown host exception on getByName() method. Is there anyway to replace the method? Am I going on a right path? Do I need to add anything along with this to send messages.
Thanks in advance
Try calling public UnknownHostException (String detailMessage) to get the detailed exception message.
Another way to call getByName() can be get from here
Below link has a step by step illustration of setting up a Wi-Fi Direct broadcaster
Connecting with Wi-Fi Direct