今儿给大伙讲个笑话
有一天,我写了一个项目(依托四方大佬救济的那种写)
整完了之后跑起来是这样
经过各种调试之后,运行了之后是这样
我就纳闷,难道是哪里出错了?
没道理啊?
后来找到了大佬,大佬跑了一遍,没问题,,,
后来大佬一机灵,在真机上面跑了一遍
成了。。。
所以这个模块是没办法在虚拟机上面跑了,大伙有兴趣的可以下载之后在手机上面跑一跑(对,我真的没手机。。。家里穷。。。用的用的都是iPhone7及以下版本 别喷我不爱国 真和爱国没什么关系)
好了 废话到这里就结束了
下面说说项目吧
首先是必不可少是权限申请
这里百度了不少,肯定不是最精炼的,但差不多是最全的了,能用的不能用的全部放上去了
src/main/AndroIDManifest.xml 中插入mainfest标签下
<uses-permission androID:name="androID.permission.BLUetoOTH" /> <uses-permission androID:name="androID.permission.BLUetoOTH_admin" /> <uses-permission androID:name="androID.permission.BLUetoOTH_PRIVILEGED" /> <uses-permission androID:name="androID.permission.ACCESS_COARSE_LOCATION" /> <uses-permission androID:name="androID.permission.WRITE_EXTERNAL_STORAGE"/> <uses-permission androID:name="androID.permission.READ_EXTERNAL_STORAGE"/> <uses-permission androID:name="androID.permission.SYstem_ALERT_WINDOW"/>
然后就是src/main/java/cn/com/lenew/bluetooth/activity/MainActivity.java
没有别的,主要还是一个对各个类的调用,控制显示之类的
仅附上部分代码
public voID onClick(VIEw vIEw){ showToast("开始扫描"); List.clear(); List.addAll(BluetoothUtils.getInstance(mContext).getAvailableDevices()); adapter.notifyDataSetChanged(); BluetoothUtils.getInstance(this).scanDevices(); } private voID initReceiver() { IntentFilter filter = new IntentFilter(); filter.addAction(BluetoothDevice.ACTION_FOUND); filter.addAction(BluetoothAdapter.ACTION_disCOVERY_STARTED); filter.addAction(BluetoothAdapter.ACTION_disCOVERY_FINISHED); filter.addAction(BluetoothMessage.ACTION_INIT_COMPLETE); filter.addAction(BluetoothMessage.ACTION_CONNECTED_SERVER); filter.addAction(BluetoothMessage.ACTION_CONNECT_ERROR); registerReceiver(receiver, filter); } broadcastReceiver receiver = new broadcastReceiver() { @OverrIDe public voID onReceive(Context context, Intent intent) { switch (intent.getAction()){ case BluetoothDevice.ACTION_FOUND: BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); for(int i=0;i<List.size();i++){ if(device.getAddress()==null || device.getAddress().equals(List.get(i).getAddress())){ return; } } List.add(device); adapter.notifyDataSetChanged(); break; case BluetoothAdapter.ACTION_disCOVERY_STARTED:// showToast("开始扫描"); break; case BluetoothAdapter.ACTION_disCOVERY_FINISHED:// showToast("扫描完成"); break; case BluetoothMessage.ACTION_INIT_COMPLETE: ProgressUtils.dismissprogress(); break; case BluetoothMessage.ACTION_CONNECTED_SERVER: ProgressUtils.dismissprogress(); String remoteAddress = intent.getStringExtra(BluetoothUtils.EXTRA_REMOTE_ADDRESS); openChatRoom(remoteAddress); break; case BluetoothMessage.ACTION_CONNECT_ERROR: ProgressUtils.dismissprogress(); showToast(intent.getStringExtra(BluetoothUtils.EXTRA_ERROR_MSG)); break; } } }; private voID openChatRoom(String remoteAddress) { Intent intent = new Intent(mContext,ChatActivity.class); intent.putExtra("remoteAddress",remoteAddress); startActivity(intent); }
随后就是蓝牙通信的协议问题,这个相对来说就比较复杂了
这里说一下 ,我使用的是BluetoothSocket和BluetoothServerSocket
src/main/java/cn/com/lenew/bluetooth/utils/BluetoothUtils.java
/** * Created by xuhuan 0007. */public class BluetoothUtils { private static final String PROTOCol_SCHEME_RFCOMM = "server_name"; private static final String UUIDString = "00001101-0000-1000-8000-00805F9B34FB"; public static final String EXTRA_REMOTE_ADDRESS = "remoteAddress"; public static final String EXTRA_ERROR_MSG = "error_msg"; private static BluetoothUtils instance; /** 已连接到服务器 */ private static final int CONNECTED_SERVER = 1; /** 连接服务器出错 */ private static final int CONNECT_SERVER_ERROR = CONNECTED_SERVER + 1; /** 正在连接服务器 */ private static final int IS_CONNECTING_SERVER = CONNECT_SERVER_ERROR + 1; /** 等待客户端连接 */ private static final int WAITING_FOR_CLIENT = IS_CONNECTING_SERVER + 1; /** 已连接客户端 */ private static final int CONNECTED_CLIENT = WAITING_FOR_CLIENT + 1; /** 连接客户端出错 */ private static final int CONNECT_CLIENT_ERROR = CONNECTED_CLIENT + 1; private BluetoothAdapter bluetoothAdapter; private Context mContext; /** * socket集合 */ private HashMap<String, BluetoothSocket> socketMap = new HashMap<>(); /** * 远程设备集合 */// private HashMap<String, BluetoothDevice> remoteDeviceMap = new HashMap<>(); private HashMap<String,ReadThread> readThreadMap = new HashMap<>(); private BluetoothServerSocket mServerSocket; private Handler linkDetectedHandler = new Handler() { @OverrIDe public voID handleMessage(Message msg) { if(msg.obj instanceof BluetoothMessage){ BluetoothMessage message = (BluetoothMessage) msg.obj; Intent intent = new Intent(); intent.setAction(BluetoothMessage.ACTION_RECEIVED_NEW_MSG); intent.putExtra("msg", message); mContext.sendOrderedbroadcast(intent, null); DBManager.save(message);// mContext.sendbroadcast(intent); }else { Intent intent = new Intent(); switch (msg.what){ case WAITING_FOR_CLIENT: //初始化服务器完成 intent.setAction(BluetoothMessage.ACTION_INIT_COMPLETE); break; case IS_CONNECTING_SERVER: //正在连接服务器 break; case CONNECTED_CLIENT: //有客户端连接到自己 break; case CONNECT_CLIENT_ERROR: //连接客户端出错 break; case CONNECT_SERVER_ERROR: //连接服务器出错 intent.putExtra(EXTRA_ERROR_MSG,(String)msg.obj); intent.setAction(BluetoothMessage.ACTION_CONNECT_ERROR); break; case CONNECTED_SERVER: intent.putExtra(EXTRA_REMOTE_ADDRESS,(String)msg.obj); intent.setAction(BluetoothMessage.ACTION_CONNECTED_SERVER); break; } mContext.sendbroadcast(intent);// String msgContent = (String) msg.obj;// Toast.makeText(mContext, msgContent, Toast.LENGTH_SHORT).show(); } } }; private BluetoothUtils(Context context) { mContext = context; if (context == null) { throw new RuntimeException("Parameter context can not be null !"); } bluetoothAdapter = BluetoothAdapter.getDefaultAdapter(); } public static BluetoothUtils getInstance(Context context) { if (instance == null) { instance = new BluetoothUtils(context); } return instance; } public voID enableBluetooth() { if (!bluetoothAdapter.isEnabled()) {// Intent intent = new Intent(BluetoothAdapter.ACTION_REQUEST_disCOVERABLE);// intent.putExtra(BluetoothAdapter.EXTRA_disCOVERABLE_DURATION, 300);// mContext.startActivity(intent); bluetoothAdapter.enable(); } } public voID scanDevices() { if (!bluetoothAdapter.isEnabled()) { enableBluetooth(); return; } bluetoothAdapter.startdiscovery(); startService(); } private voID startService() { Intent serverIntent = new Intent(mContext, ServerService.class); mContext.startService(serverIntent); Intent clIEntIntent = new Intent(mContext, MessageService.class); mContext.startService(clIEntIntent); } public boolean isEnabled() { return bluetoothAdapter.isEnabled(); } public ArrayList<BluetoothDevice> getAvailableDevices() { Set<BluetoothDevice> availableDevices = bluetoothAdapter.getBondedDevices(); ArrayList availableList = new ArrayList(); for (Iterator<BluetoothDevice> iterator = availableDevices.iterator(); iterator.hasNext(); ) { availableList.add(iterator.next()); } return availableList; } public boolean isBonded(BluetoothDevice device) { Set<BluetoothDevice> availableDevices = bluetoothAdapter.getBondedDevices(); for (Iterator<BluetoothDevice> iterator = availableDevices.iterator(); iterator.hasNext(); ) { if (device.getAddress().equals(iterator.next().getAddress())) { return true; } } return false; } public boolean isdiscoverying() { return bluetoothAdapter.isdiscovering(); } public voID cancelScan() { bluetoothAdapter.canceldiscovery(); } //开启客户端 private class ClIEntThread extends Thread { private String remoteAddress; public ClIEntThread(String remoteAddress) { this.remoteAddress = remoteAddress; } @OverrIDe public voID run() { try { //创建一个Socket连接:只需要服务器在注册时的UUID号 // socket = device.createRfcommSocketToServiceRecord(BluetoothProtocols.OBEX_OBJECT_PUSH_PROTOCol_UUID); BluetoothDevice device = bluetoothAdapter.getRemoteDevice(remoteAddress); BluetoothSocket socket = device.createRfcommSocketToServiceRecord(UUID.fromString(UUIDString));// socketMap.put(remoteAddress, socket); //连接 Message msg2 = new Message(); msg2.obj = "请稍候,正在连接服务器:" + remoteAddress; msg2.what = IS_CONNECTING_SERVER; linkDetectedHandler.sendMessage(msg2); socket.connect();// socketMap.put(BluetoothMessage.bluetoothAddress, socket); socketMap.put(remoteAddress, socket); Message msg = new Message();// msg.obj = "已经连接上服务端!可以发送信息。"; msg.obj = remoteAddress; msg.what = CONNECTED_SERVER; linkDetectedHandler.sendMessage(msg); //启动接受数据 ReadThread mreadThread = new ReadThread(remoteAddress); readThreadMap.put(remoteAddress,mreadThread); mreadThread.start(); } catch (IOException e) { e.printstacktrace(); socketMap.remove(remoteAddress); Log.e("connect", e.getMessage(), e); Message msg = new Message(); msg.obj = "连接服务端异常!断开连接重新试一试。"+e.getMessage(); msg.what = CONNECT_SERVER_ERROR; linkDetectedHandler.sendMessage(msg);// remoteDeviceMap.remove(remoteAddress); } } } //开启服务器 private class ServerThread extends Thread { @OverrIDe public voID run() { try { /* 创建一个蓝牙服务器 * 参数分别:服务器名称、UUID */ mServerSocket = bluetoothAdapter.ListenUsingRfcommWithServiceRecord(PROTOCol_SCHEME_RFCOMM, UUID.fromString(UUIDString)); while (true){ Log.d("server", "wait cilent connect..."); Message msg = new Message(); msg.obj = "请稍候,正在等待客户端的连接..."; msg.what = WAITING_FOR_CLIENT; linkDetectedHandler.sendMessage(msg); /* 接受客户端的连接请求 */ BluetoothSocket socket = mServerSocket.accept(); socketMap.put(socket.getRemoteDevice().getAddress(), socket);// remoteDeviceMap.put(socket.getRemoteDevice().getAddress(),socket.getRemoteDevice()); Log.d("server", "accept success !"); Message msg2 = new Message(); String info = "客户端已经连接上!可以发送信息。"; msg2.obj = info; msg.what = CONNECTED_CLIENT; linkDetectedHandler.sendMessage(msg2); //启动接受数据 ReadThread mreadThread = new ReadThread(socket.getRemoteDevice().getAddress()); readThreadMap.put(socket.getRemoteDevice().getAddress(),mreadThread); mreadThread.start(); } } catch (IOException e) { e.printstacktrace(); } } } /* 停止服务器 *///略 /* 停止客户端连接 *///略 //发送数据//略 //读取数据//略
当然 这个模块到这里肯定是不算结束的,还有部分类,我就不一一展示了,末尾我会附上源代码
接下来是通信服务:
src/main/java/cn/com/lenew/bluetooth/service/MessageService.java:
/** * Created by xuhuan 0010. */public class MessageService extends Service{ private Context mContext; private notificationmanager notificationmanager; @Nullable @OverrIDe public IBinder onBind(Intent intent) { return null; } @OverrIDe public voID onCreate() { super.onCreate(); mContext = this; notificationmanager = (notificationmanager) getSystemService(NOTIFICATION_SERVICE); IntentFilter intentFilter = new IntentFilter(BluetoothMessage.ACTION_RECEIVED_NEW_MSG); intentFilter.setPriority(990); registerReceiver(msgReceiver, intentFilter); } @OverrIDe public voID onDestroy() { super.onDestroy(); unregisterReceiver(msgReceiver); } @OverrIDe public int onStartCommand(Intent intent, int flags, int startID) { return Service.START_STICKY; } public voID sendNotification(String content,String remoteAddress,BluetoothMessage message){ Intent chatIntent = new Intent(mContext, ChatActivity.class); chatIntent.putExtra("remoteAddress",remoteAddress); chatIntent.putExtra("lastmsg",message); PendingIntent pendingIntent = PendingIntent.getActivity(mContext, 0, chatIntent, PendingIntent.FLAG_UPDATE_CURRENT); Notification notification = new Notification.Builder(mContext) .setContentText(content) .setContentIntent(pendingIntent) .setSmallicon(R.mipmap.icon_logo) .setautoCancel(true) .setContentTitle("您有一条新消息") .build(); notification.defaults = Notification.DEFAulT_SOUND; notificationmanager.notify(1,notification); } broadcastReceiver msgReceiver = new broadcastReceiver() { @OverrIDe public voID onReceive(Context context, Intent intent) { BluetoothMessage bluetoothMessage = (BluetoothMessage) intent.getSerializableExtra("msg"); bluetoothMessage.setIsMe(0); String remoteAddress = bluetoothMessage.getSender(); String msgContent; if(bluetoothMessage.getContent().length()>10){ msgContent = bluetoothMessage.getContent().substring(0,10); }else { msgContent = bluetoothMessage.getContent(); } String msg = bluetoothMessage.getSenderNick()+":"+msgContent; sendNotification(msg,remoteAddress,bluetoothMessage); } };}
还有数据服务:
src/main/java/cn/com/lenew/bluetooth/database/DBManager.java:
/** * Created by xuhuan . */public class DBManager { private static DbManager.DaoConfig daoConfig; public static DbManager.DaoConfig getDaoConfig(){ if(daoConfig==null){ daoConfig = new DbManager.DaoConfig(); daoConfig.setDbVersion(2); } return daoConfig; } public static voID save(Object obj){ try { x.getDb(DBManager.getDaoConfig()).save(obj); } catch (DbException e) { e.printstacktrace(); } } public static List<BluetoothMessage> findAll(String remoteAddress) { try { Selector<BluetoothMessage> selector = x.getDb(getDaoConfig()).selector(BluetoothMessage.class); selector.where("sender","=",remoteAddress); selector.or("receiver","=",remoteAddress); return selector.findAll(); } catch (DbException e) { e.printstacktrace(); } return null; }}
差不多就是以上了,至于布局还有其他的,这里也就不继续展开了 需要的可以自行下载,当然 先提前声明,代码绝对不是最简单或者说完美的,很多地方我也是在网上down的,有些部分或许根本没有用到。反正是修修补补的,大概差不多就是这么个原理。
那么最后 附上码云地址:项目源码
以上是内存溢出为你收集整理的Android Studio实验作业之蓝牙聊天功能全部内容,希望文章能够帮你解决Android Studio实验作业之蓝牙聊天功能所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)