国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 系統 > Android > 正文

Android實現藍牙客戶端與服務器端通信示例

2019-12-12 04:02:03
字體:
來源:轉載
供稿:網友

一、首先說明:藍牙通信必須用手機測試,因為avd里沒有相關的硬件,會報錯!

好了,看看最后的效果圖:

這里寫圖片描述 這里寫圖片描述

二、概述:

1.判斷是否支持Bluetooth

BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();if(bluetoothAdapter == null) {  //the device doesn't support bluetooth} else {  //the device support bluetooth}

2.如果支持,打開Bluetooth

if(!bluetoothAdapter.isEnable()) {  Intent enableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);  startActivityForResult(enableIntent,REQUEST_ENABLE_BT);}

3.監視Bluetooth打開狀態

BroadcastReceiver bluetoothState = new BroadcastReceiver() {  public void onReceive(Context context, Intent intent) {  String stateExtra = BluetoothAdapter.EXTRA_STATE;    int state = intent.getIntExtra(stateExtra, -1);    switch(state) {  case BluetoothAdapter.STATE_TURNING_ON:    break;  case BluetoothAdapter.STATE_ON:    break;  case BluetoothAdapter.STATE_TURNING_OFF:    break;  case BluetoothAdapter.STATE_OFF:    break;  }  }} registerReceiver(bluetoothState,new IntentFilter(BluetoothAdapter.ACTION_STATE_CHANGED));

4.設置本地設備可以被其它設備搜索

Intent discoveryIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);startActivityForResult(discoveryIntent,REQUEST_DISCOVERY);BroadcastReceiver discovery = new BroadcastReceiver() {  @Override  public void onRecevie(Content context, Intent intent) {    String scanMode = BluetoothAdapter.EXTRA_SCAN_MODE;    String preScanMode = BluetoothAdapter.EXTRA_PREVIOUS_SCAN_MODE;    int mode = intent.getIntExtra(scanMode);  }}registerReceiver(discovery,new IntentFilter(BluetoothAdapter.ACTION_SCAN_MODE_CHANGED);

5.搜索設備

開始搜索 bluetoothAdapter.startDiscovery();

停止搜索 bluetoothAdapter.cancelDiscovery();

當發現一個設備時,系統會發出ACTION_FOUND廣播消息,我們可以實現接收這個消息的BroadcastReceiver

BroadcastReceiver deviceFound = new BroadcastReceiver() {  @Override  public void onReceiver(Content content, Intent intent) {    String remoteDeviceName = intent.getStringExtra(BluetoothAdapter.EXTRA_NAME);    BluetoothDevice remoteDevice = intent.getParcelableExtra(BluetoothAdapter.EXTRA_DEVICE);  }}registerReceiver(deviceFound, new IntentFilter(BluetoothAdapter.ACTION_FOUND);

6.連接設備

連接兩個藍牙設備要分別實現服務器端(BluetoothServerSocket)和客戶端(BluetoothSocket),這點與J2SE中的

ServerSocket和Socket很類似。

BluetoothServerSocket在服務器端調用方法accept()監聽,當有客戶端請求到來時,accept()方法返回BluetoothSocket,客戶端得到后,兩端便可以通信。通過InputStream和OutputStream來實現數據的傳輸。

accept方法是阻塞的,所以不能放在UI線程中,當用到BluetoothServerSocket和BluetoothSocket時,通常把它們放在各自的新線程中。

三、如何實現

以下是開發中的幾個關鍵步驟:

1)首先開啟藍牙

2)搜索可用設備

3)創建藍牙socket,獲取輸入輸出流

4)讀取和寫入數據

5)斷開連接關閉藍牙

1、因為有頁面切換,這里我使用了TabHost,但原來的效果不好,沒有動畫,那只好自己復寫了

