如何通过蓝牙获取InputStream并放入Textview?

use*_*122 3 android bluetooth inputstream textview

这是我在SO中的第一个问题.我是新的(并且很兴奋)在Android编程中,这是我的问题:我正在使用我的Android手机和微控制器构建项目.微控制器有一个距离传感器并传输其值.我已经设法连接到微控制器并发送正确的信号,但我无法获得距离测量或其他任何东西.应用程序不会崩溃或任何它不会从微控制器获取数据(我的计算机从微控制器获取数据(数据是字符串)).我的Android应用程序的代码是这样的:

公共类Accelerometer扩展Activity {

// Intent request codes
private static final int REQUEST_CONNECT_DEVICE = 1;
private static final int REQUEST_ENABLE_BT = 2;
private static final int RECIEVE_MESSAGE = 3;

// Program variables
private byte microcOut;
private boolean ledStat;
private boolean connectStat = false;
private Button btnled;
private Button connect_button;
private TextView yAccel, xAccel, incoming;
protected static final int MOVE_TIME = 80;
private long lastWrite = 0;
OnClickListener myClickListener;
ProgressDialog myProgressDialog;
private Toast failToast;
private Handler mHandler,h;
private StringBuilder sb = new StringBuilder();

// Sensor object used to handle accelerometer
private SensorManager mySensorManager; 
private List<Sensor> sensors; 
private Sensor accSensor;

// Bluetooth Stuff
private BluetoothAdapter btAdapter = null;
private BluetoothSocket btSocket = null; 
private OutputStream outStream = null;
private InputStream inStream = null;
private ConnectThread mConnectThread = null;
private ConnectedThread mConnectedThread;

private String deviceAddress = null;
// Well known SPP UUID (will *probably* map to RFCOMM channel 1 (default) if not in use); 
private static final UUID SPP_UUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");

//Sound Clip to make app prettier
MediaPlayer myclip;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
    setContentView(R.layout.activity_accelerometer);
    myclip = MediaPlayer.create(this, R.raw.cartcar);
    myclip.start();
     // Finds buttons in .xml layout file
    btnled = (Button) findViewById(R.id.led_button1);
    connect_button = (Button) findViewById(R.id.connect_button1);
    yAccel = (TextView) findViewById(R.id.accText1);
    xAccel = (TextView) findViewById(R.id.accText2);
    incoming = (TextView) findViewById(R.id.incoming);
    // Set Sensor
    mySensorManager = (SensorManager)getSystemService(Context.SENSOR_SERVICE); 
    sensors = mySensorManager.getSensorList(Sensor.TYPE_ACCELEROMETER);
    if(sensors.size() > 0) accSensor = sensors.get(0);

    myProgressDialog = new ProgressDialog(this);
    failToast = Toast.makeText(this, R.string.failedToConnect, Toast.LENGTH_SHORT);
    mHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
         if (myProgressDialog.isShowing()) {
                myProgressDialog.dismiss();
            }

         // Check if bluetooth connection was made to selected device
            if (msg.what == 1) {
                // Set button to display current status
                connectStat = true;
                connect_button.setText(R.string.connected);

                // Reset the BluCar
                microcOut = 0;
                ledStat = false;
                write(microcOut);
            }else {
                // Connection failed
             failToast.show();
            }
        }
    };


    h = new Handler() {
        public void handleMessage(android.os.Message msg) {
            switch (msg.what) {
            case RECIEVE_MESSAGE:                                                   // if receive massage
                byte[] readBuf = (byte[]) msg.obj;
                String strIncom = new String(readBuf, 0, msg.arg1);                 // create string from bytes array
                sb.append(strIncom);                                                // append string
                int endOfLineIndex = sb.indexOf("\r\n");                            // determine the end-of-line
                if (endOfLineIndex > 0) {                                            // if end-of-line,
                    String sbprint = sb.substring(0, endOfLineIndex);               // extract string
                    sb.delete(0, sb.length());                                      // and clear
                    incoming.setText("Data from Arduino: " + sbprint);            // update TextView 
                }
                //Log.d(TAG, "...String:"+ sb.toString() +  "Byte:" + msg.arg1 + "...");
                break;
            }
        };
    };
 // Check whether bluetooth adapter exists
    btAdapter = BluetoothAdapter.getDefaultAdapter(); 
    if (btAdapter == null) { 
         Toast.makeText(this, R.string.no_bt_device, Toast.LENGTH_LONG).show(); 
         finish(); 
         return; 
    } 

    // If BT is not on, request that it be enabled.
    if (!btAdapter.isEnabled()) {
        Intent enableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
        startActivityForResult(enableIntent, REQUEST_ENABLE_BT);
    }
    /**********************************************************************
     * Buttons for controlling BluCar
     */
    connect_button.setOnClickListener(new View.OnClickListener() {

        // Connect to Bluetooth Module
        @Override
        public void onClick(View v) {
            if (connectStat) {
                // Attempt to disconnect from the device
                disconnect();
            }else{
                // Attempt to connect to the device
                connect();
            }
        }
    });

    // Toggle Headlights
    btnled.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            if (ledStat) {
                microcOut = (byte) (microcOut & 124);
                btnled.setText(R.string.ledbuttonON);
                ledStat = false;
            }else{
                microcOut = (byte) (microcOut | 128);
                btnled.setText(R.string.ledbuttonOFF);
                ledStat = true;
            }
            write(microcOut);
        }
    });

}
/** Thread used to connect to a specified Bluetooth Device */
public class ConnectThread extends Thread {
private String address;
private boolean connectionStatus;

