通过蓝牙,锁定的应用程序连接到设备

时间:2011-06-30 15:23:39

标签: android bluetooth connection

我正在尝试连接到实际可行的嵌入式设备但是当我连接它时消耗了大量资源,应用程序停止了一段时间后会在强制退出或等待对话框中响应。

在某处读取背景线程是解决此问题的方法,但我不知道如何实现它。我应该作为服务吗?..或?对我来说,实时编程是很久以前的事了,你们的一些帮助将不胜感激。

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();
}

它在sock.connect()失败了。那么我该如何解决这个问题呢?

修改 所以我一直在探索不同的选择,但它仍然锁定。现在我尝试将线程实现为Runnable,并通过Handler以下列方式执行它们:

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实施Runnablerun()覆盖。问题是UI线程仍然被锁定,我无法弄清楚如何。 ThreadHandler位于正在运行的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);
        }

    }
};

我即将尝试另一种方法,例如AsyncTask。这会对上面的应用程序有效吗?或者我在当前的实现中做了哪些不正确的事情?

2 个答案:

答案 0 :(得分:4)

您的代码违反了有关Android编程的基本规则,因为您无法在UI线程上执行任何耗时的工作(尤其是与网络相关的工作),因此您需要使用一些线程。只需按照Android蓝牙指南进行操作即可解释如何在各个线程中实现连接和连接状态。一切都在那里。

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

幸运的是,实际上你需要做很少的事情来启动和运行,因为上面链接中讨论的大多数编程已经在蓝牙聊天示例中为你完成了。您可以快速入门,因为它为您提供了一个可用于从中派生自己的应用程序的工作应用程序。

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

以上信息提供了有关如何在各个线程中处理蓝牙连接的所有信息。

现在,我认为,您是否使用单独的服务处理蓝牙网络的东西,确实是一个问题,您是否希望能够维持多个活动的蓝牙连接和/或在后台定期执行网络通信当用户在手机上做其他事情时。例如,我正在做的我的应用程序有几个Activity类(即几个不同的UI屏幕),它们都使用蓝牙连接到设备。在最初创建连接之后,我希望在用户在“活动”之间移动时保持连接。此外,我甚至希望在用户执行其他操作时将连接保留在后台,以便我的应用程序可以继续从设备进行数据记录。因此,对我来说,在服务中实施蓝牙网络至关重要。如果您只需要连接在单个Activity的持续时间内可用,而它位于前台,那么就可以在同一个Activity中实现所有连接(当然还可以使用线程)就像蓝牙聊天示例一样。

需要注意的是,使用服务本身将包含在其中的代码放在一个单独的线程中;您放入服务的任何内容仍在主UI线程中运行。如果您使用服务,您仍然希望在服务的单独线程中执行冗长的通信内容。

看起来您的应用程序与汽车相关,这就是我的应用程序。

最后需要注意的是,您通常需要对蓝牙聊天应用程序进行的一项基本修改是更改UUID,使其连接到远程设备的SPP(串行端口)配置文件。例如,如果您碰巧尝试与汽车OBD2通信到蓝牙适配器,那么它最有可能通过SPP交换串行数据。您将蓝牙聊天示例中的UUID更改为:

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

答案 1 :(得分:3)

createRfcommSocket的反映在某些设备上由于“引擎盖下”的不同实现而失败 - 对于没有SDP的设备使用特殊的UUID 00001101-0000-1000-8000-00805F9B34FB应该为你做的伎俩

PS:请注明问题android问题http://code.google.com/p/android/issues/detail?id=5427以向Google展示像我们这样的用例...