Android数据通信开发与应用(二):Android App通信

目录

第一节:AIDL实现远程服务的通信

一、远程服务的开启

二、远程服务的通信

第二节:Android线程间通信

一、什么是多线程?

二、ANR 的基础知识及产生

1、原因:

2、三种情况:

三、线程

四、实现的两种方式:

五、线程间通信

第三节:Socket&Https通信

一、什么是Socket

UDP:

DatagramSocket:

DatagramPacket:

TCP:

ServerSocket

Socket

二、UDP实例:服务端、客户端通信

三、TCP实例:多人聊天室

四、Https通信

第四节:经典蓝牙通信

一、蓝牙权限:

二、设置蓝牙:

第五节:低功耗蓝牙应用


第一节:AIDL实现远程服务的通信

AIDL

全称:(Android Interface definition language),Android接口定义的语言。

作用:进程间的通信接口。

一、远程服务的开启

1、在服务提供端App的Manifest文件中为service配置action属性,exported必须为true。

<service
            android:name=".MyService"
            android:enabled="true"
            android:exported="true">
            <intent-filter>
                <action android:name="com.imooc.admin.myservice"/>
            </intent-filter>
        </service>

2、本地App端声明Intent对象,设置action和package,action为服务端manifest文件中指定的值,package为服务端包名,然后利用startService、BindService启动、绑定服务。

    public void onClick(View v) {
        switch (v.getId()){
            case R.id.start_btn: {
                //Android5.0 以前版本 可以隐式声明
                //Intent intent=new Intent("com.imooc.admin.myservice");

                //Android5.0以后版本 必须显示声明
                Intent intent = new Intent();
                intent.setAction("com.imooc.admin.myservice");
                intent.setPackage("com.example.servicedemo");
                startService(intent);
                break;
            }
            case R.id.stop_btn: {
                Intent intent=new Intent();
                intent.setAction("com.imooc.admin.myservice");
                intent.setPackage("com.example.servicedemo");
                stopService(intent);
                break;
            }
            case R.id.bind_btn: {
                Intent intent=new Intent();
                intent.setAction("com.imooc.admin.myservice");
                intent.setPackage("com.example.servicedemo");
                bindService(intent,mConnection,BIND_AUTO_CREATE);
                break;
            }
            case R.id.unbind_btn: {
                unbindService(mConnection);
                break;
            }
        }
    }

二、远程服务的通信

远程服务的启动并不能进行通信,要实现通信需要使用AIDL。IBinder也能实现通信,但是IBinder仅限于同一进程,而AIDL是进程间的通信。

步骤:

1、在远端创建AIDL文件。

  • 右键->new->AIDL->AIDL File;
  • 添加自定义方法,ReBuild。
interface IMyAidlInterface {
    /**
     * Demonstrates some basic types that you can use as parameters
     * and return values in AIDL.
     */
    void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat,
            double aDouble, String aString);

    //自定义方法:显示进度
    void showProgress();
}

2、实现AIDL。实例化AIDL对象,并在Service的onBind中返回。

   public IBinder onBind(Intent intent) {
        // TODO: Return the communication channel to the service.
        Log.d(TAG, "onBind: 服务绑定了");
        //throw new UnsupportedOperationException("Not yet implemented");
        return new IMyAidlInterface.Stub() {
            @Override
            public void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat, double aDouble, String aString) throws RemoteException {

            }

            @Override
            public void showProgress() throws RemoteException {
                Log.d(TAG, "showProgress: 当前进度:"+mCount);
            }
        };
    }

3、本地端创建目录,并拷贝远端aidl文件。

  • 切换project模式,创建目录\src\main\aidl\远端包名
  • 拷贝aidl文件到目录中,rebuild。

4、在Serviceconnection 中获取aidl,并调用自定义方法。

    private ServiceConnection mConnection=new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            IMyAidlInterface aidlInterface=IMyAidlInterface.Stub.asInterface(service);
            try {
                aidlInterface.showProgress();
            } catch (RemoteException e) {
                e.printStackTrace();
            }
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {

        }
    };

 

