android-蓝牙

  1. 安卓 整型转字符串 String s = Integer.toString(i);

    安卓 蓝牙串口 UUID 00001101-0000-1000-8000-00805F9B34FB

  2. <?xml version="1.0" encoding="utf-8"?>  
  3. <!-- Copyright (C) 2009 The Android Open Source Project   
  4.      Licensed under the Apache License, Version 2.0 (the "License");   
  5.      you may not use this file except in compliance with the License.   
  6.      You may obtain a copy of the License at   
  7.           http://www.apache.org/licenses/LICENSE-2.0   
  8.      Unless required by applicable law or agreed to in writing, software   
  9.      distributed under the License is distributed on an "AS IS" BASIS,   
  10.      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.   
  11.      See the License for the specific language governing permissions and   
  12.      limitations under the License.   
  13. -->  
  14. <manifest xmlns:android="http://schemas.android.com/apk/res/android"  
  15.       package="com.example.android.BluetoothChat"  
  16.       android:versionCode="1"  
  17.       android:versionName="1.0">  
  18.     <uses-sdk minSdkVersion="6" />  
  19.     <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />  
  20.     <uses-permission android:name="android.permission.BLUETOOTH" />  
  21.     <!-- 获取权限BlueTooth-->  
  22.     <application android:label="@string/app_name"  
  23.                  android:icon="@drawable/app_icon" >  
  24.         <activity android:name=".BluetoothChat"  
  25.                   android:label="@string/app_name"  
  26.                   android:configChanges="orientation|keyboardHidden">  
  27.             <intent-filter>  
  28.                 <action android:name="android.intent.action.MAIN" />  
  29.                 <category android:name="android.intent.category.LAUNCHER" />  
  30.             </intent-filter>  
  31.         </activity>  
  32.         <activity android:name=".DeviceListActivity"  
  33.                   android:label="@string/select_device"  
  34.                   android:theme="@android:style/Theme.Dialog"                 
  35.                   android:configChanges="orientation|keyboardHidden" />  
  36.                       <!-- android:theme="@android:style/Theme.Dialog" 设置界面主题:弹出框主题 -->  
  37.     </application>  
  38. </manifest>  
  39. package com.example.android.BluetoothChat;   
  40. import android.app.Activity;   
  41. import android.bluetooth.BluetoothAdapter;   
  42. import android.bluetooth.BluetoothDevice;   
  43. import android.content.Intent;   
  44. import android.os.Bundle;   
  45. import android.os.Handler;   
  46. import android.os.Message;   
  47. import android.util.Log;   
  48. import android.view.KeyEvent;   
  49. import android.view.Menu;   
  50. import android.view.MenuInflater;   
  51. import android.view.MenuItem;   
  52. import android.view.View;   
  53. import android.view.Window;   
  54. import android.view.View.OnClickListener;   
  55. import android.view.inputmethod.EditorInfo;   
  56. import android.widget.ArrayAdapter;   
  57. import android.widget.Button;   
  58. import android.widget.EditText;   
  59. import android.widget.ListView;   
  60. import android.widget.TextView;   
  61. import android.widget.Toast;   
  62. /**  
  63.  * This is the main Activity that displays the current chat session. 
  64.  */  
  65. public class BluetoothChat extends Activity {   
  66.     // Debugging   
  67.     private static final String TAG = "BluetoothChat";   
  68.     private static final boolean D = true;   
  69.     // Message types sent from the BluetoothChatService Handler  
  70.     public static final int MESSAGE_STATE_CHANGE = 1;   
  71.     public static final int MESSAGE_READ = 2;   
  72.     public static final int MESSAGE_WRITE = 3;   
  73.     public static final int MESSAGE_DEVICE_NAME = 4;   
  74.     public static final int MESSAGE_TOAST = 5;   
  75.     // Key names received from the BluetoothChatService Handler  
  76.     public static final String DEVICE_NAME = "device_name";   
  77.     public static final String TOAST = "toast";   
  78.     // Intent request codes   
  79.     private static final int REQUEST_CONNECT_DEVICE = 1;   
  80.     private static final int REQUEST_ENABLE_BT = 2;   
  81.     // Layout Views   
  82.     private TextView mTitle;   
  83.     private ListView mConversationView;   
  84.     private EditText mOutEditText;   
  85.     private Button mSendButton;   
  86.     // Name of the connected device   
  87.     private String mConnectedDeviceName = null;   
  88.     // Array adapter for the conversation thread   
  89.     private ArrayAdapter<String> mConversationArrayAdapter;   
  90.     // String buffer for outgoing messages   
  91.     private StringBuffer mOutStringBuffer;   
  92.     // Local Bluetooth adapter   
  93.     private BluetoothAdapter mBluetoothAdapter = null;   
  94.     // Member object for the chat services   
  95.     private BluetoothChatService mChatService = null;   
  96.   
  97.     @Override  
  98.     public void onCreate(Bundle savedInstanceState) {   
  99.         super.onCreate(savedInstanceState);   
  100.         if(D) Log.e(TAG, "+++ ON CREATE +++");   
  101.         // Set up the window layout 设置Activity的标题栏格式Window.FEATURE_CUSTOM_TITLE普通、Window.FEATURE_NO_TITLE无标题栏、Window.FEATURE_INDETERMINATE_PROGRESS进度条  
  102.         requestWindowFeature(Window.FEATURE_CUSTOM_TITLE);   
  103.         setContentView(R.layout.main);   
  104.         //设置标题栏的布局资源   
  105.         getWindow().setFeatureInt(Window.FEATURE_CUSTOM_TITLE, R.layout.custom_title);   
  106.            
  107.         // Set up the custom title   
  108.         mTitle = (TextView) findViewById(R.id.title_left_text);   
  109.         mTitle.setText(R.string.app_name);   
  110.         mTitle = (TextView) findViewById(R.id.title_right_text);   
  111.         // Get local Bluetooth adapter   
  112.        //从根本上讲,这是你的出发点,所有的蓝牙行动。一旦你的本地适配器,getBondedDevices()所有配对设备对象设置;  
  113.         //与startDiscovery()启动设备可被发现,或建立一个BluetoothServerSocket监听与listenUsingRfcommWithServiceRecord(字符串,UUID的)传入的连接请求。  
  114.         mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();   
  115.         // If the adapter is null, then Bluetooth is not supported  
  116.         if (mBluetoothAdapter == null) {   
  117.             Toast.makeText(this, "Bluetooth is not available", Toast.LENGTH_LONG).show();   
  118.             finish();   
  119.             return;   
  120.         }   
  121.     }   
  122.     @Override  
  123.     public void onStart() {   
  124.         super.onStart();   
  125.         if(D) Log.e(TAG, "++ ON START ++");   
  126.         // If BT is not on, request that it be enabled.   
  127.         // setupChat() will then be called during onActivityResult  
  128.         //判断蓝牙是否开启,否则请求开启   
  129.         if (!mBluetoothAdapter.isEnabled()) {   
  130.             Intent enableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);   
  131.             startActivityForResult(enableIntent, REQUEST_ENABLE_BT);   
  132.         // Otherwise, setup the chat session   
  133.         } else {   
  134.             if (mChatService == null) setupChat();   
  135.         }   
  136.     }   
  137.     @Override  
  138.     public synchronized void onResume() {   
  139.         super.onResume();   
  140.         if(D) Log.e(TAG, "+ ON RESUME +");   
  141.         // Performing this check in onResume() covers the case in which BT was  
  142.         // not enabled during onStart(), so we were paused to enable it...  
  143.         // onResume() will be called when ACTION_REQUEST_ENABLE activity returns.  
  144.         if (mChatService != null) {   
  145.             // Only if the state is STATE_NONE, do we know that we haven't started already  
  146.             if (mChatService.getState() == BluetoothChatService.STATE_NONE) { //STATE_NONE及刚创建为启动状态,如果是从后台切换到前台应为STATE_LISTEN,无需再次启动  
  147.               // Start the Bluetooth chat services    
  148.               mChatService.start();   
  149.             }   
  150.         }   
  151.     }   
  152.     private void setupChat() {   
  153.         Log.d(TAG, "setupChat()");   
  154.         // Initialize the array adapter for the conversation thread   
  155.         mConversationArrayAdapter = new ArrayAdapter<String>(this, R.layout.message);   
  156.         mConversationView = (ListView) findViewById(R.id.in);   
  157.         mConversationView.setAdapter(mConversationArrayAdapter);   
  158.         // Initialize the compose field with a listener for the return key  
  159.         mOutEditText = (EditText) findViewById(R.id.edit_text_out);   
  160.         mOutEditText.setOnEditorActionListener(mWriteListener);注册编辑状态监听  
  161.         // Initialize the send button with a listener that for click events  
  162.         mSendButton = (Button) findViewById(R.id.button_send);   
  163.         mSendButton.setOnClickListener(new OnClickListener() {   
  164.             public void onClick(View v) {   
  165.                 // Send a message using content of the edit text widget  
  166.                 TextView view = (TextView) findViewById(R.id.edit_text_out);   
  167.                 String message = view.getText().toString();   
  168.                 sendMessage(message); //点击发送则向蓝牙发送消息   
  169.             }   
  170.         });   
  171.         // Initialize the BluetoothChatService to perform bluetooth connections  
  172.         mChatService = new BluetoothChatService(this, mHandler);   
  173.         // Initialize the buffer for outgoing messages   
  174.         mOutStringBuffer = new StringBuffer("");   
  175.     }   
  176.     @Override  
  177.     public synchronized void onPause() {   
  178.         super.onPause();   
  179.         if(D) Log.e(TAG, "- ON PAUSE -");   
  180.     }   
  181.     @Override  
  182.     public void onStop() {   
  183.         super.onStop();   
  184.         if(D) Log.e(TAG, "-- ON STOP --");   
  185.     }   
  186.     @Override  
  187.     public void onDestroy() {   
  188.         super.onDestroy();   
  189.         // Stop the Bluetooth chat services   
  190.         if (mChatService != null) mChatService.stop(); //UI关闭时,蓝牙服务应也停止  
  191.         if(D) Log.e(TAG, "--- ON DESTROY ---");   
  192.     }   
  193.     private void ensureDiscoverable() {   
  194.         if(D) Log.d(TAG, "ensure discoverable");   
  195.         if (mBluetoothAdapter.getScanMode() !=   
  196.             BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE) { //如果蓝牙状态为不可被发现则请求开启为可被发现,时间300秒内  
  197.             Intent discoverableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);   
  198.             discoverableIntent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 300);   
  199.             startActivity(discoverableIntent);   
  200.         }   
  201.     }   
  202.     /**  
  203.      * Sends a message.  
  204.      * @param message  A string of text to send.  
  205.      */  
  206.     private void sendMessage(String message) {   
  207.         // Check that we're actually connected before trying anything  
  208.         if (mChatService.getState() != BluetoothChatService.STATE_CONNECTED) {   
  209.             Toast.makeText(this, R.string.not_connected, Toast.LENGTH_SHORT).show();   
  210.             return;   
  211.         }   
  212.         // Check that there's actually something to send   
  213.         if (message.length() > 0) {   
  214.             // Get the message bytes and tell the BluetoothChatService to write  
  215.             byte[] send = message.getBytes();   
  216.             mChatService.write(send);   
  217.             // Reset out string buffer to zero and clear the edit text field  
  218.             mOutStringBuffer.setLength(0); //mOutStringBuffer 一直未使用,何意?  
  219.             mOutEditText.setText(mOutStringBuffer);//清空编辑框 窃以为使用mOutEditText.setText("");即可  
  220.         }   
  221.     }   
  222.     // The action listener for the EditText widget, to listen for the return key  
  223.     private TextView.OnEditorActionListener mWriteListener =   
  224.         new TextView.OnEditorActionListener() {   
  225.         public boolean onEditorAction(TextView view, int actionId, KeyEvent event) {   
  226.             // If the action is a key-up event on the return key, send the message   
  227.             //经测试应为点击回车键后放开时发送消息   
  228.             if (actionId == EditorInfo.IME_NULL && event.getAction() == KeyEvent.ACTION_UP) {   
  229.                 String message = view.getText().toString();   
  230.                 sendMessage(message);   
  231.             }   
  232.             if(D) Log.i(TAG, "END onEditorAction");   
  233.             return true;   
  234.         }   
  235.     };   
  236.     // The Handler that gets information back from the BluetoothChatService  
  237.     //更新标题栏右边状态和读写状态的Handler   
  238.     private final Handler mHandler = new Handler() {   
  239.         @Override  
  240.         public void handleMessage(Message msg) {   
  241.             switch (msg.what) {   
  242.             case MESSAGE_STATE_CHANGE:   
  243.                 if(D) Log.i(TAG, "MESSAGE_STATE_CHANGE: " + msg.arg1);   
  244.                 switch (msg.arg1) {   
  245.                 case BluetoothChatService.STATE_CONNECTED:   
  246.                     mTitle.setText(R.string.title_connected_to);   
  247.                     mTitle.append(mConnectedDeviceName);   
  248.                     mConversationArrayAdapter.clear(); //清空消息  
  249.                     break;   
  250.                 case BluetoothChatService.STATE_CONNECTING:   
  251.                     mTitle.setText(R.string.title_connecting);   
  252.                     break;   
  253.                 case BluetoothChatService.STATE_LISTEN:   
  254.                 case BluetoothChatService.STATE_NONE:   
  255.                     mTitle.setText(R.string.title_not_connected);   
  256.                     break;   
  257.                 }   
  258.                 break;   
  259.             case MESSAGE_WRITE:   
  260.                 byte[] writeBuf = (byte[]) msg.obj;   
  261.                 // construct a string from the buffer   
  262.                 String writeMessage = new String(writeBuf);   
  263.                 mConversationArrayAdapter.add("Me:  " + writeMessage);   
  264.                 break;   
  265.             case MESSAGE_READ:   
  266.                 byte[] readBuf = (byte[]) msg.obj;   
  267.                 // construct a string from the valid bytes in the buffer  
  268.                 String readMessage = new String(readBuf, 0, msg.arg1);   
  269.                 mConversationArrayAdapter.add(mConnectedDeviceName+":  " + readMessage);   
  270.                 break;   
  271.             case MESSAGE_DEVICE_NAME:   
  272.                 // save the connected device's name   
  273.                 mConnectedDeviceName = msg.getData().getString(DEVICE_NAME);   
  274.                 Toast.makeText(getApplicationContext(), "Connected to "  
  275.                                + mConnectedDeviceName, Toast.LENGTH_SHORT).show();   
  276.                 break;   
  277.             case MESSAGE_TOAST:   
  278.                 Toast.makeText(getApplicationContext(), msg.getData().getString(TOAST),   
  279.                                Toast.LENGTH_SHORT).show();   
  280.                 break;   
  281.             }   
  282.         }   
  283.     };   
  284.     public void onActivityResult(int requestCode, int resultCode, Intent data) {   
  285.         if(D) Log.d(TAG, "onActivityResult " + resultCode);   
  286.         switch (requestCode) {   
  287.         case REQUEST_CONNECT_DEVICE:   
  288.             // When DeviceListActivity returns with a device to connect  
  289.             if (resultCode == Activity.RESULT_OK) {   
  290.                 // Get the device MAC address   
  291.                 String address = data.getExtras()   
  292.                                      .getString(DeviceListActivity.EXTRA_DEVICE_ADDRESS);   
  293.                 // Get the BLuetoothDevice object   
  294.                 if(address==null){   
  295.                     break;   
  296.                 }   
  297.                 //获取设备进行连接   
  298.                 BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(address);   
  299.                 // Attempt to connect to the device   
  300.                 mChatService.connect(device);   
  301.             }   
  302.             break;   
  303.         case REQUEST_ENABLE_BT:   
  304.             // When the request to enable Bluetooth returns  
  305.             if (resultCode == Activity.RESULT_OK) {   
  306.                 // Bluetooth is now enabled, so set up a chat session  
  307.                 //蓝牙开启成功,则继续初始化UI   
  308.                 setupChat();   
  309.             } else {   
  310.                 // User did not enable Bluetooth or an error occured  
  311.                 Log.d(TAG, "BT not enabled");   
  312.                 Toast.makeText(this, R.string.bt_not_enabled_leaving, Toast.LENGTH_SHORT).show();   
  313.                 finish();   
  314.             }   
  315.         }   
  316.     }   
  317.     @Override  
  318.     public boolean onCreateOptionsMenu(Menu menu) {   
  319.         //从Menu资源中初始化Menu 返回true则弹出默认menu,false则不弹出Menu,须自定义  
  320.         MenuInflater inflater = getMenuInflater();   
  321.         inflater.inflate(R.menu.option_menu, menu);   
  322.         return true;    
  323.     }   
  324.     @Override  
  325.     public boolean onOptionsItemSelected(MenuItem item) {   
  326.         switch (item.getItemId()) {   
  327.         case R.id.scan:   
  328.             // Launch the DeviceListActivity to see devices and do scan  
  329.             //启动DeviceListActivity,并等待返回   
  330.             Intent serverIntent = new Intent(this, DeviceListActivity.class);   
  331.             startActivityForResult(serverIntent, REQUEST_CONNECT_DEVICE);   
  332.             return true;   
  333.         case R.id.discoverable:   
  334.             // Ensure this device is discoverable by others  
  335.             ensureDiscoverable();   
  336.             return true;   
  337.         }   
  338.         return false;   
  339.     }   
  340. }  
        
  1. package com.example.android.BluetoothChat;   
  2. import java.util.Set;   
  3. import android.app.Activity;   
  4. import android.bluetooth.BluetoothAdapter;   
  5. import android.bluetooth.BluetoothDevice;   
  6. import android.content.BroadcastReceiver;   
  7. import android.content.Context;   
  8. import android.content.Intent;   
  9. import android.content.IntentFilter;   
  10. import android.os.Bundle;   
  11. import android.util.Log;   
  12. import android.view.View;   
  13. import android.view.Window;   
  14. import android.view.View.OnClickListener;   
  15. import android.widget.AdapterView;   
  16. import android.widget.ArrayAdapter;   
  17. import android.widget.Button;   
  18. import android.widget.ListView;   
  19. import android.widget.TextView;   
  20. import android.widget.AdapterView.OnItemClickListener;   
  21. /**  
  22.  * This Activity appears as a dialog. It lists any paired devices and 
  23.  * devices detected in the area after discovery. When a device is chosen 
  24.  * by the user, the MAC address of the device is sent back to the parent 
  25.  * Activity in the result Intent.  
  26.  */  
  27. public class DeviceListActivity extends Activity {   
  28.     // Debugging   
  29.     private static final String TAG = "DeviceListActivity";   
  30.     private static final boolean D = true;   
  31.     // Return Intent extra   
  32.     public static String EXTRA_DEVICE_ADDRESS = "device_address";   
  33.     // Member fields   
  34.     private BluetoothAdapter mBtAdapter;   
  35.     private ArrayAdapter<String> mPairedDevicesArrayAdapter;   
  36.     private ArrayAdapter<String> mNewDevicesArrayAdapter;   
  37.     @Override  
  38.     protected void onCreate(Bundle savedInstanceState) {   
  39.         super.onCreate(savedInstanceState);   
  40.         // Setup the window   
  41.         requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);   
  42.         setContentView(R.layout.device_list);   
  43.         // Set result CANCELED incase the user backs out   
  44.         //先设置为Canceled 防止点击回退键时BluetoothChat认为是Result_OK状态  
  45.         setResult(Activity.RESULT_CANCELED);   
  46.         // Initialize the button to perform device discovery  
  47.         Button scanButton = (Button) findViewById(R.id.button_scan);   
  48.         scanButton.setOnClickListener(new OnClickListener() {   
  49.             public void onClick(View v) {   
  50.                 doDiscovery();   
  51.                 v.setVisibility(View.GONE);   
  52.             }   
  53.         });   
  54.         // Initialize array adapters. One for already paired devices and  
  55.         // one for newly discovered devices   
  56.         mPairedDevicesArrayAdapter = new ArrayAdapter<String>(this, R.layout.device_name);   
  57.         mNewDevicesArrayAdapter = new ArrayAdapter<String>(this, R.layout.device_name);   
  58.         // Find and set up the ListView for paired devices  
  59.         ListView pairedListView = (ListView) findViewById(R.id.paired_devices);   
  60.         pairedListView.setAdapter(mPairedDevicesArrayAdapter);   
  61.         pairedListView.setOnItemClickListener(mDeviceClickListener);   
  62.         // Find and set up the ListView for newly discovered devices  
  63.         ListView newDevicesListView = (ListView) findViewById(R.id.new_devices);   
  64.         newDevicesListView.setAdapter(mNewDevicesArrayAdapter);   
  65.         newDevicesListView.setOnItemClickListener(mDeviceClickListener);   
  66.         // Register for broadcasts when a device is discovered 发现设备时监听过滤  
  67.         IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);   
  68.         this.registerReceiver(mReceiver, filter);   
  69.         // Register for broadcasts when discovery has finished发现设备程序运行结束时监听过滤  
  70.         filter = new IntentFilter(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);   
  71.         this.registerReceiver(mReceiver, filter);   
  72.         // Get the local Bluetooth adapter   
  73.         mBtAdapter = BluetoothAdapter.getDefaultAdapter();   
  74.         // Get a set of currently paired devices 获取当前已经互联过的设备  
  75.         Set<BluetoothDevice> pairedDevices = mBtAdapter.getBondedDevices();   
  76.         // If there are paired devices, add each one to the ArrayAdapter  
  77.         if (pairedDevices.size() > 0) {   
  78.             findViewById(R.id.title_paired_devices).setVisibility(View.VISIBLE);    
  79.             for (BluetoothDevice device : pairedDevices) {   
  80.                 mPairedDevicesArrayAdapter.add(device.getName() + "\n" + device.getAddress());   
  81.             }   
  82.         } else {   
  83.             String noDevices = getResources().getText(R.string.none_paired).toString();   
  84.             mPairedDevicesArrayAdapter.add(noDevices);   
  85.         }   
  86.     }   
  87.     @Override  
  88.     protected void onDestroy() {   
  89.         super.onDestroy();   
  90.         // Make sure we're not doing discovery anymore   
  91.         if (mBtAdapter != null) {   
  92.             mBtAdapter.cancelDiscovery(); //BluetoothAdapter 不受UI管理受系统管理,所以要即使cancelDiscovery  
  93.         }   
  94.         // Unregister broadcast listeners   
  95.         this.unregisterReceiver(mReceiver); //取消监听当UI销毁时  
  96.     }   
  97.     /**  
  98.      * Start device discover with the BluetoothAdapter  
  99.      */  
  100.     private void doDiscovery() {   
  101.         if (D) Log.d(TAG, "doDiscovery()");   
  102.         // Indicate scanning in the title 设置标题加载loading条可见  
  103.         setProgressBarIndeterminateVisibility(true);    
  104.         setTitle(R.string.scanning); //设置标题   
  105.         // Turn on sub-title for new devices   
  106.         findViewById(R.id.title_new_devices).setVisibility(View.VISIBLE);   
  107.         // If we're already discovering, stop it   
  108.         if (mBtAdapter.isDiscovering()) {   
  109.             mBtAdapter.cancelDiscovery();    
  110.         }   
  111.         // Request discover from BluetoothAdapter   
  112.         mBtAdapter.startDiscovery();   
  113.     }   
  114.     // The on-click listener for all devices in the ListViews 点击蓝牙列表的监听  
  115.     private OnItemClickListener mDeviceClickListener = new OnItemClickListener() {   
  116.         public void onItemClick(AdapterView<?> av, View v, int arg2, long arg3) {   
  117.             // Cancel discovery because it's costly and we're about to connect  
  118.             mBtAdapter.cancelDiscovery();    
  119.             // Get the device MAC address, which is the last 17 chars in the View IP地址17位  
  120.             String info = ((TextView) v).getText().toString();   
  121.             String address = info.substring(info.length() - 17);   
  122.             // Create the result Intent and include the MAC address  
  123.             Intent intent = new Intent();   
  124.             intent.putExtra(EXTRA_DEVICE_ADDRESS, address);   
  125.             // Set result and finish this Activity   
  126.             setResult(Activity.RESULT_OK, intent);   
  127.             finish();   
  128.         }   
  129.     };   
  130.     // The BroadcastReceiver that listens for discovered devices and  
  131.     // changes the title when discovery is finished   
  132.     private final BroadcastReceiver mReceiver = new BroadcastReceiver() {   
  133.         @Override  
  134.         public void onReceive(Context context, Intent intent) {   
  135.             String action = intent.getAction();   
  136.             // When discovery finds a device 搜索到设备   
  137.             if (BluetoothDevice.ACTION_FOUND.equals(action)) {   
  138.                 // Get the BluetoothDevice object from the Intent  
  139.                 BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);   
  140.                 // If it's already paired, skip it, because it's been listed already  
  141.                 if (device.getBondState() != BluetoothDevice.BOND_BONDED) {   
  142.                     mNewDevicesArrayAdapter.add(device.getName() + "\n" + device.getAddress());   
  143.                 }   
  144.             // When discovery is finished, change the Activity title  
  145.             } else if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)) {    
  146.                 setProgressBarIndeterminateVisibility(false);//搜索完毕,loading条不可见  
  147.                 setTitle(R.string.select_device);   
  148.                 if (mNewDevicesArrayAdapter.getCount() == 0) {   
  149.                     String noDevices = getResources().getText(R.string.none_found).toString();   
  150.                     mNewDevicesArrayAdapter.add(noDevices);   
  151.                 }   
  152.             }   
  153.         }   
  154.     };   
  155. }  
  156.  
  157. package com.example.android.BluetoothChat;   
  158. import java.io.IOException;   
  159. import java.io.InputStream;   
  160. import java.io.OutputStream;   
  161. import java.util.UUID;   
  162. import android.bluetooth.BluetoothAdapter;   
  163. import android.bluetooth.BluetoothDevice;   
  164. import android.bluetooth.BluetoothServerSocket;   
  165. import android.bluetooth.BluetoothSocket;   
  166. import android.content.Context;   
  167. import android.os.Bundle;   
  168. import android.os.Handler;   
  169. import android.os.Message;   
  170. import android.util.Log;   
  171. /**  
  172.  * This class does all the work for setting up and managing Bluetooth 
  173.  * connections with other devices. It has a thread that listens for 
  174.  * incoming connections, a thread for connecting with a device, and a 
  175.  * thread for performing data transmissions when connected.  
  176.  */  
  177. public class BluetoothChatService {   
  178.     // Debugging   
  179.     private static final String TAG = "BluetoothChatService";   
  180.     private static final boolean D = true;   
  181.     // Name for the SDP record when creating server socket  
  182.     private static final String NAME = "BluetoothChat";   
  183.     // Unique UUID for this application   
  184.     private static final UUID MY_UUID = UUID.fromString("fa87c0d0-afac-11de-8a39-0800200c9a66");   
  185.     // Member fields   
  186.     private final BluetoothAdapter mAdapter;   
  187.     private final Handler mHandler;   
  188.     private AcceptThread mAcceptThread;   
  189.     private ConnectThread mConnectThread;   
  190.     private ConnectedThread mConnectedThread;   
  191.     private int mState;   
  192.     // Constants that indicate the current connection state  
  193.     public static final int STATE_NONE = 0;       // we're doing nothing  
  194.     public static final int STATE_LISTEN = 1;     // now listening for incoming connections  
  195.     public static final int STATE_CONNECTING = 2; // now initiating an outgoing connection  
  196.     public static final int STATE_CONNECTED = 3;  // now connected to a remote device  
  197.     /**  
  198.      * Constructor. Prepares a new BluetoothChat session.  
  199.      * @param context  The UI Activity Context  
  200.      * @param handler  A Handler to send messages back to the UI Activity 
  201.      */  
  202.     public BluetoothChatService(Context context, Handler handler) {   
  203.         mAdapter = BluetoothAdapter.getDefaultAdapter();   
  204.         mState = STATE_NONE;   
  205.         mHandler = handler;   
  206.     }   
  207.     /**  
  208.      * Set the current state of the chat connection  
  209.      * @param state  An integer defining the current connection state 
  210.      */  
  211.     private synchronized void setState(int state) {   
  212.         if (D) Log.d(TAG, "setState() " + mState + " -> " + state);   
  213.         mState = state;   
  214.         // Give the new state to the Handler so the UI Activity can update 更新状态,使用Handler向UI发送消息提示  
  215.         mHandler.obtainMessage(BluetoothChat.MESSAGE_STATE_CHANGE, state, -1).sendToTarget();   
  216.     }   
  217.     /**  
  218.      * Return the current connection state. */  
  219.     public synchronized int getState() {   
  220.         return mState;   
  221.     }   
  222.     /**  
  223.      * Start the chat service. Specifically start AcceptThread to begin a 
  224.      * session in listening (server) mode. Called by the Activity onResume() */  
  225.     public synchronized void start() {   
  226.         if (D) Log.d(TAG, "start");   
  227.         // Cancel any thread attempting to make a connection  
  228.         if (mConnectThread != null) {mConnectThread.cancel(); mConnectThread = null;}   
  229.         // Cancel any thread currently running a connection  
  230.         if (mConnectedThread != null) {mConnectedThread.cancel(); mConnectedThread = null;}   
  231.         // Start the thread to listen on a BluetoothServerSocket  
  232.         if (mAcceptThread == null) {   
  233.             mAcceptThread = new AcceptThread();   
  234.             mAcceptThread.start();   
  235.         }   
  236.         setState(STATE_LISTEN);   
  237.     }   
  238.     /**  
  239.      * Start the ConnectThread to initiate a connection to a remote device. 
  240.      * @param device  The BluetoothDevice to connect  
  241.      */  
  242.     public synchronized void connect(BluetoothDevice device) {   
  243.         if (D) Log.d(TAG, "connect to: " + device);   
  244.         // Cancel any thread attempting to make a connection  
  245.         if (mState == STATE_CONNECTING) {   
  246.             if (mConnectThread != null) {mConnectThread.cancel(); mConnectThread = null;}   
  247.         }   
  248.         // Cancel any thread currently running a connection  
  249.         if (mConnectedThread != null) {mConnectedThread.cancel(); mConnectedThread = null;}   
  250.         // Start the thread to connect with the given device 设置正在状态为正在连接  
  251.         mConnectThread = new ConnectThread(device);   
  252.         mConnectThread.start();   
  253.         setState(STATE_CONNECTING);   
  254.     }   
  255.     /**  
  256.      * Start the ConnectedThread to begin managing a Bluetooth connection 
  257.      * @param socket  The BluetoothSocket on which the connection was made 
  258.      * @param device  The BluetoothDevice that has been connected 
  259.      */  
  260.     public synchronized void connected(BluetoothSocket socket, BluetoothDevice device) {   
  261.         if (D) Log.d(TAG, "connected");   
  262.         // Cancel the thread that completed the connection  
  263.         if (mConnectThread != null) {mConnectThread.cancel(); mConnectThread = null;}   
  264.         // Cancel any thread currently running a connection  
  265.         if (mConnectedThread != null) {mConnectedThread.cancel(); mConnectedThread = null;}   
  266.         // Cancel the accept thread because we only want to connect to one device  
  267.         if (mAcceptThread != null) {mAcceptThread.cancel(); mAcceptThread = null;}   
  268.         // Start the thread to manage the connection and perform transmissions  
  269.         mConnectedThread = new ConnectedThread(socket);   
  270.         mConnectedThread.start();   
  271.         // Send the name of the connected device back to the UI Activity  
  272.         Message msg = mHandler.obtainMessage(BluetoothChat.MESSAGE_DEVICE_NAME);   
  273.         Bundle bundle = new Bundle();   
  274.         bundle.putString(BluetoothChat.DEVICE_NAME, device.getName());   
  275.         msg.setData(bundle);   
  276.         mHandler.sendMessage(msg);   
  277.         setState(STATE_CONNECTED);   
  278.     }   
  279.     /**  
  280.      * Stop all threads  
  281.      */  
  282.     public synchronized void stop() {   
  283.         if (D) Log.d(TAG, "stop");   
  284.         if (mConnectThread != null) {mConnectThread.cancel(); mConnectThread = null;}   
  285.         if (mConnectedThread != null) {mConnectedThread.cancel(); mConnectedThread = null;}   
  286.         if (mAcceptThread != null) {mAcceptThread.cancel(); mAcceptThread = null;}   
  287.         setState(STATE_NONE);   
  288.     }   
  289.     /**  
  290.      * Write to the ConnectedThread in an unsynchronized manner  
  291.      * @param out The bytes to write  
  292.      * @see ConnectedThread#write(byte[])  
  293.      */  
  294.     public void write(byte[] out) {   
  295.         // Create temporary object   
  296.         ConnectedThread r;   
  297.         // Synchronize a copy of the ConnectedThread   
  298.         synchronized (this) {   
  299.             if (mState != STATE_CONNECTED) return;   
  300.             r = mConnectedThread;   
  301.         }   
  302.         // Perform the write unsynchronized   
  303.         r.write(out);   
  304.     }   
  305.     /**  
  306.      * Indicate that the connection attempt failed and notify the UI Activity. 
  307.      */  
  308.     private void connectionFailed() {   
  309.         setState(STATE_LISTEN);   
  310.         // Send a failure message back to the Activity更新状态,使用Handler向UI发送消息提示  
  311.         Message msg = mHandler.obtainMessage(BluetoothChat.MESSAGE_TOAST);   
  312.         Bundle bundle = new Bundle();   
  313.         bundle.putString(BluetoothChat.TOAST, "Unable to connect device");   
  314.         msg.setData(bundle);   
  315.         mHandler.sendMessage(msg);   
  316.     }   
  317.     /**  
  318.      * Indicate that the connection was lost and notify the UI Activity. 
  319.      */  
  320.     private void connectionLost() {   
  321.         setState(STATE_LISTEN);   
  322.         // Send a failure message back to the Activity更新状态,使用Handler向UI发送消息提示  
  323.         Message msg = mHandler.obtainMessage(BluetoothChat.MESSAGE_TOAST);   
  324.         Bundle bundle = new Bundle();   
  325.         bundle.putString(BluetoothChat.TOAST, "Device connection was lost");   
  326.         msg.setData(bundle);   
  327.         mHandler.sendMessage(msg);   
  328.     }   
  329.     /**  
  330.      * This thread runs while listening for incoming connections. It behaves 
  331.      * like a server-side client. It runs until a connection is accepted 
  332.      * (or until cancelled).  
  333.      */  
  334.     private class AcceptThread extends Thread {   
  335.         // The local server socket   
  336.         private final BluetoothServerSocket mmServerSocket;   
  337.         public AcceptThread() {   
  338.             BluetoothServerSocket tmp = null;   
  339.             // Create a new listening server socket   
  340.             try {   
  341.                 tmp = mAdapter.listenUsingRfcommWithServiceRecord(NAME, MY_UUID);   
  342.             } catch (IOException e) {   
  343.                 Log.e(TAG, "listen() failed", e);   
  344.             }   
  345.             mmServerSocket = tmp;   
  346.         }   
  347.         public void run() {   
  348.             if (D) Log.d(TAG, "BEGIN mAcceptThread" + this);   
  349.             setName("AcceptThread");   
  350.             BluetoothSocket socket = null;   
  351.             // Listen to the server socket if we're not connected 不断监听是否有蓝牙连接请求  
  352.             while (mState != STATE_CONNECTED) {    
  353.                 try {   
  354.                     // This is a blocking call and will only return on a  
  355.                     // successful connection or an exception  
  356.                     socket = mmServerSocket.accept();   
  357.                 } catch (IOException e) {   
  358.                     Log.e(TAG, "accept() failed", e);   
  359.                     break;   
  360.                 }   
  361.                 // If a connection was accepted   
  362.                 if (socket != null) {   
  363.                     synchronized (BluetoothChatService.this) {   
  364.                         switch (mState) {   
  365.                         case STATE_LISTEN:   
  366.                         case STATE_CONNECTING:   
  367.                             // Situation normal. Start the connected thread. 当有连接请求且状态是正在连接时  
  368.                             connected(socket, socket.getRemoteDevice());   
  369.                             break;   
  370.                         case STATE_NONE:   
  371.                         case STATE_CONNECTED:   
  372.                             // Either not ready or already connected. Terminate new socket.  
  373.                             try {   
  374.                                 socket.close();   
  375.                             } catch (IOException e) {   
  376.                                 Log.e(TAG, "Could not close unwanted socket", e);   
  377.                             }   
  378.                             break;   
  379.                         }   
  380.                     }   
  381.                 }   
  382.             }   
  383.             if (D) Log.i(TAG, "END mAcceptThread");   
  384.         }   
  385.         public void cancel() {   
  386.             if (D) Log.d(TAG, "cancel " + this);   
  387.             try {   
  388.                 mmServerSocket.close();   
  389.             } catch (IOException e) {   
  390.                 Log.e(TAG, "close() of server failed", e);   
  391.             }   
  392.         }   
  393.     }   
  394.   
  395.     /**  
  396.      * This thread runs while attempting to make an outgoing connection 
  397.      * with a device. It runs straight through; the connection either 
  398.      * succeeds or fails.  
  399.      */  
  400.     private class ConnectThread extends Thread {   
  401.         private final BluetoothSocket mmSocket;   
  402.         private final BluetoothDevice mmDevice;   
  403.         public ConnectThread(BluetoothDevice device) {   
  404.             mmDevice = device;   
  405.             BluetoothSocket tmp = null;   
  406.             // Get a BluetoothSocket for a connection with the  
  407.             // given BluetoothDevice   
  408.             try {   
  409.                 tmp = device.createRfcommSocketToServiceRecord(MY_UUID);   
  410.             } catch (IOException e) {   
  411.                 Log.e(TAG, "create() failed", e);   
  412.             }   
  413.             mmSocket = tmp;   
  414.         }   
  415.         public void run() {   
  416.             Log.i(TAG, "BEGIN mConnectThread");   
  417.             setName("ConnectThread");   
  418.             // Always cancel discovery because it will slow down a connection  
  419.             mAdapter.cancelDiscovery();   
  420.             // Make a connection to the BluetoothSocket   
  421.             try {   
  422.                 // This is a blocking call and will only return on a  
  423.                 // successful connection or an exception   
  424.                 mmSocket.connect();   
  425.             } catch (IOException e) {   
  426.                 connectionFailed();   
  427.                 // Close the socket   
  428.                 try {   
  429.                     mmSocket.close();   
  430.                 } catch (IOException e2) {   
  431.                     Log.e(TAG, "unable to close() socket during connection failure", e2);   
  432.                 }   
  433.                 // Start the service over to restart listening mode  
  434.                 BluetoothChatService.this.start();   
  435.                 return;   
  436.             }   
  437.             // Reset the ConnectThread because we're done   
  438.             synchronized (BluetoothChatService.this) {   
  439.                 mConnectThread = null;   
  440.             }   
  441.             // Start the connected thread   
  442.             connected(mmSocket, mmDevice);   
  443.         }   
  444.         public void cancel() {   
  445.             try {   
  446.                 mmSocket.close();   
  447.             } catch (IOException e) {   
  448.                 Log.e(TAG, "close() of connect socket failed", e);   
  449.             }   
  450.         }   
  451.     }   
  452.     /**  
  453.      * This thread runs during a connection with a remote device. 
  454.      * It handles all incoming and outgoing transmissions.  
  455.      */  
  456.     private class ConnectedThread extends Thread {   
  457.         private final BluetoothSocket mmSocket;   
  458.         private final InputStream mmInStream;   
  459.         private final OutputStream mmOutStream;   
  460.         public ConnectedThread(BluetoothSocket socket) {   
  461.             Log.d(TAG, "create ConnectedThread");   
  462.             mmSocket = socket;   
  463.             InputStream tmpIn = null;   
  464.             OutputStream tmpOut = null;   
  465.             // Get the BluetoothSocket input and output streams  
  466.             try {   
  467.                 tmpIn = socket.getInputStream();   
  468.                 tmpOut = socket.getOutputStream();   
  469.             } catch (IOException e) {   
  470.                 Log.e(TAG, "temp sockets not created", e);   
  471.             }   
  472.             mmInStream = tmpIn;   
  473.             mmOutStream = tmpOut;   
  474.         }   
  475.         public void run() {   
  476.             Log.i(TAG, "BEGIN mConnectedThread");   
  477.             byte[] buffer = new byte[1024];   
  478.             int bytes;   
  479.             // Keep listening to the InputStream while connected  
  480.             while (true) {   
  481.                 try {   
  482.                     // Read from the InputStream    
  483.                     bytes = mmInStream.read(buffer);   
  484.                     // Send the obtained bytes to the UI Activity  
  485.                     mHandler.obtainMessage(BluetoothChat.MESSAGE_READ, bytes, -1, buffer)   
  486.                             .sendToTarget();   
  487.                 } catch (IOException e) {   
  488.                     Log.e(TAG, "disconnected", e);   
  489.                     connectionLost();   
  490.                     break;   
  491.                 }   
  492.             }   
  493.         }   
  494.         /**  
  495.          * Write to the connected OutStream.  
  496.          * @param buffer  The bytes to write  
  497.          */  
  498.         public void write(byte[] buffer) {   
  499.             try {   
  500.                 mmOutStream.write(buffer); //向对方写数据   
  501.                 // Share the sent message back to the UI Activity  
  502.                 mHandler.obtainMessage(BluetoothChat.MESSAGE_WRITE, -1, -1, buffer)   
  503.                         .sendToTarget();   
  504.             } catch (IOException e) {   
  505.                 Log.e(TAG, "Exception during write", e);   
  506.             }   
  507.         }   
  508.         public void cancel() {   
  509.             try {   
  510.                 mmSocket.close();   
  511.             } catch (IOException e) {   
  512.                 Log.e(TAG, "close() of connect socket failed", e);   
  513.             }   
  514.         }   
  515.     }   
  516. }     

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值