/** * 帶有動畫效果的TabHost *  * @Project App_Bluetooth * @Package com.android.bluetooth * @author chenlin * @version 1.0 * @Date 2013年6月2日 * @Note TODO */public class AnimationTabHost extends TabHost {  private int mCurrentTabID = 0;//當前的tabId  private final long mDuration = 400;//動畫時間  public AnimationTabHost(Context context) {    this(context, null);  }  public AnimationTabHost(Context context, AttributeSet attrs) {    super(context, attrs);  }  /**   * 切換動畫   */  @Override  public void setCurrentTab(int index) {    //向右平移     if (index > mCurrentTabID) {      TranslateAnimation translateAnimation = new TranslateAnimation(Animation.RELATIVE_TO_SELF, 0f, Animation.RELATIVE_TO_SELF,          -1.0f, Animation.RELATIVE_TO_SELF, 0f, Animation.RELATIVE_TO_SELF, 0f);      translateAnimation.setDuration(mDuration);      getCurrentView().startAnimation(translateAnimation);      //向左平移    } else if (index < mCurrentTabID) {      TranslateAnimation translateAnimation = new TranslateAnimation(          Animation.RELATIVE_TO_SELF, 0f, Animation.RELATIVE_TO_SELF, 1.0f, Animation.RELATIVE_TO_SELF, 0f,          Animation.RELATIVE_TO_SELF, 0f);      translateAnimation.setDuration(mDuration);      getCurrentView().startAnimation(translateAnimation);    }     super.setCurrentTab(index);    //-----方向平移------------------------------    if (index > mCurrentTabID) {      TranslateAnimation translateAnimation = new TranslateAnimation( //          Animation.RELATIVE_TO_PARENT, 1.0f,// RELATIVE_TO_SELF          Animation.RELATIVE_TO_PARENT, 0f, Animation.RELATIVE_TO_PARENT, 0f, Animation.RELATIVE_TO_PARENT, 0f);      translateAnimation.setDuration(mDuration);      getCurrentView().startAnimation(translateAnimation);    } else if (index < mCurrentTabID) {      TranslateAnimation translateAnimation = new TranslateAnimation(          Animation.RELATIVE_TO_PARENT, -1.0f, Animation.RELATIVE_TO_PARENT, 0f, Animation.RELATIVE_TO_PARENT, 0f,          Animation.RELATIVE_TO_PARENT, 0f);      translateAnimation.setDuration(mDuration);      getCurrentView().startAnimation(translateAnimation);    }    mCurrentTabID = index;  }}

2、先搭建好主頁,使用復寫的TabHost滑動,如何滑動,根據狀態,有三種狀態

/** * 主頁 *  * @Project App_Bluetooth * @Package com.android.bluetooth * @author chenlin * @version 1.0 * @Date 2013年6月2日 */@SuppressWarnings("deprecation")public class BluetoothActivity extends TabActivity {  static AnimationTabHost mTabHost;//動畫tabhost  static String BlueToothAddress;//藍牙地址  static Type mType = Type.NONE;//類型  static boolean isOpen = false;  //類型:  enum Type {    NONE, SERVICE, CILENT  };  @Override  public void onCreate(Bundle savedInstanceState) {    super.onCreate(savedInstanceState);    setContentView(R.layout.main);    initTab();  }  private void initTab() {    //初始化    mTabHost = (AnimationTabHost) getTabHost();    //添加tab    mTabHost.addTab(mTabHost.newTabSpec("Tab1").setIndicator("設備列表", getResources().getDrawable(android.R.drawable.ic_menu_add))        .setContent(new Intent(this, DeviceActivity.class)));    mTabHost.addTab(mTabHost.newTabSpec("Tab2").setIndicator("會話列表", getResources().getDrawable(android.R.drawable.ic_menu_add))        .setContent(new Intent(this, ChatActivity.class)));    //添加監聽    mTabHost.setOnTabChangedListener(new OnTabChangeListener() {      public void onTabChanged(String tabId) {        if (tabId.equals("Tab1")) {          //TODO        }      }    });    //默認在第一個tabhost上面    mTabHost.setCurrentTab(0);  }  public void onActivityResult(int requestCode, int resultCode, Intent data) {    Toast.makeText(this, "address:", Toast.LENGTH_SHORT).show();  }}

3、有了主頁,就開始分別實現兩個列表頁面,一個是尋找設備頁面DeviceActivity.Java,另一個是會話頁面ChatActivity.java

1)設備頁面DeviceActivity.java

/** * 發現的設備列表 * @Project  App_Bluetooth * @Package  com.android.bluetooth * @author   chenlin * @version  1.0 * @Date    2013年6月2日 * @Note    TODO */public class DeviceActivity extends Activity {  private ListView mListView;  //數據  private ArrayList<DeviceBean> mDatas;  private Button mBtnSearch, mBtnService;  private ChatListAdapter mAdapter;  //藍牙適配器  private BluetoothAdapter mBtAdapter;  @Override  public void onCreate(Bundle savedInstanceState) {    super.onCreate(savedInstanceState);    setContentView(R.layout.devices);    initDatas();    initViews();    registerBroadcast();    init();  }  private void initDatas() {    mDatas = new ArrayList<DeviceBean>();    mAdapter = new ChatListAdapter(this, mDatas);    mBtAdapter = BluetoothAdapter.getDefaultAdapter();  }  /**   * 列出所有的藍牙設備   */  private void init() {    Log.i("tag", "mBtAdapter=="+ mBtAdapter);    //根據適配器得到所有的設備信息    Set<BluetoothDevice> deviceSet = mBtAdapter.getBondedDevices();    if (deviceSet.size() > 0) {      for (BluetoothDevice device : deviceSet) {        mDatas.add(new DeviceBean(device.getName() + "/n" + device.getAddress(), true));        mAdapter.notifyDataSetChanged();        mListView.setSelection(mDatas.size() - 1);      }    } else {      mDatas.add(new DeviceBean("沒有配對的設備", true));      mAdapter.notifyDataSetChanged();      mListView.setSelection(mDatas.size() - 1);    }  }  /**   * 注冊廣播   */  private void registerBroadcast() {    //設備被發現廣播    IntentFilter discoveryFilter = new IntentFilter(BluetoothDevice.ACTION_FOUND);    this.registerReceiver(mReceiver, discoveryFilter);    // 設備發現完成    IntentFilter foundFilter = new IntentFilter(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);    this.registerReceiver(mReceiver, foundFilter);  }  /**   * 初始化視圖   */  private void initViews() {    mListView = (ListView) findViewById(R.id.list);    mListView.setAdapter(mAdapter);    mListView.setFastScrollEnabled(true);    mListView.setOnItemClickListener(mDeviceClickListener);    mBtnSearch = (Button) findViewById(R.id.start_seach);    mBtnSearch.setOnClickListener(mSearchListener);    mBtnService = (Button) findViewById(R.id.start_service);    mBtnService.setOnClickListener(new OnClickListener() {      @Override      public void onClick(View arg0) {        BluetoothActivity.mType = Type.SERVICE;        BluetoothActivity.mTabHost.setCurrentTab(1);      }    });  }  /**   * 搜索監聽   */  private OnClickListener mSearchListener = new OnClickListener() {    @Override    public void onClick(View arg0) {      if (mBtAdapter.isDiscovering()) {        mBtAdapter.cancelDiscovery();        mBtnSearch.setText("重新搜索");      } else {        mDatas.clear();        mAdapter.notifyDataSetChanged();        init();        /* 開始搜索 */        mBtAdapter.startDiscovery();        mBtnSearch.setText("ֹͣ停止搜索");      }    }  };  /**   * 點擊設備監聽   */  private OnItemClickListener mDeviceClickListener = new OnItemClickListener() {    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {      DeviceBean bean = mDatas.get(position);      String info = bean.message;      String address = info.substring(info.length() - 17);      BluetoothActivity.BlueToothAddress = address;      AlertDialog.Builder stopDialog = new AlertDialog.Builder(DeviceActivity.this);      stopDialog.setTitle("連接");//標題      stopDialog.setMessage(bean.message);      stopDialog.setPositiveButton("連接", new DialogInterface.OnClickListener() {        public void onClick(DialogInterface dialog, int which) {          mBtAdapter.cancelDiscovery();          mBtnSearch.setText("重新搜索");          BluetoothActivity.mType = Type.CILENT;          BluetoothActivity.mTabHost.setCurrentTab(1);          dialog.cancel();        }      });      stopDialog.setNegativeButton("取消", new DialogInterface.OnClickListener() {        public void onClick(DialogInterface dialog, int which) {          BluetoothActivity.BlueToothAddress = null;          dialog.cancel();        }      });      stopDialog.show();    }  };  /**   * 發現設備廣播   */  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) {          mDatas.add(new DeviceBean(device.getName() + "/n" + device.getAddress(), false));          mAdapter.notifyDataSetChanged();          mListView.setSelection(mDatas.size() - 1);        }        // 如果搜索完成了      } else if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)) {        setProgressBarIndeterminateVisibility(false);        if (mListView.getCount() == 0) {          mDatas.add(new DeviceBean("û沒有發現藍牙設備", false));          mAdapter.notifyDataSetChanged();          mListView.setSelection(mDatas.size() - 1);        }        mBtnSearch.setText("重新搜索");      }    }  };  @Override  public void onStart() {    super.onStart();    if (!mBtAdapter.isEnabled()) {      Intent enableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);      startActivityForResult(enableIntent, 3);    }  }  @Override  protected void onDestroy() {    super.onDestroy();    if (mBtAdapter != null) {      mBtAdapter.cancelDiscovery();    }    this.unregisterReceiver(mReceiver);  }}

2)會話頁面ChatActivity.java

/** * 會話界面 *  * @Project App_Bluetooth * @Package com.android.bluetooth * @author chenlin * @version 1.0 * @Date 2013年3月2日 * @Note TODO */public class ChatActivity extends Activity implements OnItemClickListener, OnClickListener {  private static final int STATUS_CONNECT = 0x11;  private ListView mListView;  private ArrayList<DeviceBean> mDatas;  private Button mBtnSend;// 發送按鈕  private Button mBtnDisconn;// 斷開連接  private EditText mEtMsg;  private DeviceListAdapter mAdapter;  /* 一些常量,代表服務器的名稱 */  public static final String PROTOCOL_SCHEME_L2CAP = "btl2cap";  public static final String PROTOCOL_SCHEME_RFCOMM = "btspp";  public static final String PROTOCOL_SCHEME_BT_OBEX = "btgoep";  public static final String PROTOCOL_SCHEME_TCP_OBEX = "tcpobex";  // 藍牙服務端socket  private BluetoothServerSocket mServerSocket;  // 藍牙客戶端socket  private BluetoothSocket mSocket;  // 設備  private BluetoothDevice mDevice;  private BluetoothAdapter mBluetoothAdapter;  // --線程類-----------------  private ServerThread mServerThread;  private ClientThread mClientThread;  private ReadThread mReadThread;  @Override  public void onCreate(Bundle savedInstanceState) {    super.onCreate(savedInstanceState);    setContentView(R.layout.chat);    initDatas();    initViews();    initEvents();  }  private void initEvents() {    mListView.setOnItemClickListener(this);    // 發送信息    mBtnSend.setOnClickListener(new OnClickListener() {      @Override      public void onClick(View arg0) {        String text = mEtMsg.getText().toString();        if (!TextUtils.isEmpty(text)) {          // 發送信息          sendMessageHandle(text);          mEtMsg.setText("");          mEtMsg.clearFocus();          // 隱藏軟鍵盤          InputMethodManager manager = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);          manager.hideSoftInputFromWindow(mEtMsg.getWindowToken(), 0);        } else          Toast.makeText(ChatActivity.this, "發送內容不能為空!", Toast.LENGTH_SHORT).show();      }    });    // 關閉會話    mBtnDisconn.setOnClickListener(new OnClickListener() {      @Override      public void onClick(View view) {        if (BluetoothActivity.mType == Type.CILENT) {          shutdownClient();        } else if (BluetoothActivity.mType == Type.SERVICE) {          shutdownServer();        }        BluetoothActivity.isOpen = false;        BluetoothActivity.mType = Type.NONE;        Toast.makeText(ChatActivity.this, "已斷開連接!", Toast.LENGTH_SHORT).show();      }    });  }  private void initViews() {    mListView = (ListView) findViewById(R.id.list);    mListView.setAdapter(mAdapter);    mListView.setFastScrollEnabled(true);    mEtMsg = (EditText) findViewById(R.id.MessageText);    mEtMsg.clearFocus();    mBtnSend = (Button) findViewById(R.id.btn_msg_send);    mBtnDisconn = (Button) findViewById(R.id.btn_disconnect);  }  private void initDatas() {    mDatas = new ArrayList<DeviceBean>();    mAdapter = new DeviceListAdapter(this, mDatas);    mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();  }  /**   * 信息處理   */  private Handler mHandler = new Handler() {    @Override    public void handleMessage(Message msg) {      String info = (String) msg.obj;      switch (msg.what) {      case STATUS_CONNECT:        Toast.makeText(ChatActivity.this, info, 0).show();        break;      }      if (msg.what == 1) {        mDatas.add(new DeviceBean(info, true));        mAdapter.notifyDataSetChanged();        mListView.setSelection(mDatas.size() - 1);      }else {        mDatas.add(new DeviceBean(info, false));        mAdapter.notifyDataSetChanged();        mListView.setSelection(mDatas.size() - 1);      }    }  };  @Override  public void onResume() {    super.onResume();    if (BluetoothActivity.isOpen) {      Toast.makeText(this, "連接已經打開,可以通信。如果要再建立連接,請先斷開", Toast.LENGTH_SHORT).show();      return;    }    if (BluetoothActivity.mType == Type.CILENT) {      String address = BluetoothActivity.BlueToothAddress;      if (!"".equals(address)) {        mDevice = mBluetoothAdapter.getRemoteDevice(address);        mClientThread = new ClientThread();        mClientThread.start();        BluetoothActivity.isOpen = true;      } else {        Toast.makeText(this, "address is null !", Toast.LENGTH_SHORT).show();      }    } else if (BluetoothActivity.mType == Type.SERVICE) {      mServerThread = new ServerThread();      mServerThread.start();      BluetoothActivity.isOpen = true;    }  }  // 客戶端線程  private class ClientThread extends Thread {    public void run() {      try {        mSocket = mDevice.createRfcommSocketToServiceRecord(UUID.fromString("00001101-0000-1000-8000-00805F9B34FB"));        Message msg = new Message();        msg.obj = "請稍候,正在連接服務器:" + BluetoothActivity.BlueToothAddress;        msg.what = STATUS_CONNECT;        mHandler.sendMessage(msg);        mSocket.connect();        msg = new Message();        msg.obj = "已經連接上服務端!可以發送信息。";        msg.what = STATUS_CONNECT;        mHandler.sendMessage(msg);        // 啟動接受數據        mReadThread = new ReadThread();        mReadThread.start();      } catch (IOException e) {        Message msg = new Message();        msg.obj = "連接服務端異常!斷開連接重新試一試。";        msg.what = STATUS_CONNECT;        mHandler.sendMessage(msg);      }    }  };  // 開啟服務器  private class ServerThread extends Thread {    public void run() {      try {        // 創建一個藍牙服務器 參數分別:服務器名稱、UUID        mServerSocket = mBluetoothAdapter.listenUsingRfcommWithServiceRecord(PROTOCOL_SCHEME_RFCOMM,            UUID.fromString("00001101-0000-1000-8000-00805F9B34FB"));        Message msg = new Message();        msg.obj = "請稍候,正在等待客戶端的連接...";        msg.what = STATUS_CONNECT;        mHandler.sendMessage(msg);        /* 接受客戶端的連接請求 */        mSocket = mServerSocket.accept();        msg = new Message();        msg.obj = "客戶端已經連接上!可以發送信息。";        msg.what = STATUS_CONNECT;        mHandler.sendMessage(msg);        // 啟動接受數據        mReadThread = new ReadThread();        mReadThread.start();      } catch (IOException e) {        e.printStackTrace();      }    }  };  /* 停止服務器 */  private void shutdownServer() {    new Thread() {      public void run() {        if (mServerThread != null) {          mServerThread.interrupt();          mServerThread = null;        }        if (mReadThread != null) {          mReadThread.interrupt();          mReadThread = null;        }        try {          if (mSocket != null) {            mSocket.close();            mSocket = null;          }          if (mServerSocket != null) {            mServerSocket.close();            mServerSocket = null;          }        } catch (IOException e) {          Log.e("server", "mserverSocket.close()", e);        }      };    }.start();  }  /* ͣ停止客戶端連接 */  private void shutdownClient() {    new Thread() {      public void run() {        if (mClientThread != null) {          mClientThread.interrupt();          mClientThread = null;        }        if (mReadThread != null) {          mReadThread.interrupt();          mReadThread = null;        }        if (mSocket != null) {          try {            mSocket.close();          } catch (IOException e) {            e.printStackTrace();          }          mSocket = null;        }      };    }.start();  }  // 發送數據  private void sendMessageHandle(String msg) {    if (mSocket == null) {      Toast.makeText(this, "沒有連接", Toast.LENGTH_SHORT).show();      return;    }    try {      OutputStream os = mSocket.getOutputStream();      os.write(msg.getBytes());      mDatas.add(new DeviceBean(msg, false));      mAdapter.notifyDataSetChanged();      mListView.setSelection(mDatas.size() - 1);    } catch (IOException e) {      e.printStackTrace();    }  }  // 讀取數據  private class ReadThread extends Thread {    public void run() {      byte[] buffer = new byte[1024];      int bytes;      InputStream is = null;      try {        is = mSocket.getInputStream();        while (true) {          if ((bytes = is.read(buffer)) > 0) {            byte[] buf_data = new byte[bytes];            for (int i = 0; i < bytes; i++) {              buf_data[i] = buffer[i];            }            String s = new String(buf_data);            Message msg = new Message();            msg.obj = s;            msg.what = 1;            mHandler.sendMessage(msg);          }        }      } catch (IOException e1) {        e1.printStackTrace();      } finally {        try {          is.close();        } catch (IOException e1) {          e1.printStackTrace();        }      }    }  }  @Override  public void onItemClick(AdapterView<?> parent, View view, int position, long id) {  }  @Override  public void onClick(View view) {  }  @Override  protected void onDestroy() {    super.onDestroy();    if (BluetoothActivity.mType == Type.CILENT) {      shutdownClient();    } else if (BluetoothActivity.mType == Type.SERVICE) {      shutdownServer();    }    BluetoothActivity.isOpen = false;    BluetoothActivity.mType = Type.NONE;  }}

三、相關代碼下載

demo下載:http://xiazai.VeVB.COm/201701/yuanma/App_BlueTooth_jb51.rar

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持武林網。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 淮阳县| 汉中市| 霸州市| 湟中县| 尼玛县| 于田县| 普格县| 扎囊县| 从化市| 抚顺县| 凤山县| 宽城| 乌拉特中旗| 尼勒克县| 清流县| 汕头市| 通山县| 木兰县| 北安市| 凤庆县| 沙洋县| 和顺县| 万州区| 福清市| 兴安盟| 红河县| 合水县| 科技| 紫阳县| 鸡泽县| 武夷山市| 佛坪县| 祁东县| 临沂市| 永仁县| 杭州市| 泌阳县| 丹寨县| 彩票| 南和县| 扎鲁特旗|