    ConnectThread(String MACaddress) {
        address = MACaddress;
        connectionStatus = true;
}

    public void run() {
    // When this returns, it will 'know' about the server, 
       // via it's MAC address. 
        try {
            BluetoothDevice device = btAdapter.getRemoteDevice(address);

            // We need two things before we can successfully connect 
            // (authentication issues aside): a MAC address, which we 
            // already have, and an RFCOMM channel. 
            // Because RFCOMM channels (aka ports) are limited in 
            // number, Android doesn't allow you to use them directly; 
            // instead you request a RFCOMM mapping based on a service 
            // ID. In our case, we will use the well-known SPP Service 
            // ID. This ID is in UUID (GUID to you Microsofties) 
            // format. Given the UUID, Android will handle the 
            // mapping for you. Generally, this will return RFCOMM 1, 
            // but not always; it depends what other BlueTooth services 
            // are in use on your Android device. 
            try { 
                 btSocket = device.createRfcommSocketToServiceRecord(SPP_UUID); 
            } catch (IOException e) { 
                connectionStatus = false;
            } 
        }catch (IllegalArgumentException e) {
            connectionStatus = false;
        }

       // Discovery may be going on, e.g., if you're running a 
       // 'scan for devices' search from your handset's Bluetooth 
       // settings, so we call cancelDiscovery(). It doesn't hurt 
       // to call it, but it might hurt not to... discovery is a 
       // heavyweight process; you don't want it in progress when 
       // a connection attempt is made. 
       btAdapter.cancelDiscovery(); 

       // Blocking connect, for a simple client nothing else can 
       // happen until a successful connection is made, so we 
       // don't care if it blocks. 
       try {
            btSocket.connect(); 
       } catch (IOException e1) {
            try {
                 btSocket.close(); 
            } catch (IOException e2) {
            }
       }

       // Create a data stream so we can talk to server. 
       try { 
        outStream = btSocket.getOutputStream(); 
       } catch (IOException e2) {
        connectionStatus = false;
       }

       // Send final result
       if (connectionStatus) {
        mHandler.sendEmptyMessage(1);
       }else {
        mHandler.sendEmptyMessage(0);
       }
    }
}
public void onActivityResult(int requestCode, int resultCode, Intent data) {
     switch (requestCode) {
       case REQUEST_CONNECT_DEVICE:
         // When DeviceListActivity returns with a device to connect
           if (resultCode == Activity.RESULT_OK) {
            // Show please wait dialog
            myProgressDialog = ProgressDialog.show(this, getResources().getString(R.string.pleaseWait), getResources().getString(R.string.makingConnectionString), true);

            // Get the device MAC address
            deviceAddress = data.getExtras().getString(DeviceList.EXTRA_DEVICE_ADDRESS);
            // Connect to device with specified MAC address
              mConnectThread = new ConnectThread(deviceAddress);
              mConnectThread.start();

           }else {
             // Failure retrieving MAC address
             Toast.makeText(this, R.string.macFailed, Toast.LENGTH_SHORT).show();
           }
           break;
       case REQUEST_ENABLE_BT:
           // When the request to enable Bluetooth returns
           if (resultCode == Activity.RESULT_OK) {
               // Bluetooth is now enabled
           } else {
               // User did not enable Bluetooth or an error occured
               Toast.makeText(this, R.string.bt_not_enabled_leaving, Toast.LENGTH_SHORT).show();
               finish();
           }
        }
   }

