android 源码自带的Demo BluetoothChat

聊天的主页面

/*

* Copyright (C) 2009 The Android Open Source Project

*

* Licensed under the Apache License, Version 2.0 (the "License");

* you may not use this file except in compliance with the License.

* You may obtain a copy of the License at

*

*      http://www.apache.org/licenses/LICENSE-2.0

*

* Unless required by applicable law or agreed to in writing, software

* distributed under the License is distributed on an "AS IS" BASIS,

* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

* See the License for the specific language governing permissions and

* limitations under the License.

*/

package com.example.android.BluetoothChat;

import android.app.ActionBar;

import android.app.Activity;

import android.bluetooth.BluetoothAdapter;

import android.bluetooth.BluetoothDevice;

import android.content.Intent;

import android.os.Bundle;

import android.os.Handler;

import android.os.Message;

import android.util.Log;

import android.view.KeyEvent;

import android.view.Menu;

import android.view.MenuInflater;

import android.view.MenuItem;

import android.view.View;

import android.view.Window;

import android.view.View.OnClickListener;

import android.view.inputmethod.EditorInfo;

import android.widget.ArrayAdapter;

import android.widget.Button;

import android.widget.EditText;

import android.widget.ListView;

import android.widget.TextView;

import android.widget.Toast;

/**

* This is the main Activity that displays the current chat session.

*/

public class BluetoothChat extends Activity {

// Debugging

private static final String TAG = "BluetoothChat";

private static final boolean D = true;

// Message types sent from the BluetoothChatService Handler

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;

// Key names received from the BluetoothChatService Handler

public static final String DEVICE_NAME = "device_name";

public static final String TOAST = "toast";

// Intent request codes

private static final int REQUEST_CONNECT_DEVICE_SECURE = 1;

private static final int REQUEST_CONNECT_DEVICE_INSECURE = 2;

private static final int REQUEST_ENABLE_BT = 3;

// Layout Views

private ListView mConversationView;

private EditText mOutEditText;

private Button mSendButton;

// Name of the connected device

private String mConnectedDeviceName = null;

// Array adapter for the conversation thread

private ArrayAdapter<String> mConversationArrayAdapter;

// String buffer for outgoing messages

private StringBuffer mOutStringBuffer;

// Local Bluetooth adapter

private BluetoothAdapter mBluetoothAdapter = null;

// Member object for the chat services

private BluetoothChatService mChatService = null;

@Override

public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

if(D) Log.e(TAG, "+++ ON CREATE +++");

// Set up the window layout

setContentView(R.layout.main);

// Get local Bluetooth adapter

mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();

// If the adapter is null, then Bluetooth is not supported

if (mBluetoothAdapter == null) {

Toast.makeText(this, "Bluetooth is not available", Toast.LENGTH_LONG).show();

finish();

return;

}

}

@Override

public void onStart() {

super.onStart();

if(D) Log.e(TAG, "++ ON START ++");

// If BT is not on, request that it be enabled.

// setupChat() will then be called during onActivityResult

// 检查蓝牙设备是否可用,获得蓝牙设备的操作。

if (!mBluetoothAdapter.isEnabled()) {

Intent enableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);

startActivityForResult(enableIntent, REQUEST_ENABLE_BT);

// Otherwise, setup the chat session

} else {

if (mChatService == null) setupChat();

}

}

@Override

public synchronized void onResume() {

super.onResume();

if(D) Log.e(TAG, "+ ON RESUME +");

// Performing this check in onResume() covers the case in which BT was

// not enabled during onStart(), so we were paused to enable it...

// onResume() will be called when ACTION_REQUEST_ENABLE activity returns.

if (mChatService != null) {

// Only if the state is STATE_NONE, do we know that we haven‘t started already

if (mChatService.getState() == BluetoothChatService.STATE_NONE) {

// Start the Bluetooth chat services

mChatService.start();

}

}

}

private void setupChat() {

Log.d(TAG, "setupChat()");

// Initialize the array adapter for the conversation thread

mConversationArrayAdapter = new ArrayAdapter<String>(this, R.layout.message);

mConversationView = (ListView) findViewById(R.id.in);

mConversationView.setAdapter(mConversationArrayAdapter);

// Initialize the compose field with a listener for the return key

mOutEditText = (EditText) findViewById(R.id.edit_text_out);

mOutEditText.setOnEditorActionListener(mWriteListener);

// Initialize the send button with a listener that for click events

mSendButton = (Button) findViewById(R.id.button_send);

mSendButton.setOnClickListener(new OnClickListener() {

public void onClick(View v) {

// Send a message using content of the edit text widget

TextView view = (TextView) findViewById(R.id.edit_text_out);

String message = view.getText().toString();

sendMessage(message);

}

});

// Initialize the BluetoothChatService to perform bluetooth connections

mChatService = new BluetoothChatService(this, mHandler);

// Initialize the buffer for outgoing messages

mOutStringBuffer = new StringBuffer("");

}

