Problem connecting Android app to socket using cell connection - android

I'm trying to get my android app to connect to a socket on a server across the internet. I notice that when I have my Wi-fi turned on in the phone, the App can successfully connect to the port, but if I turn off the wi-fi, I get a time out on the connection. I can access and browse the internet on the phone seamlessly when wi-fi is off but connecting to that server always fails.
I've verified that the server is listening on that port and I can always connect from any other computer across the internet and on the phone if wi-fi is enabled.
I'm wondering what could be different between using the wireless connection and the cell connection to reach that location. The IP I'm using to connect to the address is a public address.
Button SendButton = (Button) findViewById(R.id.SendButton);
SendButton.setOnClickListener(new Button.OnClickListener() {
#Override
public void onClick(View v) {
Socket kkSocket = null;
PrintWriter out = null;
try {
kkSocket = new Socket("X.X.X.X", 4444);
out = new PrintWriter(kkSocket.getOutputStream(), true);
} catch (UnknownHostException e) {
System.err.println("Don't know about host: X.X.X.X");
} catch (IOException e) {
System.err.println("Couldn't get I/O for the connection to: X.X.X.X");
}

Related

Connecting a socket with static IP on a WiFi network while mobile data is turned on

I am required to design an application in Android which requires the phone to connect to a server by opening a socket. I am able to achieve this when I am just connected to the particular wifi network (ie the Wifi network which hosts the server ) but in a situation when I am connected to the wifi network and the Mobile data network I get a socket exception thrown as android tries to connect the socket over the mobile network
I have already been able to connect the device when its just connected to the wifi of the device that needs the socket connection to be established
static class StartTCPconnection extends AsyncTask<Void, Void, Void> {
final WeakReference<RemoteActivity> activity;
StartTCPconnection(WeakReference<RemoteActivity> activity) {
this.activity = activity;
}
#Override
protected Void doInBackground(Void... voids) {
try {
socket = new Socket("192.168.4.1", 900);
Log.d(TAG, "is socket connected ? ...." + socket.isConnected());
printWriter = new PrintWriter(socket.getOutputStream(), true);
Log.i(TAG, "Checking if socket is really connected " + (socket.getLocalSocketAddress()));
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
if (socket != null) {
if (socket.isConnected() && isWifi) {
Log.d(TAG, "onPostExecute: " + socket.isConnected());
Toast.makeText(activity.get(), "Connection established", Toast.LENGTH_SHORT).show();
Log.e(TAG, "onPostExecute: " + activity.get().getSharedPreferences(Constants.REMOTE_SWITCH_SHARED_PREFERENCE, Context.MODE_PRIVATE).getInt(Constants.REMOTE_SWITCH_KEY, 99));
if (activity.get().getSharedPreferences(Constants.REMOTE_SWITCH_SHARED_PREFERENCE, Context.MODE_PRIVATE).getInt(Constants.REMOTE_SWITCH_KEY, 1) == 1) {
activity.get().joyStickFragment.checkSocketInstance(socket);
activity.get().joyStickFragment.changeUIForConnect();
} else if (activity.get().getSharedPreferences(Constants.REMOTE_SWITCH_SHARED_PREFERENCE, Context.MODE_PRIVATE).getInt(Constants.REMOTE_SWITCH_KEY, 1) == 2) {
Log.e(TAG, "onPostExecute:Check " + socket.isConnected());
activity.get().buttonRemoteFragment.checkSocketInstance(socket);
activity.get().buttonRemoteFragment.changeUIForConnect();
}
activity.get().connectionIndicatorImage.setImageResource(R.drawable.avishkaar_logo_on);
activity.get().wifiIndicator.setImageResource(R.drawable.wifi_connected_icon);
}
} else {
// Toast.makeText(activity.get(), "Wrong Wifi Network connected", Toast.LENGTH_SHORT).show();
}
}
}
The above mentioned code connects me to the socket if the only network available is the WiFi of the device and the mobile network is turned off
There is nothing special from the programming perspective between connecting to a server which is in the local network and a server which is not. The only requirement is that the server is actually reachable in the first place, i.e. not in a private unreachable network and not blocked by a firewall or similar. And of course that the public reachable address of the server is used as destination in the program.
socket = new Socket("192.168.4.1", 900);
192.168.4.1 is an address in a private network. This means it is not accessible from the internet, which also means that it cannot be reached if your are connecting with mobile data or if you use wifi within a different network (like a public hotspot).
To make a connection from outside this private network possible the server must be reachable from outside this network, i.e. needs to have a public routable IP address. If the server is in some typical home network this can be achieved with port forwarding in the router. For larger setups such servers are located at data centers directly reachable from the internet or (as a special case of this) in the cloud.

Android: Disconnect bluetooth headset to connect my SPP app using bluetooth

I have a SPP Bluetooth app, the problem is this case.
The android device is connected to a Bluetooth Speaker, when i try to connect to my SPP Micro device i can't for the same reason the Bluetooth is already connected.
How i can disconnect the Bluetooth Speaker from my App so i can connect to my SPP micro device after the disconnection.
Thanks!
UPDATE:
Sorry, i forget to specify, the connection to the Bluetooth speaker is made before opening my app, its already connected to the speaker when i open my app and i want to disconnect the bluetooth speaker from my app that didn't connect to the bluetooth speaker and with my app close that connection
You need to manually disconnect your device by closing the socket
You need to check, If the devices are connected. If yes, call reset function
if (BluetoothDevice.ACTION_ACL_CONNECTED.equals(action)) {
resetConnection
}
ResetConnection function definition.
private void resetConnection() {
if (mBTInputStream != null) {
try {mBTInputStream.close();} catch (Exception e) {}
mBTInputStream = null;
}
if (mBTOutputStream != null) {
try {mBTOutputStream.close();} catch (Exception e) {}
mBTOutputStream = null;
}
if (mBTSocket != null) {
try {mBTSocket.close();} catch (Exception e) {}
mBTSocket = null;
}
}
Edit 1
You will have to create a new BluetoothSocket and then call this method getRemoteDevice().
getRemoteDevice ()
Added in API level 5
Get the remote device this socket is connecting or connected to.
Here is a link to Documentation BluetoothSocket

Connect bluetooth with getRemoteDevice() from BluetoothAdapter

I would like to manually connect a bluetooth device with its MAC address because it is faster and I know exactly which MAC to connect.
I use this method to get the BluetoothDevice : http://developer.android.com/reference/android/bluetooth/BluetoothAdapter.html#getRemoteDevice%28byte[]%29
But the Android doc does not say if Android ensure that the device is in range before creating the BluetoothDevice object.
Do you have this information ?
My code can automatically connect the device, and I would like to check if the target is in range before trying to connect, but without perform a large scan (which can be long...)
When local device connects to remote device using BluetoothSocket, an exception is required.
If remote device isn't in range, It's not found
private class ConnectThread extends Thread {
public ConnectThread(BluetoothDevice device, boolean isSecure, UUID sharedUUID) throws IncorrectSetupException {
try {
//Secure connections requires to get paired before connect
//Insecure connections allows to connect without pairing
if (isSecure) {
mSocket = device.createRfcommSocketToServiceRecord(sharedUUID);
} else {
mSocket = device.createInsecureRfcommSocketToServiceRecord(sharedUUID);
}
} catch (IOException e) {
//Is there some problem with the setup?
}
}
public void run() {
try {
mSocket.connect();
} catch (IOException e) {
//If device is not found, this exception is throwed
}
}
}

Use TCP in Internet

I'am use TCP for connect my android phone with Windows 7 PC. When I'am send message phone-PC in LAN this system is work, as i`am use this system in Internet she is down because android app send me "time out". Why?
// The host name can either be a machine name, such as "java.sun.com", or a
// textual representation of its IP address
String host = "10.26.144.118";
int port = 20;
try {
Socket socket = new Socket(InetAddress.getByName(host), port);
BufferedReader reader = new BufferedReader(
new InputStreamReader(socket.getInputStream()));
PrintWriter writer = new PrintWriter(socket.getOutputStream(), true);
// true for auto flush
writer.println("Hello World");
myView.setText("Send hello world");
} catch (Exception e) {
System.out.println("Error" + e);
myView.setText("Error" + e);
}
You are probably looking for port-forwarding
Your problem is that you mixed up the LAN (local area network) with the WAN (wide area network) aka the internet. Your personal LAN is protected from outside.
You need a static public IP or a DDNS (Dynamic DNS) solution e.g. dyndns. Than you have to forward the traffic from your public IP to you internal Server IP. See also thax's answer.
Than can your smartphone connect to your static public ip or to your DDNS address. Than should your app also work with the mobile network.

android socket communication through internet

I'm experimenting with socket communication between android and windows.
Everything works fine till i use the 10.0.2.2 address which is the loopback to the computer on which the emulator is running. But if i give any other address to the Socket constructor the connection is timing out.
My goal is to communicate between my phone and my computer through the internet.
I also tried it on my phone, so i don't think that it's a firewall problem.
Here is my code:
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
try {
clientSocket = new Socket("10.0.2.2", 48555);
Log.d("Offdroid", "socket connected");
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
System.out.println(e.toString());
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
System.out.println(e.toString());
}
}
public void connectServer(View button) {
try {
String message = "shutdown";
byte[] messageBytes = message.getBytes("US-ASCII");
int messageByteCount = messageBytes.length;
byte[] messageSizeBytes = new byte[2];
messageSizeBytes = intToByteArray(messageByteCount);
byte[] sendBytes = concatenateArrays(messageSizeBytes, messageBytes);
Log.d("Offdroid", Integer.toString(messageSizeBytes.length));
clientSocket.setReceiveBufferSize(16);
clientSocket.setSendBufferSize(512);
OutputStream outStream = clientSocket.getOutputStream();
//InputStream inStream = clientSocket.getInputStream();
outStream.write(sendBytes, 0, sendBytes.length);
} catch(Exception EX) {
Log.e("Offdroid", EX.getMessage());
}
}
I'm also looking for a java built in function instead of the concatenateArrays function which simply put two byte array together.
Edit:
Sorry, maybe i not provided enough information. I have already tried my external ip used for the internet connection and my LAN ip. Port on router is forwarded to my computer. So if i write "192.168.1.101" or the ip given by the internet service provider in place of "10.0.2.2", than i cannot connect.
Edit:
Ok, i figured out it was my firewall.
Emulator takes uses the same network as that of your computer, so it will be able to route it to the computer. But for your phone to connect with your computer, you have to give a different IP, which is basically the IP of the computer.
I am guessing you are using some shared Network, and getting this (10.0.2.2) IP. Your computer should be directly connected to Internet in order for this to work from phone.
Ok, i figured out it was my firewall.
When you use a real Android phone as Internet Remote device, don't you have to set up your WiFi router, connected to your PC (or Android), for Port Forwarding? Then you give your Android Client the PC Server's External IP Address and the Server Port Number. Only then, provided the Port Forwarding works on the router, your remote Android Client (on SIM) can communicate with your PC Server connected to your router.

Categories

Resources