Android在类微信程序中实现蓝牙聊天功能的示例代码

项目要求

1.初次打开程序时右上角标题栏显示“无连接”,点击旁边的按钮选择“我的好友”,进入配对界面;
2.选择好友之后,返回主界面,标题栏会显示已连接的手机型号;
3.两部手机间可通过蓝牙聊天

效果展示


项目结构

主要代码

1.在清单文件中注册权限

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

2.在文件res / values / strings.xml里,添加程序运行过程中的状态描述文本及配色代码等

<?xml version="1.0" encoding="utf-8"?>
<resources>
 <string name="app_name">蓝牙Demo</string>
 <string name="send">发送</string>
 <string name="not_connected">你没有链接一个设备</string>
 <string name="bt_not_enabled_leaving">蓝牙不可用,离开聊天室</string>
 <string name="title_connecting">链接中...</string>
 <string name="title_connected_to">连接到:</string>
 <string name="title_not_connected">无链接</string>
 <string name="scanning">蓝牙设备搜索中...</string>
 <string name="select_device">选择一个好友链接</string>
 <string name="none_paired">没有配对好友</string>
 <string name="none_found">附近没有发现好友</string>
 <string name="title_paired_devices">已配对好友</string>
 <string name="title_other_devices">其它可连接好友</string>
 <string name="button_scan">搜索好友</string>
 <string name="connect">我的好友</string>
 <string name="discoverable">设置在线</string>
 <string name="back">退出</string>
 <string name="startVideo">开始聊天</string>
 <string name="stopVideo">结束聊天</string>
</resources>

用于蓝牙会话的服务组件ChatService.java中有三个内部类:AcceptThread(接受新连接)、ConnectThread(发出连接)和ConnectedThread (已连接)。