@Override

public synchronized void onPause() {

super.onPause();

if(D) Log.e(TAG, "- ON PAUSE -");

}

@Override

public void onStop() {

super.onStop();

if(D) Log.e(TAG, "-- ON STOP --");

}

@Override

public void onDestroy() {

super.onDestroy();

// Stop the Bluetooth chat services

if (mChatService != null) mChatService.stop();

if(D) Log.e(TAG, "--- ON DESTROY ---");

}

private void ensureDiscoverable() {

if(D) Log.d(TAG, "ensure discoverable");

if (mBluetoothAdapter.getScanMode() !=

BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE) {

Intent discoverableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);

discoverableIntent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 300);

startActivity(discoverableIntent);

}

}

/**

* Sends a message.

* @param message  A string of text to send.

*/

private void sendMessage(String message) {

// Check that we‘re actually connected before trying anything

if (mChatService.getState() != BluetoothChatService.STATE_CONNECTED) {

Toast.makeText(this, R.string.not_connected, Toast.LENGTH_SHORT).show();

return;

}

// Check that there‘s actually something to send

if (message.length() > 0) {

// Get the message bytes and tell the BluetoothChatService to write

byte[] send = message.getBytes();

mChatService.write(send);

// Reset out string buffer to zero and clear the edit text field

mOutStringBuffer.setLength(0);

mOutEditText.setText(mOutStringBuffer);

}

}

// The action listener for the EditText widget, to listen for the return key

private TextView.OnEditorActionListener mWriteListener =

new TextView.OnEditorActionListener() {

public boolean onEditorAction(TextView view, int actionId, KeyEvent event) {

// If the action is a key-up event on the return key, send the message

if (actionId == EditorInfo.IME_NULL && event.getAction() == KeyEvent.ACTION_UP) {

String message = view.getText().toString();

sendMessage(message);

}

if(D) Log.i(TAG, "END onEditorAction");

return true;

}

};

private final void setStatus(int resId) {

final ActionBar actionBar = getActionBar();

actionBar.setSubtitle(resId);

}

private final void setStatus(CharSequence subTitle) {

final ActionBar actionBar = getActionBar();

actionBar.setSubtitle(subTitle);

}

// The Handler that gets information back from the BluetoothChatService

private final Handler mHandler = new Handler() {

@Override

public void handleMessage(Message msg) {

switch (msg.what) {

case MESSAGE_STATE_CHANGE:

if(D) Log.i(TAG, "MESSAGE_STATE_CHANGE: " + msg.arg1);

switch (msg.arg1) {

case BluetoothChatService.STATE_CONNECTED:

setStatus(getString(R.string.title_connected_to, mConnectedDeviceName));

mConversationArrayAdapter.clear();

break;

case BluetoothChatService.STATE_CONNECTING:

setStatus(R.string.title_connecting);

break;

case BluetoothChatService.STATE_LISTEN:

case BluetoothChatService.STATE_NONE:

setStatus(R.string.title_not_connected);

break;

}

break;

case MESSAGE_WRITE:

byte[] writeBuf = (byte[]) msg.obj;

// construct a string from the buffer

String writeMessage = new String(writeBuf);

mConversationArrayAdapter.add("Me:  " + writeMessage);

break;

case MESSAGE_READ:

byte[] readBuf = (byte[]) msg.obj;

// construct a string from the valid bytes in the buffer

String readMessage = new String(readBuf, 0, msg.arg1);

mConversationArrayAdapter.add(mConnectedDeviceName+":  " + readMessage);

break;

case MESSAGE_DEVICE_NAME:

// save the connected device‘s name

mConnectedDeviceName = msg.getData().getString(DEVICE_NAME);

Toast.makeText(getApplicationContext(), "Connected to "

+ mConnectedDeviceName, Toast.LENGTH_SHORT).show();

break;

case MESSAGE_TOAST:

Toast.makeText(getApplicationContext(), msg.getData().getString(TOAST),

Toast.LENGTH_SHORT).show();

break;

}

}

};

