2013-06-13 105 views
1

好吧,我是新來的android,我試圖創建一個應用程序,通過藍牙與arduino接口。我已經看到了藍牙示例,並看到它如何使用處理程序在「服務」,由它產生的線程和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; 
} 

但在各種其他處理程序中未收到消息。 在here中聲明「特定線程的所有Handler對象都接收相同的消息。」所以我不明白這個問題。 每次開始活動時,我是否都需要傳遞給Handler在該Activity中聲明的服務以使其接收消息?這似乎有效,但對我來說這似乎不是一個好習慣。

回答

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通信,並不能得到它的工作。我確切地忘記了我遇到的問題是什麼,並且很可能使用服務也是可行的,但我並沒有最終走上這條路。

祝你好運。

+0

很抱歉,如果我沒有做我自己很清楚,但是「真實」的問題是:「一個線程的所有處理程序是否都收到相同的消息,正如API培訓中所述,或者如果我理解錯誤是真的。無論如何,謝謝你的回答 – Campig

3

如果你想在所有應用程序中發送消息,你應該使用BroadcastReceiver,我這是你的情況下最好的方法。

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

的任何活動,接收信息(你CAND在不止一個活動使用)

BroadcastReceiver connectionUpdates = new BroadcastReceiver() { 

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

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

希望這是有益的

乾杯,