// 创建监听线程,准备接受新连接。使用阻塞方式,调用 BluetoothServerSocket.accept()
 private class AcceptThread extends Thread {
  private final BluetoothServerSocket mmServerSocket;

  public AcceptThread() {
   BluetoothServerSocket tmp = null;
   try {
    //使用射频端口(RF comm)监听
    tmp = mAdapter.listenUsingRfcommWithServiceRecord(NAME, MY_UUID);
   } catch (IOException e) {
   }
   mmServerSocket = tmp;
  }

  @Override
  public void run() {
   setName("AcceptThread");
   BluetoothSocket socket = null;
   while (mState != STATE_CONNECTED) {
    try {
     socket = mmServerSocket.accept();
    } catch (IOException e) {
     break;
    }
    if (socket != null) {
     synchronized (ChatService.this) {
      switch (mState) {
       case STATE_LISTEN:
       case STATE_CONNECTING:
        connected(socket, socket.getRemoteDevice());
        break;
       case STATE_NONE:
       case STATE_CONNECTED:
        try {
         socket.close();
        } catch (IOException e) {
         e.printStackTrace();
        }
        break;
      }
     }
    }
   }
  }

  public void cancel() {
   try {
    mmServerSocket.close();
   } catch (IOException e) {
    e.printStackTrace();
   }
  }
 }

 /*
  连接线程,专门用来对外发出连接对方蓝牙的请求和处理流程。
  构造函数里通过 BluetoothDevice.createRfcommSocketToServiceRecord() ,
  从待连接的 device 产生 BluetoothSocket. 然后在 run 方法中 connect ,
  成功后调用 BluetoothChatSevice 的 connected() 方法。定义 cancel() 在关闭线程时能够关闭相关socket 。
  */
 private class ConnectThread extends Thread {
  private final BluetoothSocket mmSocket;
  private final BluetoothDevice mmDevice;

  public ConnectThread(BluetoothDevice device) {
   mmDevice = device;
   BluetoothSocket tmp = null;
   try {
    tmp = device.createRfcommSocketToServiceRecord(MY_UUID);
   } catch (IOException e) {
    e.printStackTrace();
   }
   mmSocket = tmp;
  }

  @Override
  public void run() {
   setName("ConnectThread");
   mAdapter.cancelDiscovery();
   try {
    mmSocket.connect();
   } catch (IOException e) {
    connectionFailed();
    try {
     mmSocket.close();
    } catch (IOException e2) {
     e.printStackTrace();
    }
    ChatService.this.start();
    return;
   }
   synchronized (ChatService.this) {
    mConnectThread = null;
   }
   connected(mmSocket, mmDevice);
  }

  public void cancel() {
   try {
    mmSocket.close();
   } catch (IOException e) {
    e.printStackTrace();
   }
  }
 }

 /*
  双方蓝牙连接后一直运行的线程;构造函数中设置输入输出流。
  run()方法中使用阻塞模式的 InputStream.read()循环读取输入流,然后发送到 UI 线程中更新聊天消息。
  本线程也提供了 write() 将聊天消息写入输出流传输至对方,传输成功后回写入 UI 线程。最后使用cancel()关闭连接的 socket
  */
 private class ConnectedThread extends Thread {
  private final BluetoothSocket mmSocket;
  private final InputStream mmInStream;
  private final OutputStream mmOutStream;

  public ConnectedThread(BluetoothSocket socket) {
   mmSocket = socket;
   InputStream tmpIn = null;
   OutputStream tmpOut = null;
   try {
    tmpIn = socket.getInputStream();
    tmpOut = socket.getOutputStream();
   } catch (IOException e) {
    e.printStackTrace();
   }
   mmInStream = tmpIn;
   mmOutStream = tmpOut;
  }

  @Override
  public void run() {
   byte[] buffer = new byte[1024];
   int bytes;
   while (true) {
    try {
     bytes = mmInStream.read(buffer);
     mHandler.obtainMessage(weixinFragment.MESSAGE_READ, bytes, -1, buffer).sendToTarget();
    } catch (IOException e) {
     connectionLost();
     break;
    }
   }
  }

  public void write(byte[] buffer) {
   try {
    mmOutStream.write(buffer);
    mHandler.obtainMessage(weixinFragment.MESSAGE_WRITE, -1, -1, buffer).sendToTarget();
   } catch (IOException e) {
    e.printStackTrace();
   }
  }

  public void cancel() {
   try {
    mmSocket.close();
   } catch (IOException e) {
    e.printStackTrace();
   }
  }
 }

新建Activity组件DeviceList,实现拾取与之会话的蓝牙设备。本程序供菜单项主界面的选项菜单“我的友好”调用,用于:

(1)显示已配对的好友列表;
(2)搜索可配对的好友进行配对
(3)新选择并配对的蓝牙设备将刷新好友列表

注意:发现新的蓝牙设备并请求配对时,需要对应接受

关键技术:动态注册一个广播接收者,处理蓝牙设备扫描的结果