public void onActivityResult(int requestCode, int resultCode, Intent data) {

if(D) Log.d(TAG, "onActivityResult " + resultCode);

switch (requestCode) {

case REQUEST_CONNECT_DEVICE_SECURE:

// When DeviceListActivity returns with a device to connect

if (resultCode == Activity.RESULT_OK) {

connectDevice(data, true);

}

break;

case REQUEST_CONNECT_DEVICE_INSECURE:

// When DeviceListActivity returns with a device to connect

if (resultCode == Activity.RESULT_OK) {

connectDevice(data, false);

}

break;

case REQUEST_ENABLE_BT:

// When the request to enable Bluetooth returns

if (resultCode == Activity.RESULT_OK) {

// Bluetooth is now enabled, so set up a chat session

setupChat();

} else {

// User did not enable Bluetooth or an error occurred

Log.d(TAG, "BT not enabled");

Toast.makeText(this, R.string.bt_not_enabled_leaving, Toast.LENGTH_SHORT).show();

finish();

}

}

}

private void connectDevice(Intent data, boolean secure) {

// Get the device MAC address

String address = data.getExtras()

.getString(DeviceListActivity.EXTRA_DEVICE_ADDRESS);

// Get the BluetoothDevice object

BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(address);

// Attempt to connect to the device

mChatService.connect(device, secure);

}

@Override

public boolean onCreateOptionsMenu(Menu menu) {

MenuInflater inflater = getMenuInflater();

inflater.inflate(R.menu.option_menu, menu);

return true;

}

@Override

public boolean onOptionsItemSelected(MenuItem item) {

Intent serverIntent = null;

switch (item.getItemId()) {

case R.id.secure_connect_scan:

// Launch the DeviceListActivity to see devices and do scan

serverIntent = new Intent(this, DeviceListActivity.class);

startActivityForResult(serverIntent, REQUEST_CONNECT_DEVICE_SECURE);

return true;

case R.id.insecure_connect_scan:

// Launch the DeviceListActivity to see devices and do scan

serverIntent = new Intent(this, DeviceListActivity.class);

startActivityForResult(serverIntent, REQUEST_CONNECT_DEVICE_INSECURE);

return true;

case R.id.discoverable:

// Ensure this device is discoverable by others

ensureDiscoverable();

return true;

}

return false;

}

}

蓝牙聊天的后台线程类用于接受和发送信息和根据蓝牙的状态更新UI。

/*

* Copyright (C) 2009 The Android Open Source Project

*

* Licensed under the Apache License, Version 2.0 (the "License");

* you may not use this file except in compliance with the License.

* You may obtain a copy of the License at

*

*      http://www.apache.org/licenses/LICENSE-2.0

*

* Unless required by applicable law or agreed to in writing, software

* distributed under the License is distributed on an "AS IS" BASIS,

* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

* See the License for the specific language governing permissions and

* limitations under the License.

*/

package com.example.android.BluetoothChat;

import java.io.IOException;

import java.io.InputStream;

import java.io.OutputStream;

import java.util.UUID;

import android.bluetooth.BluetoothAdapter;

import android.bluetooth.BluetoothDevice;

import android.bluetooth.BluetoothServerSocket;

import android.bluetooth.BluetoothSocket;

import android.content.Context;

import android.os.Bundle;

import android.os.Handler;

import android.os.Message;

import android.util.Log;

/**

* This class does all the work for setting up and managing Bluetooth

* connections with other devices. It has a thread that listens for incoming

* connections, a thread for connecting with a device, and a thread for

* performing data transmissions when connected.

*/