public void write(byte data) {
     if (outStream != null) {
          try {
             outStream.write(data);
          } catch (IOException e) {
          }
      }
  }

  public void emptyOutStream() {
     if (outStream != null) {
          try {
             outStream.flush();
          } catch (IOException e) {
          }
      }
  }

  public void connect() {
     // Launch the DeviceListActivity to see devices and do scan
      Intent serverIntent = new Intent(this, DeviceList.class);
      startActivityForResult(serverIntent, REQUEST_CONNECT_DEVICE);
  }

  public void disconnect() {
     if (outStream != null) {
         try {
                outStream.close();
                connectStat = false;
                connect_button.setText(R.string.disconnected);
            } catch (IOException e) {
            }
     } 
  }
  private final SensorEventListener mSensorListener = new SensorEventListener() {

        @Override
        public void onAccuracyChanged(Sensor sensor, int accuracy) {}

        @Override
        public void onSensorChanged(SensorEvent event) {
            // Checks whether to send steering command or not
            long date = System.currentTimeMillis();
            if (date - lastWrite > MOVE_TIME) {
                yAccel.setText(" " + event.values[1]);
                xAccel.setText(" " + event.values[0]);
                if (event.values[1] > 2.5) {
                    // Turn right
                    microcOut = (byte) (microcOut & 248);
                    microcOut = (byte) (microcOut | 4);
                }else if (event.values[1] < -2.5) {
                    // Turn left
                    microcOut = (byte) (microcOut & 244);
                    microcOut = (byte) (microcOut | 8);
                }else {
                    // Center the steering servo
                    microcOut = (byte) (microcOut & 240);
                }
                write(microcOut);
                lastWrite = date;
            }
        }
      };

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.activity_accelerometer, menu);
    return true;
}
public void onResume() { 
     super.onResume();
     mySensorManager.registerListener(mSensorListener, accSensor, SensorManager.SENSOR_DELAY_GAME);
}
@Override 
public void onDestroy() { 
     emptyOutStream();
     disconnect();
     if (mSensorListener != null) {
         mySensorManager.unregisterListener(mSensorListener);
     }
     super.onDestroy(); 
     myclip.release();
} 
private class ConnectedThread extends Thread {
    private final InputStream mmInStream;
    private final OutputStream mmOutStream;

    public ConnectedThread(BluetoothSocket socket) {
        InputStream tmpIn = null;
        OutputStream tmpOut = null;

        // Get the input and output streams, using temp objects because
        // member streams are final
        try {
            tmpIn = socket.getInputStream();
            tmpOut = socket.getOutputStream();
        } catch (IOException e) { }

        mmInStream = tmpIn;
        mmOutStream = tmpOut;
    }

