简体   繁体   中英

Connecting to device via bluetooth, locked app

I'm trying to connect to a embedded device which actually works but when i'm connecting it consumes alot of resources and the app comes to a halt which after some while will respond in a force quit or wait dialog.

Read somewhere that a backgroundthread would be the way to go about this but I don't know how to implement it. Should I do it as a service?.. or? Real-time programming was a long time ago for me and some help from you guys would be appreciated.

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.carsetup);
    car1 = (TextView) findViewById(R.id.carsetuptest1);
    car2 = (TextView) findViewById(R.id.carsetuptest2);
    car3 = (TextView) findViewById(R.id.carsetuptest3);
    Intent i = getIntent();
    selectedcar = (CarModule) i.getParcelableExtra("car");
    car1.setText(selectedcar.getRealname());
    car2.setText(selectedcar.getRealname());
    car3.setText(selectedcar.getAddress());

    try {
        for (int c = 0; c < 3; c++) {
            connectBluetooth();
        }
    } catch (Exception e) {
        e.printStackTrace();
    }

}
private void connectBluetooth() throws Exception {
    if (connected) {
        return;
    }
    BluetoothDevice car = BluetoothAdapter.getDefaultAdapter().
    getRemoteDevice(selectedcar.getAddress());
    Method m = car.getClass().getMethod("createRfcommSocket",
        new Class[] { int.class });
    sock = (BluetoothSocket)m.invoke(car, Integer.valueOf(1));
    Log.d(selectedcar.getRealname(), "++++ Connecting");
    sock.connect();
    Log.d(selectedcar.getRealname(), "++++ Connected");
}

}
@Override
public void onBackPressed() {
    setResult(RESULT_CANCELED);
    super.onBackPressed();
}

It's at sock.connect() it fails. So how would I go about this problem?

EDIT: So I've been exploring different options but it still locks up. Now I've tried to implement the threads as Runnable and execute them through a Handler in the following manner:

void connectBluetooth(boolean nextstage, IOException e1){
    if(!nextstage){
        showDialog(DIALOG_BT_ADDING);
        new Handler().post(new ConnectThread(ThreadHandler, selected_car.getDevice()));
    }
    else{
        if(e1 != null){
            new Handler().post(new BluetoothCheckThread(ThreadHandler,mBluetoothAdapter, 
                    5000, car_bt, after_bt));
            search_dialog.dismiss();
        }
        else{
            showDialog(DIALOG_BT_ADDING_FAILED);
        }


    }
}

ConnectThread implements Runnable and has run() overidden. The problem is that the UI thread is still locked up and I cannot figure out how. ThreadHandler is located in the running Activity :

Handler ThreadHandler = new Handler (){
    public void handleMessage(Message msg) {
        Log.i("MESSAGEHANDLER", "Message "+ msg.arg1 + " recieved" );
        if(msg.arg1 == 0){
            launchAndPrepare();
        }
        if(msg.arg1 == 1 || msg.arg1 == 2){
            search_dialog.dismiss();
            showDialog(DIALOG_BT_ADDING_FAILED);
        }

    }
};

I'm on the verge of trying another approach like AsyncTask . Will that work on the application above? Or have I done something incorrect in my current implementation?

Your code breaks a fundamental rule about Android programming in that you simply cannot perform any time-consuming work (especially network related) on the UI thread, so you need to use some threading. Just follow the Android Bluetooth guide which explains how to implement the connection and connected states in individual threads. It's all there.

http://developer.android.com/guide/topics/wireless/bluetooth.html

Fortunately there's very little you actually need to do to get up and running, because most of the programming discussed in the above link is already done for you in the Bluetooth Chat example. You can get started very quickly with this, as it gives you a working application that you can use to derive your own application from.

http://developer.android.com/resources/samples/BluetoothChat/index.html

The above information provides all you need to know regarding how to handle Bluetooth connectivity in individual Threads.

Now, whether you use a separate Service to handle the Bluetooth networking stuff is, I think, really a question of whether you want to be able to maintain the Bluetooth connection for several Activities and/or periodically perform network communications in the background when the user is doing other things on the phone. For instance, my application I'm currently doing has several Activity classes (ie several different UI screens) that all use a Bluetooth connection to a device. After the connection is initially created, I wish for the connection to remain up as the user moves between Activities. Furthermore, I even want the connection to remain in the background while the user is doing other stuff so that my application can continue to do datalogging from the device. Therefore, for me, implementing the Bluetooth networking in a Service was essential. If you only require the connection to be available for a duration of a single Activity while it's in the foreground, it may be sufficient to just implement it all within the same Activity (but of course using threads) just like the Bluetooth Chat example does.

What has to be noted is that using a Service in itself does not put the code contained within on a separate thread; anything you put into a Service is still running in the main UI thread. You'd still want to perform the long-winded communications stuff within separate threads in the Service, if you do use a Service.

It looks like your application is to be automotive related, which is what mine is.

On a final note, one basic modification you usually need to do to the Bluetooth Chat application straight away is to change the UUID so that it connects to the remote device's SPP (Serial Port) Profile. If, for example, you happen to be trying to talk to a car OBD2 to Bluetooth dongle, then it's most probably exchanging serial data over SPP. You change the UUID in the Bluetooth Chat example to:

// UUID for Serial Port Profile
private static final UUID MY_UUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");

the reflection of createRfcommSocket fails on some devices because of different implementations "under the hood" - using the special UUID 00001101-0000-1000-8000-00805F9B34FB for devices without SDP should do the trick for you

PS: please star that issue android issue http://code.google.com/p/android/issues/detail?id=5427 to show google that use-cases like ours exist..

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM