如何从Android上的蓝牙InputStream中读取

时间:2014-08-22 09:04:29

标签: android io bluetooth inputstream android-bluetooth

我正在尝试测试this bluetooth communication example between a PC and an Android phone。我的SPP客户端就是那个客户端,它运行正常。我是Android的新手,我不想让它在一个单独的线程中运行,因为我不知道如何,所以我只是在onCreate()方法中做了所有事情。如果这不是最好的方法,请随意指出一个更好的方法,但这不是我的主要问题。

问题是我想在textView上显示通过蓝牙接收的文字,我不知道如何从InputStream读取。当代码保持这样时,它会显示类似java.io.DataInputStream@41b0cb68的内容 我试过像here它没有显示任何内容,我也不知道正在使用什么编码。

这是我的Android应用程序代码:

import android.app.Activity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.UUID;

import android.app.Activity;
import android.bluetooth.*;
import android.util.Log;
import android.widget.RelativeLayout;
import android.widget.TextView;

public class MainActivity extends Activity {

//based on java.util.UUID
private static UUID MY_UUID = UUID.fromString("446118f0-8b1e-11e2-9e96-0800200c9a66");

// The local server socket
private BluetoothServerSocket mmServerSocket;

// based on android.bluetooth.BluetoothAdapter
private BluetoothAdapter mAdapter;
private BluetoothDevice remoteDevice;
TextView text;

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

    text = (TextView) findViewById(R.id.textView_Text);

    BluetoothSocket socket = null;
    mAdapter = BluetoothAdapter.getDefaultAdapter();        

    // Listen to the server socket if we're not connected
   // while (true) {

        try {
            // Create a new listening server socket
            Log.d((String) this.getTitle(), ".....Initializing RFCOMM SERVER....");

            // MY_UUID is the UUID you want to use for communication
            mmServerSocket = mAdapter.listenUsingRfcommWithServiceRecord("MyService",    MY_UUID);
            //mmServerSocket =  mAdapter.listenUsingInsecureRfcommWithServiceRecord(NAME, MY_UUID); // you can also try  using In Secure connection...

            // This is a blocking call and will only return on a
            // successful connection or an exception
            socket = mmServerSocket.accept();

        } catch (Exception e) {

        }

        try {
            Log.d((String) this.getTitle(), "Closing Server Socket.....");
            mmServerSocket.close();

            InputStream tmpIn = null;
            OutputStream tmpOut = null;

            // Get the BluetoothSocket input and output streams

            tmpIn = socket.getInputStream();
            tmpOut = socket.getOutputStream();

            DataInputStream mmInStream = new DataInputStream(tmpIn);
            DataOutputStream mmOutStream = new DataOutputStream(tmpOut);

            // here you can use the Input Stream to take the string from the client  whoever is connecting
            //similarly use the output stream to send the data to the client


            text.setText(mmInStream.toString());
        } catch (Exception e) {
            //catch your exception here
        }
   // }
}
}

我注释了while(true)循环,因为我认为在调用onPause()时我的应用程序崩溃了。我知道这不是最好的实现,但我真的想从蓝牙中读取我觉得我非常接近:),其他方面将在事后处理(比如使用线程等)。

2 个答案:

答案 0 :(得分:4)

我终于设法在TextView中正确显示从PC发送的字符串(“来自SPP Client \ r \ n的测试字符串”)。

我使用了this question,即这段代码,位于DataOutputStream mmOutStream = new DataOutputStream(tmpOut);

之下
// Read from the InputStream
            bytes = mmInStream.read(buffer);
            String readMessage = new String(buffer, 0, bytes);
            // Send the obtained bytes to the UI Activity

这是一个非常基本的示例,旨在展示如何在设备屏幕上显示通过蓝牙接收的字符串。它不是在一个单独的线程中完成的,在收到字符串后你必须关闭应用程序并重新启动它,但是应用程序的主要目的是实现的(正如我在提出这个问题时所述)。我真正想要的是从PC接收一个字符串并将其显示在屏幕上。

这是我的完整MainActivity,如果有人要我发布更完整的方法(比如使用单独的帖子),我会在完成后将其发布在此处。

import android.app.Activity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.UUID;

import android.app.Activity;
import android.bluetooth.*;
import android.util.Log;
import android.widget.RelativeLayout;
import android.widget.TextView;

public class MainActivity extends Activity {

//based on java.util.UUID
private static UUID MY_UUID = UUID.fromString("446118f0-8b1e-11e2-9e96-0800200c9a66");

// The local server socket
private BluetoothServerSocket mmServerSocket;

// based on android.bluetooth.BluetoothAdapter
private BluetoothAdapter mAdapter;
private BluetoothDevice remoteDevice;
TextView text;

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

    text = (TextView) findViewById(R.id.textView_Text);

    BluetoothSocket socket = null;
    mAdapter = BluetoothAdapter.getDefaultAdapter();        

    // Listen to the server socket if we're not connected
   // while (true) {

        try {
            // Create a new listening server socket
            Log.d((String) this.getTitle(), ".....Initializing RFCOMM SERVER....");

            // MY_UUID is the UUID you want to use for communication
            mmServerSocket = mAdapter.listenUsingRfcommWithServiceRecord("MyService",    MY_UUID);
            //mmServerSocket =  mAdapter.listenUsingInsecureRfcommWithServiceRecord(NAME, MY_UUID); // you can also try  using In Secure connection...

            // This is a blocking call and will only return on a
            // successful connection or an exception
            socket = mmServerSocket.accept();

        } catch (Exception e) {

        }

        byte[] buffer = new byte[256];  // buffer store for the stream
        int bytes; // bytes returned from read()
        try {
            Log.d((String) this.getTitle(), "Closing Server Socket.....");
            mmServerSocket.close();

            InputStream tmpIn = null;
            OutputStream tmpOut = null;

            // Get the BluetoothSocket input and output streams

            tmpIn = socket.getInputStream();
            tmpOut = socket.getOutputStream();

            DataInputStream mmInStream = new DataInputStream(tmpIn);
            DataOutputStream mmOutStream = new DataOutputStream(tmpOut);            
            // here you can use the Input Stream to take the string from the client  whoever is connecting
            //similarly use the output stream to send the data to the client

         // Read from the InputStream
            bytes = mmInStream.read(buffer);
            String readMessage = new String(buffer, 0, bytes);
            // Send the obtained bytes to the UI Activity


            text.setText(readMessage);
        } catch (Exception e) {
            //catch your exception here
        }
   // }
}
}

有任何问题吗? :)

答案 1 :(得分:1)

基本上,您需要匹配从一台设备发送数据的方式与另一台设备接收数据的方式。

SPP是基于流的,并传输数据字节。因此,接收器必须正确解释发送设备发送的任何字节。

InputStream使您可以访问传输的原始字节,并且您必须对它们执行某些操作;即根据需要以某种方式解码它们。例如,如果发送方在传输之前使用ObjectOutputStream进行编码,则接收方必须使用ObjectInputStream来解码输入。

您可能希望阅读InputStreamread()),ObjectInputStreamtoString()

此外,从阻塞流中读取几乎总是在一个单独的线程中完成;特别是当从一些远程设备/主机/网络/ ...读取时可能有未知的延迟或传输速度。