2017-07-17 34 views
0

Android携帯から別の携帯電話に文字列を送信できるアプリを作成しようとしています。このコードは以下のとおりです。しかし、私はpairDevice()セクションの下でtry catchコードから例外を取得し続けるので、うまくいきません。なぜ私はこれを得るかもしれないのか誰にも分かりますか?Bluetoothのアンドロイドスタジオでメッセージを送受信する方法

import android.bluetooth.BluetoothAdapter; 
import android.bluetooth.BluetoothDevice; 
import android.bluetooth.BluetoothSocket; 
import android.content.Intent; 
import android.os.ParcelUuid; 
import android.support.v7.app.AppCompatActivity; 
import android.os.Bundle; 
import android.view.View; 
import android.widget.EditText; 
import android.widget.TextView; 
import android.widget.Toast; 

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

public class MainActivity extends AppCompatActivity { 

    InputStream inStream; 
    OutputStream outputStream; 
    private static final int REQUEST_ENABLE_BT = 1; 

    public void pairDevice() { 
     BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter(); 
     if (bluetoothAdapter != null && !bluetoothAdapter.isEnabled()) { 
      Intent enableBtIntent = new 
      Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE); 
      startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);} 

     Set<BluetoothDevice> pairedDevices = bluetoothAdapter.getBondedDevices(); 
     if (pairedDevices.size() > 0) { 
      Object[] devices = pairedDevices.toArray(); 
      BluetoothDevice device = (BluetoothDevice) devices[0]; 
      ParcelUuid[] uuid = device.getUuids(); 
      try { 
       BluetoothSocket socket = device.createInsecureRfcommSocketToServiceRecord(uuid[0].getUuid()); 
       socket.connect(); 
       Toast.makeText(this, "Socket connected", Toast.LENGTH_LONG).show(); 
       outputStream = socket.getOutputStream(); 
       inStream = socket.getInputStream(); 
      } catch (IOException e) { 
       Toast.makeText(this, "Exception found", Toast.LENGTH_LONG).show(); 
      } 

     } 
    } 


public void SendMessage(View v) { 
    EditText outMessage = (EditText) findViewById(R.id.editText); 
    try { 
     if (outputStream != null) 
      outputStream.write(outMessage.toString().getBytes()); 
      TextView displayMessage = (TextView) findViewById(R.id.textView); 
      Scanner s = new Scanner(inStream).useDelimiter("\\A"); 
      displayMessage.setText(s.hasNext() ? s.next() : ""); 
    } catch (IOException e) {/*Do nothing*/} 
    Toast.makeText(this,"No output stream", Toast.LENGTH_LONG).show(); 
} 





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

}

答えて

1

私はあなたのアプリケーションにいくつかの変更を加えた

private class AcceptThread extends Thread { 
    private final BluetoothServerSocket mmServerSocket; 

    public AcceptThread() { 
     // Use a temporary object that is later assigned to mmServerSocket 
     // because mmServerSocket is final. 
     BluetoothServerSocket tmp = null; 
     try { 
      // MY_UUID is the app's UUID string, also used by the client code. 
      tmp = mBluetoothAdapter.listenUsingRfcommWithServiceRecord(NAME, MY_UUID); 
     } catch (IOException e) { 
      Log.e(TAG, "Socket's listen() method failed", e); 
     } 
     mmServerSocket = tmp; 
    } 

    public void run() { 
     BluetoothSocket socket = null; 
     // Keep listening until exception occurs or a socket is returned. 
     while (true) { 
      try { 
       socket = mmServerSocket.accept(); 
      } catch (IOException e) { 
       Log.e(TAG, "Socket's accept() method failed", e); 
       break; 
      } 

      if (socket != null) { 
       // A connection was accepted. Perform work associated with 
       // the connection in a separate thread. 
       manageMyConnectedSocket(socket); 
       mmServerSocket.close(); 
       break; 
      } 
     } 
    } 

    // Closes the connect socket and causes the thread to finish. 
    public void cancel() { 
     try { 
      mmServerSocket.close(); 
     } catch (IOException e) { 
      Log.e(TAG, "Could not close the connect socket", e); 
     } 
    } 
} 

Androidのドキュメント:着信接続を受け入れるサーバー・コンポーネントのためのスレッドを簡素化

Bluetooth接続を作成してConnectThreadにする責任があります。

2)着信接続のリスンには、AcceptThreadが追加され、BTC接続の維持、データの送信、および着信データの受信ストリームがそれぞれ に追加されました。 3)ConnectThreadとAcceptThreadを開始する2つのボタンを作成しました。

