雖然 IM / Instant Messaging(即時通訊)互連程式可以使用行業上的協定規範,但需要更多的設置和編程,所以筆者現在是利用 Bluetooth(藍牙)來使到兩部手機互相直接溝通,不用架構服務器或線上代理,祇是利用 Bluetooth(藍牙)直接互相傳輸資料,使用到 Socket 通訊協定,直接實現點對點傳輸。。程式是 IM / Instant Messaging(即時通訊)服務端(Server)程式。
Android Studio - Bluetooth 即時通訊服務端(Server)程式(四十四): |
- 操作系統:Windows 7 64-bit 版本
- 開發環境:Android Studio 4.0.1 版本
- 原程式:C:\Development\Development_Android\Android_Project\DIY-Android-010-01D Bluetooth IM Server
- 程式:C:\Development\Development_Android\Android_Project\DIY-Android-010-01D Bluetooth IM Server
- 設定 Bluetooth 許可權限後
- 設定 Bluetooth 許可權限後
- 設定手機藍牙
- 啟動手機藍牙
- 等待 Client 掃描周邊的藍牙設備
- 連接設備
- 在手機設備之間設定傳輸資料
當連接兩台設備設備時,要在兩台設備間創建連接,必須同時實現服務端(Server)和用戶端(Client)機制,其中一台設備(可檢測到的設備)需將自身設置為可接收傳入的連接請求。首先是要配對(配對意味著兩台設備知曉彼此的存在),然後連接完成綁定過程,因此其中一台設備必須開放的服務端,而另一台設備必須發起連接,具有可用於身份驗證的共用鏈路金鑰,並且能夠與彼此建立加密連接。當服務端和用戶端在同一 RFCOMM 通道上分別擁有已連接的 BluetoothSocket 時,二者將被視為彼此連接。藍牙通訊介面與 TCP Socket 相似。可以允許通過 InputStream 和 OutputStream 與其他藍牙設備交換資料,使用 read(byte[]) 和 write(byte[]) 讀取資料並寫入到資料流。
MainActivity.java:
import androidx.appcompat.app.AppCompatActivity; import android.os.Bundle; import android.content.Intent; import android.os.Handler; import android.os.Message; import android.view.View; import android.widget.Button; import android.widget.EditText; import android.widget.ListView; import android.widget.TextView; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.util.UUID;
import android.bluetooth.BluetoothAdapter; import android.bluetooth.BluetoothDevice; import android.bluetooth.BluetoothServerSocket; import android.bluetooth.BluetoothSocket;
public class MainActivity extends AppCompatActivity { Button mbtn_server, mbtn_send, mbtn_scan; ListView mlv_device; TextView mtv_msg, mtv_status, mtv_mode; EditText met_msg; BluetoothAdapter bluetoothAdapter;
// BluetoothDevice Array Definition BluetoothDevice [] bluetoothDevices;
// SendReceive variable SendReceive sendReceive;
// Fixed value static final int STATE_LISTENING = 1; static final int STATE_CONNECTING = 2; static final int STATE_CONNECTED = 3; static final int STATE_CONNECTION_FAILED = 4; static final int STATE_MESSAGE_RECEIVED = 5;
int REQUEST_ENABLE_BLUETOOTH = 1; int mStatus;
private static final String APP_NAME = "BluetoothIMApp"; private static final UUID MY_UUID = UUID.fromString("318c6089-985c-4773-b7ca-4c6130e4209e");
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main);
mbtn_server = findViewById(R.id.btn_server); mbtn_send = findViewById(R.id.btn_send); mbtn_scan = findViewById(R.id.btn_scan); mlv_device = findViewById(R.id.lv_device); mtv_status = findViewById(R.id.tv_status); mtv_msg = findViewById(R.id.tv_msg); met_msg = findViewById(R.id.et_msg); mtv_mode = findViewById(R.id.tv_mode);
bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
mtv_status.setText("Disconnect"); mtv_mode.setText("Mode ?"); mStatus = 0;
if (!bluetoothAdapter.isEnabled()){ Intent enableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE); startActivityForResult(enableIntent,REQUEST_ENABLE_BLUETOOTH); }
implementListeners(); }
private void implementListeners() { mbtn_server.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { mtv_mode.setText("Server Mode"); ServerClass serverClass = new ServerClass(); serverClass.start(); } });
mbtn_send.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { String string = String.valueOf(met_msg.getText()); if (mStatus == 3) { sendReceive.write(string.getBytes()); } } }); }
Handler handler = new Handler(new Handler.Callback() { @Override public boolean handleMessage(Message msg) {
// Handler : UI Thread is enable communication switch (msg.what){ case STATE_LISTENING: mtv_status.setText("Listening"); mStatus = 1; break;
case STATE_CONNECTING: mtv_status.setText("Connecting"); mStatus = 2; break;
case STATE_CONNECTED: mtv_status.setText("Connected"); mStatus = 3; break;
case STATE_CONNECTION_FAILED: mtv_status.setText("Connection Failed"); mStatus = 0; break;
case STATE_MESSAGE_RECEIVED: byte[] readBuffer = (byte[]) msg.obj; String tempMessage = new String(readBuffer,0,msg.arg1); mtv_msg.setText(tempMessage); break; } return true; } });
// SendReceive private class SendReceive extends Thread{
private final BluetoothSocket bluetoothSocket; private final InputStream inputStream; private final OutputStream outputStream;
public SendReceive(BluetoothSocket socket){ bluetoothSocket = socket; InputStream tempInput = null; OutputStream tempOutput = null;
try { tempInput = bluetoothSocket.getInputStream(); tempOutput = bluetoothSocket.getOutputStream(); } catch (IOException e) { e.printStackTrace(); }
inputStream = tempInput; outputStream = tempOutput; }
public void run(){ byte [] buffer = new byte[1024]; int bytes;
while (true){ try { bytes = inputStream.read(buffer); handler.obtainMessage(STATE_MESSAGE_RECEIVED,bytes,-1,buffer).sendToTarget(); } catch (IOException e) { e.printStackTrace(); } } }
// write public void write (byte[] bytes){ try { outputStream.write(bytes); } catch (IOException e) { e.printStackTrace(); } }
}
} |
MainActivity.java - Server Class:
// Server Class private class ServerClass extends Thread{ private BluetoothServerSocket serverSocket;
public ServerClass(){ try{ serverSocket = bluetoothAdapter.listenUsingRfcommWithServiceRecord(APP_NAME,MY_UUID); }catch (IOException e){ e.printStackTrace(); } }
public void run(){ BluetoothSocket socket = null; while (socket == null){ try{ Message message = Message.obtain(); message.what = STATE_CONNECTING; handler.sendMessage(message); socket = serverSocket.accept(); } catch (IOException e) { e.printStackTrace(); Message message = Message.obtain(); message.what = STATE_CONNECTION_FAILED; handler.sendMessage(message); }
if (socket!=null){ Message message = Message.obtain(); message.what = STATE_CONNECTED; handler.sendMessage(message); sendReceive = new SendReceive(socket); sendReceive.start(); break; } } } } |
activity¬main.xml:
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout 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=".MainActivity">
<TextView android:id="@+id/tv_status" android:layout_width="120dp" android:layout_height="wrap_content" android:layout_alignParentTop="true" android:layout_alignParentEnd="true" android:layout_alignParentRight="true" android:layout_marginTop="6dp" android:layout_marginEnd="31dp" android:layout_marginRight="31dp" android:text="STATUS" />
<Button android:id="@+id/btn_server" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentStart="true" android:layout_alignParentLeft="true" android:layout_alignParentTop="true" android:layout_marginStart="12dp" android:layout_marginLeft="12dp" android:layout_marginTop="5dp" android:text="SERVER" />
<Button android:id="@+id/btn_scan" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentTop="true" android:layout_marginStart="19dp" android:layout_marginLeft="19dp" android:layout_marginTop="5dp" android:layout_toEndOf="@+id/btn_server" android:layout_toRightOf="@+id/btn_server" android:text="DEVICE" />
<ListView android:id="@+id/lv_device" android:layout_width="358dp" android:layout_height="110dp" android:layout_alignParentBottom="true" android:layout_centerInParent="true" android:layout_marginStart="16dp" android:layout_marginLeft="16dp" android:layout_marginBottom="11dp" android:background="@android:color/holo_green_dark" />
<Button android:id="@+id/btn_send" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentTop="true" android:layout_marginStart="37dp" android:layout_marginLeft="37dp" android:layout_marginTop="57dp" android:background="@android:color/black" android:textColor="@android:color/white" android:layout_toEndOf="@+id/et_msg" android:layout_toRightOf="@+id/et_msg" android:text="Send" />
<TextView android:id="@+id/tv_msg" android:layout_width="390dp" android:layout_height="494dp" android:layout_below="@+id/et_msg" android:layout_alignParentStart="true" android:layout_alignParentLeft="true" android:layout_centerHorizontal="true" android:layout_marginStart="15dp" android:layout_marginLeft="15dp" android:layout_marginTop="-17dp" android:text="Message" />
<EditText android:id="@+id/et_msg" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@+id/btn_server" android:layout_marginStart="16dp" android:layout_marginLeft="16dp" android:layout_marginTop="5dp" android:layout_marginBottom="28dp" android:ems="10" android:inputType="textPersonName" android:textColor="@android:color/black" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintStart_toStartOf="parent" />
<TextView android:id="@+id/tv_mode" android:layout_width="120dp" android:layout_height="wrap_content" android:layout_below="@+id/tv_status" android:layout_alignParentEnd="true" android:layout_alignParentRight="true" android:layout_marginTop="5dp" android:layout_marginEnd="29dp" android:layout_marginRight="29dp" android:text="MODE" /> </RelativeLayout> |
Android Studio Bluetooth 即時通訊服務程式 |
沒有留言:
張貼留言