public class DeviceList extends Activity{
  private BluetoothAdapter mBtAdapter;
  private ArrayAdapter<String> mPairedDevicesArrayAdapter;
  private ArrayAdapter<String> mNewDevicesArrayAdapter;
  public static String EXTRA_DEVICE_ADDRESS = "device_address"; //Mac地址
  //定义广播接收者,用于处理扫描蓝牙设备后的结果
  private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
   @Override
   public void onReceive(Context context, Intent intent) {
    String action = intent.getAction();
    if (BluetoothDevice.ACTION_FOUND.equals(action)) {
     BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
     if (device.getBondState() != BluetoothDevice.BOND_BONDED) {
      mNewDevicesArrayAdapter.add(device.getName() + "\n" + device.getAddress());
     }
    } else if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)) {
     if (mNewDevicesArrayAdapter.getCount() == 0) {
      String noDevices = getResources().getText(R.string.none_found).toString();
      mNewDevicesArrayAdapter.add(noDevices);
     }
    }
   }
  };
  @Override
  protected void onCreate(Bundle savedInstanceState) {
   super.onCreate(savedInstanceState);
   setContentView(R.layout.device_list);
   //在被调用活动里,设置返回结果码
   setResult(Activity.RESULT_CANCELED);
   init(); //活动界面
  }
  private void init() {
   Button scanButton = findViewById(R.id.button_scan);
   scanButton.setOnClickListener(new OnClickListener() {
    public void onClick(View v) {
     Toast.makeText(DeviceList.this, R.string.scanning, Toast.LENGTH_LONG).show();
     doDiscovery(); //搜索蓝牙设备
    }
   });
   mPairedDevicesArrayAdapter = new ArrayAdapter<String>(this, R.layout.device_name);
   mNewDevicesArrayAdapter = new ArrayAdapter<String>(this, R.layout.device_name);
   //已配对蓝牙设备列表
   ListView pairedListView =findViewById(R.id.paired_devices);
   pairedListView.setAdapter(mPairedDevicesArrayAdapter);
   pairedListView.setOnItemClickListener(mPaireDeviceClickListener);
   //未配对蓝牙设备列表
   ListView newDevicesListView = findViewById(R.id.new_devices);
   newDevicesListView.setAdapter(mNewDevicesArrayAdapter);
   newDevicesListView.setOnItemClickListener(mNewDeviceClickListener);
   //动态注册广播接收者
   IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
   registerReceiver(mReceiver, filter);
   filter = new IntentFilter(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
   registerReceiver(mReceiver, filter);
   mBtAdapter = BluetoothAdapter.getDefaultAdapter();
   Set<BluetoothDevice> pairedDevices = mBtAdapter.getBondedDevices();
   if (pairedDevices.size() > 0) {
    findViewById(R.id.title_paired_devices).setVisibility(View.VISIBLE);
    for (BluetoothDevice device : pairedDevices) {
     mPairedDevicesArrayAdapter.add(device.getName() + "\n" + device.getAddress());
    }
   } else {
    String noDevices = getResources().getText(R.string.none_paired).toString();
    mPairedDevicesArrayAdapter.add(noDevices);
   }
  }
  @Override
  protected void onDestroy() {
   super.onDestroy();
   if (mBtAdapter != null) {
    mBtAdapter.cancelDiscovery();
   }
   this.unregisterReceiver(mReceiver);
  }
  private void doDiscovery() {
   findViewById(R.id.title_new_devices).setVisibility(View.VISIBLE);
   if (mBtAdapter.isDiscovering()) {
    mBtAdapter.cancelDiscovery();
   }
   mBtAdapter.startDiscovery(); //开始搜索蓝牙设备并产生广播
    //startDiscovery是一个异步方法
   //找到一个设备时就发送一个BluetoothDevice.ACTION_FOUND的广播
  }
  private OnItemClickListener mPaireDeviceClickListener = new OnItemClickListener() {
   public void onItemClick(AdapterView<?> av, View v, int arg2, long arg3) {
    mBtAdapter.cancelDiscovery();
    String info = ((TextView) v).getText().toString();
    String address = info.substring(info.length() - 17);
    Intent intent = new Intent();
    intent.putExtra(EXTRA_DEVICE_ADDRESS, address); //Mac地址
    setResult(Activity.RESULT_OK, intent);
    finish();
   }
  };
  private OnItemClickListener mNewDeviceClickListener = new OnItemClickListener() {
   public void onItemClick(AdapterView<?> av, View v, int arg2, long arg3) {
    mBtAdapter.cancelDiscovery();
    Toast.makeText(DeviceList.this, "请在蓝牙设置界面手动连接设备",Toast.LENGTH_SHORT).show();
    Intent intent = new Intent(Settings.ACTION_BLUETOOTH_SETTINGS);
    startActivityForResult(intent,1);
   }
  };
  //回调方法:进入蓝牙配对设置界面返回后执行
  @Override
  protected void onActivityResult(int requestCode, int resultCode, Intent data) {
   super.onActivityResult(requestCode, resultCode, data);
   init(); //刷新好友列表
  }
 }