public class BluetoothChatService {

// Debugging

private static final String TAG = "BluetoothChatService";

private static final boolean D = true;

// Name for the SDP record when creating server socket

private static final String NAME_SECURE = "BluetoothChatSecure";

private static final String NAME_INSECURE = "BluetoothChatInsecure";

// Unique UUID for this application

private static final UUID MY_UUID_SECURE = UUID

.fromString("fa87c0d0-afac-11de-8a39-0800200c9a66");

private static final UUID MY_UUID_INSECURE = UUID

.fromString("8ce255c0-200a-11e0-ac64-0800200c9a66");

// Member fields

private final BluetoothAdapter mAdapter;

private final Handler mHandler;

private AcceptThread mSecureAcceptThread;

private AcceptThread mInsecureAcceptThread;

private ConnectThread mConnectThread;

private ConnectedThread mConnectedThread;

private int mState;

// Constants that indicate the current connection state

public static final int STATE_NONE = 0; // we‘re doing nothing

public static final int STATE_LISTEN = 1; // now listening for incoming

// connections

public static final int STATE_CONNECTING = 2; // now initiating an outgoing

// connection

public static final int STATE_CONNECTED = 3; // now connected to a remote

// device

/**

* Constructor. Prepares a new BluetoothChat session.

*

* @param context

*            The UI Activity Context

* @param handler

*            A Handler to send messages back to the UI Activity

*/

public BluetoothChatService(Context context, Handler handler) {

mAdapter = BluetoothAdapter.getDefaultAdapter();

mState = STATE_NONE;

mHandler = handler;

}

/**

* Set the current state of the chat connection

*

* @param state

*            An integer defining the current connection state

*/

private synchronized void setState(int state) {

if (D)

Log.d(TAG, "setState() " + mState + " -> " + state);

mState = state;

// Give the new state to the Handler so the UI Activity can update

mHandler.obtainMessage(BluetoothChat.MESSAGE_STATE_CHANGE, state, -1)

.sendToTarget();

}

/**

* Return the current connection state.

*/

public synchronized int getState() {

return mState;

}

/**

* Start the chat service. Specifically start AcceptThread to begin a

* session in listening (server) mode. Called by the Activity onResume()

*/

public synchronized void start() {

if (D)

Log.d(TAG, "start");

// Cancel any thread attempting to make a connection

if (mConnectThread != null) {

mConnectThread.cancel();

mConnectThread = null;

}

// Cancel any thread currently running a connection

if (mConnectedThread != null) {

mConnectedThread.cancel();

mConnectedThread = null;

}

setState(STATE_LISTEN);

// Start the thread to listen on a BluetoothServerSocket

if (mSecureAcceptThread == null) {

mSecureAcceptThread = new AcceptThread(true);

mSecureAcceptThread.start();

}

if (mInsecureAcceptThread == null) {

mInsecureAcceptThread = new AcceptThread(false);

mInsecureAcceptThread.start();

}

}

/**

* Start the ConnectThread to initiate a connection to a remote device.

*

* @param device

*            The BluetoothDevice to connect

* @param secure

*            Socket Security type - Secure (true) , Insecure (false)

*/

public synchronized void connect(BluetoothDevice device, boolean secure) {

if (D)

Log.d(TAG, "connect to: " + device);

// Cancel any thread attempting to make a connection

if (mState == STATE_CONNECTING) {

if (mConnectThread != null) {

mConnectThread.cancel();

mConnectThread = null;

}

}

// Cancel any thread currently running a connection

if (mConnectedThread != null) {

mConnectedThread.cancel();

mConnectedThread = null;

}

// Start the thread to connect with the given device

mConnectThread = new ConnectThread(device, secure);

mConnectThread.start();

setState(STATE_CONNECTING);

}

/**

* Start the ConnectedThread to begin managing a Bluetooth connection

*

* @param socket

*            The BluetoothSocket on which the connection was made

* @param device

*            The BluetoothDevice that has been connected

*/

public synchronized void connected(BluetoothSocket socket,

BluetoothDevice device, final String socketType) {

if (D)

Log.d(TAG, "connected, Socket Type:" + socketType);

// Cancel the thread that completed the connection

if (mConnectThread != null) {

mConnectThread.cancel();

mConnectThread = null;

}

// Cancel any thread currently running a connection

if (mConnectedThread != null) {

mConnectedThread.cancel();

mConnectedThread = null;

}

// Cancel the accept thread because we only want to connect to one

// device

if (mSecureAcceptThread != null) {

mSecureAcceptThread.cancel();

mSecureAcceptThread = null;

}

if (mInsecureAcceptThread != null) {

mInsecureAcceptThread.cancel();

mInsecureAcceptThread = null;

}

// Start the thread to manage the connection and perform transmissions

mConnectedThread = new ConnectedThread(socket, socketType);

mConnectedThread.start();

// Send the name of the connected device back to the UI Activity

Message msg = mHandler.obtainMessage(BluetoothChat.MESSAGE_DEVICE_NAME);

Bundle bundle = new Bundle();

bundle.putString(BluetoothChat.DEVICE_NAME, device.getName());

msg.setData(bundle);

mHandler.sendMessage(msg);

setState(STATE_CONNECTED);

}

/**

* Stop all threads

*/

public synchronized void stop() {

if (D)

Log.d(TAG, "stop");

if (mConnectThread != null) {

mConnectThread.cancel();

mConnectThread = null;

}

if (mConnectedThread != null) {

mConnectedThread.cancel();

mConnectedThread = null;

}

if (mSecureAcceptThread != null) {

mSecureAcceptThread.cancel();

mSecureAcceptThread = null;

}

if (mInsecureAcceptThread != null) {

mInsecureAcceptThread.cancel();

mInsecureAcceptThread = null;

}

setState(STATE_NONE);

}

/**

* Write to the ConnectedThread in an unsynchronized manner

*

* @param out

*            The bytes to write

* @see ConnectedThread#write(byte[])

*/

public void write(byte[] out) {

// Create temporary object

ConnectedThread r;

// Synchronize a copy of the ConnectedThread

synchronized (this) {

if (mState != STATE_CONNECTED)

return;

r = mConnectedThread;

}

// Perform the write unsynchronized

r.write(out);

}

/**

* Indicate that the connection attempt failed and notify the UI Activity.

*/

private void connectionFailed() {

// Send a failure message back to the Activity

Message msg = mHandler.obtainMessage(BluetoothChat.MESSAGE_TOAST);

Bundle bundle = new Bundle();

bundle.putString(BluetoothChat.TOAST, "Unable to connect device");

msg.setData(bundle);

mHandler.sendMessage(msg);

// Start the service over to restart listening mode

BluetoothChatService.this.start();

}

/**

* Indicate that the connection was lost and notify the UI Activity.

*/

private void connectionLost() {

// Send a failure message back to the Activity

Message msg = mHandler.obtainMessage(BluetoothChat.MESSAGE_TOAST);

Bundle bundle = new Bundle();

bundle.putString(BluetoothChat.TOAST, "Device connection was lost");

msg.setData(bundle);

mHandler.sendMessage(msg);

// Start the service over to restart listening mode

BluetoothChatService.this.start();

}

/**

* This thread runs while listening for incoming connections. It behaves

* like a server-side client. It runs until a connection is accepted (or

* until cancelled).

*/

private class AcceptThread extends Thread {

// The local server socket

private final BluetoothServerSocket mmServerSocket;

private String mSocketType;

public AcceptThread(boolean secure) {

BluetoothServerSocket tmp = null;

mSocketType = secure ? "Secure" : "Insecure";

// Create a new listening server socket

try {

if (secure) {

tmp = mAdapter.listenUsingRfcommWithServiceRecord(

NAME_SECURE, MY_UUID_SECURE);

} else {

tmp = mAdapter.listenUsingInsecureRfcommWithServiceRecord(

NAME_INSECURE, MY_UUID_INSECURE);

}

} catch (IOException e) {

Log.e(TAG, "Socket Type: " + mSocketType + "listen() failed", e);

}

mmServerSocket = tmp;

}

public void run() {

if (D)

Log.d(TAG, "Socket Type: " + mSocketType

+ "BEGIN mAcceptThread" + this);

setName("AcceptThread" + mSocketType);

BluetoothSocket socket = null;

// Listen to the server socket if we‘re not connected

while (mState != STATE_CONNECTED) {

try {

// This is a blocking call and will only return on a

// successful connection or an exception

socket = mmServerSocket.accept();

} catch (IOException e) {

Log.e(TAG, "Socket Type: " + mSocketType

+ "accept() failed", e);

break;

}

// If a connection was accepted

if (socket != null) {

synchronized (BluetoothChatService.this) {

switch (mState) {

case STATE_LISTEN:

case STATE_CONNECTING:

// Situation normal. Start the connected thread.

connected(socket, socket.getRemoteDevice(),

mSocketType);

break;

case STATE_NONE:

case STATE_CONNECTED:

// Either not ready or already connected. Terminate

// new socket.

try {

socket.close();

} catch (IOException e) {

Log.e(TAG, "Could not close unwanted socket", e);

}

break;

}

}

}

}

if (D)

Log.i(TAG, "END mAcceptThread, socket Type: " + mSocketType);

}

public void cancel() {

if (D)

Log.d(TAG, "Socket Type" + mSocketType + "cancel " + this);

try {

mmServerSocket.close();

} catch (IOException e) {

Log.e(TAG, "Socket Type" + mSocketType

+ "close() of server failed", e);

}

}

}

/**

* This thread runs while attempting to make an outgoing connection with a

* device. It runs straight through; the connection either succeeds or

* fails.

*/

private class ConnectThread extends Thread {

private final BluetoothSocket mmSocket;

private final BluetoothDevice mmDevice;

private String mSocketType;

public ConnectThread(BluetoothDevice device, boolean secure) {

mmDevice = device;

BluetoothSocket tmp = null;

mSocketType = secure ? "Secure" : "Insecure";

// Get a BluetoothSocket for a connection with the

// given BluetoothDevice

try {

if (secure) {

tmp = device

.createRfcommSocketToServiceRecord(MY_UUID_SECURE);

} else {

tmp = device

.createInsecureRfcommSocketToServiceRecord(MY_UUID_INSECURE);

}

} catch (IOException e) {

Log.e(TAG, "Socket Type: " + mSocketType + "create() failed", e);

}

mmSocket = tmp;

}

public void run() {

Log.i(TAG, "BEGIN mConnectThread SocketType:" + mSocketType);

setName("ConnectThread" + mSocketType);

// Always cancel discovery because it will slow down a connection

mAdapter.cancelDiscovery();

// Make a connection to the BluetoothSocket

try {

// This is a blocking call and will only return on a

// successful connection or an exception

mmSocket.connect();

} catch (IOException e) {

// Close the socket

try {

mmSocket.close();

} catch (IOException e2) {

Log.e(TAG, "unable to close() " + mSocketType

+ " socket during connection failure", e2);

}

connectionFailed();

return;

}

// Reset the ConnectThread because we‘re done

synchronized (BluetoothChatService.this) {

mConnectThread = null;

}

// Start the connected thread

connected(mmSocket, mmDevice, mSocketType);

}

public void cancel() {

try {

mmSocket.close();

} catch (IOException e) {

Log.e(TAG, "close() of connect " + mSocketType

+ " socket failed", e);

}

}

}

/**

* This thread runs during a connection with a remote device. It handles all

* incoming and outgoing transmissions.

*/

private class ConnectedThread extends Thread {

private final BluetoothSocket mmSocket;

private final InputStream mmInStream;

private final OutputStream mmOutStream;

public ConnectedThread(BluetoothSocket socket, String socketType) {

Log.d(TAG, "create ConnectedThread: " + socketType);

mmSocket = socket;

InputStream tmpIn = null;

OutputStream tmpOut = null;

// Get the BluetoothSocket input and output streams

try {

tmpIn = socket.getInputStream();

tmpOut = socket.getOutputStream();

} catch (IOException e) {

Log.e(TAG, "temp sockets not created", e);

}

mmInStream = tmpIn;

mmOutStream = tmpOut;

}

public void run() {

Log.i(TAG, "BEGIN mConnectedThread");

byte[] buffer = new byte[1024];

int bytes;

// Keep listening to the InputStream while connected

while (true) {

try {

// Read from the InputStream

bytes = mmInStream.read(buffer);

// Send the obtained bytes to the UI Activity

mHandler.obtainMessage(BluetoothChat.MESSAGE_READ, bytes,

-1, buffer).sendToTarget();

} catch (IOException e) {

Log.e(TAG, "disconnected", e);

connectionLost();

// Start the service over to restart listening mode

BluetoothChatService.this.start();

break;

}

}

}

/**

* Write to the connected OutStream.

*

* @param buffer

*            The bytes to write

*/

public void write(byte[] buffer) {

try {

mmOutStream.write(buffer);

// Share the sent message back to the UI Activity

mHandler.obtainMessage(BluetoothChat.MESSAGE_WRITE, -1, -1,

buffer).sendToTarget();

} catch (IOException e) {

Log.e(TAG, "Exception during write", e);

}

}

public void cancel() {

try {

mmSocket.close();

} catch (IOException e) {

Log.e(TAG, "close() of connect socket failed", e);

}

}

}

}