    public void run() {
        byte[] buffer = new byte[256];  // buffer store for the stream
        int bytes; // bytes returned from read()

        // Keep listening to the InputStream until an exception occurs
        while (true) {
            try {
                // Read from the InputStream
                bytes = mmInStream.read(buffer);        // Get number of bytes and message in "buffer"
                h.obtainMessage(RECIEVE_MESSAGE, bytes, -1, buffer).sendToTarget();     // Send to message queue Handler
            } catch (IOException e) {
                break;
            }
        }
    }

    /* Call this from the main activity to send data to the remote device */
    public void write(String message) {

        byte[] msgBuffer = message.getBytes();
        try {
            mmOutStream.write(msgBuffer);
        } catch (IOException e) {

          }
    }
}
Run Code Online (Sandbox Code Playgroud)

}

我已经阅读了关于这个主题的所有内容(蓝牙,互联网上的人们的项目...),我很累.任何帮助深表感谢.

- 编辑 -

I have managed to get the inputstream into my texteview. My problem now is that my application when it is trying to connect to my device (microcontroller or my pc) gets stuck in the progressdialog (it is connected to the device but the progressdialog will not go away)and waits for something to come in. After a while (like 5-6 secs) even if something comes in it remains stuck and I have to force it to close. I think the problem is in the way the handler handles the thread. In the debugger there is no problem all threads run ok.

The changes in my code are: In my ConnectThread: `/**Thread used to connect to a specified Bluetooth Device*/ public class ConnectThread extends Thread { private String address; private boolean connectionStatus;

    ConnectThread(String MACaddress) {
        address = MACaddress;
        connectionStatus = true;
}

    public void run() {
    // When this returns, it will 'know' about the server, 
       // via it's MAC address. 
        try {
            BluetoothDevice device = btAdapter.getRemoteDevice(address);

            // We need two things before we can successfully connect 
            // (authentication issues aside): a MAC address, which we 
            // already have, and an RFCOMM channel. 
            // Because RFCOMM channels (aka ports) are limited in 
            // number, Android doesn't allow you to use them directly; 
            // instead you request a RFCOMM mapping based on a service 
            // ID. In our case, we will use the well-known SPP Service 
            // ID. This ID is in UUID (GUID to you Microsofties) 
            // format. Given the UUID, Android will handle the 
            // mapping for you. Generally, this will return RFCOMM 1, 
            // but not always; it depends what other BlueTooth services 
            // are in use on your Android device. 
            try { 
                 btSocket = device.createRfcommSocketToServiceRecord(SPP_UUID); 
            } catch (IOException e) { 
                connectionStatus = false;
            } 
        }catch (IllegalArgumentException e) {
            connectionStatus = false;
        }

       // Discovery may be going on, e.g., if you're running a 
       // 'scan for devices' search from your handset's Bluetooth 
       // settings, so we call cancelDiscovery(). It doesn't hurt 
       // to call it, but it might hurt not to... discovery is a 
       // heavyweight process; you don't want it in progress when 
       // a connection attempt is made. 
       btAdapter.cancelDiscovery(); 

       // Blocking connect, for a simple client nothing else can 
       // happen until a successful connection is made, so we 
       // don't care if it blocks. 
       try {
            btSocket.connect(); 
       } catch (IOException e1) {
            try {
                 btSocket.close(); 
            } catch (IOException e2) {
            }
       }

       // Create a data stream so we can talk to server. 
       try { 
            outStream = btSocket.getOutputStream(); 
          } catch (IOException e2) {
            connectionStatus = false;
          }
       try{
        inStream = btSocket.getInputStream();
    }catch (IOException e2){
        connectionStatus = false;
    }
        int bytes; // bytes returned from read()
       // Keep listening to the InputStream until an exception occurs
       while (connectionStatus) {
           try {
               byte[] b = new byte[64];  // buffer store for the stream
               // Read from the InputStream
               bytes = inStream.read(b);        // Get number of bytes and message in "buffer"
               mHandler.obtainMessage(RECIEVE_MESSAGE, bytes, -1, b).sendToTarget();     // Send to message queue Handler
           } catch (IOException e) {
               break;
           }
       }
       // Send final result
       if (connectionStatus) {
        mHandler.obtainMessage(1);
       }else {
        mHandler.sendEmptyMessage(0);
       }
    }
}
Run Code Online (Sandbox Code Playgroud)

` And in my mHandler in my onCreate method:

 mHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
         if (myProgressDialog.isShowing()) {
                myProgressDialog.dismiss();
            }

         // Check if bluetooth connection was made to selected device
            if (msg.what == 1) {
                // Set button to display current status
                connectStat = true;
                connect_button.setText(R.string.connected);
                // Reset the BluCar
                microcOut = 0;
                ledStat = false;
                write(microcOut);
            }else if (msg.what == 2){
                byte[] readBuf = (byte[]) msg.obj;
                String strIncom = new String(readBuf, 0, msg.arg1);                 // create string from bytes array
                sb.append(strIncom);                                                // append string
                int endOfLineIndex = sb.indexOf(".");                            // determine the end-of-line
                if (endOfLineIndex > 0) {                                            // if end-of-line,
                    String sbprint = sb.substring(0, endOfLineIndex);               // extract string
                    sb.delete(0, sb.length());                                      // and clear
                    incoming.setText(sbprint);            // update TextView
                    connectStat = true;
                    connect_button.setText(R.string.connected);
                }else{
                    incoming.setText("Problem!");
                }
            }else {
                // Connection failed
             failToast.show();
            }
        }
    };