蓝牙会话的主Activity组件程序fragment.java

public class weixinFrament extends Fragment {
 public static final int MESSAGE_STATE_CHANGE = 1;
 public static final int MESSAGE_READ = 2;
 public static final int MESSAGE_WRITE = 3;
 public static final int MESSAGE_DEVICE_NAME = 4;
 public static final int MESSAGE_TOAST = 5;
 public static final String DEVICE_NAME = "device_name";
 public static final String TOAST = "toast";
 private static final int REQUEST_CONNECT_DEVICE = 1; //请求连接设备
 private static final int REQUEST_ENABLE_BT = 2;
 private TextView mTitle;
 private ListView mConversationView;
 private EditText mOutEditText;
 private Button mSendButton;
 private String mConnectedDeviceName = null;
 private ArrayAdapter<String> mConversationArrayAdapter;
 private StringBuffer mOutStringBuffer;
 private BluetoothAdapter mBluetoothAdapter = null;
 private ChatService mChatService = null;

 private View view;

 public weixinFrament() {

 }

 @Override
 public View onCreateView(LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState) {

  view = inflater.inflate(R.layout.tab_01, container, false);

  Toolbar toolbar = view.findViewById(R.id.toolbar);
  setHasOptionsMenu(true);

  if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
   if (ContextCompat.checkSelfPermission(this.getContext(), Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
    ActivityCompat.requestPermissions(getActivity(), new String[]{Manifest.permission.ACCESS_COARSE_LOCATION}, 1);
   }
  }

  //创建选项菜单
  toolbar.inflateMenu(R.menu.option_menu);
  //选项菜单监听
  toolbar.setOnMenuItemClickListener(new MyMenuItemClickListener());
  mTitle = view.findViewById(R.id.title_left_text);
  mTitle.setText(R.string.app_name);
  mTitle = view.findViewById(R.id.title_right_text);
  // 得到本地蓝牙适配器
  mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
  if (mBluetoothAdapter == null) {
   Toast.makeText(view.getContext(), "蓝牙不可用", Toast.LENGTH_LONG).show();
   getActivity().finish();
   return view;
  }
  if (!mBluetoothAdapter.isEnabled()) { //若当前设备蓝牙功能未开启
   Intent enableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
   startActivityForResult(enableIntent, REQUEST_ENABLE_BT); //
  } else {
   if (mChatService == null) {
    setupChat(); //创建会话
   }
  }

  return view;
 }

