蓝牙即服务并从中发送/接收

时间:2019-03-06 19:47:40

标签: android bluetooth

我正在尝试使用蓝牙接收/发送数据到arduino板,并且我可以通过一项活动连接到板。我知道我可以使用服务使其他活动与蓝牙连接,但是我不知道如何将蓝牙作为服务。而且我不知道如何发送和接收它。 我的配对设备代码:

public class BTConnect extends AppCompatActivity {


private static final String TAG = "BTConnect"; 

ListView IdLista;

public static String EXTRA_DEVICE_ADDRESS = "device_address";


private BluetoothAdapter mBtAdapter;
private ArrayAdapter<String> mPairedDevicesArrayAdapter;

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

@Override
public void onResume()
{
    super.onResume();
    //---------------------------------
    VerificarEstadoBT();

    //
    mPairedDevicesArrayAdapter = new ArrayAdapter<String>(this, R.layout.btconnect_nombre);

    IdLista = (ListView)findViewById(R.id.Id2);
    IdLista.setAdapter(mPairedDevicesArrayAdapter);
    IdLista.setOnItemClickListener(mDeviceClickListener);

    mBtAdapter = BluetoothAdapter.getDefaultAdapter();


    Set<BluetoothDevice> pairedDevices = mBtAdapter.getBondedDevices();


    if (pairedDevices.size() > 0)
    {
        for (BluetoothDevice device: pairedDevices) { 
            mPairedDevicesArrayAdapter.add(device.getName() + "\n" + device.getAddress());

        }
    }
}


private AdapterView.OnItemClickListener mDeviceClickListener = new AdapterView.OnItemClickListener() {
    public void onItemClick(AdapterView av, View v, int arg2, long arg3) {


        String info = ((TextView) v).getText().toString();
        String address = info.substring(info.length() - 17);


        Intent i = new Intent(BTConnect.this, device.class);
        i.putExtra(EXTRA_DEVICE_ADDRESS, address);
        startActivity(i);
    }
};

private void VerificarEstadoBT() {

    mBtAdapter= BluetoothAdapter.getDefaultAdapter();
    if(mBtAdapter==null) {
        Toast.makeText(getBaseContext(), "the device can't connect to BT", Toast.LENGTH_SHORT).show();
    } else {
        if (mBtAdapter.isEnabled()) {
            Log.d(TAG, "...Bluetooth Activation...");
        } else {

            Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
            startActivityForResult(enableBtIntent, 1);

        }
    }
}}

还有我的第一个活动“设备”:

public class device extends AppCompatActivity {
Button IdEncender, IdApagar,IdDesconectar,IdReset;
ArrayList<String> addArray = new ArrayList<String>();
ListView show;
//-------------------------------------------
Handler bluetoothIn;
final int handlerState = 0;
private BluetoothAdapter btAdapter = null;
private BluetoothSocket btSocket = null;
private StringBuilder DataStringIN = new StringBuilder();
private ConnectedThread MyConexionBT;
// Identificador unico de servicio - SPP UUID
private static final UUID BTMODULEUUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");
// String para la direccion MAC
private static String address = null;
//-------------------------------------------

@SuppressLint("HandlerLeak")
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_device);
    IdEncender = (Button) findViewById(R.id.IdEncender);
    IdApagar = (Button) findViewById(R.id.IdApagar);
    IdDesconectar = (Button) findViewById(R.id.IdDisconectar);
    show = (ListView) findViewById(R.id.LIST1) ;
    IdReset=(Button)findViewById(R.id.IdReset);
    bluetoothIn = new Handler() {
        public void handleMessage(android.os.Message msg) {
            if (msg.what == handlerState) {
                String readMessage = (String) msg.obj;
                DataStringIN.append(readMessage);

                int endOfLineIndex = DataStringIN.indexOf("#");

                if (endOfLineIndex > 0) {
                    String dataInPrint = DataStringIN.substring(0, endOfLineIndex);
                    String newline = "\r\n";
                    DataStringIN.delete(0, DataStringIN.length());

                   //--List adapter--//
                    addArray.add(dataInPrint);
                    ArrayAdapter<String> adapter =new ArrayAdapter<String>(device.this, android.R.layout.simple_list_item_1, addArray);
                    show.setAdapter(adapter);

            }
        }
    };

    btAdapter = BluetoothAdapter.getDefaultAdapter(); // get Bluetooth adapter
    VerificarEstadoBT();

    IdEncender.setOnClickListener(new View.OnClickListener() {
        public void onClick(View v)
        {
            MyConexionBT.write("1");
        }
    });

    IdApagar.setOnClickListener(new View.OnClickListener() {
        public void onClick(View v) {
            MyConexionBT.write("0");
        }
    });

    IdDesconectar.setOnClickListener(new View.OnClickListener() {
        public void onClick(View v) {
            if (btSocket!=null)
            {
                try {btSocket.close();}
                catch (IOException e)
                { Toast.makeText(getBaseContext(), "Error", Toast.LENGTH_SHORT).show();;}
            }
            finish();
        }
    });

configurebutton();

}

