高温菌 2019-07-10 16:39 采纳率: 50%
浏览 545
已采纳

通过Handler实现Service和Activity的数据交互,与onbind返回Binder对象冲突,我该如何解决?

在做service和activity通讯,需要服务能够控制活动的运行,同时能够实时进行数据传输
我通过Handler实现Service和Activity的数据交互,但尴尬的是onBind已经用于传递BleBind的一个实例了,没办法return messenger.getBinder();

package com.example.bluserver;

import android.app.Service;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothSocket;
import android.content.Context;
import android.content.Intent;
import android.os.Binder;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.os.Messenger;
import android.util.Log;
import android.widget.TextView;
import android.widget.Toast;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.UUID;

public class bluService extends Service {
    public static final int MSG = 123;
    private static final String TAG = "BleService";
    private BluetoothAdapter mBA;
    private Context mContext;
    private final UUID MY_UUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");//这是蓝牙透传的uuid
    // 这里本身即是服务端也是客户端,需要如下类
    private BluetoothSocket mSocket;
    private BluetoothDevice mOldDevice;
    private BluetoothDevice mCurDevice;
    // 输出流_客户端需要往服务端输出
    private OutputStream os;
    private Messenger mActivityMessenger;
    private BleBinder bleBinder=new BleBinder();
    @Override
    public IBinder onBind(Intent intent) {
        Messenger messenger=new Messenger(handler);
        //return  messenger.getBinder();//Handler实现Service和Activity的数据交互
        return bleBinder;//返回BleBinder实例供活动调用
    }
    class BleBinder extends Binder{//以下是以供调用的公共方法
        //开始读取传感器数据
        public void startread(){
            {
                new Thread(new Runnable() {
                    @Override
                    public void run() {
                        try {
                            Log.d(TAG,"开始运行run()函数");
                            InputStream is = mSocket.getInputStream();
                            Log.d(TAG,"已获取输入流");
                            while (true) {
                                synchronized (this) {
                                    //Log.d(TAG,"已获取锁");
                                    //Thread.sleep(50);
                                    byte[] tt = new byte[is.available()];
                                    if (tt.length > 0) {
                                        is.read(tt, 0, tt.length);
                                        Message msg = new Message();
                                        msg.obj = new String(tt, "GBK");
                                        //大概在这里要获取整个字符串,字符串以回车分割,如此才能准确识别
                                        Log.e(TAG, "客户端:" + msg.obj);
                                        showToast("客户端:" + msg.obj);
                                        mActivityMessenger.send(msg);
                                        //handler.sendMessage(msg);
                                    }
                                }
                            }
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                    }
                }).start();
            }
        }
        public void stopread(){}//停止读取传感器数据
        /**
         * 弹出Toast窗口
         *
         * @param message
         */
        private void showToast(String message) {
            if (mContext != null) {
                Toast.makeText(mContext, message, Toast.LENGTH_LONG).show();
            } else {
                Log.e(TAG, "message:" + message);
            }
        }
        /**
         * 主动连接蓝牙
         *
         * @param device
         */
        public void connectDevice(BluetoothDevice device) {
            // 判断是否在搜索,如果在搜索,就取消搜索
            if (mBA.isDiscovering()) {
                mBA.cancelDiscovery();
            }
            try {
                // 获得远程设备
                Log.e(TAG, "开始检索");
                if (mCurDevice == null || mCurDevice != mOldDevice) {
                    mCurDevice = mBA.getRemoteDevice(device.getAddress());
                    Log.e(TAG, device.getAddress());
                    mOldDevice = mCurDevice;
                    Log.e(TAG, "device:" + mCurDevice);
                    mSocket = mCurDevice.createRfcommSocketToServiceRecord(MY_UUID);
                    // 连接
                    mSocket.connect();
                    // 获得输出流
                    os = mSocket.getOutputStream();
                    Log.e(TAG, "获取输入流");
                    startread();
                    Log.e(TAG, "开启读线程");
                    //intent流转byte数组
//                byte[] input=ByteToInputStream.input2byte(mSocket.getInputStream());
//                Intent intent=new Intent();
//                intent.putExtra("inputstream",input);
//                mContext.startActivity(intent);
                }
                // 如果成功获得输出流
                Log.e(TAG, "3");
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        /**
         * 判断是否打开蓝牙
         *
         * @return
         */
        public boolean isEnabled() {
            if (mBA.isEnabled()) {
                return true;
            }
            return false;
        }
        /**
         * 传输数据
         *
         * @param message
         */
        public void write(String message) {
            try {
                if (os != null) {
                    os.write(message.getBytes("GBK"));
                }
                Log.e(TAG, "write:" + message);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        public BluetoothDevice getCurDevice() {
            return mCurDevice;
        }
    }
    public bluService() {
        mBA = BluetoothAdapter.getDefaultAdapter();
    }

    private Handler handler = new Handler() {
        public void handleMessage(Message msg) {
            //Toast.makeText(this,String.valueOf(msg.obj),Toast.LENGTH_LONG);
            //将在此处向主线程发送信息,用于更新界面(已废弃)
            //将在此处处理来自活动的消息,发送消息在线程内
            // 参考代码  https://blog.csdn.net/CodeNoodles/article/details/51679532
            switch (msg.what){
                case MSG:
                    mActivityMessenger = msg.replyTo;
                    break;
            }
            Log.e(TAG, "服务端:" + msg.obj);
            super.handleMessage(msg);
        }
    };
    @Override
    public void onDestroy() {
        Log.d(TAG,"服务已销毁");
        super.onDestroy();
    }
    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Log.d(TAG,"服务已启动");
        return super.onStartCommand(intent, flags, startId);
    }
    @Override
    public void onCreate() {
        super.onCreate();
        Log.d(TAG,"服务已创建");
    }
}

  • 写回答

2条回答

  • Jimmy_buer 2019-07-11 10:33
    关注

    没有必要用handler去传消息。 太麻烦。 监听 , 广播, 都可以实现实时的消息传递。

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥15 这是哪个作者做的宝宝起名网站
  • ¥60 版本过低apk如何修改可以兼容新的安卓系统
  • ¥25 由IPR导致的DRIVER_POWER_STATE_FAILURE蓝屏
  • ¥50 有数据,怎么建立模型求影响全要素生产率的因素
  • ¥50 有数据,怎么用matlab求全要素生产率
  • ¥15 TI的insta-spin例程
  • ¥15 完成下列问题完成下列问题
  • ¥15 C#算法问题, 不知道怎么处理这个数据的转换
  • ¥15 YoloV5 第三方库的版本对照问题
  • ¥15 请完成下列相关问题!