I have a part of code in which I firstly setText, then make a Toast and after that I'm trying to connect via Bluetooth. The problem is that my setText and Toasts appear only after connection has been made.
I tried to put Log.i instead of Toasts and they were shown simultaneously.
Can somebody explain me why and how to make Toasts simultaneously?
Code:
........
else if (BluetoothDevice.ACTION_ACL_DISCONNECTED.equals(action)) {
tvDevices.setText("");
Toast.makeText(getApplicationContext(), "Lost connection!", Toast.LENGTH_SHORT).show();
connect(btDevice, ConstantsVariables.reconnectionAttempts);
}
public void connect(BluetoothDevice bt, int attempts){
Toast.makeText(getApplicationContext(), "Trying to connect...", Toast.LENGTH_SHORT).show();
if(attempts > 0){
for(int i = 1; i <= ConstantsVariables.reconnectionAttempts; i++){
ConnectThread thread = new ConnectThread(bt);
boolean connectVar = thread.connect();
if(connectVar){
break;
}
}
}
}
.......
public boolean connect() {
BA.cancelDiscovery();
try {
mSocket.connect();
} catch (IOException e) {
Log.d("CONNECTTHREAD","Could not connect: " + e.toString());
try {
mSocket.close();
} catch (IOException exception){}
return false;
}
return true;
}
It is possible that you're blocking the UI Thread while connection is being attempted. Try to move the connection code to a background thread, or an AsyncTask, and handle the UI Changes in the AsyncTask's callbacks.
Edit: Also the context getApplicationContext() passed to Toast is ambiguous. Are you in an activity? In that case it should simply point to the Activity's context i.e. this and not the Application's context
Related
I'm trying to connect to a TCP/IP socket in a thread the moment my app is opened, and would like to show a progress dialog while connecting. The problem is that the thread is always executed before the progress dialog is shown, which means that it is shown only after the socket connection has actually happened (or failed).
public static boolean startConnection (Context c) {
boolean[] ret = new boolean[1];
ProgressDialog progressDialog = new ProgressDialog(c);
progressDialog.setMessage("Connecting...");
progressDialog.show();
Thread t = new Thread() {
#Override
public void run() {
try {
clientSocket = new Socket();
clientSocket.connect(new InetSocketAddress(SERVER_IP, SERVER_PORT), 5000);
ret[0] = true;
}
catch (IOException e) {
e.printStackTrace();
ret[0] = false;
}
((Activity)c).runOnUiThread(progressDialog::dismiss);
}
};
t.start();
try {
t.join();
}
catch (InterruptedException e) {
e.printStackTrace();
}
return ret[0];
}
And I'm invoking startConnection in the onStart() method:
protected void onStart() {
super.onStart();
if (ConnectionHandler.startConnection(this)) {
goToMainActivity();
}
else {
Toast.makeText(this, "Connection error.", Toast.LENGTH_LONG).show();
}
}
How can I make it so that the progress dialog is shown before the thread actually starts?
t.join(); waits on the UI main thread until second thread t finishes, that's the reason your code is blocking the UI thread and the dialog doesn't appear.
In addition you can't call progressDialog.dismiss(); on the t thread, all code that interacts with the UI must be called on the main thread, you can try tom call it using runOnUIThread() activity method
Apologies, I know this question has been asked a couple times.
But I've tried the suggested solution and have had no success.
In my Android app, I started randomly getting this error out of nowhere, I didn't modify the code, it ran fine a couple of times, and now it shows me this error:
`E/ViewRootImpl: sendUserActionEvent() mView == null`
It happens when I call my java class where I set up a BluetoothConnectionService. Specifically, it occurs when the method to dismiss a Progress Dialog box is called.
`public ConnectedThread(BluetoothSocket mSocket) {
Log.d(TAG, "ConnectedThread: Starting");
mmBTSocket = mSocket;
InputStream mTempIn = null;
OutputStream mTempOut = null;
// dismiss the progressdialog when the connection is established.
try{
mProgressDialog.dismiss();
} catch (NullPointerException e) {
Log.e(TAG, "ConnectedThread: Couldn't dismiss progressDialogBox" + e.getMessage(), e);
}
try {
mTempIn = mmBTSocket.getInputStream();
mTempOut = mmBTSocket.getOutputStream();
} catch (IOException e) {
Log.e(TAG, "ConnectedThread: Failed to get I/O Stream: " + e.getMessage(), e);
}
mInStream = mTempIn;
mOutStream = mTempOut;
}`
In the Dialog.java file, I think it is occurring in this method.
`#Override
public void dismiss() {
if (Looper.myLooper() == mHandler.getLooper()) {
dismissDialog();
} else {
mHandler.post(mDismissAction);
}
}`
Previous suggestions for this error which I have found here on stackoverflow, haven't worked. I have tried adding the following code to my AndroidManifest which didn't work:
` android:name=".MainActivity"
android:configChanges="keyboardHidden|orientation|screenLayout|screenSize"
android:label="#string/app_name"`
Please, any suggestions would help as I had the app mostly finished before this started happening and I can't figure out why!!
You need to check if your context is getting null. This mostly happens when context or view to which you are pointing becomes null. Just try to implement following checks before calling that:
if ( getContext() != null && getView != null )
{
// do your stuff here
}
Also you need to update views on main thread. If you are not on a main thread then you should implement handler to update your UI components. Visit following link for details:
https://developer.android.com/training/multiple-threads/communicate-ui
Do the following:
Handler handler = new Handler(); // write in onCreate function
handler.post(new Runnable() {
#Override
public void run()
{
// Update your UI components here
}
});
I have use The AsyncTask For connecting Internet. a Progress dialog can show at onPreExecute() and i check is Online of that mobile if yes means it will execute the http connections code also dismiss the progress dialog at onPostExecute() and its work as good.
But i have problem if net connection is available at time of Request and connection closed before get Response means the Progress dialog showing always.
Now i want solve this if interconnect disconnect before get Response mean it's alert me as No internet connection and dismiss the progress dialog (may set loading time limit for 30 seconds).
below is my code.
can any one help?
public class SubjectTask extends AsyncTask<Void, Void, Integer> {
#Override
protected void onPreExecute() {
progressDialog = ProgressDialog.show(Login.this, "Loading",
"Please wait...");
//checkConnection();
}
#Override
protected Integer doInBackground(Void... arg0) {
if (isOnline()) { //using ConnectivityManager And Network Info
try {
//Http Request connections
} catch (Exception e) {
e.printStackTrace();
}
return 1;
} else {
alert("Check your internet connection");
return 0;
}
}
protected void onPostExecute(Integer result) {
super.onPostExecute(result);
if (progressDialog.isShowing()) {
progressDialog.dismiss();
}
}
}
You can use broadcast receiver to get the event of network connect or disconnect. register this receiver in doInbackground method and unregister it in onPostExecute method.
broadcastReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
ConnectivityManager connectivity = (ConnectivityManager) context
.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo info = connectivity.getActiveNetworkInfo();
//Play with the info about current network state
if(info.getState()== NetworkInfo.State.DISCONNECTED) {
// hide loader and show alert here
}
}
}
};
intentFilter = new IntentFilter();
intentFilter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
registerReceiver(broadcastReceiver, intentFilter);
If the connection will be closed before or while the http request an IOException will be thrown. Catch that exception and close your Dialog there and inform the user about this event.
if (isOnline()) { //using ConnectivityManager And Network Info
try {
//Http Request connections
} catch (IOException e) {
e.printStackTrace();
// Do the error handling here
} catch (ClientProtocolException e) {
e.printStackTrace();
}
}
I don't know if you really need a return value to your onPostExecute(). If yes consder to make the logic aware that an exception could occur.
i thank to Steve Benettand Bhawna Raheja,
sorry for the late reply,
Simply i have solve this error by set Timeout via HttpRequest.TimeOut .
i dont know how i forgot to set time out.
One again thank to You both.
I've been trying to create a function in my app that consist in a bluetooth RFID scanner, it's paired to my device and I have it working and all.
I can receive the text and log it in the console, when I compile the activity, everything goes fine, the stick reads the code, and then appends the text into an EditText, but if I go back and enter the activity again, I can see the code in the log, but the text doesn't go to the Edittext.
I tried a lot of different approaches, but nothing seems to work :/
here's the code I have:
/**
* Called when the activity is first created.
*/
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.bluetooth);
mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
Set<BluetoothDevice> bondedSet = mBluetoothAdapter.getBondedDevices();
if (mBluetoothAdapter == null) {
Toast.makeText(this, "Bluetooth is not available.", Toast.LENGTH_LONG).show();
}
if (!mBluetoothAdapter.isEnabled()) {
Toast.makeText(this, "Please enable your BT and re-run this program.", Toast.LENGTH_LONG).show();
finish();
}
if (mBluetoothAdapter.isEnabled()) {
if(bondedSet.size() == 1){
for(BluetoothDevice device : bondedSet){
address = device.getAddress();
Log.d("bt:", address);
}
}
}
String address = "00:A0:96:2A:0A:1B";
out = (EditText) findViewById(R.id.output);
BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(address);
Log.d(TAG, device.getName() + " connected");
myConnection = new ConnectThread(device);
myConnection.start();
}
private class ConnectThread extends Thread {
private final BluetoothSocket mySocket;
Message msg;
public ConnectThread(BluetoothDevice device) {
BluetoothSocket tmp = null;
try {
tmp = device.createRfcommSocketToServiceRecord(MY_UUID);
} catch (IOException e) {
Log.d(TAG, "CONNECTION IN THREAD DIDNT WORK");
}
mySocket = tmp;
}
Handler uiThreadHandler = new Handler() {
public void handleMessage(Message msg) {
out = (EditText) findViewById(R.id.output);
Object o = msg.obj;
out.append(o.toString().trim());
Log.d("handler", o.toString());
}
};
public void run() {
out = (EditText) findViewById(R.id.output);
Log.d(TAG, "STARTING TO CONNECT THE SOCKET");
setName("My Connection Thread");
InputStream inStream = null;
boolean run = false;
mBluetoothAdapter.cancelDiscovery();
try {
mySocket.connect();
run = true;
} catch (IOException e) {
Log.d(TAG, this.getName() + ": CONN DIDNT WORK, Try closing socket");
try {
mySocket.close();
Log.d(TAG, this.getName() + ": CLOSED SOCKET");
} catch (IOException e1) {
Log.d(TAG, this.getName() + ": COULD CLOSE SOCKET", e1);
this.destroy();
}
run = false;
}
synchronized (BluetoothActivity.this) {
myConnection = null;
}
byte[] buffer = new byte[1024];
int bytes;
// handle Connection
try {
inStream = mySocket.getInputStream();
while (run) {
try {
bytes = inStream.read(buffer);
readMessage = new String(buffer, 0, bytes);
msg = uiThreadHandler.obtainMessage();
msg.obj = readMessage;
uiThreadHandler.sendMessage(msg);
Log.d(TAG, "Received: " + readMessage);
} catch (IOException e3) {
Log.d(TAG, "disconnected");
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
My guess is that this has something to do with the Thread itself. When you start your Activity for the first time, you also call .start() on the Thread, that would work fine.
The problem is when you leave your Activity and open it up again. In that case, one of onStop() or onPause() is called (depending on situation), and onRestart() or onResume() will be called afterwards respectively.
The trick comes now: Meanwhile all that process, your Thread is still running. As you show your code, it has not been stopped/paused, and keeps running all the time. So basically my tip is that there's something you do within your onCreate() method of your Activity that should also be done in your onPause() and onStop() events, and my another tip it's somewhere within your ConnectThread(BluetoothDevice device) method.
To know how to procceed, I'd firstly define both onStop() and onPause() methods within your Activity and see which is fired, log every attribute to see its value/state, and that way you'll be able to debug what is failing.
There's a diagram of the Activity lifecycle.
Problem was solved, the code works, and the TextView get the inputstream, the problem was when i left the activity, the thread continued to work, so far, no problem at all, after TONS of hours spent on this, i turn the TextView a static var and it worked :)
If anyone reads this, i hope it helps.
I'm currently trying to fix a problem I encountered with my Android app which require a Bluetooth connection. For a moment everything seem to work right, But i noticed something strange when the slave Bluetooth device, I want to connect with, is not powered on. Here is my code :
private void connectDevice() {
mBluetoothAdapter.cancelDiscovery();
BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(address);
try {
btSocket = createBluetoothSocket(device);
} catch (IOException e) {
errorExit("Fatal Error", "Socket create failed: " + e.getMessage() + ".");
}
//Try to establish the connection. This will block until it connects.
Log.d(TAG, "...Connecting...");
try {
btSocket.connect();
Log.d(TAG, "....Connection ok...");
} catch (IOException e) {
try {
btSocket.close();
} catch (IOException e2) {
errorExit("Fatal Error", "Unable to close socket during connection failure" + e2.getMessage() + ".");
}
}
//Create a data stream so we can talk to server.
Log.d(TAG, "...Create Socket...");
mConnectedThread = new ConnectedThread(btSocket);
mConnectedThread.start();
mActionBar.setSubtitle("Connected");
return;
}
And here is where I call this method :
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
switch(requestCode){
case REQUEST_ENABLE_BT:
if (resultCode == RESULT_OK) {
Toast.makeText(this, R.string.bt_enabled, Toast.LENGTH_SHORT).show();
setupCom();
break;
}
else {
// User did not enable Bluetooth or an error occurred
if(D) Log.d(TAG, "BT not enabled");
Toast.makeText(this, R.string.bt_not_enabled_leaving, Toast.LENGTH_SHORT).show();
finish();
break;
}
case REQUEST_CONNECT_DEVICE:
if (resultCode == RESULT_OK){
retrieveAddresse(data);
connectDevice();
}
break;
}
return;
}
My problem is that, when I'm not in range or the device I want to connect to is not powered on, the connectDevice() method seem to execute all the code even if it's not possible to connect because Android OS don't want to be blocked by the connection process. I noticed this problem because mActionBar.setSubtitle("Connected"); get executed and because when I try to reconnect when I'm in range or the slave bluetooth module is ON. I can't connect to it unless I relaunch my application.
Put these lines :
mConnectedThread = new ConnectedThread(btSocket);
mConnectedThread.start();
mActionBar.setSubtitle("Connecté");
inside the first try. In this way they will be executed only if the devices establish a connection. As actually they are outside try/catch, they will always executed, even without connection.