获取当前的蓝牙设备的信息,(已配对,可用的蓝牙列表)

/*

* Copyright (C) 2009 The Android Open Source Project

*

* Licensed under the Apache License, Version 2.0 (the "License");

* you may not use this file except in compliance with the License.

* You may obtain a copy of the License at

*

*      http://www.apache.org/licenses/LICENSE-2.0

*

* Unless required by applicable law or agreed to in writing, software

* distributed under the License is distributed on an "AS IS" BASIS,

* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

* See the License for the specific language governing permissions and

* limitations under the License.

*/

package com.example.android.BluetoothChat;

import java.util.Set;

import android.app.Activity;

import android.bluetooth.BluetoothAdapter;

import android.bluetooth.BluetoothDevice;

import android.content.BroadcastReceiver;

import android.content.Context;

import android.content.Intent;

import android.content.IntentFilter;

import android.os.Bundle;

import android.util.Log;

import android.view.View;

import android.view.Window;

import android.view.View.OnClickListener;

import android.widget.AdapterView;

import android.widget.ArrayAdapter;

import android.widget.Button;

import android.widget.ListView;

import android.widget.TextView;

import android.widget.AdapterView.OnItemClickListener;

/**

* This Activity appears as a dialog. It lists any paired devices and

* devices detected in the area after discovery. When a device is chosen

* by the user, the MAC address of the device is sent back to the parent

* Activity in the result Intent.

*/

