服务发现失败 - 通过蓝牙发送/接收数据

时间:2014-08-05 13:11:46

标签: java android bluetooth android-bluetooth service-discovery

我想通过蓝牙发送和接收一些数据。我关注了这篇文章:Bluetooth Sending and Receiving Text Data

我的 MainActivity.java

package com.example.proba2x8;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Set;
import java.util.UUID;

import android.app.Activity;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothSocket;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;

public class MainActivity extends Activity {

BluetoothAdapter mBluetoothAdapter;
  BluetoothSocket mmSocket;
  BluetoothDevice mmDevice;

  OutputStream mmOutputStream;
  InputStream mmInputStream;
  Thread workerThread;

  EditText myTextbox;
  TextView myLabel;

  byte[] readBuffer;
  int readBufferPosition;
  int counter;
  volatile boolean stopWorker;

  @Override
  protected void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      setContentView(R.layout.activity_main);
      try {
          Button sendButton = (Button) findViewById(R.id.send);
          Button openButton = (Button) findViewById(R.id.open);
          myTextbox = (EditText) findViewById(R.id.editText);
          myLabel = (TextView) findViewById(R.id.textView);

          openButton.setOnClickListener(new View.OnClickListener() {
              @Override
              public void onClick(View v) {
                  try {
                      findBT();
                      openBT();
                  } catch (IOException ex) {
                  }

              }
          });
          // send data typed by the user to be printed
          sendButton.setOnClickListener(new View.OnClickListener() {
              public void onClick(View v) {
                  try {
                      sendData();
                  } catch (IOException ex) {
                  }
              }
          });
      } catch (NullPointerException e) {
          e.printStackTrace();
      } catch (Exception e) {
          e.printStackTrace();
      }
  }

  // This will find a bluetooth device
  void findBT() {

      try {
          mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();

          if (mBluetoothAdapter == null) {
              myLabel.setText("No bluetooth adapter available");
          }

          if (!mBluetoothAdapter.isEnabled()) {
              Intent enableBluetooth = new Intent(
                      BluetoothAdapter.ACTION_REQUEST_ENABLE);
              startActivityForResult(enableBluetooth, 0);
          }

          Set<BluetoothDevice> pairedDevices = mBluetoothAdapter
                  .getBondedDevices();
          if (pairedDevices.size() > 0) {
              for (BluetoothDevice device : pairedDevices) {

                  // Xperia mini pro is the name of the bluetooth device
                  if (device.getName().equals("Xperia mini pro")) {
                      mmDevice = device;
                      break;
                  }
              }
          }
          myLabel.setText("Bluetooth Device Found");
      } catch (NullPointerException e) {
          e.printStackTrace();
      } catch (Exception e) {
          e.printStackTrace();
      }
  }

  // Tries to open a connection to the bluetooth device
  void openBT() throws IOException {
      try {
          // Standard SerialPortService ID
          UUID uuid = UUID.fromString("00001101-0000-1000-8000-00805f9b34fb");
          mmSocket = mmDevice.createRfcommSocketToServiceRecord(uuid);
          mmSocket.connect();
          mmOutputStream = mmSocket.getOutputStream();
          mmInputStream = mmSocket.getInputStream();

          beginListenForData();

          myLabel.setText("Bluetooth Opened");
      } catch (NullPointerException e) {
          e.printStackTrace();
      } catch (Exception e) {
          e.printStackTrace();
      }
  }

  // After opening a connection to bluetooth device,
  // we have to listen and check if a data were sent to be printed.
  void beginListenForData() {
      try {
          final Handler handler = new Handler();

          // This is the ASCII code for a newline character
          final byte delimiter = 10;

          stopWorker = false;
          readBufferPosition = 0;
          readBuffer = new byte[1024];

          workerThread = new Thread(new Runnable() {
              public void run() {
                  while (!Thread.currentThread().isInterrupted()
                          && !stopWorker) {

                      try {

                          int bytesAvailable = mmInputStream.available();
                          if (bytesAvailable > 0) {
                              byte[] packetBytes = new byte[bytesAvailable];
                              mmInputStream.read(packetBytes);
                              for (int i = 0; i < bytesAvailable; i++) {
                                  byte b = packetBytes[i];
                                  if (b == delimiter) {
                                      byte[] encodedBytes = new byte[readBufferPosition];
                                      System.arraycopy(readBuffer, 0,
                                              encodedBytes, 0,
                                              encodedBytes.length);
                                      final String data = new String(
                                              encodedBytes, "US-ASCII");
                                      readBufferPosition = 0;

                                      handler.post(new Runnable() {
                                          public void run() {
                                              myLabel.setText(data);
                                          }
                                      });
                                  } else {
                                      readBuffer[readBufferPosition++] = b;
                                  }
                              }
                          }

                      } catch (IOException ex) {
                          stopWorker = true;
                      }

                  }
              }
          });

          workerThread.start();
      } catch (NullPointerException e) {
          e.printStackTrace();
      } catch (Exception e) {
          e.printStackTrace();
      }
  }

  /*
   * This will send data to be printed by the bluetooth
   */
  void sendData() throws IOException {
      try {

          // the text typed by the user
          String msg = myTextbox.getText().toString();
          msg += "\n";

          mmOutputStream.write(msg.getBytes());
          // tell the user data were sent
          myLabel.setText("Data Sent");

      } catch (NullPointerException e) {
          e.printStackTrace();
      } catch (Exception e) {
          e.printStackTrace();
      }

  }
}