注:デバイスがペアになっていると、あなた に接続しようとしているデバイスがリストの一番上にあるの両方を確認してください(または単にデバイスの両方からすべての ペアリングデバイスを削除し、唯一のペアリング接続するデバイス )。また、あなたはConnectThread

詳細な応答のための

MAINACTIVITY.JAVA

public class MainActivity extends AppCompatActivity { 

    private static final UUID MY_UUID_INSECURE = 
      UUID.fromString("8ce255c0-200a-11e0-ac64-0800200c9a66"); 

    private static final int REQUEST_ENABLE_BT = 1; 
    BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter(); 
    private BluetoothDevice mmDevice; 
    private UUID deviceUUID; 
    ConnectedThread mConnectedThread; 
    private Handler handler; 

    String TAG = "MainActivity"; 
    EditText send_data; 
    TextView view_data; 
    StringBuilder messages; 






    public void pairDevice(View v) { 

     Set<BluetoothDevice> pairedDevices = bluetoothAdapter.getBondedDevices(); 
     Log.e("MAinActivity", "" + pairedDevices.size()); 
     if (pairedDevices.size() > 0) { 
      Object[] devices = pairedDevices.toArray(); 
      BluetoothDevice device = (BluetoothDevice) devices[0]; 
      //ParcelUuid[] uuid = device.getUuids(); 
      Log.e("MAinActivity", "" + device); 
      //Log.e("MAinActivity", "" + uuid) 

      ConnectThread connect = new ConnectThread(device,MY_UUID_INSECURE); 
      connect.start(); 

     } 
    } 

    private class ConnectThread extends Thread { 
     private BluetoothSocket mmSocket; 

     public ConnectThread(BluetoothDevice device, UUID uuid) { 
      Log.d(TAG, "ConnectThread: started."); 
      mmDevice = device; 
      deviceUUID = uuid; 
     } 

     public void run(){ 
      BluetoothSocket tmp = null; 
      Log.i(TAG, "RUN mConnectThread "); 

      // Get a BluetoothSocket for a connection with the 
      // given BluetoothDevice 
      try { 
       Log.d(TAG, "ConnectThread: Trying to create InsecureRfcommSocket using UUID: " 
         +MY_UUID_INSECURE); 
       tmp = mmDevice.createRfcommSocketToServiceRecord(MY_UUID_INSECURE); 
      } catch (IOException e) { 
       Log.e(TAG, "ConnectThread: Could not create InsecureRfcommSocket " + e.getMessage()); 
      } 

      mmSocket = tmp; 

      // Make a connection to the BluetoothSocket 

      try { 
       // This is a blocking call and will only return on a 
       // successful connection or an exception 
       mmSocket.connect(); 

      } catch (IOException e) { 
       // Close the socket 
       try { 
        mmSocket.close(); 
        Log.d(TAG, "run: Closed Socket."); 
       } catch (IOException e1) { 
        Log.e(TAG, "mConnectThread: run: Unable to close connection in socket " + e1.getMessage()); 
       } 
       Log.d(TAG, "run: ConnectThread: Could not connect to UUID: " + MY_UUID_INSECURE); 
      } 

      //will talk about this in the 3rd video 
      connected(mmSocket); 
     } 
     public void cancel() { 
      try { 
       Log.d(TAG, "cancel: Closing Client Socket."); 
       mmSocket.close(); 
      } catch (IOException e) { 
       Log.e(TAG, "cancel: close() of mmSocket in Connectthread failed. " + e.getMessage()); 
      } 
     } 
    } 

    private void connected(BluetoothSocket mmSocket) { 
     Log.d(TAG, "connected: Starting."); 

     // Start the thread to manage the connection and perform transmissions 
     mConnectedThread = new ConnectedThread(mmSocket); 
     mConnectedThread.start(); 
    } 

    private class ConnectedThread extends Thread { 
     private final BluetoothSocket mmSocket; 
     private final InputStream mmInStream; 
     private final OutputStream mmOutStream; 

     public ConnectedThread(BluetoothSocket socket) { 
      Log.d(TAG, "ConnectedThread: Starting."); 

      mmSocket = socket; 
      InputStream tmpIn = null; 
      OutputStream tmpOut = null; 



      try { 
       tmpIn = mmSocket.getInputStream(); 
       tmpOut = mmSocket.getOutputStream(); 
      } catch (IOException e) { 
       e.printStackTrace(); 
      } 

      mmInStream = tmpIn; 
      mmOutStream = tmpOut; 
     } 

