Bluetooth Socket [isConnected()] - java

I have 3 activities that uses Bluetooth Connection/Communication.
On my first page, I connect to a bluetooth device already. When I move to another activity, I tried using this code:
BluetoothSocket btSocket;
try{
if(btSocket.isConnected(){
System.out.println("connected");
}
}
catch (Exception e{
}
I did not get anything in my Logcat at all and the Activity did not crash too. I'm not sure on how to use a Thread/Runnable for this Bluetooth Connection to stay in connection through activities and such. So I was thinking if this is possible?
Thanks.

Your current approach seem to fail with an NullPointerException, which will be catched by your Exception-Block. I would suggest you to implement a Background service which will handle the BT-connection in background. A sample could be found on the bottom of this page: http://developer.android.com/guide/topics/connectivity/bluetooth.html (Related Samples)

That is because you are ignoring the Exception that btSocket is null.
try
catch (Exception e{ e.printStackTrace ();
}
You will need to finad a way to pass you active Bluetooth connection to this method/activity.

Related

How to fix "java.io.IOException: read failed, socket might closed or timeout" when trying to connect to a paired device?

I've made a ListView with devices currently paired to my phone so that I can select one of them and connect to it. To determine which device was selected, I'm storing their MAC Addresses in an array so that I can get a device by its address. When I select a device, the app freezes for a bit then restores with no success of connecting. I cannot find the solution anywhere and I'm stuck. I'm still a beginner and do not understand much. An exception occurs that goes like:
java.io.IOException: read failed, socket might be closed or timeout, read ret: -1
Here is my code.
// If the UUID is incorrect then this one does not work as well
// 00001101-0000-1000-8000-00805f9b34fb
private static final UUID CONNECTION_UUID = UUID.fromString("0000110E-0000-1000-8000-00805F9B34FB");
public static boolean connectDevice(final int a) {
try {
BluetoothDevice mBluetoothDevice = btAdapter.getRemoteDevice(deviceAddress[a]);
BluetoothSocket mBluetoothSocket = mBluetoothDevice.createInsecureRfcommSocketToServiceRecord(CONNECTION_UUID);
btAdapter.cancelDiscovery();
mBluetoothSocket.connect();
mmOutputStream = new DataOutputStream(mBluetoothSocket.getOutputStream());
mmInputStream = new DataInputStream(mBluetoothSocket.getInputStream());
mBluetoothSocket.close();
} catch (NullPointerException e) {
e.printStackTrace();
return false;
} catch (Exception e) {
e.printStackTrace();
return false;
}
return true;
}
From the CONNECTION_UUID that you provided in your code, I assume that you are connecting with a Bluetooth serial board. I am not sure about the problem yet, however, I thought of writing this answer to provide a probable solution that might solve your issue.
I think in case of the paired devices, you need to initiate the connection with a secure channel. Currently, you are using an insecure channel.
From the documentation...
The communication channel will not have an authenticated link key i.e
it will be subject to man-in-the-middle attacks. For Bluetooth 2.1
devices, the link key will be encrypted, as encryption is mandatory.
For legacy devices (pre Bluetooth 2.1 devices) the link key will be
not be encrypted. Use createRfcommSocketToServiceRecord(UUID) if an
encrypted and authenticated communication channel is desired.
Hence you might consider using createRfcommSocketToServiceRecord() for your case.
Instead of this
BluetoothSocket mBluetoothSocket = mBluetoothDevice.createInsecureRfcommSocketToServiceRecord(CONNECTION_UUID);
Use this...
BluetoothSocket mBluetoothSocket = mBluetoothDevice.createRfcommSocketToServiceRecord(CONNECTION_UUID);
I hope that solves your problem.
From the comment below - The UUID that actually worked here is 00001101-0000-1000-8000-00805f9b34fb

How to handle data roaming when you use sockets in Android?

I'm programming a game in Android that uses AI, which requires big CPU power, that a normal Android device just doesn't have. So I decided to write a server in Java using sockets that will calculate everything and return a value to the client (the android device).
Now, I'm used to program for PC, but not for phones. In mobile, the IP of the device can change back and forth due to data roaming and WIFI.
My question is, how do you handle a changing IP? How do you tell a new connection is the same device? Or maybe the Android device does all of that automatically?
I'm new to stackoverflow, I hope I didn't ask too many questions. :)
Thank you very much for your answers!
You don't need to handle ip changing at all. A client(an android device) must know server host/ip and reconnect if it was disconnected from network, nothing more.
private static class ConnectionTask implements Runnable {
private boolean connected;
#Override public void run() {
try {
InetAddress serverAddress = InetAddress.getByName("host");
Socket socket = new Socket(serverAddress, 9999);
connected = true;
while (connected) {
// sending or writing data
}
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
//here you lost the connection due to some reason
//you need to notify user about the problem and wait for connection
}
}
}
To receive event about network state you need to register receiver:
context.registerReceiver(new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
if (isNetworkAvailable()) {
unregisterReceiver(this);
tryToConnect();
}
}
}, new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION));
Okay guys I figured out a way, thank to Fox in socks' answer.
Each time a user connects to the server socket, you take his UUID (or an hashed version of it, if you want more security :P ).
Then, when that user disconnects for some reason and tries to connect to the server socket again, he'll send the same UUID. That way, you can tell both of the connections are the same, and continue with the processing.
For more information about UUID, look here:
Is there a unique Android device ID?
Thank you all! :)
Now how do I mark this question as a closed one? :P

