BluetoothChat.java
上传用户:hollekit
上传日期:2021-04-23
资源大小:91k
文件大小:13k
源码类别:

android开发

开发平台:

Java

  1. /*
  2.  * Copyright (C) 2009 The Android Open Source Project
  3.  *
  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.  *
  8.  *      http://www.apache.org/licenses/LICENSE-2.0
  9.  *
  10.  * Unless required by applicable law or agreed to in writing, software
  11.  * distributed under the License is distributed on an "AS IS" BASIS,
  12.  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13.  * See the License for the specific language governing permissions and
  14.  * limitations under the License.
  15.  */
  16. package com.example.android.BluetoothChat;
  17. import android.app.Activity;
  18. import android.bluetooth.BluetoothAdapter;
  19. import android.bluetooth.BluetoothDevice;
  20. import android.content.Intent;
  21. import android.os.Bundle;
  22. import android.os.Handler;
  23. import android.os.Message;
  24. import android.util.Log;
  25. import android.view.KeyEvent;
  26. import android.view.Menu;
  27. import android.view.MenuInflater;
  28. import android.view.MenuItem;
  29. import android.view.View;
  30. import android.view.Window;
  31. import android.view.View.OnClickListener;
  32. import android.view.inputmethod.EditorInfo;
  33. import android.widget.ArrayAdapter;
  34. import android.widget.Button;
  35. import android.widget.EditText;
  36. import android.widget.ListView;
  37. import android.widget.TextView;
  38. import android.widget.Toast;
  39. /**
  40.  * This is the main Activity that displays the current chat session.
  41.  */
  42. public class BluetoothChat extends Activity {
  43.     // Debugging
  44.     private static final String TAG = "BluetoothChat";
  45.     private static final boolean D = true;
  46.     // Message types sent from the BluetoothChatService Handler
  47.     public static final int MESSAGE_STATE_CHANGE = 1;
  48.     public static final int MESSAGE_READ = 2;
  49.     public static final int MESSAGE_WRITE = 3;
  50.     public static final int MESSAGE_DEVICE_NAME = 4;
  51.     public static final int MESSAGE_TOAST = 5;
  52.     // Key names received from the BluetoothChatService Handler
  53.     public static final String DEVICE_NAME = "device_name";
  54.     public static final String TOAST = "toast";
  55.     // Intent request codes
  56.     private static final int REQUEST_CONNECT_DEVICE = 1;
  57.     private static final int REQUEST_ENABLE_BT = 2;
  58.     // Layout Views
  59.     private TextView mTitle;
  60.     private ListView mConversationView;
  61.     private EditText mOutEditText;
  62.     private Button mSendButton;
  63.     // Name of the connected device
  64.     private String mConnectedDeviceName = null;
  65.     // Array adapter for the conversation thread
  66.     private ArrayAdapter<String> mConversationArrayAdapter;
  67.     // String buffer for outgoing messages
  68.     private StringBuffer mOutStringBuffer;
  69.     // Local Bluetooth adapter
  70.     private BluetoothAdapter mBluetoothAdapter = null;
  71.     // Member object for the chat services
  72.     private BluetoothChatService mChatService = null;
  73.     @Override
  74.     public void onCreate(Bundle savedInstanceState) {
  75.         super.onCreate(savedInstanceState);
  76.         if(D) Log.e(TAG, "+++ ON CREATE +++");
  77.         // Set up the window layout
  78.         requestWindowFeature(Window.FEATURE_CUSTOM_TITLE);
  79.         setContentView(R.layout.main);
  80.         getWindow().setFeatureInt(Window.FEATURE_CUSTOM_TITLE, R.layout.custom_title);
  81.         // Set up the custom title
  82.         mTitle = (TextView) findViewById(R.id.title_left_text);
  83.         mTitle.setText(R.string.app_name);
  84.         mTitle = (TextView) findViewById(R.id.title_right_text);
  85.         // Get local Bluetooth adapter
  86.         mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
  87.         // If the adapter is null, then Bluetooth is not supported
  88.         if (mBluetoothAdapter == null) {
  89.             Toast.makeText(this, "Bluetooth is not available", Toast.LENGTH_LONG).show();
  90.             finish();
  91.             return;
  92.         }
  93.     }
  94.     @Override
  95.     public void onStart() {
  96.         super.onStart();
  97.         if(D) Log.e(TAG, "++ ON START ++");
  98.         // If BT is not on, request that it be enabled.
  99.         // setupChat() will then be called during onActivityResult
  100.         if (!mBluetoothAdapter.isEnabled()) {
  101.             Intent enableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
  102.             startActivityForResult(enableIntent, REQUEST_ENABLE_BT);
  103.         // Otherwise, setup the chat session
  104.         } else {
  105.             if (mChatService == null) setupChat();
  106.         }
  107.     }
  108.     @Override
  109.     public synchronized void onResume() {
  110.         super.onResume();
  111.         if(D) Log.e(TAG, "+ ON RESUME +");
  112.         // Performing this check in onResume() covers the case in which BT was
  113.         // not enabled during onStart(), so we were paused to enable it...
  114.         // onResume() will be called when ACTION_REQUEST_ENABLE activity returns.
  115.         if (mChatService != null) {
  116.             // Only if the state is STATE_NONE, do we know that we haven't started already
  117.             if (mChatService.getState() == BluetoothChatService.STATE_NONE) {
  118.               // Start the Bluetooth chat services
  119.               mChatService.start();
  120.             }
  121.         }
  122.     }
  123.     private void setupChat() {
  124.         Log.d(TAG, "setupChat()");
  125.         // Initialize the array adapter for the conversation thread
  126.         mConversationArrayAdapter = new ArrayAdapter<String>(this, R.layout.message);
  127.         mConversationView = (ListView) findViewById(R.id.in);
  128.         mConversationView.setAdapter(mConversationArrayAdapter);
  129.         // Initialize the compose field with a listener for the return key
  130.         mOutEditText = (EditText) findViewById(R.id.edit_text_out);
  131.         mOutEditText.setOnEditorActionListener(mWriteListener);
  132.         // Initialize the send button with a listener that for click events
  133.         mSendButton = (Button) findViewById(R.id.button_send);
  134.         mSendButton.setOnClickListener(new OnClickListener() {
  135.             public void onClick(View v) {
  136.                 // Send a message using content of the edit text widget
  137.                 TextView view = (TextView) findViewById(R.id.edit_text_out);
  138.                 String message = view.getText().toString();
  139.                 sendMessage(message);
  140.             }
  141.         });
  142.         // Initialize the BluetoothChatService to perform bluetooth connections
  143.         mChatService = new BluetoothChatService(this, mHandler);
  144.         // Initialize the buffer for outgoing messages
  145.         mOutStringBuffer = new StringBuffer("");
  146.     }
  147.     @Override
  148.     public synchronized void onPause() {
  149.         super.onPause();
  150.         if(D) Log.e(TAG, "- ON PAUSE -");
  151.     }
  152.     @Override
  153.     public void onStop() {
  154.         super.onStop();
  155.         if(D) Log.e(TAG, "-- ON STOP --");
  156.     }
  157.     @Override
  158.     public void onDestroy() {
  159.         super.onDestroy();
  160.         // Stop the Bluetooth chat services
  161.         if (mChatService != null) mChatService.stop();
  162.         if(D) Log.e(TAG, "--- ON DESTROY ---");
  163.     }
  164.     private void ensureDiscoverable() {
  165.         if(D) Log.d(TAG, "ensure discoverable");
  166.         if (mBluetoothAdapter.getScanMode() !=
  167.             BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE) {
  168.             Intent discoverableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
  169.             discoverableIntent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 300);
  170.             startActivity(discoverableIntent);
  171.         }
  172.     }
  173.     /**
  174.      * Sends a message.
  175.      * @param message  A string of text to send.
  176.      */
  177.     private void sendMessage(String message) {
  178.         // Check that we're actually connected before trying anything
  179.         if (mChatService.getState() != BluetoothChatService.STATE_CONNECTED) {
  180.             Toast.makeText(this, R.string.not_connected, Toast.LENGTH_SHORT).show();
  181.             return;
  182.         }
  183.         // Check that there's actually something to send
  184.         if (message.length() > 0) {
  185.             // Get the message bytes and tell the BluetoothChatService to write
  186.             byte[] send = message.getBytes();
  187.             mChatService.write(send);
  188.             // Reset out string buffer to zero and clear the edit text field
  189.             mOutStringBuffer.setLength(0);
  190.             mOutEditText.setText(mOutStringBuffer);
  191.         }
  192.     }
  193.     // The action listener for the EditText widget, to listen for the return key
  194.     private TextView.OnEditorActionListener mWriteListener =
  195.         new TextView.OnEditorActionListener() {
  196.         public boolean onEditorAction(TextView view, int actionId, KeyEvent event) {
  197.             // If the action is a key-up event on the return key, send the message
  198.             if (actionId == EditorInfo.IME_NULL && event.getAction() == KeyEvent.ACTION_UP) {
  199.                 String message = view.getText().toString();
  200.                 sendMessage(message);
  201.             }
  202.             if(D) Log.i(TAG, "END onEditorAction");
  203.             return true;
  204.         }
  205.     };
  206.     // The Handler that gets information back from the BluetoothChatService
  207.     private final Handler mHandler = new Handler() {
  208.         @Override
  209.         public void handleMessage(Message msg) {
  210.             switch (msg.what) {
  211.             case MESSAGE_STATE_CHANGE:
  212.                 if(D) Log.i(TAG, "MESSAGE_STATE_CHANGE: " + msg.arg1);
  213.                 switch (msg.arg1) {
  214.                 case BluetoothChatService.STATE_CONNECTED:
  215.                     mTitle.setText(R.string.title_connected_to);
  216.                     mTitle.append(mConnectedDeviceName);
  217.                     mConversationArrayAdapter.clear();
  218.                     break;
  219.                 case BluetoothChatService.STATE_CONNECTING:
  220.                     mTitle.setText(R.string.title_connecting);
  221.                     break;
  222.                 case BluetoothChatService.STATE_LISTEN:
  223.                 case BluetoothChatService.STATE_NONE:
  224.                     mTitle.setText(R.string.title_not_connected);
  225.                     break;
  226.                 }
  227.                 break;
  228.             case MESSAGE_WRITE:
  229.                 byte[] writeBuf = (byte[]) msg.obj;
  230.                 // construct a string from the buffer
  231.                 String writeMessage = new String(writeBuf);
  232.                 mConversationArrayAdapter.add("Me:  " + writeMessage);
  233.                 break;
  234.             case MESSAGE_READ:
  235.                 byte[] readBuf = (byte[]) msg.obj;
  236.                 // construct a string from the valid bytes in the buffer
  237.                 String readMessage = new String(readBuf, 0, msg.arg1);
  238.                 mConversationArrayAdapter.add(mConnectedDeviceName+":  " + readMessage);
  239.                 break;
  240.             case MESSAGE_DEVICE_NAME:
  241.                 // save the connected device's name
  242.                 mConnectedDeviceName = msg.getData().getString(DEVICE_NAME);
  243.                 Toast.makeText(getApplicationContext(), "Connected to "
  244.                                + mConnectedDeviceName, Toast.LENGTH_SHORT).show();
  245.                 break;
  246.             case MESSAGE_TOAST:
  247.                 Toast.makeText(getApplicationContext(), msg.getData().getString(TOAST),
  248.                                Toast.LENGTH_SHORT).show();
  249.                 break;
  250.             }
  251.         }
  252.     };
  253.     public void onActivityResult(int requestCode, int resultCode, Intent data) {
  254.         if(D) Log.d(TAG, "onActivityResult " + resultCode);
  255.         switch (requestCode) {
  256.         case REQUEST_CONNECT_DEVICE:
  257.             // When DeviceListActivity returns with a device to connect
  258.             if (resultCode == Activity.RESULT_OK) {
  259.                 // Get the device MAC address
  260.                 String address = data.getExtras()
  261.                                      .getString(DeviceListActivity.EXTRA_DEVICE_ADDRESS);
  262.                 // Get the BLuetoothDevice object
  263.                 BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(address);
  264.                 // Attempt to connect to the device
  265.                 mChatService.connect(device);
  266.             }
  267.             break;
  268.         case REQUEST_ENABLE_BT:
  269.             // When the request to enable Bluetooth returns
  270.             if (resultCode == Activity.RESULT_OK) {
  271.                 // Bluetooth is now enabled, so set up a chat session
  272.                 setupChat();
  273.             } else {
  274.                 // User did not enable Bluetooth or an error occured
  275.                 Log.d(TAG, "BT not enabled");
  276.                 Toast.makeText(this, R.string.bt_not_enabled_leaving, Toast.LENGTH_SHORT).show();
  277.                 finish();
  278.             }
  279.         }
  280.     }
  281.     @Override
  282.     public boolean onCreateOptionsMenu(Menu menu) {
  283.         MenuInflater inflater = getMenuInflater();
  284.         inflater.inflate(R.menu.option_menu, menu);
  285.         return true;
  286.     }
  287.     @Override
  288.     public boolean onOptionsItemSelected(MenuItem item) {
  289.         switch (item.getItemId()) {
  290.         case R.id.scan:
  291.             // Launch the DeviceListActivity to see devices and do scan
  292.             Intent serverIntent = new Intent(this, DeviceListActivity.class);
  293.             startActivityForResult(serverIntent, REQUEST_CONNECT_DEVICE);
  294.             return true;
  295.         case R.id.discoverable:
  296.             // Ensure this device is discoverable by others
  297.             ensureDiscoverable();
  298.             return true;
  299.         }
  300.         return false;
  301.     }
  302. }