     public void run(){ 
      byte[] buffer = new byte[1024]; // buffer store for the stream 

      int bytes; // bytes returned from read() 

      // Keep listening to the InputStream until an exception occurs 
      while (true) { 
       // Read from the InputStream 
       try { 
        bytes = mmInStream.read(buffer); 
        final String incomingMessage = new String(buffer, 0, bytes); 
        Log.d(TAG, "InputStream: " + incomingMessage); 

        runOnUiThread(new Runnable() { 

         @Override 
         public void run() { 
          view_data.setText(incomingMessage); 
         } 
        }); 


       } catch (IOException e) { 
        Log.e(TAG, "write: Error reading Input Stream. " + e.getMessage()); 
        break; 
       } 
      } 
     } 


     public void write(byte[] bytes) { 
      String text = new String(bytes, Charset.defaultCharset()); 
      Log.d(TAG, "write: Writing to outputstream: " + text); 
      try { 
       mmOutStream.write(bytes); 
      } catch (IOException e) { 
       Log.e(TAG, "write: Error writing to output stream. " + e.getMessage()); 
      } 
     } 

     /* Call this from the main activity to shutdown the connection */ 
     public void cancel() { 
      try { 
       mmSocket.close(); 
      } catch (IOException e) { } 
     } 
    } 


    public void SendMessage(View v) { 
     byte[] bytes = send_data.getText().toString().getBytes(Charset.defaultCharset()); 
     mConnectedThread.write(bytes); 
    } 


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


     send_data =(EditText) findViewById(R.id.editText); 
     view_data = (TextView) findViewById(R.id.textView); 

     if (bluetoothAdapter != null && !bluetoothAdapter.isEnabled()) { 
      Intent enableBtIntent = new 
        Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE); 
      startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT); 
     } 


    } 

    public void Start_Server(View view) { 

     AcceptThread accept = new AcceptThread(); 
     accept.start(); 

    } 

    private class AcceptThread extends Thread { 

     // The local server socket 
     private final BluetoothServerSocket mmServerSocket; 

     public AcceptThread(){ 
      BluetoothServerSocket tmp = null ; 

      // Create a new listening server socket 
      try{ 
       tmp = bluetoothAdapter.listenUsingInsecureRfcommWithServiceRecord("appname", MY_UUID_INSECURE); 

       Log.d(TAG, "AcceptThread: Setting up Server using: " + MY_UUID_INSECURE); 
      }catch (IOException e){ 
       Log.e(TAG, "AcceptThread: IOException: " + e.getMessage()); 
      } 

      mmServerSocket = tmp; 
     } 

     public void run(){ 
      Log.d(TAG, "run: AcceptThread Running."); 

      BluetoothSocket socket = null; 

      try{ 
       // This is a blocking call and will only return on a 
       // successful connection or an exception 
       Log.d(TAG, "run: RFCOM server socket start....."); 

       socket = mmServerSocket.accept(); 

       Log.d(TAG, "run: RFCOM server socket accepted connection."); 

      }catch (IOException e){ 
       Log.e(TAG, "AcceptThread: IOException: " + e.getMessage()); 
      } 

      //talk about this is in the 3rd 
      if(socket != null){ 
       connected(socket); 
      } 

      Log.i(TAG, "END mAcceptThread "); 
     } 

     public void cancel() { 
      Log.d(TAG, "cancel: Canceling AcceptThread."); 
      try { 
       mmServerSocket.close(); 
      } catch (IOException e) { 
       Log.e(TAG, "cancel: Close of AcceptThread ServerSocket failed. " + e.getMessage()); 
      } 
     } 

    } 

ACTIVITY_MAIN.XML