private void configurebutton() {
    Button startbutton = (Button)findViewById(R.id.Start);
    startbutton.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            startActivity(new Intent(device.this,chart.class));
        }
    });
}

private BluetoothSocket createBluetoothSocket(BluetoothDevice device) throws IOException
{
    return device.createRfcommSocketToServiceRecord(BTMODULEUUID);
}

@Override
public void onResume()
{
    super.onResume();
    Intent intent = getIntent();
    address = intent.getStringExtra(BTConnect.EXTRA_DEVICE_ADDRESS);
    BluetoothDevice device = btAdapter.getRemoteDevice(address);

    try
    {
        btSocket = createBluetoothSocket(device);
    } catch (IOException e) {
        Toast.makeText(getBaseContext(), "fail", Toast.LENGTH_LONG).show();
    }
    try
    {
        btSocket.connect();
    } catch (IOException e) {
        try {
            btSocket.close();
        } catch (IOException e2) {}
    }
    MyConexionBT = new ConnectedThread(btSocket);
    MyConexionBT.start();
}

@Override
public void onPause()
{
    super.onPause();
    try
    { 
        btSocket.close();
    } catch (IOException e2) {}
}

private void VerificarEstadoBT() {

    if(btAdapter==null) {
        Toast.makeText(getBaseContext(), "error in bluetooth connection", Toast.LENGTH_LONG).show();
    } else {
        if (btAdapter.isEnabled()) {
        } else {
            Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
            startActivityForResult(enableBtIntent, 1);
        }
    }
}
public void savefile(String file, String text){
    try {
        FileOutputStream fos = openFileOutput(file, Context.MODE_APPEND);
        fos.write(text.getBytes());
        fos.close();
        Toast.makeText(device.this, "saved!", Toast.LENGTH_LONG).show();

    } catch (IOException e) {
            e.printStackTrace();
            Toast.makeText(device.this,"error",Toast.LENGTH_LONG).show();
    }

}

//Crea la clase que permite crear el evento de conexion
private class ConnectedThread extends Thread
{
    private final InputStream mmInStream;
    private final OutputStream mmOutStream;

    public ConnectedThread(BluetoothSocket socket)
    {
        InputStream tmpIn = null;
        OutputStream tmpOut = null;
        try
        {
            tmpIn = socket.getInputStream();
            tmpOut = socket.getOutputStream();
        } catch (IOException e) { }
        mmInStream = tmpIn;
        mmOutStream = tmpOut;
    }

    public void run()
    {
        byte[] buffer = new byte[256];
        int bytes;

        while (true) {
            try {
                bytes = mmInStream.read(buffer);
                String readMessage = new String(buffer, 0, bytes);
                bluetoothIn.obtainMessage(handlerState, bytes, -1, readMessage).sendToTarget();
            } catch (IOException e) {
                break;
            }
        }
    }
    public void write(String input)
    {
        try {
            mmOutStream.write(input.getBytes());
        }
        catch (IOException e)
        {
            Toast.makeText(getBaseContext(), "fail to connect", Toast.LENGTH_LONG).show();
            finish();
        }
    }
}

}

