2017-03-03 494 views
0

我正試圖做一個應用程序,可以通過藍牙從arduino發送和接收數據。我發送數據的部分非常簡單,所以我設法正確。我被困在接收數據。如何使用藍牙讀取/接收數據?

我的程序有2個佈局。首先有一個帶有CONNECT按鈕和一些可以改變佈局的按鈕的佈局。這是代碼:

Public class MainActivity extends AppCompatActivity { 
ImageButton test, manual,connect; 
Button back; 

private BluetoothAdapter mbluetoothAdapter; 
protected AlertDialog.Builder builder; 
ConnectThread mBluetooth = new ConnectThread(); 
String mBluetoothName = ""; 
String mBluetoothAdress = ""; 

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.main); 
    final Context context = this; 
    //final LayoutInflater factory = getLayoutInflater(); 
    //final View textEntryView = factory.inflate(R.layout.activity_main); 
    builder = new AlertDialog.Builder(this); 
    mbluetoothAdapter = BluetoothAdapter.getDefaultAdapter(); 


    connect = (ImageButton) findViewById(R.id.connect); 
    test = (ImageButton) findViewById(R.id.test); 
    manual = (ImageButton) findViewById(R.id.manual); 


    test.setOnClickListener(new View.OnClickListener() { 
     @Override 
     public void onClick(View view) { 
      Intent intent = new Intent(context,SecondActivity.class); 
      context.startActivity(intent); 
     } 

    }); 
    manual.setOnClickListener(new View.OnClickListener() { 
     @Override 
     public void onClick(View view) { 
      Intent intent = new Intent(context,SecondActivity.class); 
      context.startActivity(intent); 
     } 

    }); 
    connect.setOnClickListener(new View.OnClickListener() { 
     @Override 
     public void onClick(View v) { 
      if (!mbluetoothAdapter.isEnabled()) { 
       Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE); 
       startActivity(enableBtIntent); 
      } else { 
       if (!mBluetooth.mBluetoothAddress.equals("")) {//if another connection is already exits then close it first 
        stopAllActivities(); 
       } else { 
        try { 
         Intent serverIntent = new Intent(MainActivity.this, DeviceListActivity.class); 
         startActivityForResult(serverIntent, Helper.REQUEST_CONNECT_DEVICE); 
        } catch (Exception e) { 
         showToast(getString(R.string.errorOccured) + ": " + e.getMessage()); 
         e.printStackTrace(); 
        } 
       } 
      } 
     } 
    }); 
} 

@Override 
public void onActivityResult(int requestCode, int resultCode, Intent data) { 
    switch (requestCode) { 
     case Helper.REQUEST_CONNECT_DEVICE: 
      if (resultCode == Activity.RESULT_OK) { 
       mBluetoothName = data.getExtras().getString(Helper.EXTRA_BLUETOOTH_NAME); 
       mBluetoothAdress = data.getExtras().getString(Helper.EXTRA_BLUETOOTH_ADDRESS); 

       // setBluetoothInfo(); 
       showToast(R.string.connectedDevice + mBluetoothName); 

       if (!mBluetoothAdress.equals("")) { 
        if (!mBluetooth.connect(mBluetoothAdress)){ 


        } 
       } 
      } 
      break; 
    } 
} 

SecondActivity包含此應用程序的主要目的:發送和接收數據。這是它的樣子:

public class SecondActivity extends AppCompatActivity { 
final Context context = this; 
Button back; 
ImageButton btnup, btndown, btnright, btnleft; 
ConnectThread mBluetooth = new ConnectThread(); 

@Override 
public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_main); 

btnup = (ImageButton) findViewById(R.id.btnup); 
btndown = (ImageButton) findViewById(R.id.btndown); 
btnleft = (ImageButton) findViewById(R.id.btnleft); 
btnright = (ImageButton) findViewById(R.id.btnright); 
final TextView direction = (TextView) findViewById(R.id.text_direction); 
final TextView steering = (TextView) findViewById(R.id.steering_direction); 
final TextView speed = (TextView) findViewById(R.id.speed); 
final TextView battery = (TextView) findViewById(R.id.batery); 
final Chronometer chronometer = (Chronometer) findViewById(R.id.chronometer); 

btndown.setOnTouchListener(new View.OnTouchListener() { 
    @Override 
    public boolean onTouch(View v, MotionEvent event) { 
     if (event.getAction() == MotionEvent.ACTION_DOWN) { 
      mBluetooth.write("2"); 
      direction.setText(R.string.Backwards); 
     } else if (event.getAction() == MotionEvent.ACTION_UP) { 
      mBluetooth.write("x"); 
      direction.setText(R.string.blank); 
     } 


     return false; 

    } 
}); 

注:我沒有發佈整個代碼,因爲我有更多的按鈕與上面完全相同的代碼。

藍牙連接我有2個單獨的類一個名爲ConnectThread:

public class ConnectThread { 
    BluetoothAdapter mBluetoothAdapter = null; 
    BluetoothSocket mSocket = null; 
    OutputStream mOutStream = null; 
    InputStream mInStream=null; 
    String mBluetoothAddress = ""; 