public class DeviceListActivity extends Activity {

// Debugging

private static final String TAG = "DeviceListActivity";

private static final boolean D = true;

// Return Intent extra

public static String EXTRA_DEVICE_ADDRESS = "device_address";

// Member fields

private BluetoothAdapter mBtAdapter;

private ArrayAdapter<String> mPairedDevicesArrayAdapter;

private ArrayAdapter<String> mNewDevicesArrayAdapter;

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

// Setup the window

requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);

setContentView(R.layout.device_list);

// Set result CANCELED in case the user backs out

setResult(Activity.RESULT_CANCELED);

// Initialize the button to perform device discovery

Button scanButton = (Button) findViewById(R.id.button_scan);

scanButton.setOnClickListener(new OnClickListener() {

public void onClick(View v) {

doDiscovery();

v.setVisibility(View.GONE);

}

});

// Initialize array adapters. One for already paired devices and

// one for newly discovered devices

mPairedDevicesArrayAdapter = new ArrayAdapter<String>(this, R.layout.device_name);

mNewDevicesArrayAdapter = new ArrayAdapter<String>(this, R.layout.device_name);

// Find and set up the ListView for paired devices

ListView pairedListView = (ListView) findViewById(R.id.paired_devices);

pairedListView.setAdapter(mPairedDevicesArrayAdapter);

