package com.lfk.justweengine.utils.blueTooth; import android.annotation.SuppressLint; import android.app.Activity; import android.bluetooth.BluetoothAdapter; import android.bluetooth.BluetoothDevice; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.os.Handler; import android.os.Message; import android.util.Log; import android.widget.Toast; import com.lfk.justweengine.R; import java.util.ArrayList; import java.util.Arrays; import java.util.Set; /** * Created by liufengkai on 16/1/20. */ public class BlueToothServer { // Debugging private static final String TAG = "BluetoothChat"; private static final boolean D = true; // Message types sent from the BluetoothChatService Handler public static final int MESSAGE_STATE_CHANGE = 1; public static final int MESSAGE_READ = 2; public static final int MESSAGE_WRITE = 3; public static final int MESSAGE_DEVICE_NAME = 4; public static final int MESSAGE_TOAST = 5; // Key names received from the BluetoothChatService Handler public static final String DEVICE_NAME = "device_name"; public static final String TOAST = "toast"; // Intent request codes private static final int REQUEST_CONNECT_DEVICE_SECURE = 1; private static final int REQUEST_CONNECT_DEVICE_INSECURE = 2; private static final int REQUEST_ENABLE_BT = 3; // Name of the connected device private String mConnectedDeviceName = null; // Array adapter for the conversation thread private BluetoothChatService mChatService = null; private BluetoothAdapter mBluetoothAdapter = null; private Activity context; private CharSequence mBlueToothState = null; // msg handler private BlueToothMsgHandler mHandler; private ArrayList<String> mNewDeviceList; private OnMessageBack onMessageBack = null; public BlueToothServer(Activity context, OnMessageBack messageBack) { this.context = context; this.onMessageBack = messageBack; this.mHandler = new BlueToothMsgHandler(); // Get local Bluetooth adapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter(); // If the adapter is null, then Bluetooth is not supported if (mBluetoothAdapter == null) { Toast.makeText(context, "Bluetooth is not available", Toast.LENGTH_LONG).show(); } } public void init() { if (!mBluetoothAdapter.isEnabled()) { Intent enableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE); context.startActivityForResult(enableIntent, REQUEST_ENABLE_BT); // Otherwise, setup the chat session } else { if (mChatService == null) setupChat(); } // Register for broadcasts when a device is discovered IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND); context.registerReceiver(mReceiver, filter); // Register for broadcasts when discovery has finished filter = new IntentFilter(BluetoothAdapter.ACTION_DISCOVERY_FINISHED); context.registerReceiver(mReceiver, filter); } public void unBindService() { if (mChatService != null) mChatService.stop(); if (mBluetoothAdapter != null) { mBluetoothAdapter.cancelDiscovery(); } // Unregister broadcast listeners context.unregisterReceiver(mReceiver); } private void setupChat() { Log.d(TAG, "setupChat()"); // Initialize the BluetoothChatService to perform bluetooth connections mChatService = new BluetoothChatService(context, mHandler); this.mNewDeviceList = new ArrayList<>(); } /** * handler for message */ @SuppressLint("HandlerLeak") private class BlueToothMsgHandler extends Handler { @Override public void handleMessage(Message msg) { super.handleMessage(msg); switch (msg.what) { case MESSAGE_STATE_CHANGE: if (D) Log.i(TAG, "MESSAGE_STATE_CHANGE: " + msg.arg1); switch (msg.arg1) { case BluetoothChatService.STATE_CONNECTED: setStatus(context.getString(R.string.title_connected_to, mConnectedDeviceName)); break; case BluetoothChatService.STATE_CONNECTING: setStatus(R.string.title_connecting); break; case BluetoothChatService.STATE_LISTEN: case BluetoothChatService.STATE_NONE: setStatus(R.string.title_not_connected); break; } break; case MESSAGE_WRITE: byte[] writeBuf = (byte[]) msg.obj; // construct a string from the buffer onMessageBack.sendMessage(Arrays.toString(writeBuf)); break; case MESSAGE_READ: byte[] readBuf = (byte[]) msg.obj; // construct a string from the valid bytes in the buffer onMessageBack.getMessage(Arrays.toString(readBuf)); break; case MESSAGE_DEVICE_NAME: // save the connected device's name mConnectedDeviceName = msg.getData().getString(DEVICE_NAME); Toast.makeText(context, "Connected to " + mConnectedDeviceName, Toast.LENGTH_SHORT).show(); break; case MESSAGE_TOAST: Toast.makeText(context, msg.getData().getString(TOAST), Toast.LENGTH_SHORT).show(); break; } } } /** * set BlueTooth state * * @param s */ private void setStatus(CharSequence s) { this.mBlueToothState = s; } private void setStatus(int res) { this.mBlueToothState = context.getString(res); } /** * enable for discover by others' phone */ public void ensureDiscoverable() { if (D) Log.d(TAG, "ensure discoverable"); if (mBluetoothAdapter.getScanMode() != BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE) { Intent discoverableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE); discoverableIntent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 300); context.startActivity(discoverableIntent); } } /** * send message * * @param message */ public void sendMessage(String message) { // Check that we're actually connected before trying anything if (mChatService.getState() != BluetoothChatService.STATE_CONNECTED) { Toast.makeText(context, R.string.not_connected, Toast.LENGTH_SHORT).show(); return; } // Check that there's actually something to send if (message.length() > 0) { // Get the message bytes and tell the BluetoothChatService to write byte[] send = message.getBytes(); mChatService.write(send); } } /** * do discovery */ public void doDiscovery() { if (D) Log.d(TAG, "doDiscovery()"); // If we're already discovering, stop it if (mBluetoothAdapter.isDiscovering()) { mBluetoothAdapter.cancelDiscovery(); } // Request discover from BluetoothAdapter mBluetoothAdapter.startDiscovery(); } // The BroadcastReceiver that listens for discovered devices and // changes the title when discovery is finished private final BroadcastReceiver mReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { String action = intent.getAction(); // When discovery finds a device if (BluetoothDevice.ACTION_FOUND.equals(action)) { // Get the BluetoothDevice object from the Intent BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); // If it's already paired, skip it, because it's been listed already if (device.getBondState() != BluetoothDevice.BOND_BONDED) { mNewDeviceList.add(device.getName() + "\n" + device.getAddress()); } // When discovery is finished, change the Activity title } else if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)) { if (mNewDeviceList.size() == 0) { mNewDeviceList.clear(); } onMessageBack.getDevice(mNewDeviceList); } } }; /** * connect to a device * * @param address mac * @param secure is secure? */ public void connectToDevice(String address, boolean secure) { // Get the BluetoothDevice object BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(address); // Attempt to connect to the device mChatService.connect(device, secure); } public ArrayList<String> getPairedDevices() { ArrayList<String> arrayList = new ArrayList<>(); Set<BluetoothDevice> pairedDevices = mBluetoothAdapter.getBondedDevices(); // If there are paired devices, add each one to the ArrayAdapter if (pairedDevices.size() > 0) { for (BluetoothDevice device : pairedDevices) { arrayList.add(device.getName() + "\n" + device.getAddress()); } } else { arrayList.clear(); } return arrayList; } }