第二节:Android线程间通信

一、什么是多线程?

线程是程序中一个单一的顺序控制流程,在单个程序中同时运行多个线程完成不同的工作,称为多线程。

二、ANR 的基础知识及产生

应用程序无响应ANR(Application Not Responding)

1、原因:

  • 系统繁忙
  • app没有优化好

2、三种情况:

  1. 主要类型案件或触摸事件在特定时间(5秒)内无响应。
  2. BroadcastReceiver在特定时间(10秒)内无法处理完成。
  3. 小概率类型Service在特定的时间内无法完成处理。

三、线程

线程状态:创建、就绪、运行、阻塞、消亡

线程中常用的方法:

  • start方法:启动线程。
  • run方法:不需要调用,继承Thread类必须重写
  • sleep方法:让当前线程睡眠,交出CPU,让CPU去执行其他的任务
  • yield方法:让当前线程交出CPU权限,让CPU去执行其他线程。但是yield不能控制具体交出CPU的时间,另外、yield方法只能让拥有相同优先级的线程有获取CPU执行时间的机会。调用yield方法并不会让线程进入阻塞状态,而是让线程重回就绪状态,它只需要等待重新获取CPU执行时间,这一点是和sleep方法不一样的。
  • join方法:让调用join方法的线程占用CPU指定的时间或直到线程执行完毕。
  • interrupt方法:中断,可以使处于阻塞状态的线程抛出一个异常,也就是说,它可以用来中断一个处于阻塞状态的线程。
  • getName方法:获取线程名称。
  • currentThread方法:静态方法,获取当前线程。

提示:多线程会增加一定的系统开销,如,新建线程分配资源、线程切换的状态保存等,所以编程时应确定是否真的需要使用多线程。

四、实现的两种方式:

  • 扩展java.lang.Thread类:创建类继承Thread或者new Thread。
  • 实现Runnable接口:创建类实现Runnable接口,new Thread(runnable).start();

五、线程间通信

Handler、Looper、MessageQueue、Thread之间的关系

  • 一个线程对应一个Looper。
  • 一个Looper对应一个MessageQueue。
  • 一个Looper可以对应多个Handler。
  • 主线程默认开启Looper。
  • 子线程Looper需要手动启动:Looper.prepare();Looper.loop();

备注:Looper.getMainLooper();获取主线程的Looper。

 

第三节:Socket&Https通信

一、什么是Socket

网络上的两个程序通过一个双向的通信连接实现数据的交换,这个连接的一端称为一个socket(套接字)。

  • IP用来定位主机,Socket用来定位应用。
  • Socket有两种通信模型UDP和TCP,都是传输层协议。

Http与socket的区别。在日常开发中客户端与服务端数据交互(xml或json格式)一般常用http协议,为什么还需要socket呢?二者的区别主要在以下几个方面:

  • http是应用层协议,socket是传输层协议。
  • http是无状态的协议,无法实现推送功能。
  • http协议传输过程复杂,不适合传输少量的数据;socket的灵活性更高。

InetAddress类:

静态方法:

常用方法:

UDP:

(User Datagram Protocol 用户数据报协议)使用UDP协议进行信息的传输之前不需要进行连接。换句话说就是客户端向服务器发送信息,客户端只需要给出服务器的ip地址和端口号,然后将信息封装到一个待发送的报文中并且发送出去。至于服务器端是否存在,或者能否收到该报文,客户端根本不用管。

应用:视频、语音通讯等。特点是速度快,但是不可靠,容易丢包。

DatagramSocket:

表示数据报包,数据报包用来实现无连接包投递服务。每条报文仅根据该包中包含的信息从一台机器路由到另一台机器。从一台机器发送到另一台机器的多个包可能选择不同的路由,也可能按不同的顺序到达。

构造:

常用方法:

DatagramPacket:

常用构造:

常用方法:

TCP:

(Transmission Control Protocol 传输控制协议)应用: 浏览器、邮件、文件传输等。特点速度慢,可靠,占用系统资源高。

ServerSocket