 @Override
 public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
  super.onRequestPermissionsResult(requestCode, permissions, grantResults);
  if (grantResults.length > 0) {
   if (grantResults[0] != PackageManager.PERMISSION_GRANTED) {
    Toast.makeText(view.getContext(), "未授权,蓝牙搜索功能将不可用!", Toast.LENGTH_SHORT).show();
   }
  }
 }

 @Override
 public synchronized void onResume() { //synchronized:同步方法实现排队调用
  super.onResume();
  if (mChatService != null) {
   if (mChatService.getState() == ChatService.STATE_NONE) {
    mChatService.start();
   }
  }
 }

 private void setupChat() {
  mConversationArrayAdapter = new ArrayAdapter<String>(view.getContext(), R.layout.message);
  mConversationView = view.findViewById(R.id.in);
  mConversationView.setAdapter(mConversationArrayAdapter);
  mOutEditText = view.findViewById(R.id.edit_text_out);
  mOutEditText.setOnEditorActionListener(mWriteListener);
  mSendButton = view.findViewById(R.id.button_send);
  mSendButton.setOnClickListener(new View.OnClickListener() {
   public void onClick(View v) {
    TextView textview = view.findViewById(R.id.edit_text_out);
    String message = textview.getText().toString();
    sendMessage(message);
   }
  });
  //创建服务对象
  mChatService = new ChatService(view.getContext(), mHandler);
  mOutStringBuffer = new StringBuffer("");
 }

 @Override
 public void onDestroy() {
  super.onDestroy();
  if (mChatService != null)
   mChatService.stop();
 }

 private void ensureDiscoverable() { //修改本机蓝牙设备的可见性
  //打开手机蓝牙后,能被其它蓝牙设备扫描到的时间不是永久的
  if (mBluetoothAdapter.getScanMode() != BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE) {
   Intent discoverableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
   //设置在300秒内可见(能被扫描)
   discoverableIntent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 300);
   startActivity(discoverableIntent);
   Toast.makeText(view.getContext(), "已经设置本机蓝牙设备的可见性,对方可搜索了。", Toast.LENGTH_SHORT).show();
  }
 }

 private void sendMessage(String message) {
  if (mChatService.getState() != ChatService.STATE_CONNECTED) {
   Toast.makeText(view.getContext(), R.string.not_connected, Toast.LENGTH_SHORT).show();
   return;
  }
  if (message.length() > 0) {
   byte[] send = message.getBytes();
   mChatService.write(send);
   mOutStringBuffer.setLength(0);
   mOutEditText.setText(mOutStringBuffer);
  }
 }

 private TextView.OnEditorActionListener mWriteListener = new TextView.OnEditorActionListener() {
  @Override
  public boolean onEditorAction(TextView view, int actionId, KeyEvent event) {
   if (actionId == EditorInfo.IME_NULL && event.getAction() == KeyEvent.ACTION_UP) {
    //软键盘里的回车也能发送消息
    String message = view.getText().toString();
    sendMessage(message);
   }
   return true;
  }
 };
 //使用Handler对象在UI主线程与子线程之间传递消息
 private final Handler mHandler = new Handler() { //消息处理
  @Override
  public void handleMessage(Message msg) {
   switch (msg.what) {
    case MESSAGE_STATE_CHANGE:
     switch (msg.arg1) {
      case ChatService.STATE_CONNECTED:
       mTitle.setText(R.string.title_connected_to);
       mTitle.append(mConnectedDeviceName);
       mConversationArrayAdapter.clear();
       break;
      case ChatService.STATE_CONNECTING:
       mTitle.setText(R.string.title_connecting);
       break;
      case ChatService.STATE_LISTEN:
      case ChatService.STATE_NONE:
       mTitle.setText(R.string.title_not_connected);
       break;
     }
     break;
    case MESSAGE_WRITE:
     byte[] writeBuf = (byte[]) msg.obj;
     String writeMessage = new String(writeBuf);
     mConversationArrayAdapter.add("我: " + writeMessage);
     break;
    case MESSAGE_READ:
     byte[] readBuf = (byte[]) msg.obj;
     String readMessage = new String(readBuf, 0, msg.arg1);
     mConversationArrayAdapter.add(mConnectedDeviceName + ": "
       + readMessage);
     break;
    case MESSAGE_DEVICE_NAME:
     mConnectedDeviceName = msg.getData().getString(DEVICE_NAME);
     Toast.makeText(getActivity().getApplicationContext(), "链接到 " + mConnectedDeviceName, Toast.LENGTH_SHORT).show();
     break;
    case MESSAGE_TOAST:
     Toast.makeText(getActivity().getApplicationContext(),
       msg.getData().getString(TOAST), Toast.LENGTH_SHORT).show();
     break;
   }
  }
 };

 //返回进入好友列表操作后的数回调方法
 public void onActivityResult(int requestCode, int resultCode, Intent data) {
  switch (requestCode) {
   case REQUEST_CONNECT_DEVICE:
    if (resultCode == Activity.RESULT_OK) {
     String address = data.getExtras().getString(DeviceList.EXTRA_DEVICE_ADDRESS);
     BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(address);
     mChatService.connect(device);
    } else if (resultCode == Activity.RESULT_CANCELED) {
     Toast.makeText(view.getContext(), "未选择任何好友!", Toast.LENGTH_SHORT).show();
    }
    break;
   case REQUEST_ENABLE_BT:
    if (resultCode == Activity.RESULT_OK) {
     setupChat();
    } else {
     Toast.makeText(view.getContext(), R.string.bt_not_enabled_leaving, Toast.LENGTH_SHORT).show();
     getActivity().finish();
    }
  }
 }

 //内部类,选项菜单的单击事件处理
 private class MyMenuItemClickListener implements Toolbar.OnMenuItemClickListener {
  @Override
  public boolean onMenuItemClick(MenuItem item) {
   switch (item.getItemId()) {
    case R.id.scan:
     //启动DeviceList这个Activity
     Intent serverIntent = new Intent(weixinFrament.this.getActivity(), DeviceList.class);
     startActivityForResult(serverIntent, REQUEST_CONNECT_DEVICE);
     return true;
    case R.id.discoverable:
     ensureDiscoverable();
     return true;
    case R.id.back:
     getActivity().finish();
     System.exit(0);
     return true;
   }
   return false;
  }
 }
}

