Отправка текста через Bluetooth с сервера Java на клиент Android

Прежде всего... не перенаправляйте меня в Bluetooth-чат, и я полностью прочитал его.

У меня есть Android-клиент, который правильно стабилизирует соединение с сервером, и, что самое большее, я могу отправить текст на сервер на моем компьютере и показать его правильно, но я не могу выполнить обратное действие, отправив простую строку с сервера на клиент и показать его в моем приложении для Android.

Я не хочу реализовывать чат, просто чтобы показать, как работает BT связь между Java-сервером и клиентом Android.

Чтобы сделать это легко:

Я отправляю текст в конце метода startServer() в классе сервера.

Я пытаюсь прочитать текст с сервера в начале onPause ().

**

[Решено] Решение ниже

**.

Код выглядит следующим образом:

Android BT Client:

/*...libraries here...*/
  public class ConnectTest extends Activity {
  TextView out;
  private static final int REQUEST_ENABLE_BT = 1;
  private BluetoothAdapter btAdapter = null;
  private BluetoothSocket btSocket = null;
  private OutputStream outStream = null;

  // Well known SPP UUID
  private static final UUID MY_UUID =
      UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");

  // Insert your server's MAC address
  private static String address = "00:10:60:AA:B9:B2";

  /** Called when the activity is first created. */
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    out = (TextView) findViewById(R.id.out);

    out.append("\n...In onCreate()...");

    btAdapter = BluetoothAdapter.getDefaultAdapter();
    CheckBTState();
  }

  public void onStart() {
    super.onStart();
    out.append("\n...In onStart()...");
  }

  public void onResume() {
    super.onResume();

    out.append("\n...In onResume...\n...Attempting client 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) {
      AlertBox("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.
    try {
      btSocket.connect();
      out.append("\n...Connection established and data link opened...");
    } catch (IOException e) {
      try {
        btSocket.close();
      } catch (IOException e2) {
        AlertBox("Fatal Error", "In onResume() and unable to close socket during connection failure" + e2.getMessage() + ".");
      }
    }

    // Create a data stream so we can talk to server.
    out.append("\n...Sending message to server...");
    String message = "Hello from Android.\n";
    out.append("\n\n...The message that we will send to the server is: "+message);

    try {
      outStream = btSocket.getOutputStream();
    } catch (IOException e) {
      AlertBox("Fatal Error", "In onResume() and output stream creation failed:" + e.getMessage() + ".");
    }

    byte[] msgBuffer = message.getBytes();
    try {
      outStream.write(msgBuffer);
    } catch (IOException e) {
      String msg = "In onResume() and an exception occurred during write: " + e.getMessage();
      if (address.equals("00:00:00:00:00:00")) 
        msg = msg + ".\n\nUpdate your server address from 00:00:00:00:00:00 to the correct address on line 37 in the java code";
      msg = msg +  ".\n\nCheck that the SPP UUID: " + MY_UUID.toString() + " exists on server.\n\n";

      AlertBox("Fatal Error", msg);       
    }
  }

  public void onPause() {
    super.onPause();

    //out.append("\n...Hello\n");
    InputStream inStream;
    try {
        inStream = btSocket.getInputStream();
        BufferedReader bReader=new BufferedReader(new InputStreamReader(inStream));
        String lineRead=bReader.readLine();
        out.append("\n..."+lineRead+"\n");

    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

    out.append("\n...In onPause()...");



    if (outStream != null) {
      try {
        outStream.flush();
      } catch (IOException e) {
        AlertBox("Fatal Error", "In onPause() and failed to flush output stream: " + e.getMessage() + ".");
      }
    }

    try     {
      btSocket.close();
    } catch (IOException e2) {
      AlertBox("Fatal Error", "In onPause() and failed to close socket." + e2.getMessage() + ".");
    }
  }

  public void onStop() {
    super.onStop();
    out.append("\n...In onStop()...");
  }

  public void onDestroy() {
    super.onDestroy();
    out.append("\n...In onDestroy()...");
  }

  private void CheckBTState() {
    // Check for Bluetooth support and then check to make sure it is turned on

    // Emulator doesn't support Bluetooth and will return null
    if(btAdapter==null) { 
      AlertBox("Fatal Error", "Bluetooth Not supported. Aborting.");
    } else {
      if (btAdapter.isEnabled()) {
        out.append("\n...Bluetooth is enabled...");
      } else {
        //Prompt user to turn on Bluetooth
        Intent enableBtIntent = new Intent(btAdapter.ACTION_REQUEST_ENABLE);
        startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);
      }
    }
  }

  public void AlertBox( String title, String message ){
    new AlertDialog.Builder(this)
    .setTitle( title )
    .setMessage( message + " Press OK to exit." )
    .setPositiveButton("OK", new OnClickListener() {
        public void onClick(DialogInterface arg0, int arg1) {
          finish();
        }
    }).show();
  }
}

и сервер Java BT:

    import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;

import javax.bluetooth.*;
import javax.microedition.io.*;

/**
* Class that implements an SPP Server which accepts single line of
* message from an SPP client and sends a single line of response to the client.
*/
public class SimpleSPPServer {

    //start server
    private void startServer() throws IOException{

        //Create a UUID for SPP
        UUID uuid = new UUID("1101", true);
        //Create the servicve url
        String connectionString = "btspp://localhost:" + uuid +";name=Sample SPP Server";

        //open server url
        StreamConnectionNotifier streamConnNotifier = (StreamConnectionNotifier)Connector.open( connectionString );

        //Wait for client connection
        System.out.println("\nServer Started. Waiting for clients to connect...");
        StreamConnection connection=streamConnNotifier.acceptAndOpen();

        RemoteDevice dev = RemoteDevice.getRemoteDevice(connection);
        System.out.println("Remote device address: "+dev.getBluetoothAddress());
        System.out.println("Remote device name: "+dev.getFriendlyName(true));

        //read string from spp client
        InputStream inStream=connection.openInputStream();
        BufferedReader bReader=new BufferedReader(new InputStreamReader(inStream));
        String lineRead=bReader.readLine();
        System.out.println(lineRead);

        //send response to spp client
        OutputStream outStream=connection.openOutputStream();
        BufferedWriter bWriter=new BufferedWriter(new OutputStreamWriter(outStream));
        bWriter.write("Response String from SPP Server\r\n");

        /*PrintWriter pWriter=new PrintWriter(new OutputStreamWriter(outStream));
        pWriter.write("Response String from SPP Server\r\n");
        pWriter.flush();
        pWriter.close();*/

        streamConnNotifier.close();

    }


    public static void main(String[] args) throws IOException {

        //display local device address and name
        LocalDevice localDevice = LocalDevice.getLocalDevice();
        System.out.println("Address: "+localDevice.getBluetoothAddress());
        System.out.println("Name: "+localDevice.getFriendlyName());

        SimpleSPPServer sampleSPPServer=new SimpleSPPServer();
        sampleSPPServer.startServer();

    }
}

Решение: это всего лишь небольшое изменение на стороне сервера. Я не знаю почему, но вместо использования BufferedWrite для записи в сокет, нам нужно использовать PrinterWriter для этого. Я добавляю этот фрагмент кода:

BT сервер:

    ....
    //read string from spp client
    InputStream inStream=connection.openInputStream();
    BufferedReader bReader=new BufferedReader(new InputStreamReader(inStream));
    String lineRead=bReader.readLine();
    System.out.println(lineRead);

    //send response to spp client
    OutputStream outStream=connection.openOutputStream();
    PrintWriter pWriter=new PrintWriter(new OutputStreamWriter(outStream));
    pWriter.write("Response String from SPP Server\r\n");
    pWriter.flush();

    pWriter.close();

    streamConnNotifier.close();
    ...

1 ответ

Похоже, ваш кэш BufferedWriter не был очищен, данные просто оставались в буфере без отправки. призвание bWriter.flush() после вашего bWriter.write() должен устранить проблему и вызвать сброс данных в поток вывода. Вы также можете изменить свой код, чтобы выполнить следующие действия:

PrintWriter pWriter = new PrintWriter(new BufferedWriter(new OutputStreamWriter(outStream)));

Это приведет к тому, что выходные данные PrintWriter будут буферизироваться вместо немедленной записи в выходной поток, что может быть неэффективно.

Для ваших целей, тем не менее, исключение BufferedWriter должно подойти, так как вы, скорее всего, захотите немедленную очистку выходного потока (что делает PrintWriter).

Другие вопросы по тегам