构造方法:

  • ServerSocket()
  • ServerSocket​(int port)
  • ServerSocket​(int port, int backlog)
  • ServerSocket​(int port, int backlog, InetAddress bindAddr) port服务端要监听的端口,设置0,自动分配;backlog客户端连接请求的队列长度;bindAddr服务端绑定IP,多个网卡时使用。

常用方法:

accept() 等待客户端接入,返回客户端的Socket,阻塞状态。

getInetAddress() 返回IP地址,InetAddress类型。

getLocalPort() 返回端口,int类型。

Socket

构造方法:

  • Socket()
  • Socket​(String host, int port)
  • Socket​(String host, int port, InetAddress localAddr, int localPort)
  • Socket​(InetAddress address, int port)
  • Socket​(InetAddress address, int port, InetAddress localAddr, int localPort) 参数分别为目标IP、目标端口、绑定本地IP、绑定本地端口。除不带参数的构造外,其它构造函数会尝试建立与服务器的连接。如果成功,则返回Socket对象。

常用方法:

 

Http、Socket区别:

  • Http 应用层协议
  • Socket传输层协议,灵活高效,服务端推送能力

网络七层协议(OSI:Open System Interconnection开放系统互联):

  • 分别是物理层、数据链路层、网络层、传输层、会话层、表示层、应用层。

Https :验证证书、校验域名。

二、UDP实例:服务端、客户端通信

public class UdpClient {
    private String mServerIp="172.20.10.4";
    private InetAddress mServerAddress;
    private int mServerPort=7777;
    private DatagramSocket mSocket;
    private Scanner mScanner;

    public UdpClient() {
        try {
            mServerAddress=InetAddress.getByName(mServerIp);
            mSocket=new DatagramSocket();
            mScanner=new Scanner(System.in);
            mScanner.useDelimiter("\n");
        } catch (SocketException e) {
            e.printStackTrace();
        } catch (UnknownHostException e) {
            e.printStackTrace();
        }
    }

