2

好的,我是 android 新手,我正在尝试创建一个通过蓝牙与 arduino 交互的应用程序。我已经看到了示例 BluetoothChat,并看到了它如何使用处理程序在“服务”、由它产生的线程和 MainActivity 之间进行通信。我的问题是我有多个活动需要使用蓝牙服务。对于每个活动,我都有一个这样的处理程序:

        mHandler = new Handler(){
        @Override
        public void handleMessage(Message message) {
            switch (message.what){
           case BtService.CHANGE_STATE:
               if (message.arg1 == BtService.STATE_CONNECTING){
                   Intent i = new Intent (MainActivity.this,ConnectedActivity.class);
                   startActivity(i);

               }
               break;
           }
        }

    };

在服务构造函数中我得到了这个:

    private BtService(){
    btm = BluetoothAdapter.getDefaultAdapter();
    mHandler= new Handler(Looper.getMainLooper());
}

当我需要发送消息时,我会这样做:

    private synchronized void setState(int state){
    mHandler.obtainMessage(CHANGE_STATE, state, -1).sendToTarget();
    mState = state;
}

但是在其他各种处理程序中没有收到消息。此处声明“特定线程的所有 Handler 对象都接收相同的消息” 。所以我无法理解这个问题。每次启动活动时,我是否需要将在该活动中声明的处理程序传递给服务以使其接收消息?这似乎有效,但对我来说似乎不是一个好习惯。

4

2 回答 2

5

如果您想在所有应用程序中发送消息,您应该使用 BroadcastReceiver,这是您情况下的最佳方式。

 Intent intent = new Intent(ApplicationConstants.MY_MESSAGE);
 LocalBroadcastManager.getInstance(context).sendBroadcast(intent);

在任何活动中接收消息(您可以在不止一个活动中使用它)

   BroadcastReceiver connectionUpdates = new BroadcastReceiver() {

        @Override
        public void onReceive(Context arg0, Intent intent) {

                     ...//TODO here
        }
    };
    LocalBroadcastManager.getInstance(this).registerReceiver(
            connectionUpdates ,
            new IntentFilter(ApplicationConstants.MY_MESSAGE));

希望这有帮助

干杯,

于 2013-06-21T13:38:46.197 回答
0

您可以扩展应用层并使用它来维护线程来检索和管理通过蓝牙连接收集的数据,而不是让每个活动都通过蓝牙连接。然后,如果需要,只需在每个活动中使用一个处理程序,让它们根据应用程序层中收集的数据进行刷新。

我唯一使用 btAdapter 和套接字的活动是第一个实际需要蓝牙信息的活动(在菜单和 bt 配置活动之后)。

在我的第一个活动中,onRusume() 看起来像这样,注释解释..:

@Override
public void onResume() {
super.onResume();

Log.d(TAG, "...onResume - try connect...");

// Set up a pointer to the remote node using it's address.
BluetoothDevice device = btAdapter.getRemoteDevice(address);

// Two things are needed to make a connection:
//   A MAC address, which we got above.
//   A Service ID or UUID.  In this case we are using the
//     UUID for SPP.
try {
  btSocket = device.createRfcommSocketToServiceRecord(MY_UUID);
} catch (IOException e) {
  errorExit("Fatal Error", "In onResume() and socket create failed: " + e.getMessage() + ".");
}

// Discovery is resource intensive.  Make sure it isn't going on
// when you attempt to connect and pass your message.
btAdapter.cancelDiscovery();

// 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", "In onResume() and unable to close socket during connection failure" + e2.getMessage() + ".");
  }
}

// Create a data stream so we can talk to server.
Log.d(TAG, "...Create Socket...");

/**
 * **Here I am kicking off the thread in the application that retrieves all data
 * needed by all my activities.  Then it stores the information in its member
 * variables.  Each activity then refreshes as often as needed, gets the data from
 * the application layer it needs and does some logic on it.**
 */
if(mConnectedThread == null) {
    mConnectedThread = app.new ConnectedThread(btSocket);
    mConnectedThread.start();
}

// This kicks off the handler for this activity that refreshes the activity every
// xxxx ms  and checks the data retrieved from bt in the application layer.
startUpdatingTicketView();
}

这几乎是我如何让它为我工作的核心。

只是一个额外的说明......我还尝试使用后台服务中管理的 bt 通信来执行此操作,但无法使其正常工作。我完全忘记了我遇到的问题是什么,使用服务很有可能也可以,但我最终没有走这条路。

祝你好运。

于 2013-06-13T13:38:37.687 回答