1 个答案:

答案 0 :(得分:0)

如果不久将您的connection / message_exchange逻辑移动到Thread / Runnable并从Service启动它。您可以使用BroadcastReceivers或Messenger在服务和活动/活动之间交换数据。我也建议您使用Bluetooth lib: implementation 'me.aflak.libraries:bluetooth:1.3.4',该线程已经具有内部线程,因此很容易嵌入到您的服务中。

使用此lib和Messenger的服务示例代码:

private ArrayList<Messenger> mClients = new ArrayList<>();
final private Messenger inComingMessenger = new Messenger(mIncomingHandler);
@SuppressLint("HandlerLeak")
final Handler mIncomingHandler = new Handler() {
    @Override
    public void handleMessage(Message msg) {

        switch (msg.what) {
            case Constants.MSG_REGISTER_CLIENT:
                mClients.add(msg.replyTo);
                Log.d(TAG, "handleMessage: new client connected. Total: " + mClients.size());
                break;

            case Constants.MSG_UNREGISTER_CLIENT:
                mClients.remove(msg.replyTo);
                Log.d(TAG, "handleMessage: client disconnected. Total: " + mClients.size());
                break;
            case Constants.MSG_YOUR_MESSAGE_TYPE:
                String val = (String) msg.obj;
                // stuff to do
                break;
        }
    }
};

/**
 * Send message to connected activities
 */
public void sendMessageToClients(int msgSignal, Object obj) {
    if (mClients.size() == 0)
        return;

    sendMessage(mClients.get(0), Message.obtain(null, msgSignal, obj));

    for (int i = 1; i < mClients.size(); i++) {
        if (mClients.get(i) == null)
            continue;
        sendMessage(mClients.get(i), Message.obtain(null, msgSignal, obj));
    }
}

/**
 * Send message to binded activity
 */
private void sendMessage(Messenger msgr, Message msg) {
    try {
        msgr.send((msg));
    } catch (RemoteException e) {
        Log.e(TAG, "can't send message", e);
        e.printStackTrace();
    }
}

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
    super.onStartCommand(intent, flags, startId);
    Log.d(TAG, "onStartCommand");
    return START_STICKY;
}

@Nullable
@Override
public IBinder onBind(Intent intent) {
    Log.d(TAG, "onBind");
    return inComingMessenger.getBinder();
}

@Override
public void onCreate() {
    super.onCreate();
    bleDevices = new ArrayList<>();

    if(bluetooth == null) {
        bluetooth = new Bluetooth(this);

        bluetooth.setBluetoothCallback(new BluetoothCallback() {
            @Override
            public void onBluetoothTurningOn() {}

            @Override
            public void onBluetoothOn() {}

            @Override
            public void onBluetoothTurningOff() {
                bluetooth = null;
            }

            @Override
            public void onBluetoothOff() { }

            @Override
            public void onUserDeniedActivation() {
                // when using bluetooth.showEnableDialog()
                // you will also have to call bluetooth.onActivityResult()
            }
        });

        bluetooth.setDiscoveryCallback(new DiscoveryCallback() {
            @Override public void onDiscoveryStarted() {

            }
            @Override public void onDiscoveryFinished() {
                bleDevices.clear();
            }
            @Override public void onDeviceFound(BluetoothDevice device) {
                if(bleDevices.indexOf(device)<0) {
                    bleDevices.add(device);
                    Log.d(TAG, "Found new device while scanning: "+device.getAddress());
                    sendMessageToClients(Constants.MSG_BLE_DEVICE_FOUND, device);
                }
            }
            @Override public void onDevicePaired(BluetoothDevice device) {}
            @Override public void onDeviceUnpaired(BluetoothDevice device) {}
            @Override public void onError(String message) {
                Log.e(TAG, "DiscoveryCallback onError "+message);
            }
        });
        bluetooth.setDeviceCallback(new DeviceCallback() {
            @Override public void onDeviceConnected(BluetoothDevice device) { }
            @Override public void onDeviceDisconnected(BluetoothDevice device, String message) { }
            @Override public void onMessage(String message) {
                // Handle your message
                yourHandleFunction(message.replaceAll(" ",""));
                Log.d(TAG, message);
            }
            @Override public void onError(String message) {
                Log.e(TAG, "DeviceCallback onError "+message);
            }
            @Override public void onConnectError(BluetoothDevice device, String message) { }
        });
        bluetooth.onStart();
    }

    connectToSavedDevice();
}
}
private void connectToSavedDevice() {
    Log.d(TAG, "connectToSavedDevice state="+getState());
    if(getState() != STATE_DISCONNECTED) return;
    SharedPreferences pref = getSharedPreferences(App.TAG, 0);
    String address = pref.getString(Constants.PREF_AUTO_CONNECT_TO_ADDRESS, null);
    if(address == null) {
        Log.d(TAG, "saved address==null start scan for devices");
        scanDevices();
        return;
    }
    BluetoothDevice device = bluetoothAdapter.getRemoteDevice(address);
    if(device!=null) {
        Log.d(TAG, "device found try to connect/bound, connect to Arduino");
        bluetooth.connectToAddress(address,false);
    }
}