    public void start(){
        while(true){
            try {
                String clientMsg=mScanner.next();
                byte[] clientMsgBytes=clientMsg.getBytes();
                DatagramPacket clientPacket=new DatagramPacket(clientMsgBytes,clientMsgBytes.length,mServerAddress,mServerPort);
                mSocket.send(clientPacket);

                byte[] buf=new byte[1024];
                DatagramPacket serverMsgPacket=new DatagramPacket(buf,buf.length);
                mSocket.receive(serverMsgPacket);

                String serverMsg=new String(serverMsgPacket.getData(),0,serverMsgPacket.getLength());
                System.out.println("msg="+serverMsg);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    public static void main(String[] args){
        new UdpClient().start();
    }
}
public class UdpServer {
    private InetAddress mInetAddress;
    private  int mPort = 7777;
    private DatagramSocket mSocket;
    private Scanner mScanner;

    public UdpServer() {
        try {
            mInetAddress=InetAddress.getLocalHost();
            mSocket=new DatagramSocket(mPort,mInetAddress);

            mScanner=new Scanner(System.in);
            mScanner.useDelimiter("\n");
        } catch (UnknownHostException e) {
            e.printStackTrace();
        } catch (SocketException e) {
            e.printStackTrace();
        }
    }

    public void start(){
        while(true){
            try {
                //接收
                byte[] buf=new byte[1024];
                DatagramPacket receivedPacket=new DatagramPacket(buf,buf.length);
                mSocket.receive(receivedPacket);//阻塞

                //显示
                InetAddress address = receivedPacket.getAddress();
                int port = receivedPacket.getPort();
                byte[] data = receivedPacket.getData();
                String clientMsg=new String(data,0,receivedPacket.getLength());
                System.out.println("address="+address+",port="+port+",msg="+clientMsg);

                //发送
                String returnedMsg = mScanner.next();
                DatagramPacket sendPacket=new DatagramPacket(
                        returnedMsg.getBytes(),
                        returnedMsg.getBytes().length,
                        receivedPacket.getSocketAddress());
                mSocket.send(sendPacket);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    public static void main(String[] args){
        new UdpServer().start();
    }
}

三、TCP实例:多人聊天室

服务端

public class TcpServer {
    private ServerSocket mServerSocket;

    public void start(){
        try {
            //监听9090端口
            mServerSocket = new ServerSocket(9090);

            //启动消息池
            MsgPool.getInstance().start();
            while(true) {

                    //等待客户端接入
                    Socket socket = mServerSocket.accept();//等待客户端,阻塞状态
                    System.out.println("IP="+socket.getInetAddress().getHostAddress()+
                    " Port="+socket.getPort()+" is online...");

                    //两个流都是阻塞状态,直接读取会导致其他客户端的接入进入等待状态。
                    //socket.getInputStream();//获取客户端输入流
                    //socket.getOutputStream();//获取客户端输出流

                    //为每个接入的客户端单独启动一个线程,进行读写操作
                    ClientTask clientTask=new ClientTask(socket);
                    //监听消息池
                    MsgPool.getInstance().addListener(clientTask);

                    clientTask.start();

            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args){
        new TcpServer().start();
    }
}

服务端子线程:接收客户端发送的信息,并向所有客户端转发

public class ClientTask extends Thread implements MsgPool.MsgComingListener {
    private Socket mSocket;
    private InputStream mInputStream;
    private OutputStream mOutputStream;

    public ClientTask(Socket socket) {
        try {
            mSocket = socket;
            mInputStream = socket.getInputStream();
            mOutputStream = socket.getOutputStream();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void run() {

        BufferedReader reader = new BufferedReader(new InputStreamReader(mInputStream));
        try {
            String line = null;
            while ((line = reader.readLine()) != null) {
                String msg=mSocket.getPort()+":"+line;
                //显示客户端发来的消息
                System.out.println(msg);
                //将消息发送到消息池队列
                MsgPool.getInstance().sendMsg(msg);
            }
        } catch (IOException e) {
            System.out.println("异常:"+e.getMessage());
        } finally {
            System.out.println("ip=" + mSocket.getInetAddress().toString() + " port=" +
                    mSocket.getPort() + " is offline...");
        }

    }

    //监听消息池发送出来的消息,发送给客户端
    @Override
    public void onMsgComing(String msg) {
        try {
            mOutputStream.write(msg.getBytes());
            mOutputStream.write("\n".getBytes());
            mOutputStream.flush();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

利用消息池,解决服务端向所有客户端转发数据可能出现的并发问题

//创建阻塞队列的消息池,实现单例模式
public class MsgPool {
    private static MsgPool sInstance=new MsgPool();
    private LinkedBlockingQueue<String> mQueue=new LinkedBlockingQueue<>();

    //创建接口用来向订阅者发送消息
    public interface MsgComingListener{
        public void onMsgComing(String msg);
    }
    private List<MsgComingListener> mListeners=new ArrayList<>();

    public void addListener(MsgComingListener listener){
        mListeners.add(listener);
    }

    private MsgPool(){}

    public static MsgPool getInstance(){
        return sInstance;
    }

    //向消息队列添加消息
    public void sendMsg(String msg){
        try {
            mQueue.put(msg);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    //启动消息池,只要消息队列中有信息就会自动发送给所有订阅者
    public void start(){
        new Thread(){
            @Override
            public void run() {
                while(true){
                    try {
                        String msg = mQueue.take();
                        notifyMsgComing(msg);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }.start();
    }

    public void notifyMsgComing(String msg){
        for(MsgComingListener listener:mListeners){
            listener.onMsgComing(msg);
        }
    }
}

客户端

public class TcpClient {
    private Socket mSocket;
    private InputStream mInputStream;
    private OutputStream mOutputStream;
    private Scanner mScanner;

    public TcpClient() {
        mScanner=new Scanner(System.in);
        mScanner.useDelimiter("\n");
    }

    public void start(){
        try {
            mSocket=new Socket("172.20.10.4",9090);
            mInputStream=mSocket.getInputStream();
            mOutputStream=mSocket.getOutputStream();

            final BufferedReader reader=new BufferedReader(new InputStreamReader(mInputStream));
            BufferedWriter writer=new BufferedWriter(new OutputStreamWriter(mOutputStream));

            //创建独立线程接收消息
            new Thread(){
                @Override
                public void run() {
                    String line=null;
                    try {
                        while((line=reader.readLine())!=null) {
                            System.out.println(line);
                        }
                    } catch (IOException e) {
                        System.out.println("异常:"+e.getMessage());
                    } finally {
                        System.out.println("服务器连接已断开");
                    }
                }
            }.start();

            //发送消息
            while(true){
                String msg = mScanner.next();
                writer.write(msg);
                writer.newLine();
                writer.flush();
            }

        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args){
        new TcpClient().start();
    }
}

移动客户端业务类

public class TcpClientBiz {
    private Socket mSocket;
    private InputStream mInputStream;
    private OutputStream mOutputStream;
    private Handler mUiHandler=new Handler(Looper.getMainLooper());


    //通过创建监听实现业务类和UI解耦
    public interface MsgComingListener{
        public void onMsgComing(String msg);
        public void onError(Exception ex);
    }
    private MsgComingListener mListener;

    public void setListener(MsgComingListener listener) {
        mListener = listener;
    }


    //启动业务类后自动连接服务器,接收消息并通知UI更新数据
    public TcpClientBiz() {
        //网络操作需要启动子线程
        new Thread(){
            @Override
            public void run() {
                try {
                    mSocket=new Socket("172.20.10.4",9090);
                    mInputStream = mSocket.getInputStream();
                    mOutputStream = mSocket.getOutputStream();

                    final BufferedReader reader=new BufferedReader(new InputStreamReader(mInputStream));
                    String line=null;
                    while((line=reader.readLine())!=null){
                        //子线程更新UI需要使用handler
                        Log.d("linshi", "run: "+line);
                        final String finalLine = line;
                        mUiHandler.post(new Runnable() {
                            @Override
                            public void run() {
                                if(mListener!=null){
                                    mListener.onMsgComing(finalLine);
                                }
                            }
                        });
                    }
                } catch (IOException e) {
                    if(mListener!=null){
                        mListener.onError(e);
                    }
                }
            }
        }.start();
    }


    //向服务器发送消息
    public void sendMsg(final String msg){
        //网络操作,启动子线程
        new Thread(){
            @Override
            public void run() {
                try {
                    mOutputStream.write(msg.getBytes());
                    mOutputStream.write("\n".getBytes());
                    mOutputStream.flush();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }.start();
    }

    public void onDestroy(){
        //尽量使用独立的try-catch
        try {
            if (mInputStream != null) {
                mInputStream.close();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }

        try {
            if (mOutputStream != null) {
                mOutputStream.close();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }

        try {
            if (mSocket != null) {
                mSocket.close();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }

    }
}

移动客户端UI

public class MainActivity extends AppCompatActivity {

    private Button mBtnSend;
    private EditText mEdtInput;
    private TextView mTvContent;
    private TcpClientBiz mTcpClientBiz=new TcpClientBiz();

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

        //初始化控件
        initViews();

        //初始化监听器
        initEvents();
    }

    private void initEvents() {
        //创建匿名类订阅业务类的消息,更新UI
        mTcpClientBiz.setListener(new TcpClientBiz.MsgComingListener() {
            @Override
            public void onMsgComing(String msg) {
                Log.d("linshi", "onMsgComing: "+msg);
                mTvContent.append(msg+"\n");
            }

            @Override
            public void onError(Exception ex) {
                ex.printStackTrace();
            }
        });

        //向服务器发送消息
        mBtnSend.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                String msg=mEdtInput.getText().toString();
                mEdtInput.setText("");

                mTcpClientBiz.sendMsg(msg);
            }
        });
    }

    private void initViews() {
        mBtnSend = findViewById(R.id.btn_send);
        mEdtInput = findViewById(R.id.edt_input);
        mTvContent = findViewById(R.id.tv_content);
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        //关闭连接
        mTcpClientBiz.onDestroy();
    }
}

源码

四、Https通信

 

第四节:经典蓝牙通信

一、蓝牙权限:

执行蓝牙通信需要权限BLUETOOTH,例如:请求链接、接受链接、传输数据等;如果需要启动设备发现或操作蓝牙设置,则需要声明BLUETOOTH_ADMIN权限。

    <uses-permission android:name="android.permission.BLUETOOTH"/>
    <uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>

二、设置蓝牙:

  • 获取蓝牙适配器:BluetoothAdapter.getDefaultAdapter()
  • 设备是否支持蓝牙:bluetoothAdapter对象为null,则不支持蓝牙。
  • 设备是否开启蓝牙:bluetoothAdapter.isEnabled()
  • 开启蓝牙:startActivity(new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE));
  • 查找已配对设备:bluetoothAdapter.getBondedDevices()
  • 发现新设备:bluetoothAdapter.startDiscovery()

开启蓝牙代码:

    public static final int REQUEST_ENABLE_BT = 10001;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        
        BluetoothAdapter bluetoothAdapter=BluetoothAdapter.getDefaultAdapter();
        if(bluetoothAdapter!=null){
            Toast.makeText(this, "支持蓝牙", Toast.LENGTH_SHORT).show();
            if(bluetoothAdapter.isEnabled()){
                Toast.makeText(this, "蓝牙已开启", Toast.LENGTH_SHORT).show();
            }else{
                Intent intent=new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
                startActivityForResult(intent, REQUEST_ENABLE_BT);
            }
        }else{
            Toast.makeText(this, "不支持蓝牙", Toast.LENGTH_SHORT).show();
        }
    }
    @Override
    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if(requestCode==REQUEST_ENABLE_BT){
            Toast.makeText(this, "蓝牙已开启", Toast.LENGTH_SHORT).show();
        }
    }

查找设备代码:

                Set<BluetoothDevice> bluetoothDevices=bluetoothAdapter.getBondedDevices();
                if(bluetoothDevices.size()>0){
                    for(BluetoothDevice device:bluetoothDevices){
                        Log.d(TAG, "Device Name: "+device.getName());
                        Log.d(TAG, "Device Addr: "+device.getAddress());
                    }
                }

搜索新的设备代码:

                //如果正在搜索,则取消
                if(bluetoothAdapter.isDiscovering()){
                    bluetoothAdapter.cancelDiscovery();
                }
                bluetoothAdapter.startDiscovery();//立刻返回是否成功启动发现操作

 

    private BroadcastReceiver mBluetoothReceiver=new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            String action=intent.getAction();
            if(action.equals(BluetoothDevice.ACTION_FOUND)){
                BluetoothDevice device=intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
                Log.d(TAG, "New device name: "+device.getName());
                Log.d(TAG, "New device addr: "+device.getAddress());
            }else if(action.equals(BluetoothAdapter.ACTION_DISCOVERY_FINISHED)){
                Log.d(TAG, "Discovery done!");
            }
        }
    };
        IntentFilter filter=new IntentFilter();
        filter.addAction(BluetoothDevice.ACTION_FOUND);
        filter.addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
        registerReceiver(mBluetoothReceiver,filter);
    @Override
    protected void onDestroy() {
        super.onDestroy();
        unregisterReceiver(mBluetoothReceiver);
    }

连接为服务器

设置服务器套接字并接受连接的基本过程:
-1.通过调用 listenUsingRfcommWithServiceRecord(String, UUID)获取 BluetoothServerSocket
-2.通过调用 accept() 开始侦听连接请求
-3.除非要接受更多连接,否则调用 close()

设置客户端
- 发起与远程设备(保持开放的服务器套接字的设备)的连接
a. 首先要获取表示该远程设备的 BluetoothDevice 对象
b. 然后使用 BluetoothDevice 来获取 BluetoothSocket 并发起连接
1. 使用 BluetoothDevice,通过调用 createRfcommSocketToServiceRecord(UUID) 获取BluetoothSocket
2. 通过调用 connect() 发起连接

 

第五节:低功耗蓝牙应用

蓝牙4.0 :BLE

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值