【问题标题】:Connecting to device via bluetooth, locked app通过蓝牙连接到设备,锁定的应用程序
【发布时间】:2012-07-06 05:22:33
【问题描述】:

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

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

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 实现 Runnable 并覆盖了 run()。问题是 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。这适用于上面的应用程序吗?还是我在当前的实现中做错了什么?

【问题讨论】:

  • 我建议为 connectBluetooth() 部分使用服务。我相信在通过 Intent 传递或其他方式连接后,您可以将服务消息作为主要活动。好久没做安卓编程了,不太清楚。

标签: android bluetooth connection


【解决方案1】:

您的代码违反了有关 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 中实现所有连接(当然使用线程)就足够了。

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

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

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

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

【讨论】:

  • BlueToothChat 示例中的方法给了我一个服务发现错误。我查了资料,发现this link here
  • 编辑了上面的帖子。如果您能进一步帮助我,那就太好了
  • 通过将new Handler().post(Runnable r)更改为new Thread(Runnable r)然后执行Thread.start()解决了这个问题
【解决方案2】:

createRfcommSocket 的反射在某些设备上失败,因为“幕后”实现不同 - 对没有 SDP 的设备使用特殊的 UUID 00001101-0000-1000-8000-00805F9B34FB 应该可以为您解决问题

PS:请给那个问题加注星标 android issue http://code.google.com/p/android/issues/detail?id=5427 向谷歌展示像我们这样的用例存在..

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-01-27
    • 2016-11-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-01-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多