Run Code Online (Sandbox Code Playgroud)

我需要的另一件事是如何在缓冲区满时清空缓冲区.

PS:感谢每个人的帮助,我真的很感激.

Bri*_*n G 5

作为使用处理程序的替代方法,只需获取线程运行中的信息.

我这样做了,它对我有用.

public void run() {
            byte[] buffer = new byte[128];  // buffer store for the stream
            int bytes; // bytes returned from read()

            // Keep listening to the InputStream until an exception occurs
            while (true) {
                try {


                    bytes = mmInStream.read(buffer);
                    byte[] readBuf = (byte[]) buffer;
                    String strIncom = new String(readBuf, 0, bytes);                 // create string from bytes array
                    sb.append(strIncom);                                                // append string
                    int endOfLineIndex = sb.indexOf("\r\n");                            // determine the end-of-line
                    if (endOfLineIndex > 0) {  
                        // add the current string to eol to a local string
                        String sbprint = sb.substring(0, endOfLineIndex);

                        // get the start and end indexes of the heading
                        int startHeading = sb.indexOf("HE");
                        int endHeading = sb.indexOf("/HE");

                        // set the heading
                        Henry.this.setCurrentHeading(sb.substring((startHeading + 2), endHeading));

                        // get the start and end indexes of the front range
                        int startFrontRange = sb.indexOf("FR");
                        int endFrontRange = sb.indexOf("/FR");

                        // get the front range
                        Henry.this.currentFrontRange = sb.substring((startFrontRange + 2), endFrontRange);
             ... ( grab all the information you need here ) ...

                        // debugging output what we have
                        // System.out.println("recv: " + sbprint);

                        // clean out the sb to ready next run
                        sb.delete(0, sb.length());   
                    }
Run Code Online (Sandbox Code Playgroud)

我保存从我的应用程序(Henry)中的串行连接中检索到的所有信息,然后任何想要使用该信息的Activity都从应用程序获取它.如果视图需要对信息有更新的透视图,我会在视图中添加一个计时器,以便根据需要随时添加刷新方法.这具有额外的优势,能够使用Android应用程序中任何位置的信息.

我从arduino向设备发送大约10个数据点,从设备向arduino发送大约3个数据点.我在数据点周围添加了自己的标记来识别它们.

希望这可以帮助!