    public boolean connect(String bluetoothAddress) { 
     if (!mBluetoothAddress.equals(bluetoothAddress) && !mBluetoothAddress.equals("")) { 
      close(); 
     } 

     mBluetoothAddress = bluetoothAddress; 

     if (mBluetoothAdapter == null) { 
      mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter(); 
     } 

     if (mBluetoothAdapter == null) { 
      return false; 
     } 

     if (!mBluetoothAdapter.isEnabled()) { 
      return false; 
     } 

     try { 
      BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(mBluetoothAddress); 

      if (mSocket == null) { 
       mSocket = device.createRfcommSocketToServiceRecord(UUID.fromString("00001101-0000-1000-8000-00805F9B34FB")); 

       mSocket.connect(); 
      } 
     } catch (IOException e) { 
      mSocket = null; 

      e.printStackTrace(); 
      return false; 
     } 

     try { 
      mOutStream = mSocket.getOutputStream(); 
     } catch (IOException e) { 
      mOutStream = null; 

      e.printStackTrace(); 
      return false; 
     } 

     return true; 
    } 

    public boolean check() { 
     if (mBluetoothAdapter == null) { 
      mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter(); 
     } 

     if (mBluetoothAdapter == null) { 
      return false; 
     } 

     if (!mBluetoothAdapter.isEnabled()) { 
      return false; 
     } 
     if (!mSocket.isConnected()) { 
      return false; 
     } 

     return true; 
    } 

    public boolean close() { 
     try { 
      if (mOutStream != null) { 
       mOutStream.close(); 
      } 

      if (mSocket != null) { 
       mSocket.close(); 
      } 
     } catch (IOException e) { 
      e.printStackTrace(); 
      return false; 
     } 

     mOutStream = null; 
     mSocket = null; 

     return true; 
    } 

    public boolean write(String strData) { 
     byte[] buffer = strData.getBytes(); 

     try { 
      if (mOutStream != null && mBluetoothAdapter.getState() == BluetoothAdapter.STATE_ON) { 
       mOutStream.write(buffer); 
      } 
      else { 
       return false; 
      } 
     } catch (IOException e) { 
      e.printStackTrace(); 
      return false; 
     } 
     return true; 
    } 
} 

而另外一個DeviceListActivity:

public class DeviceListActivity extends Activity { 
    private BluetoothAdapter mBtAdapter; 
    private ArrayAdapter<String> mPairedDevicesArrayAdapter; 
    private ArrayAdapter<String> mNewDevicesArrayAdapter; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 

