java - 读取蓝牙数据并将其放入MainActivity

标签 java android bluetooth handler

我一直在寻找这个,但我尝试过的一切都还没有奏效。我实现了一个蓝牙连接服务类,让我可以通过蓝牙连接到 HC-05 模块并发送消息。我可以在控制台中看到每条消息(带有日志),但是,无论我尝试什么,我似乎都无法将收到的字节放入我可以处理它的主要 Activity 中。这是我的日志所在的 BluetoothConnectionService 类中的代码:

蓝牙连接服务:

private Handler mHandler; // handler that gets info from Bluetooth service

// Defines several constants used when transmitting messages between the
// service and the UI.
private interface MessageConstants {
    public static final int MESSAGE_READ = 0;
    public static final int MESSAGE_WRITE = 1;
    public static final int MESSAGE_TOAST = 2;

    // ... (Add other message types here as needed.)
}    

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);
                    String incomingMessage = new String(buffer, 0, bytes);
                    Log.d(TAG, "InputStream: " + incomingMessage);

                    // Send the obtained bytes to the MainActivity
                    Handler mainActivityHandler = new Handler();
                    mainActivityHandler.obtainMessage(MessageConstants.MESSAGE_READ, bytes, -1, buffer);

                    // Send the obtained bytes to the UI activity.
                    /*Message readMsg = mHandler.obtainMessage(
                            MessageConstants.MESSAGE_READ, bytes, -1,
                            buffer);
                    readMsg.sendToTarget();*/
                } catch (IOException e) {
                    Log.e(TAG, "write: Error reading Input Stream. " + e.getMessage() );
                    break;
                }
            }
        }

MainActivity:(在 onCreate 中)

btnReadGlucose.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //On va envoyer quelle personne il faut lire le data
                String patientName = mSpinner.getSelectedItem().toString();
                int patientPosition = mSpinner.getSelectedItemPosition();
                Log.d(TAG, "Le patient " + patientName + " a la position " + patientPosition + " est selectionne");

                //Trouver quelle lettre envoyer
                DataEnvoyer = mappingPatients(patientPosition);
                RequestData = true;

                //Envoi du data
                envoyerCommandeBluetooth(DataEnvoyer);

                //How do I call my handler ?

            }
        });

我仍然是蓝牙通信处理程序的新手。我想我已经接近答案了,但我真的不知道如何获取字节中的消息并将其保存到我的主要 Activity 中的值。

有人可以帮忙吗?

谢谢, 路易斯谢尔。

最佳答案

方法 1:如果此服务与 Activity 运行在同一线程上,则将该服务与 Activity 绑定(bind)。

//IN YOUR ACTIVITY 
startService(new Intent(getApplicationContext(), BluetoothService.class));
bindService(new Intent(getApplicationContext(), BluetoothService.class), mServiceConnection, Context.BIND_AUTO_CREATE);


private ServiceConnection mServiceConnection = new ServiceConnection() {
    @Override
    public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
        BluetoothService.BackgroundBinder backgroundBinder = (BluetoothService.BackgroundBinder) iBinder;
        mBackgroundService = backgroundBinder.getBackgroundService();
        startPinging();
}

    @Override
    public void onServiceDisconnected(ComponentName componentName) {
        mBackgroundService = null;
        }
};

//IN SERVICE
public class BluetoothBinder extends Binder {
    public BluetoothService getBluetoothService() {
        return BluetoothService.this;
    }
}

@Override
public IBinder onBind(Intent intent) {
    Log.d(TAG, "Inside onBind");
    return new BluetoothBinder();
}

现在服务已绑定(bind),您可以在服务中为传入消息声明一个 getter,这样当您在 Activity 中按下按钮时,它就会返回消息。

方法 2(通过处理程序):如果您需要一个跨进程通信的接口(interface),您可以创建一个 Messenger。它处理单线程上的通信。 我还没有这样做,但可以找到一篇关于此的好文章 here .

方法 3(通过 LocalBroadCast):在您的蓝牙服务中,每当收到消息时发送 localBroadcast

//SERVICE
private void sendMessage(String incomingMessage) {
    Intent intent = new Intent("UNIQUE_ACTION");
    intent.putExtra("incomingMessage", incomingMessage);
    LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
}

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);
                    String incomingMessage = new String(buffer, 0, bytes);
                    Log.d(TAG, "InputStream: " + incomingMessage);
                    sendMessage(incomingMessage);

//ACTIVITY
@Override
public void onResume() {
    super.onResume();
    // This registers mMessageReceiver to receive messages.
    LocalBroadcastManager.getInstance(this).registerReceiver(mMessageReceiver,new IntentFilter("UNIQUE_ACTION"));
}

// Handling the received Intents for the "UNIQUE_ACTION" event 
private BroadcastReceiver mMessageReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
    // Extract data included in the Intent
    String incomingMessage = intent.getStringExtra()("incomingMessage");
    Log.d(TAG, incomingMessage);
    }
};

@Override
protected void onPause() {
    // Unregister since the activity is not visible
    LocalBroadcastManager.getInstance(this).unregisterReceiver(mMessageReceiver);
    super.onPause();
}

此外,我建议查看此链接以了解 service and activity 之间的通信.

PS:看看这个 library用于蓝牙通信。它确实提供了从蓝牙获取数据的方法,我亲自测试过它可以与 HC-05 配合使用,并且还有示例。

关于java - 读取蓝牙数据并将其放入MainActivity,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47611000/

相关文章:

java - 报警管理器运行

android - 所有屏幕中的自定义 toast 消息?

java - JUnit 4 和异常暂停

java - 如何使这个删除测试独立?

java - 如何使用注释在 spring batch 中运行多个作业

ios - 核心蓝牙读取数据

ios - 查找附近的应用用户

java - 不同的对象,同名变量应该有两个不同的值,但不是吗?

android - 约束布局 : Is it possible to make TextView to wrap the text when gets too long?

与 API>=21 AND API<21 兼容的 Android 低功耗蓝牙代码