Using InetAddress to get own IP

I have an issue were if I try to InetAddress.getLocalHost() or even InetAddress.getByName(String host) it throws an exception every time even for a known website like nba.com I am a bit confused FYI the target device is an android 4.1.1 GS3 and wifi and mobile network are on. Code below
try{
InetAddress ownIP=InetAddress.getLocalHost();
System.out.println("IP of my Android := "+ownIP.getHostAddress());
}catch (Exception e){
System.out.println("Exception caught ="+e.getMessage());
String t = e.getMessage() + "yes";
}
Below is the System.out
03-12 18:59:52.636: I/System.out(18996): Exception caught =null
Thanks in advance
I use a tricky method to get my own IP. you can see whether it helps you
String getIP() {
try {
Socket socket = new Socket("google.com", 80);
return socket.getLocalAddress().getHostAddress();
} catch (Exception e) {
}
}
I believe I have found out what my issue was basically I guess you are not allowed to perform any network operations in the Main thread for android this was optional before and is now required for Honeycomb (API 11) and up below is the comment as per google specs.
"To prevent blocking the main user interface thread, Google recommends using the AsyncTask class from the android.os package:"
So all I was create a new class NetTask which extends AsyncTask and perform all network applications so now my code is working. IDK if everybody else knew that but I figured I would post this in case any newbs like me were still looking for a solution :) !!!
Thanks

Android bluetooth connection doesn't close after application crash

i'm using SPP profile for connect to my device:
Set<BluetoothDevice> devices = ba.getBondedDevices();
for(BluetoothDevice bd : devices)
{
String name = bd.getName();
if(name.equals("CELLMETER"))
{
try
{
BluetoothSocket bs = bd.createRfcommSocketToServiceRecord(UUID.fromString("00001101-0000-1000-8000-00805F9B34FB"));
bs.connect();
} catch (IOException e)
{
e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
}
}
}
All seems okay, i created function where i'm closing input output buffers and close socket.
But when application crashes or i'm stopping application when breakpoints arrives socket doesn't closes, even after i kill process manually and it's not avalible for new connection from new instance of app.
What i'm doing wrong? For each crash/debug operation i have to reboot phone :(
It's manifested only to Android 2.3.5 (Samsung 5830i) and on Android 4.0.4 (Freelander P10). On my Android 4.2.1 (Galaxy Nexus) all okay, after app crash connection closes automatically. (it seems because there is new Bluetooth stack)
I can see 2 options to work that out:
1- Add an UncaughtExceptionHandler in your app, best in Application-derived class:
mUEHandler = new Thread.UncaughtExceptionHandler()
{
#Override
public void uncaughtException(Thread t, Throwable e)
{
// Close any opened sockets here
defaultUEH.uncaughtException(t, e);
}
};
Thread.setDefaultUncaughtExceptionHandler(mUEHandler);
But that only takes care of app crashes. If user kills the app, won't get in there at all.
2- Store some socket identification that allow you to close it when app restarts.
It's not perfect, but that could work-around your issue.
I solved this problem by letting my BluetoothSockets be managed by a Service running in its own process. I open, close, read, and write the sockets by passing Messages to and from the Service. If the app crashes, the Service shuts down cleanly, closing the sockets. (It does not shut down cleanly if it's running in the same process as the app.)

Fail to connect to camera Service

I had seen many questions on stack but no one is telling if a Fail to connect to camera service will occur, how to get rid of this RuntimeException.
I have an camera application its working fine, I already take care to release the resources but if somehow user install the other application which not releasing the resources properly, my application facing RuntimeException: Fail to connect to camera Service and hence got crashed, want to avoid this situation.
If i click on original camera application it shows me a AlertDialog
Camera error: Cannot connect to camera.
That's what i exactly want to handle this. I am trying this code to handle it but cant succeed yet.
try {
camera = Camera.open();
camera.setDisplayOrientation(90);
} catch (RuntimeException e) {
// TODO: handle exception
Log.d("Inside RunTime exception", e+"//");
camera.setErrorCallback(errorCallback);
reConnectCameraVideo();
} catch(Exception e) {
finish();
}
but camera object returning null on camera.setErrorCallback because it wont open.
setErrorCallback() cannot be used for the case where the Camera will not open. You appear to be trying to still use the Camera -- AFAIK this is impossible until the user reboots their phone if some other app leaked the Camera. Simply display your own message to that effect.
Also:
Use an error logging service, like ACRA, Flurry, BugSense, etc.
Never blindly finish an activity due to an exception, as in your last catch block. Always do something to let the user and/or you (via the error logging service) know about the exception

Categories

Resources