pairedListView.setOnItemClickListener(mDeviceClickListener);

// Find and set up the ListView for newly discovered devices

ListView newDevicesListView = (ListView) findViewById(R.id.new_devices);

newDevicesListView.setAdapter(mNewDevicesArrayAdapter);

newDevicesListView.setOnItemClickListener(mDeviceClickListener);

// Register for broadcasts when a device is discovered

IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);

this.registerReceiver(mReceiver, filter);

// Register for broadcasts when discovery has finished

filter = new IntentFilter(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);

this.registerReceiver(mReceiver, filter);

// Get the local Bluetooth adapter

mBtAdapter = BluetoothAdapter.getDefaultAdapter();

// Get a set of currently paired devices

Set<BluetoothDevice> pairedDevices = mBtAdapter.getBondedDevices();

// If there are paired devices, add each one to the ArrayAdapter

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();

// Make sure we‘re not doing discovery anymore

if (mBtAdapter != null) {

mBtAdapter.cancelDiscovery();

}

// Unregister broadcast listeners

this.unregisterReceiver(mReceiver);

}

/**

* Start device discover with the BluetoothAdapter

*/

private void doDiscovery() {

if (D) Log.d(TAG, "doDiscovery()");

// Indicate scanning in the title

setProgressBarIndeterminateVisibility(true);

setTitle(R.string.scanning);

// Turn on sub-title for new devices

findViewById(R.id.title_new_devices).setVisibility(View.VISIBLE);

// If we‘re already discovering, stop it

if (mBtAdapter.isDiscovering()) {

mBtAdapter.cancelDiscovery();

}

// Request discover from BluetoothAdapter

mBtAdapter.startDiscovery();

}

// The on-click listener for all devices in the ListViews

private OnItemClickListener mDeviceClickListener = new OnItemClickListener() {

public void onItemClick(AdapterView<?> av, View v, int arg2, long arg3) {

// Cancel discovery because it‘s costly and we‘re about to connect

mBtAdapter.cancelDiscovery();

// Get the device MAC address, which is the last 17 chars in the View

String info = ((TextView) v).getText().toString();

String address = info.substring(info.length() - 17);

// Create the result Intent and include the MAC address

Intent intent = new Intent();

intent.putExtra(EXTRA_DEVICE_ADDRESS, address);

// Set result and finish this Activity

setResult(Activity.RESULT_OK, intent);

finish();

}

};

// The BroadcastReceiver that listens for discovered devices and

// changes the title when discovery is finished

private final BroadcastReceiver mReceiver = new BroadcastReceiver() {

@Override

public void onReceive(Context context, Intent intent) {

String action = intent.getAction();

// When discovery finds a device

if (BluetoothDevice.ACTION_FOUND.equals(action)) {

// Get the BluetoothDevice object from the Intent

BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);

// If it‘s already paired, skip it, because it‘s been listed already

if (device.getBondState() != BluetoothDevice.BOND_BONDED) {

mNewDevicesArrayAdapter.add(device.getName() + "\n" + device.getAddress());

}

// When discovery is finished, change the Activity title

} else if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)) {

setProgressBarIndeterminateVisibility(false);

setTitle(R.string.select_device);

if (mNewDevicesArrayAdapter.getCount() == 0) {

String noDevices = getResources().getText(R.string.none_found).toString();

mNewDevicesArrayAdapter.add(noDevices);

}

}

}

};

}

源码位置:http://download.csdn.net/detail/tianyeming/8898651

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-09-29 17:32:20

android 源码自带的Demo BluetoothChat的相关文章

android源码大放送(实战开发必备),免费安卓demo源码,例子大全文件详细列表

免费安卓demo源码,例子大全文件详细列表 本列表源码永久免费下载地址:http://www.jiandaima.com/blog/android-demo 卷 yunpan 的文件夹 PATH 列表 卷序列号为 0000-73EC E:. │ jiandaima.com文件列表生成.bat │ 例子大全说明.txt │ 本例子永久更新地址~.url │ 目录列表2016.03.10更新.txt │ ├─前台界面 │ ├─3D标签云卡片热门 │ │ Android TagCloudView云标签