     // Setup the window 
     requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS); 
     setContentView(R.layout.device_list); 

     // Set result CANCELED incase the user backs out 
     setResult(Activity.RESULT_CANCELED); 

     // Initialize the button to perform device discovery 
     Button scanButton = (Button) findViewById(R.id.button_scan); 
     scanButton.setOnClickListener(new View.OnClickListener() { 
      public void onClick(View v) { 
       if (mBtAdapter == null) 
        return; 

       doDiscovery(); 
       v.setVisibility(View.GONE); 
      } 
     }); 

     // Initialize array adapters. One for already paired devices and 
     // one for newly discovered devices 
     mPairedDevicesArrayAdapter = new ArrayAdapter<String>(this, R.layout.device_name); 
     mNewDevicesArrayAdapter = new ArrayAdapter<String>(this, R.layout.device_name); 

     // Find and set up the ListView for paired devices 
     ListView pairedListView = (ListView) findViewById(R.id.paired_devices); 
     pairedListView.setAdapter(mPairedDevicesArrayAdapter); 
     pairedListView.setOnItemClickListener(mDeviceClickListener); 

     // Find and set up the ListView for newly discovered devices 
     ListView newDevicesListView = (ListView) findViewById(R.id.new_devices); 
     newDevicesListView.setAdapter(mNewDevicesArrayAdapter); 
     newDevicesListView.setOnItemClickListener(mDeviceClickListener); 

     // Register for broadcasts when a device is discovered 
     IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND); 
     this.registerReceiver(mReceiver, filter); 

     // Register for broadcasts when discovery has finished 
     filter = new IntentFilter(BluetoothAdapter.ACTION_DISCOVERY_FINISHED); 
     this.registerReceiver(mReceiver, filter); 

     // Get the local Bluetooth adapter 
     mBtAdapter = BluetoothAdapter.getDefaultAdapter(); 
     if (mBtAdapter == null) { 
      mPairedDevicesArrayAdapter.add("DUMMY\n00:00:00:00:00:00"); 
      return; 
     } 

     // Get a set of currently paired devices 
     Set<BluetoothDevice> pairedDevices = mBtAdapter.getBondedDevices(); 

     // If there are paired devices, add each one to the ArrayAdapter 
     if (pairedDevices.size() > 0) { 
      findViewById(R.id.title_paired_devices).setVisibility(View.VISIBLE); 
      for (BluetoothDevice device : pairedDevices) { 
       mPairedDevicesArrayAdapter.add(device.getName() + "\n" + device.getAddress()); 
      } 
     } else { 
      String noDevices = getResources().getText(R.string.none_paired).toString(); 
      mPairedDevicesArrayAdapter.add(noDevices); 
     } 
    } 

    @Override 
    protected void onDestroy() { 
     super.onDestroy(); 

     // Make sure we're not doing discovery anymore 
     if (mBtAdapter != null) 
      mBtAdapter.cancelDiscovery(); 

     // Unregister broadcast listeners 
     this.unregisterReceiver(mReceiver); 
    } 

    /** 
    * Start device discover with the BluetoothAdapter 
    */ 
    private void doDiscovery() { 
     if (mBtAdapter == null) 
      return; 

     // Indicate scanning in the title 
     setProgressBarIndeterminateVisibility(true); 
     setTitle(R.string.scanning); 

     // Turn on sub-title for new devices 
     findViewById(R.id.title_new_devices).setVisibility(View.VISIBLE); 

     // If we're already discovering, stop it 
     if (mBtAdapter.isDiscovering()) { 
      mBtAdapter.cancelDiscovery(); 
     } 

     // Request discover from BluetoothAdapter 
     mBtAdapter.startDiscovery(); 
    } 

    // The on-click listener for all devices in the ListViews 
    private AdapterView.OnItemClickListener mDeviceClickListener = new AdapterView.OnItemClickListener() { 
     public void onItemClick(AdapterView<?> av, View v, int arg2, long arg3) { 
      if (mBtAdapter != null) { 
       // Cancel discovery because it's costly and we're about to connect 
       mBtAdapter.cancelDiscovery(); 
      } 

      // Get the device MAC address, which is the last 17 chars in the View 
      String info = ((TextView) v).getText().toString(); 
      String name = info.substring(0, info.length() - 18); 
      String address = info.substring(info.length() - 17); 

      // Create the result Intent and include the MAC address 
      Intent intent = new Intent(); 
      intent.putExtra(Helper.EXTRA_BLUETOOTH_ADDRESS, address); 
      intent.putExtra(Helper.EXTRA_BLUETOOTH_NAME, name); 

      // Set result and finish this Activity 
      setResult(Activity.RESULT_OK, intent); 

      finish(); 
     } 
    }; 

    // The BroadcastReceiver that listens for discovered devices and 
    // changes the title when discovery is finished 
    private final BroadcastReceiver mReceiver = new BroadcastReceiver() { 
     @Override 
     public void onReceive(Context context, Intent intent) { 
      String action = intent.getAction(); 

      // When discovery finds a device 
      if (BluetoothDevice.ACTION_FOUND.equals(action)) { 
       // Get the BluetoothDevice object from the Intent 
       BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); 
       // If it's already paired, skip it, because it's been listed already 
       if (device.getBondState() != BluetoothDevice.BOND_BONDED) { 
        for (int i = 0; i < mNewDevicesArrayAdapter.getCount(); i++) { 
         if (mNewDevicesArrayAdapter.getItem(i).equals(device.getName() + "\n" + device.getAddress())) { 
          return; 
         } 
        } 
        mNewDevicesArrayAdapter.add(device.getName() + "\n" + device.getAddress()); 
       } 
       // When discovery is finished, change the Activity title 
      } else if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)) { 
       setProgressBarIndeterminateVisibility(false); 
       setTitle(R.string.select_device); 
       if (mNewDevicesArrayAdapter.getCount() == 0) { 
        String noDevices = getResources().getText(R.string.none_found).toString(); 
        mNewDevicesArrayAdapter.add(noDevices); 
       } 
      } 
     } 
    }; 
} 

我想更新兩個TextView的與我從Arduino的接收數據。數據看起來像#first_data,second_data *,其中#是數據序列的開始和*結束。如果你能幫助我一些建議/代碼如何做到這一點,我將不勝感激。我對Java很新,而且我還沒有完全理解一切是如何工作的。

回答

0

一旦你獲得藍牙套接字,你可以使用它的流來讀/寫內容。

... 
m_Input = new DataInputStream(new BufferedInputStream(socket.getInputStream())); 
m_Output = new DataOutputStream(new BufferedOutputStream(socket.getOutputStream())); 
... 
// reading from stream 
m_Input.read(buffer, readBytes, 1) ; 

你可以使用 m_Input.available() 檢查是否可用到流的任何數據。否則,讀取方法將被阻塞,直到您讀取您指定爲第三個參數的字節數。

int readBytes=0; 
while(readBytes < expectedBytes){ 
    timeout = 0; 
    while((m_Input.available()) == 0 && timeout < ReadTimeout) { 
    timeout+=250; 
    // throws interrupted exception 
    Thread.sleep(250);// let control to other threads 
    } 
    if(timeout >= ReadTimeout){ 
     // throw new timeout exception 
    } 
    if (m_Input.read(buffer, readBytes, 1) == -1) { 
     // throw stream/socket closed 
    } 
    readBytes++; 
} 

信息寫入使用寫入方法

...  
//writting to stream 
    m_Output.write(buffer,..); 
+0

我應該在哪裏寫的?我正在嘗試閱讀SecondActivty –

相關問題