又到了Android小白的开发之路上写笔记的时间了~~
开篇都不知道说什么好... ...前两个月写了WIFI,后来也想写一下蓝牙的,可惜公司产品不给力,出现了很多BUG,一直在修啊修,最近终于有点空闲时间了。那就来简单的尝试一下
关于蓝牙开发,优秀博客一大片,你能来看我这篇辣鸡文章真是不胜感激。基础知识/理论什么的我就不说了,我也是一边看着官方文档来的,想深入了解去看看官方文档也是极好的。
我们知道Andorid的蓝牙分为两种,一种是传统的一种是低功耗蓝牙(BLE),一步一步来,这里先写一下传统蓝牙~
功能实现
主要是实现两台手机能通过蓝牙相互发送消息。两手机可以任意一台充当服务端,一台充当客户端。过程尽量越简单,让大家看的更清楚!
代码-准备工作
1.首先我们需要一个蓝牙适配器,用于搜索设备/连接设备;一个UUID,用于创建服务端;一个广播接收器,用于监听搜索结果。
public static final String BT_UUID = "00001101-0000-1000-8000-00805F9B34FB";//uuid
private BluetoothAdapter mBluetoothAdapter;//蓝牙适配器
private BlueToothStateReceiver mReceiver;//广播接收器
private ConnectThread mConnectThread; //客户端线程
private AcceptThread mAcceptThread; //服务端线程
2.然后先打开蓝牙
private void openBT() {
if (mBluetoothAdapter == null) {
mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
}
//1.设备不支持蓝牙,结束应用
if (mBluetoothAdapter == null) {
finish();
return;
}
//2.判断蓝牙是否打开
if (!mBluetoothAdapter.enable()) {
//没打开请求打开
Intent btEnable = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(btEnable, REQUEST_BT_ENABLE_CODE);
}
}
private void registerRec() {
//3.注册蓝牙广播
mReceiver = new BlueToothStateReceiver();
IntentFilter filter = new IntentFilter();
filter.addAction(BluetoothDevice.ACTION_FOUND);//搜多到蓝牙
filter.addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);//搜索结束
registerReceiver(mReceiver, filter);
}
if (mBluetoothAdapter != null) {
mBluetoothAdapter.startDiscovery();
}
class BlueToothStateReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(MainActivity.this, "触发广播", Toast.LENGTH_SHORT).show();
String action = intent.getAction();
switch (action) {
case BluetoothDevice.ACTION_FOUND:
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
Toast.makeText(MainActivity.this, "找到设备" + device.getName(), Toast.LENGTH_SHORT).show();
if (mRvAdapter != null) {
mRvAdapter.addDevice(device);
}
break;
case BluetoothAdapter.ACTION_DISCOVERY_FINISHED:
mMessageAdapter.addMessage("搜索结束");
break;
}
}
}
额~~还忘了一步,搜索完到指定设备后要记得关闭搜索
if (mBluetoothAdapter != null && mBluetoothAdapter.isDiscovering()) {
mBluetoothAdapter.cancelDiscovery();
}
----------------------------然后基础的就到这里了----------------------------------
接下来,是点击列表,然后连接对应的蓝牙。
开头说了,要实现两台手机任意充当客户端或者服务端,所以在程序中应该包含有服务端也要有客户端,因此我们需要两个线程,分别处理这两种情况。
6.首先服务端线程代码--里面有些没用到或者注释的代码还有一些通知UI更新的代码,大家可以忽略
class AcceptThread extends Thread {
private BluetoothServerSocket mServerSocket;
private BluetoothSocket mSocket;
private InputStream btIs;
private OutputStream btOs;
private PrintWriter writer;
private boolean canAccept;
private boolean canRecv;
public AcceptThread() {
canAccept = true;
canRecv = true;
}
@Override
public void run() {
try {
//获取套接字
BluetoothServerSocket temp = mBluetoothAdapter.listenUsingInsecureRfcommWithServiceRecord("TEST", UUID.fromString(BT_UUID));
mServerSocket = temp;
//监听连接请求 -- 作为测试,只允许连接一个设备
if (mServerSocket != null) {
// while (canAccept) {
mSocket = mServerSocket.accept();//阻塞等待客户端连接
sendHandlerMsg("有客户端连接");
// }
}
//获取输入输出流
btIs = mSocket.getInputStream();
btOs = mSocket.getOutputStream();
//通讯-接收消息
BufferedReader reader = new BufferedReader(new InputStreamReader(btIs, "UTF-8"));
String content = null;
while (canRecv) {
content = reader.readLine();
sendHandlerMsg("收到消息:" + content);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (mSocket != null) {
mSocket.close();
}
// btIs.close();//两个输出流都依赖socket,关闭socket即可
// btOs.close();
} catch (IOException e) {
e.printStackTrace();
sendHandlerMsg("错误:" + e.getMessage());
}
}
}
private void sendHandlerMsg(String content) {
Message msg = mHandler.obtainMessage();
msg.what = 1001;
msg.obj = content;
mHandler.sendMessage(msg);
}
public void write(String msg) {
if (btOs != null) {
try {
if (writer == null) {
writer = new PrintWriter(new OutputStreamWriter(btOs, "UTF-8"), true);
}
writer.println(msg);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
writer.close();
sendHandlerMsg("错误:" + e.getMessage());
}
}
}
}
class ConnectThread extends Thread {
private BluetoothDevice mDevice;
private BluetoothSocket mSocket;
private InputStream btIs;
private OutputStream btOs;
private boolean canRecv;
private PrintWriter writer;
public ConnectThread(BluetoothDevice device) {
mDevice = device;//被点击设备
canRecv = true;
}
@Override
public void run() {
if (mDevice != null) {
try {
//获取套接字
BluetoothSocket temp = mDevice.createInsecureRfcommSocketToServiceRecord(UUID.fromString(BT_UUID));
//mDevice.createRfcommSocketToServiceRecord(UUID.fromString(BT_UUID));//sdk 2.3以下使用
mSocket = temp;
//发起连接请求
if (mSocket != null) {
mSocket.connect();
}
sendHandlerMsg("连接 " + mDevice.getName() + "成功!");
//获取输入输出流
btIs = mSocket.getInputStream();
btOs = mSocket.getOutputStream();
//通讯-接收消息
BufferedReader reader = new BufferedReader(new InputStreamReader(btIs, "UTF-8"));
String content = null;
while (canRecv) {
content = reader.readLine();
sendHandlerMsg("收到消息:" + content);
}
} catch (IOException e) {
e.printStackTrace();
sendHandlerMsg("错误:" + e.getMessage());
} finally {
try {
if (mSocket != null) {
mSocket.close();
}
//btIs.close();//两个输出流都依赖socket,关闭socket即可
//btOs.close();
} catch (IOException e) {
e.printStackTrace();
sendHandlerMsg("错误:" + e.getMessage());
}
}
}
}
private void sendHandlerMsg(String content) {
Message msg = mHandler.obtainMessage();
msg.what = 1001;
msg.obj = content;
mHandler.sendMessage(msg);
}
public void write(String msg) {
if (btOs != null) {
try {
if (writer == null) {
writer = new PrintWriter(new OutputStreamWriter(btOs, "UTF-8"), true);
}
writer.println(msg);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
writer.close();
sendHandlerMsg("错误:" + e.getMessage());
}
}
}
}
8.然后这个两个线程的开启时机我是这么来设置的:服务端是开启蓝牙后立马启动,连接线程是点击了某个设备发起连接请求时启动。
openBT();
mMessageAdapter.addMessage("打开蓝牙");
if (mAcceptThread == null && mBluetoothAdapter != null) {
mAcceptThread = new AcceptThread();
mAcceptThread.start();
mMessageAdapter.addMessage("启动服务线程");
}
mRvAdapter.setOnItemClickListener(new RvAdapter.OnItemClickListener() {
@Override
public void onClick(BluetoothDevice device) {
mConnectThread = new ConnectThread(device);
mConnectThread.start();
}
});
看全部代码前给大家先看运行效果图,我怕大家没耐心看到后面。操作:两个设备都点击打开蓝牙,然后搜索,找出设备点击停止。最后设备1点击结果中的设备2,互发消息。 ps:设备1 Android 4.0 设备2(OnePlus3T) Android 7.1
设备1截图:
设备2截图:
-放全部代码:
首先是我的布局:消息列表显示的是各种消息,什么有客户端连接,收到什么消息,发送什么消息等。截图如下:
package cn.small_qi.bluetoothtest;
import android.Manifest;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothServerSocket;
import android.bluetooth.BluetoothSocket;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Build;
import android.os.Handler;
import android.os.Message;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.text.TextUtils;
import android.view.View;
import android.widget.EditText;
import android.widget.Toast;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.util.UUID;
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
public static final int REQUEST_BT_ENABLE_CODE = 200;
public static final String BT_UUID = "00001101-0000-1000-8000-00805F9B34FB";//uuid
private BluetoothAdapter mBluetoothAdapter;//蓝牙适配器
private BlueToothStateReceiver mReceiver;//广播接收器
private ConnectThread mConnectThread; //客户端线程
private AcceptThread mAcceptThread; //服务端线程
private RecyclerView mRecyclerView;
private RvAdapter mRvAdapter;
private RecyclerView mMessageView;
private static MsgAdapter mMessageAdapter;
private EditText inputEt;
private static Handler mHandler = new Handler() {
@Override
public void dispatchMessage(Message msg) {
mMessageAdapter.addMessage((String) msg.obj);
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//这是我是为了6.0以上的设备能搜索到结果,动态申请了位置权限。但是没有处理结果,因为我测试肯定点同意~- -
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
requestPermissions(new String[]{Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION}, 1001);
}
initUI();
registerRec();
}
private void initUI() {
findViewById(R.id.open).setOnClickListener(this);
findViewById(R.id.close).setOnClickListener(this);
findViewById(R.id.start).setOnClickListener(this);
findViewById(R.id.stop).setOnClickListener(this);
findViewById(R.id.send).setOnClickListener(this);
inputEt = (EditText) findViewById(R.id.input);
mRecyclerView = (RecyclerView) findViewById(R.id.devices);
mRecyclerView.setLayoutManager(new LinearLayoutManager(this));
mRvAdapter = new RvAdapter(this);
mRecyclerView.setAdapter(mRvAdapter);
mRvAdapter.setOnItemClickListener(new RvAdapter.OnItemClickListener() {
@Override
public void onClick(BluetoothDevice device) {
mConnectThread = new ConnectThread(device);
mConnectThread.start();
}
});
mMessageView = (RecyclerView) findViewById(R.id.msglist);
mMessageView.setLayoutManager(new LinearLayoutManager(this));
mMessageAdapter = new MsgAdapter(this);
mMessageView.setAdapter(mMessageAdapter);
}
private void openBT() {
if (mBluetoothAdapter == null) {
mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
}
//1.设备不支持蓝牙,结束应用
if (mBluetoothAdapter == null) {
finish();
return;
}
//2.判断蓝牙是否打开
if (!mBluetoothAdapter.enable()) {
//没打开请求打开
Intent btEnable = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(btEnable, REQUEST_BT_ENABLE_CODE);
}
}
private void registerRec() {
//3.注册蓝牙广播
mReceiver = new BlueToothStateReceiver();
IntentFilter filter = new IntentFilter();
filter.addAction(BluetoothDevice.ACTION_FOUND);//搜多到蓝牙
filter.addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);//搜索结束
registerReceiver(mReceiver, filter);
}
@Override
protected void onDestroy() {
if (mReceiver != null) {
unregisterReceiver(mReceiver);
}
super.onDestroy();
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == REQUEST_BT_ENABLE_CODE) {
if (resultCode == RESULT_OK) {
//用户允许打开蓝牙
mMessageAdapter.addMessage("用户同意打开蓝牙");
} else if (resultCode == RESULT_CANCELED) {
//用户取消打开蓝牙
mMessageAdapter.addMessage("用户拒绝打开蓝牙");
}
}
super.onActivityResult(requestCode, resultCode, data);
}
@Override
public void onClick(View view) {
switch (view.getId()) {
case R.id.open:
openBT();
mMessageAdapter.addMessage("打开蓝牙");
if (mAcceptThread == null && mBluetoothAdapter != null) {
mAcceptThread = new AcceptThread();
mAcceptThread.start();
mMessageAdapter.addMessage("启动服务线程");
}
break;
case R.id.close:
mBluetoothAdapter.disable();
break;
case R.id.start:
if (mBluetoothAdapter != null) {
mRvAdapter.clearDevices();//开始搜索前清空上一次的列表
mBluetoothAdapter.startDiscovery();
mMessageAdapter.addMessage("开始搜索蓝牙");
} else {
openBT();
if (mBluetoothAdapter != null) {
mRvAdapter.clearDevices();//开始搜索前清空上一次的列表
mBluetoothAdapter.startDiscovery();
mMessageAdapter.addMessage("开始搜索蓝牙");
}
}
break;
case R.id.stop:
if (mBluetoothAdapter != null && mBluetoothAdapter.isDiscovering()) {
mBluetoothAdapter.cancelDiscovery();
}
break;
case R.id.send:
/**
* 如何区分我是使用服务端的socket还是使用客户端的socket发送消息
* 1. 在单一环境下,手机一般作为客户端,外围设备是服务器。所以手机完全可以不用创建服务器,不存在这个问题。
* 2. 假如是两台手机用来聊天,可分别充当服务器和客户端,那就是发起连接方(即点击设备列表连接)作为客户端。
* 3. 假如我链接了别人,另一个人又连接了我,那我怎么区分?那你写两个界面啊~你要回复其他客户端发来的消息就用服务器的socket
* 否则就用客户端的。我这里偷懒了,一但我主动连接别人,相当于我就关闭服务端了,不给别人连我了。
* 4. 那那些蓝牙对战游戏都怎么区分的?你发现蓝牙对战需要一个人先创建房间没?那个人就是服务端,其他都是客户端,没这个问题。
*/
String msg = inputEt.getText().toString();
if (TextUtils.isEmpty(msg)) {
Toast.makeText(this, "消息为空", Toast.LENGTH_SHORT).show();
return;
}
if (mConnectThread != null) {//证明我主动去链接别人了
mConnectThread.write(msg);
} else if (mAcceptThread != null) {
mAcceptThread.write(msg);
}
mMessageAdapter.addMessage("发送消息:" + msg);
break;
}
}
class BlueToothStateReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(MainActivity.this, "触发广播", Toast.LENGTH_SHORT).show();
String action = intent.getAction();
switch (action) {
case BluetoothDevice.ACTION_FOUND:
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
Toast.makeText(MainActivity.this, "找到设备" + device.getName(), Toast.LENGTH_SHORT).show();
if (mRvAdapter != null) {
mRvAdapter.addDevice(device);
}
break;
case BluetoothAdapter.ACTION_DISCOVERY_FINISHED:
mMessageAdapter.addMessage("搜索结束");
break;
}
}
}
class ConnectThread extends Thread {
private BluetoothDevice mDevice;
private BluetoothSocket mSocket;
private InputStream btIs;
private OutputStream btOs;
private boolean canRecv;
private PrintWriter writer;
public ConnectThread(BluetoothDevice device) {
mDevice = device;
canRecv = true;
}
@Override
public void run() {
if (mDevice != null) {
try {
//获取套接字
BluetoothSocket temp = mDevice.createInsecureRfcommSocketToServiceRecord(UUID.fromString(BT_UUID));
//mDevice.createRfcommSocketToServiceRecord(UUID.fromString(BT_UUID));//sdk 2.3以下使用
mSocket = temp;
//发起连接请求
if (mSocket != null) {
mSocket.connect();
}
sendHandlerMsg("连接 " + mDevice.getName() + "成功!");
//获取输入输出流
btIs = mSocket.getInputStream();
btOs = mSocket.getOutputStream();
//通讯-接收消息
BufferedReader reader = new BufferedReader(new InputStreamReader(btIs, "UTF-8"));
String content = null;
while (canRecv) {
content = reader.readLine();
sendHandlerMsg("收到消息:" + content);
}
} catch (IOException e) {
e.printStackTrace();
sendHandlerMsg("错误:" + e.getMessage());
} finally {
try {
if (mSocket != null) {
mSocket.close();
}
//btIs.close();//两个输出流都依赖socket,关闭socket即可
//btOs.close();
} catch (IOException e) {
e.printStackTrace();
sendHandlerMsg("错误:" + e.getMessage());
}
}
}
}
private void sendHandlerMsg(String content) {
Message msg = mHandler.obtainMessage();
msg.what = 1001;
msg.obj = content;
mHandler.sendMessage(msg);
}
public void write(String msg) {
if (btOs != null) {
try {
if (writer == null) {
writer = new PrintWriter(new OutputStreamWriter(btOs, "UTF-8"), true);
}
writer.println(msg);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
writer.close();
sendHandlerMsg("错误:" + e.getMessage());
}
}
}
}
class AcceptThread extends Thread {
private BluetoothServerSocket mServerSocket;
private BluetoothSocket mSocket;
private InputStream btIs;
private OutputStream btOs;
private PrintWriter writer;
private boolean canAccept;
private boolean canRecv;
public AcceptThread() {
canAccept = true;
canRecv = true;
}
@Override
public void run() {
try {
//获取套接字
BluetoothServerSocket temp = mBluetoothAdapter.listenUsingInsecureRfcommWithServiceRecord("TEST", UUID.fromString(BT_UUID));
mServerSocket = temp;
//监听连接请求 -- 作为测试,只允许连接一个设备
if (mServerSocket != null) {
// while (canAccept) {
mSocket = mServerSocket.accept();
sendHandlerMsg("有客户端连接");
// }
}
//获取输入输出流
btIs = mSocket.getInputStream();
btOs = mSocket.getOutputStream();
//通讯-接收消息
BufferedReader reader = new BufferedReader(new InputStreamReader(btIs, "UTF-8"));
String content = null;
while (canRecv) {
content = reader.readLine();
sendHandlerMsg("收到消息:" + content);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (mSocket != null) {
mSocket.close();
}
// btIs.close();//两个输出流都依赖socket,关闭socket即可
// btOs.close();
} catch (IOException e) {
e.printStackTrace();
sendHandlerMsg("错误:" + e.getMessage());
}
}
}
private void sendHandlerMsg(String content) {
Message msg = mHandler.obtainMessage();
msg.what = 1001;
msg.obj = content;
mHandler.sendMessage(msg);
}
public void write(String msg) {
if (btOs != null) {
try {
if (writer == null) {
writer = new PrintWriter(new OutputStreamWriter(btOs, "UTF-8"), true);
}
writer.println(msg);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
writer.close();
sendHandlerMsg("错误:" + e.getMessage());
}
}
}
}
}
消息列表:
package cn.small_qi.bluetoothtest;
import android.bluetooth.BluetoothDevice;
import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import java.util.ArrayList;
import java.util.List;
/**
* Created by small_qi on 2017/9/13.
*/
public class MsgAdapter extends RecyclerView.Adapter{
private Context mContext;
private List msgList;
public MsgAdapter(Context mContext) {
this.mContext = mContext;
msgList = new ArrayList<>();
}
@Override
public MsgAdapter.MsgHolder onCreateViewHolder(ViewGroup parent, int viewType) {
return new MsgAdapter.MsgHolder(LayoutInflater.from(mContext).inflate(R.layout.item,parent,false));
}
@Override
public void onBindViewHolder(MsgAdapter.MsgHolder holder, final int position) {
holder.nameTv.setText(msgList.get(position));
}
@Override
public int getItemCount() {
return msgList.size();
}
public void addMessage(String msg) {
msgList.add(msg);
notifyItemInserted(msgList.size()-1);
}
public void clearMsgList(){
msgList.clear();
notifyDataSetChanged();
}
public interface OnItemClickListener{
void onClick(BluetoothDevice device);
}
class MsgHolder extends RecyclerView.ViewHolder{
private TextView nameTv;
public MsgHolder(View itemView) {
super(itemView);
nameTv = itemView.findViewById(R.id.name);
}
}
}
package cn.small_qi.bluetoothtest;
import android.bluetooth.BluetoothDevice;
import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.TextView;
import java.util.ArrayList;
import java.util.List;
/**
* Created by small_qi on 2017/9/13.
*/
public class RvAdapter extends RecyclerView.Adapter{
private Context mContext;
private List mDevices;
private OnItemClickListener onItemClickListener;
public void setOnItemClickListener(OnItemClickListener onItemClickListener) {
this.onItemClickListener = onItemClickListener;
}
public RvAdapter(Context mContext) {
this.mContext = mContext;
mDevices = new ArrayList<>();
}
@Override
public RvHolder onCreateViewHolder(ViewGroup parent, int viewType) {
return new RvHolder(LayoutInflater.from(mContext).inflate(R.layout.item,parent,false));
}
@Override
public void onBindViewHolder(RvHolder holder, final int position) {
holder.nameTv.setText(mDevices.get(position).getName()+":"+mDevices.get(position).getAddress());
//点击事件 点击配对
if (onItemClickListener!=null) {
holder.itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
onItemClickListener.onClick(mDevices.get(position));
}
});
}
}
@Override
public int getItemCount() {
return mDevices.size();
}
public void addDevice(BluetoothDevice device) {
mDevices.add(device);
notifyItemInserted(mDevices.size()-1);
}
public void clearDevices(){
mDevices.clear();
notifyDataSetChanged();
}
public interface OnItemClickListener{
void onClick(BluetoothDevice device);
}
class RvHolder extends RecyclerView.ViewHolder{
private TextView nameTv;
public RvHolder(View itemView) {
super(itemView);
nameTv = itemView.findViewById(R.id.name);
}
}
}
非常感谢您能看到最后~这Demo实现了,两个设备相互聊天。其实获取到socekt后,就不关蓝牙什么事了,主要是考察对socket通讯的使用了。例子中只实现了1V1聊天,至于一对多还有文件传输,可以看看我之前的Socket通讯的博客哦~博客中的WIFI通讯相关中也有类似的功能,大家有兴趣可以看看,虽然不是什么深度优秀文章。
demo就是demo各种处理都不完善,而且我只是个小白白,有问题在所难免,大家见谅。有问题评论中指出~谢谢 have a nice day