android源码编译1

一.环境说明: 1.liunx系统:Ubuntu12.04 2.jdk:sun-java6-jdk 3.g++4.5 gcc4.5 二.android源码的目录结构 |-- Makefile |-- bionic (bionic C库) |-- bootable (启动引导相关代码) |-- build (存放系统编译规则及generic等基础开发包配置) |-- cts (Android兼容性测试套件标准) |-- dalvik (dalvik JAVA虚拟机) |-- development

ym——android源码大放送(实战开发必备)

文件夹 PATH 列表 卷序列号为 000A-8F50 E:. │  javaapk.com文件列表生成工具.bat │  使用说明.txt │  免费下载更多源码.url │  目录列表.txt │ ├─android web应用 │      jqmDemo_static.zip │      jqmMobileDemo-master.zip │      jqmMobileDemo1_1-master.zip │      Location1014.rar │ ├─anko │      

2014年最新720多套Android源码2.0GB免费一次性打包下载

之前发过一个帖子,但是那个帖子有点问题我就重新发一个吧,下面的源码是我从今年3月份开始不断整理源码区和其他网站上的android源码,目前总共有720套左右,根据实现的功能被我分成了100多个类,总共2G多,还在不断更新安卓源码.初学者可以快速方便的找到自己想要的例子,大神也可以看一下别人的方法实现.虽然的例子都是我一个人辛辛苦苦花了很多时间和精力整理的,但是既然这些例子是来自于社区那就让他们免费回归社区吧,(是的!特么的不要一分钱!最看不起那些挂羊头卖狗的)你可以在本帖里面按Ctrl+F查找你

完整版linux下android源码下载、编译、模拟器启动运行

一.环境说明: 1.VMware版本:8.0.3 build-703057 2.liunx系统:Ubuntu10.10 3.jdk:sun-java6-jdk 二.Ubuntu 10.10更新源列表 由于??Ubuntu 10.10版本的源已经过期了,所以,需要对其进行更新,Ubuntu 10.10 已经发布了,下面提供更新源方法与更新源列表地址: 1.sudo gedit /etc/apt/sources.list     编辑你的源列表,将原来的内容全部删除,添加下面的源,复制到你的列表中,

Android 源码系列之&lt;十一&gt;从源码的角度深入理解AccessibilityService,打造自己的APP小外挂(下)

转载请注明出处:http://blog.csdn.net/llew2011/article/details/52843637 在上篇文章Android 源码系列之<十>从源码的角度深入理解AccessibilityService,打造自己的APP小外挂(上)中我们讲解了通过AccessibilityService实现自动安装APK小外挂的操作流程,如果你还没有看过上篇文章请点击这里.在这篇文章中我将带领小伙伴从源码的角度来深入学习一下AccessibilityServie的技术实现原理,希望这

android.mk android源码编译

http://www.cnblogs.com/chenbin7/archive/2013/01/05/2846863.html Android.mk简单分析 2013-01-05 22:51 by ...平..淡..., 884 阅读, 0 评论, 收藏, 编辑 LOCAL_PATH:= $(call my-dir) include $(CLEAR_VARS) LOCAL_MODULE_TAGS := optional LOCAL_SRC_FILES := $(call all-java-fil

Android学习进阶路线Android源码分享)

毕业8月有余,同时伴随着从事的Android经验的提升.仔细思量过去的工作内容,掐指算来也是少得可怜---主要维护FM收 音机模块,间或看看Lancher模块的代码.尽管这样,总的来说,在这八个月事件的学习里,我自我感觉收获还是很大的---自学了很多 Android相关方面的知识.虽然里真正的大牛还有很远的一段路程要走,自己也会坚持学习.坚持走下去. 再次,把自己学习过程中总结的一些经验总结出来,帮助那些刚刚步入Android的网友以及有了取得了一些经验但不知如何 继续前行的朋友,希望你们能够早

macOS(Sierra 10.12)上Android源码(AOSP)的下载、编译与导入到Android Studio

http://blog.bihe0832.com/macOS-AOSP.html [本文结构] 背景 背景简介 最近因为项目需要,要研究Android系统中应用安装的详细过程.在这种场景下,最好的办法就是Read the Fucking Source Code.之前都是在线看,这次因为看的内容比较多,而且看的比较细,因此打算在本地checkout一份.这篇文章就主要记录本人使用macOS(Sierra 10.12.1)在本地checkout出AOSP(7.1.1)并编译导入Android Stu