在活动中实现ServiceConnection接口:

protected synchronized void unbindService() {
    if (!isBound()) {
        return;
    }
    // lock object (prevents access to service while disconnecting)
    synchronized (outComingMessenger) {
        sendMessageToService(Message.obtain(null, Constants.MSG_UNREGISTER_CLIENT));
        unbindService(this);
        outComingMessenger = null;
    }
}

protected void bindService() {
    bindService(mServiceIntent, this, BIND_AUTO_CREATE);
}


@Override
public void onServiceConnected(ComponentName name, IBinder service) {
    outComingMessenger = new Messenger(service);

    final Message msg = Message.obtain(null, Constants.MSG_REGISTER_CLIENT);
    msg.replyTo = inComingMessenger;
    msg.obj = getClass().getSimpleName();
    sendMessageToService(msg);

    sendMessageToService(Constants.MSG_CHECK_IS_CONNECTION_READY);
}


@Override
public void onServiceDisconnected(ComponentName name) {
    outComingMessenger = null;
    bindService();
}

/**
 * Send message to service
 */
protected void sendMessageToService(Message msg) {
    if (!isBound()) {
        return;
    }
    try {
        msg.replyTo = inComingMessenger;
        outComingMessenger.send(msg);
    } catch (RemoteException e) {
    }
}

/**
 * Send simple message to connected service
 * @param messageId
 */
protected void sendMessageToService(int messageId) {
    sendMessageToService(Message.obtain(null, messageId));
}

/**
 * Send simple message to connected service
 * @param messageId
 */
protected void sendMessageToService(int messageId, Object obj) {
    sendMessageToService(Message.obtain(null, messageId, obj));
}

/**
 * Service is connected?
 */
protected final boolean isBound() {
    return outComingMessenger != null;
}

@SuppressLint("HandlerLeak")
private final Handler mIncomingHandler = new Handler() {
    public void handleMessage(Message msg) {
        switch (msg.what) {
            case Constants.MSG_YOUR_MESSAGE:
                int res = (int) msg.obj;

                break;

            case Constants.MSG_CONNECTION_READY:
                isReady = (boolean) msg.obj;
                if(isReady) {
                    // show toast or what you want to do with the UI
                } else {
                    // do something else
                }
                break;

            case Constants.MSG_BLE_DEVICE_FOUND:
                BluetoothDevice device = (BluetoothDevice)msg.obj;
                SharedPreferences pref = getSharedPreferences(App.TAG, 0);
                String deviceAddress = pref.getString(Constants.PREF_AUTO_CONNECT_TO_ADDRESS, null);
                break;
        }
    }
};

final private Messenger inComingMessenger = new Messenger(mIncomingHandler);