项目地址

点我进入仓库

总结

到此这篇关于Android在类微信程序中实现蓝牙聊天功能的文章就介绍到这了,更多相关android 类微信程序蓝牙聊天内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • 微信小程序--Ble蓝牙

    有一段时间没有.没有写关于小程序的文章了.3月28日,微信的api又一次新的更新.期待已久的蓝牙api更新.就开始撸一番. 源码地址 1.简述 蓝牙适配器接口是基础库版本 1.1.0 开始支持. iOS 微信客户端 6.5.6 版本开始支持,Android 客户端暂不支持 蓝牙总共增加了18个api接口. 2.Api分类 搜索类 连接类 通信类 3.API的具体使用 详细见官网: https://mp.weixin.qq.com/debug/wxadoc/dev/api/bluetooth.ht

  • 微信小程序之蓝牙的链接

    微信小程序之蓝牙的链接 微信小程序蓝牙连接2.0说明: 1.本版本区分了ANDROID和IOS系统下蓝牙连接的不同方式. 2.兼容了更多情况下的链接包括: (1)未开启设备蓝牙,当监听到开启了蓝牙后自动开始连接. (2)初始化蓝牙失败后每3000ms自动重新初始化蓝牙适配器. (3)安卓端开启蓝牙适配器扫描失败,每3000ms自动重新开启. (4)IOS端获取已连接蓝牙设备为空,每3000ms自动重新获取. (5)安卓端蓝牙开始链接后中断扫描,连接失败了,重新开始扫描. (6)IOS端开始连接设

  • 微信小程序实现蓝牙打印

    最近刚好完成了一个打印标签的项目,其中就涉及到了小程序的蓝牙功能.所以写下这篇粗略的文章记录一下,同时也是给即将做相关项目的亲们提供一个参考,也希望有什么描述不恰当或者技术上不正确的地方大家可以指出,一起进步. 蓝牙打印只要按这九个步骤(前六个步骤连接蓝牙,后三个步骤打印数据)就可以搞定啦!步骤如下: 第一步:初始化蓝牙模块 wx.openBluetoothAdapter wx.openBluetoothAdapter({ success (res) { console.log(res)//re

  • 微信小程序 蓝牙的实现实例代码

    微信小程序 蓝牙的实现实例代码 1.简述 蓝牙适配器接口是基础库版本 1.1.0 开始支持. iOS 微信客户端 6.5.6 版本开始支持,Android 客户端暂不支持 蓝牙总共增加了18个api接口. 2.Api分类 搜索类 连接类 通信类 3.API的具体使用 详细见官网: https://mp.weixin.qq.com/debug/wxadoc/dev/api/bluetooth.html#wxgetconnectedbluethoothdevicesobject 4. 案例实现 4.

  • vue+web端仿微信网页版聊天室功能

    一.项目介绍 基于Vue2.5.6+Vuex+vue-cli+vue-router+vue-gemini-scrollbar+swiper+elementUI等技术混合架构开发的仿微信web端聊天室--vueWebChat,实现了发送消息.表情(动图),图片.视频预览,右键菜单.截屏.截图可直接粘贴至文本框进行发送. 二.技术框架 •MVVM框架:Vue2.5.6 •状态管理:Vuex •页面路由:Vue-router •iconfont图标:阿里巴巴字体图标库 •自定义滚动条:vue-gemi

  • 微信小程序蓝牙连接小票打印机实例代码详解

    1.连接蓝牙 (第一次发表博客) 第一步打开蓝牙并搜索附近打印机设备// startSearch: function() { var that = this wx.openBluetoothAdapter({ success: function(res) { wx.getBluetoothAdapterState({ success: function(res) { if (res.available) { if (res.discovering) { wx.stopBluetoothDevic

  • 微信小程序websocket聊天室的实现示例代码

    背景 最近做了一个微信小程序的即时通讯功能,之前我也做过node.js的websocket服务,不过是在web端应用的socket.io服务.小程序本身对http.websocket等连接均有诸多限制,所以这次项目选择了node.js自带的ws模块. 服务端 初始化一个node.js项目,引入ws模块 const webSocket = require('ws'); 创建websocket实例,并设置监听端口 const wss = new webSocket.Server({ port: 30

  • 详解微信小程序实现仿微信聊天界面(各种细节处理)

    本文介绍了微信小程序实现仿微信聊天界面,分享给大家,具体如下: 下面先来看看效果 为实现这样的效果,首先要解决两个问题: 1.点击输入框弹出软键盘后,将已有的少许聊天内容弹出,导致看不到的问题: 2.键盘弹出或收起时,聊天消息没有自动滚到最底部. 首先解决第二个问题,自动滚动到最底部,这很简单,这里提供三种方法(推荐第三种): 1.计算每条消息的最大高度,设置scroll-top=(单条msg最大高度 * msg条数)px. 2.用 将展示msg的目标scroll-view包裹, 通过js获取到

  • Android在类微信程序中实现蓝牙聊天功能的示例代码

    项目要求 1.初次打开程序时右上角标题栏显示"无连接",点击旁边的按钮选择"我的好友",进入配对界面: 2.选择好友之后,返回主界面,标题栏会显示已连接的手机型号: 3.两部手机间可通过蓝牙聊天 效果展示 项目结构 主要代码 1.在清单文件中注册权限 <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" /> <uses-permission and

  • 微信小程序实现即时通信聊天功能的实例代码

    项目背景:小程序中实现实时聊天功能 一.服务器域名配置 配置流程 配置参考URL:https://developers.weixin.qq.com/miniprogram/dev/api/api-network.html 二.nginx中配置反向代理加密websocket(wss) upstream websocket{ hash $remote_addr consistent; server 127.0.0.1:9090 weight=5 max_fails=3 fail_timeout=30

  • 微信小程序实现幸运大转盘功能的示例代码

    目录 一.项目展示 二.抽奖页 三.领奖页 一.项目展示 幸运大转盘是一个简单的抽奖小程序 参与用户点击抽奖便可抽取轮盘的奖品 二.抽奖页 抽奖页是一个大轮盘和活动规则 页面形式简单 主要核心在于轮盘 核心代码[轮盘旋转]如下: getLottery: function () { var that = this var awardIndex = Math.random() * 6 >>> 0; // 获取奖品配置 var awardsConfig = app.awardsConfig,

  • Android开发中编写蓝牙相关功能的核心代码讲解

    一. 什么是蓝牙(Bluetooth)? 1.1  BuleTooth是目前使用最广泛的无线通信协议 1.2  主要针对短距离设备通讯(10m) 1.3  常用于连接耳机,鼠标和移动通讯设备等. 二. 与蓝牙相关的API 2.1 BluetoothAdapter: 代表了本地的蓝牙适配器 2.2 BluetoothDevice 代表了一个远程的Bluetooth设备 三. 扫描已经配对的蓝牙设备(1) 注:必须部署在真实手机上,模拟器无法实现 首先需要在AndroidManifest.xml 声

  • 微信小程序中实现手指缩放图片的示例代码

    公司开发微信小程序,pm想实现如下需求: 用手指缩放图片.其实在实现这个需求以前,并不知道,微信公众号以及微信小程序里面有一个原生的api就自带这个特效,而且微信朋友圈也是用的这个api.wx.previewImage,就是它.预览图片.除了不能预览开发环境的本地电脑的图片外,你手机真机的图片,以及http服务器上的图片都是可以预览的,而且缩放功能做得很流畅.下面就说说如何用js来实现这个功能吧. 先上源码,然后在逐步剖析: Page({ data: { touch: { distance: 0

  • 微信小程序聊天功能的示例代码

    效果 初始化滚动条高度 var keyHeight = 0; 数据格式 const CHAT_DATA=[ { type:0,//0客服1用户 content:'欢迎欢迎欢迎欢迎欢迎欢迎欢迎欢迎欢迎欢迎欢迎欢迎欢迎欢迎欢迎欢迎欢迎欢迎欢迎欢迎欢迎欢迎欢迎欢迎欢迎欢迎欢迎欢迎', headImg:'../../assets/common/images/headHortrait.jpeg',//头像 creatTime:'2019-01-01',//创建时间 contentType:'text' }

  • Android编程实现在一个程序中启动另一个程序的方法

    本文实例讲述了Android编程实现在一个程序中启动另一个程序的方法.分享给大家供大家参考,具体如下: Android 开发有时需要在一个应用中启动另一个应用,比如Launcher加载所有的已安装的程序的列表,当点击图标时可以启动另一个应用. 一般我们知道了另一个应用的包名和MainActivity的名字之后便可以直接通过如下代码来启动: Intent intent = new Intent(Intent.ACTION_MAIN); intent.addCategory(Intent.CATEG

  • 微信小程序中button去除默认的边框实例代码

    微信小程序中button去除默认的边框的实现方法如下所示: button { position:relative; display:block; margin-left:auto; margin-right:auto; padding-left:14px; padding-right:14px; box-sizing:border-box; font-size:18px; text-align:center; text-decoration:none; line-height:2.5555555

  • Android开发之在程序中时时获取logcat日志信息的方法(附demo源码下载)

    本文实例讲述了Android开发之在程序中时时获取logcat日志信息的方法.分享给大家供大家参考,具体如下: 今天分享一个在软件开发中很实用的例子,也是这几天在通宵加班中我使用的一个小例子, 在程序中监听Log信息. 为什么说它实用?原因是Android的开发厂商各种修改之后手机和手机之间以后存在很多差异.比如说魅族M9手机 开发中如果项目中涉及到访问手机系统的地方,例如访问系统短信库,M9手机它会提示一个dialog框 让用户自己去选择 访问还是不访问.这样就给开发适配带来了巨大的麻烦.本来

  • 微信小程序中上传图片并进行压缩的实现代码

    小程序上传图片要先了解他其中的各个属性值,在https://developers.weixin.qq.com/miniprogram/dev/api/media-picture.html内有详细的介绍 今天在这里主要来讲下如何去上传图片并进行压缩,了解下以下属性值 先来看下页面展示(点击上传图片,从相册中选择,上传完图片后又点了一次上传) 来来来,上代码 wxml代码 <button bindtap='chooseImageTap'>上传图片</button> <button

随机推荐