<?xml version="1.0" encoding="utf-8"?> 
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    xmlns:app="http://schemas.android.com/apk/res-auto" 
    xmlns:tools="http://schemas.android.com/tools" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    tools:context="com.example.hpi5.bluethoothshot.MainActivity" 
    tools:layout_editor_absoluteY="81dp" 
    tools:layout_editor_absoluteX="0dp"> 

    <TextView 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:text="Hello World!" 
     android:id="@+id/textView" 
     tools:layout_constraintTop_creator="1" 
     tools:layout_constraintRight_creator="1" 
     app:layout_constraintRight_toRightOf="parent" 
     android:layout_marginTop="58dp" 
     tools:layout_constraintLeft_creator="1" 
     app:layout_constraintLeft_toLeftOf="parent" 
     app:layout_constraintTop_toTopOf="parent" /> 

    <EditText 
     android:id="@+id/editText" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:ems="10" 
     android:inputType="textPersonName" 
     android:text="Name" 
     tools:layout_constraintTop_creator="1" 
     tools:layout_constraintRight_creator="1" 
     app:layout_constraintRight_toRightOf="parent" 
     android:layout_marginTop="153dp" 
     tools:layout_constraintLeft_creator="1" 
     app:layout_constraintLeft_toLeftOf="parent" 
     app:layout_constraintTop_toTopOf="parent" /> 

    <Button 
     android:id="@+id/button" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:text="Button" 
     android:onClick="SendMessage" 
     tools:layout_constraintTop_creator="1" 
     tools:layout_constraintRight_creator="1" 
     app:layout_constraintRight_toRightOf="parent" 
     android:layout_marginTop="22dp" 
     app:layout_constraintTop_toBottomOf="@+id/editText" 
     tools:layout_constraintLeft_creator="1" 
     app:layout_constraintLeft_toLeftOf="parent" /> 

    <Button 
     android:id="@+id/button2" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:text="Server" 
     android:onClick="Start_Server" 
     android:layout_marginEnd="53dp" 
     tools:layout_constraintRight_creator="1" 
     tools:layout_constraintBottom_creator="1" 
     app:layout_constraintBottom_toBottomOf="parent" 
     app:layout_constraintRight_toRightOf="parent" 
     android:layout_marginBottom="84dp" /> 

    <Button 
     android:id="@+id/button3" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:text="ConnectionREq" 
     android:onClick="pairDevice" 
     android:layout_marginStart="34dp" 
     tools:layout_constraintTop_creator="1" 
     tools:layout_constraintBottom_creator="1" 
     app:layout_constraintBottom_toBottomOf="@+id/button2" 
     tools:layout_constraintLeft_creator="1" 
     app:layout_constraintLeft_toLeftOf="parent" 
     app:layout_constraintTop_toTopOf="@+id/button2" 
     android:layout_marginLeft="30dp" 
     app:layout_constraintVertical_bias="0.0" /> 

</android.support.constraint.ConstraintLayout> 
+0

大変ありがとうございます!アプリは完璧に動作します。私はチュートリアルのためにインターネットを精練しています。あなたの答えはこれまで私のために働いていた唯一のものでした。もう1つの質問ですが、これはBluetoothデバイス(AppleからAppleまたはAndroidからAppleへ)などのすべてのBluetoothデバイスで使用できますか、またはAndroidからAndroidのみで動作しますか。 –

+0

iOSの下でAndroidアプリケーションを実行することはできません(iPhone、iPad、iPodなどの機能を搭載しています) – rayan

2

例外の説明はdefenitely役立ちますが、私は、システムがUIスレッド内のソケット接続コードを実行できないようにすることを99%確信している - ので、あなたのソケットを移動し、新しいスレッドを作成する必要があります作成およびソケット接続コードをそのスレッドに渡し、最後に、接続が実行または失敗したことをリスナーに示すコールバックを作成します。それは

1

二つの主要なPROBLEMS-

1 ;-)のでsloooow UIを作るためのアンドロイドは、UIスレッド内のネットワーク関連、時間のかかる操作を行うには、あなたの試みのほとんどをブロックすること

注意)connect()はブロッキングコールです。メインアクティビティ(UI)スレッドとは別のスレッドでこの接続プロシージャを実行する必要があります。あなたはメインスレッドでこれをやっています。

注:connect()を呼び出す前に、 デバイスがデバイス検出を実行していないことを確認するには、常にcancelDiscovery()を呼び出す必要があります。 検出が進行中の場合、接続の試行は、 が大幅に遅くなり、失敗する可能性が高くなります。

2)あなたは、私はaccept()へのコールが表示されない(あなたがデータを送信または受信することができるように)あまりにも第二のデバイス上で同じコードを使用している場合。 accept()は接続要求をリッスンします。 また、accept()コールはブロッキングコールです。メインアクティビティUIスレッドでは実行しないでください。アプリケーションが他のユーザーのやりとりに応答できるようにしてください。

はまず、私は、コードをシフト - : - BLUETOOTH

+0

おかげで前にAcceptThread を開始する必要があります。あなたの提案を自分のプログラムに実装しました。ただし、送信ボタンを押すたびにアプリケーションがクラッシュします。アプリケーションを何度も実行すると、これはコードの2行であることがわかります。Scanner s =新しいScanner(inStream).useDelimiter( "\\ A"); displayMessage.setText(s.hasNext()?s.next(): "");理由を示唆したり、出力ストリームからテキストを取り込んでTextViewのテキストに設定するコードを与えることができますか? –

関連する問題