activity_main.xml中:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="${relativePackage}.${activityClass}" >

    <LinearLayout
    android:id="@+id/linearLayout1"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_alignParentTop="true"
    android:orientation="vertical" >

    <TextView
        android:id="@+id/textView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Enter Text Here" />

    <EditText
        android:id="@+id/editText"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:ems="10" >

        <requestFocus />
    </EditText>
</LinearLayout>

<Button
    android:id="@+id/open"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignBaseline="@+id/send"
    android:layout_alignBottom="@+id/send"
    android:layout_alignRight="@+id/linearLayout1"
    android:text="Open" />

<Button
    android:id="@+id/send"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_below="@+id/linearLayout1"
    android:layout_marginTop="15dp"
    android:layout_toLeftOf="@+id/button1"
    android:text="Send" />

<TextView
    android:id="@+id/recievedText"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignLeft="@+id/send"
    android:layout_below="@+id/send"
    android:layout_marginTop="20dp"
    android:text="Received Text" />

<TextView
    android:id="@+id/rtArea"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_alignLeft="@+id/recievedText"
    android:layout_alignParentBottom="true"
    android:layout_below="@+id/recievedText"
    android:layout_marginTop="20dp"
    android:text="Received Text Will be Displayed Here..." />

</RelativeLayout>

我的问题是,当我按下“打开”按钮时, findBT(); 功能正常运行,但在我看来, openBT(); 功能不起作用。我被告知,这个问题导致,在我按下发送按钮后,我想通过蓝牙发送的文本没有被发送并显示NullPointerException(所以可能没有打开OutputStream)。

LogCat 向我显示了一些错误:

11-27 22:39:59.837: E/BluetoothEventLoop.cpp(1184): event_filter: Received signal org.bluez.Device:PropertyChanged from /org/bluez/1962/hci0/dev_90_C1_15_37_AB_E7
11-27 22:40:00.107: W/System.err(2044): java.io.IOException: Service discovery failed
11-27 22:40:00.117: W/System.err(2044):     at android.bluetooth.BluetoothSocket$SdpHelper.doSdp(BluetoothSocket.java:377)
11-27 22:40:00.117: W/System.err(2044):     at android.bluetooth.BluetoothSocket.connect(BluetoothSocket.java:201)
11-27 22:40:00.117: W/System.err(2044):     at com.example.proba2x8.MainActivity.openBT(MainActivity.java:130)
11-27 22:40:00.117: W/System.err(2044):     at com.example.proba2x8.MainActivity$1.onClick(MainActivity.java:66)
11-27 22:40:00.117: W/System.err(2044):     at android.view.View.performClick(View.java:2418)
11-27 22:40:00.117: W/System.err(2044):     at android.view.View.onTouchEvent(View.java:4233)
11-27 22:40:00.117: W/System.err(2044):     at android.widget.TextView.onTouchEvent(TextView.java:6645)
11-27 22:40:00.117: W/System.err(2044):     at android.view.View.dispatchTouchEvent(View.java:3763)
11-27 22:40:00.117: W/System.err(2044):     at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:968)
11-27 22:40:00.117: W/System.err(2044):     at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:968)
11-27 22:40:00.117: W/System.err(2044):     at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:968)
11-27 22:40:00.117: W/System.err(2044):     at com.android.internal.policy.impl.PhoneWindow$DecorView.superDispatchTouchEvent(PhoneWindow.java:1659)
11-27 22:40:00.117: W/System.err(2044):     at com.android.internal.policy.impl.PhoneWindow.superDispatchTouchEvent(PhoneWindow.java:1107)
11-27 22:40:00.117: W/System.err(2044):     at android.app.Activity.dispatchTouchEvent(Activity.java:2064)
11-27 22:40:00.117: W/System.err(2044):     at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchTouchEvent(PhoneWindow.java:1643)
11-27 22:40:00.117: W/System.err(2044):     at android.view.ViewRoot.handleMessage(ViewRoot.java:1691)
11-27 22:40:00.117: W/System.err(2044):     at android.os.Handler.dispatchMessage(Handler.java:99)
11-27 22:40:00.117: W/System.err(2044):     at android.os.Looper.loop(Looper.java:123)
11-27 22:40:00.117: W/System.err(2044):     at android.app.ActivityThread.main(ActivityThread.java:4370)
11-27 22:40:00.117: W/System.err(2044):     at java.lang.reflect.Method.invokeNative(Native Method)
11-27 22:40:00.117: W/System.err(2044):     at java.lang.reflect.Method.invoke(Method.java:521)
11-27 22:40:00.117: W/System.err(2044):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868)
11-27 22:40:00.117: W/System.err(2044):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626)
11-27 22:40:00.117: W/System.err(2044):     at dalvik.system.NativeStart.main(Native Method)
11-27 22:40:04.067: E/BluetoothEventLoop.cpp(1184): event_filter: Received signal org.bluez.Device:PropertyChanged from /org/bluez/1962/hci0/dev_90_C1_15_37_AB_E7
11-27 22:40:09.187: D/dalvikvm(1701): GC freed 279 objects / 15104 bytes in 123ms

第130行是:

mmSocket.connect();

第66行是:

openBT();

请帮我解决这个问题。

提前致谢。

编辑: 修改代码后。我试过不将 findBT() openBT()放到同一个 onClick()中,所以我移动了 findBT() setContentView(R.layout.activity_main); 之后的行 发生了同样的错误。

package com.example.proba2x8;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Set;
import java.util.UUID;

import android.app.Activity;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothSocket;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;

public class MainActivity extends Activity {


BluetoothAdapter mBluetoothAdapter;
  BluetoothSocket mmSocket;
  BluetoothDevice mmDevice;

  OutputStream mmOutputStream;
  InputStream mmInputStream;
  Thread workerThread;

  EditText myTextbox;
  TextView myLabel;

  byte[] readBuffer;
  int readBufferPosition;
  int counter;
  volatile boolean stopWorker;

  @Override
  protected void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      setContentView(R.layout.activity_main);
      findBT();
      try {
          Button sendButton = (Button) findViewById(R.id.send);
          Button openButton = (Button) findViewById(R.id.open);
          myTextbox = (EditText) findViewById(R.id.editText);
          myLabel = (TextView) findViewById(R.id.textView);

          openButton.setOnClickListener(new View.OnClickListener() {
              @Override
              public void onClick(View v) {
                  try {

                      openBT();
                  } catch (IOException ex) {
                  }

              }
          });
          // send data typed by the user to be printed
          sendButton.setOnClickListener(new View.OnClickListener() {
              public void onClick(View v) {
                  try {
                      sendData();
                  } catch (IOException ex) {
                  }
              }
          });
      } catch (NullPointerException e) {
          e.printStackTrace();
      } catch (Exception e) {
          e.printStackTrace();
      }
  }

  // This will find a bluetooth device
  void findBT() {

      try {
          mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();

          if (mBluetoothAdapter == null) {
              myLabel.setText("No bluetooth adapter available");
          }

          if (!mBluetoothAdapter.isEnabled()) {
              Intent enableBluetooth = new Intent(
                      BluetoothAdapter.ACTION_REQUEST_ENABLE);
              startActivityForResult(enableBluetooth, 0);
          }

          Set<BluetoothDevice> pairedDevices = mBluetoothAdapter
                  .getBondedDevices();
          if (pairedDevices.size() > 0) {
              for (BluetoothDevice device : pairedDevices) {

                  // Salaxy S4 is the name of the bluetooth device
                  if (device.getName().equals("Xperia mini pro")) {
                      mmDevice = device;
                      break;
                  }
              }
          }
          myLabel.setText("Bluetooth Device Found");
      } catch (NullPointerException e) {
          e.printStackTrace();
      } catch (Exception e) {
          e.printStackTrace();
      }
  }

  // Tries to open a connection to the bluetooth device
  void openBT() throws IOException {
      try {
          // Standard SerialPortService ID
          UUID uuid = UUID.fromString("00001101-0000-1000-8000-00805f9b34fb");
          mmSocket = mmDevice.createRfcommSocketToServiceRecord(uuid);
          mmSocket.connect();
          mmOutputStream = mmSocket.getOutputStream();
          mmInputStream = mmSocket.getInputStream();

          beginListenForData();

          myLabel.setText("Bluetooth Opened");
      } catch (NullPointerException e) {
          e.printStackTrace();
      } catch (Exception e) {
          e.printStackTrace();
      }
  }

  // After opening a connection to bluetooth device,
  // we have to listen and check if a data were sent to be printed.
  void beginListenForData() {
      try {
          final Handler handler = new Handler();

          // This is the ASCII code for a newline character
          final byte delimiter = 10;

          stopWorker = false;
          readBufferPosition = 0;
          readBuffer = new byte[1024];

          workerThread = new Thread(new Runnable() {
              public void run() {
                  while (!Thread.currentThread().isInterrupted()
                          && !stopWorker) {

                      try {

                          int bytesAvailable = mmInputStream.available();
                          if (bytesAvailable > 0) {
                              byte[] packetBytes = new byte[bytesAvailable];
                              mmInputStream.read(packetBytes);
                              for (int i = 0; i < bytesAvailable; i++) {
                                  byte b = packetBytes[i];
                                  if (b == delimiter) {
                                      byte[] encodedBytes = new byte[readBufferPosition];
                                      System.arraycopy(readBuffer, 0,
                                              encodedBytes, 0,
                                              encodedBytes.length);
                                      final String data = new String(
                                              encodedBytes, "US-ASCII");
                                      readBufferPosition = 0;

                                      handler.post(new Runnable() {
                                          public void run() {
                                              myLabel.setText(data);
                                          }
                                      });
                                  } else {
                                      readBuffer[readBufferPosition++] = b;
                                  }
                              }
                          }

                      } catch (IOException ex) {
                          stopWorker = true;
                      }

                  }
              }
          });

          workerThread.start();
      } catch (NullPointerException e) {
          e.printStackTrace();
      } catch (Exception e) {
          e.printStackTrace();
      }
  }

  /*
   * This will send data to be printed by the bluetooth
   */
  void sendData() throws IOException {
      try {

          // the text typed by the user
          String msg = myTextbox.getText().toString();
          msg += "\n";
          Log.w("MainActivity", msg);
          mmOutputStream.write(msg.getBytes());
          // tell the user data were sent

          myLabel.setText("Data Sent");

      } catch (NullPointerException e) {
          e.printStackTrace();
      } catch (Exception e) {
          e.printStackTrace();
      }

  }
}

1 个答案:

答案 0 :(得分:0)

您需要启用设备的可发现性

请点击此链接 http://developer.android.com/guide/topics/connectivity/bluetooth.html