您的位置:首页 > 其它

蓝牙聊天

2016-07-17 21:12 211 查看
最近通过Google学习了两部设备之间通过蓝牙连接实现聊天的功能,以下为代码:

/**
* BlueToothChat:开启蓝牙,300s可见,连接设备,线程UI处理,聊天设置,整个界面功能的实现
* @author micro
*
*/

public class BlueToothChat extends Activity {

//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;

//设备名和TOAST
public static final String DEVICE_NAME = "device_name";
public static final String TOAST = "toast";

//请求码
public static final int REQUEST_CONNECT_DEVICE = 2;
public static final int REQUEST_ENABLE_BT = 3;

//控件
private ListView mConversation;
private EditText mEdit;
private Button sendBtn;

private String mConnectedServiceName;             //设备名
private ArrayAdapter<String> mConversationAdapter;  //聊天设配器
private StringBuffer mOutString ;                   //输出的信息

private BluetoothAdapter mBluetoothAdapter = null;         //蓝牙适配器
private BlueToothChatService mBlueToothChatService = null;  //服务端

@Override
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.main);

//获取默认的蓝牙适配器
mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();

if(mBluetoothAdapter==null){

Toast.makeText(getApplicationContext(), "此设备不支持蓝牙", Toast.LENGTH_SHORT).show();
this.finish();   //结束
return ;
}

}
/**
* 在onStart方法中开启蓝牙
*/
@Override
public void onStart(){
super.onStart();

//如果蓝牙没开,则开启蓝牙,开启后回调REQUEST_ENABLE_BT
if(!mBluetoothAdapter.isEnabled()){

Intent enableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableIntent,REQUEST_ENABLE_BT);

}else{

if(mBlueToothChatService == null){
//设置聊天
setupChat();

}

}

}
/**
* 在onResume方法中开启服务端里的线程
*/

@Override
public void onResume(){
super.onResume();

//只有满足以下的两个条件之后我们才会开启
if(mBlueToothChatService!=null){

if(mBlueToothChatService.getState()==BlueToothChatService.STATE_NONE){

mBlueToothChatService.start();
}
}

}

/**
* 聊天设置,初始化及监听
*/
private void setupChat() {
// TODO Auto-generated method stub

//初始化ListView

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

mConversation = (ListView)findViewById(R.id.chat_list);

mConversation.setAdapter(mConversationAdapter);

//发送按钮
sendBtn = (Button)findViewById(R.id.send_btn);
sendBtn.setOnClickListener(new OnClickListener() {

@Override
public void onClick(View arg0) {
// TODO Auto-generated method stub

TextView mTextView = (TextView)findViewById(R.id.edit_text);
String message = mTextView.getText().toString();
sendMessage(message);

}

});

//Edit监听
mEdit = (EditText)findViewById(R.id.edit_text);
mEdit.setOnEditorActionListener(mWriteLisentner);
//初始化
mBlueToothChatService = new BlueToothChatService(this,handler);

mOutString = new StringBuffer("");

}

//发送信息到Handler处理
private void sendMessage(String message) {
// TODO Auto-generated method stub

if(mBlueToothChatService.getState()!=BlueToothChatService.STATE_CONNECTED){

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

return ;

}

if(message.length()>0){

//在这里发送信息
byte[] send = message.getBytes();

mBlueToothChatService.write(send);

//重置清空
mOutString.setLength(0);

mEdit.setText(mOutString);

}

}

/**
* 监听编辑器的结果
*/
private TextView.OnEditorActionListener mWriteLisentner = new TextView.OnEditorActionListener() {

@Override
public boolean onEditorAction(TextView view, int actionId, KeyEvent event) {
// TODO Auto-generated method stub
//如果结果为空,提示
if(actionId == EditorInfo.IME_NULL && event.getAction() == KeyEvent.ACTION_UP){

String message = view.getText().toString();
sendMessage(message);
}
return true;
}
};

//通过ActionBar显示
private final void setStatus(int resId){
final ActionBar actionBar = getActionBar();
actionBar.setSubtitle(resId);
}

public final void setStatus(CharSequence subTitle){
final ActionBar actionBar = getActionBar();
actionBar.setSubtitle(subTitle);
}

//handler处理机制
private Handler handler = new Handler(){

@Override
public void handleMessage(Message msg){
switch(msg.what){

case MESSAGE_STATE_CHANGE:
switch(msg.arg1){

case BlueToothChatService.STATE_CONNECTED:

setStatus( "connected to "+mConnectedServiceName);
mConversationAdapter.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;
String writemessage = new String(writebuf);
mConversationAdapter.add("Me:  "+writemessage);

break;
case MESSAGE_READ:
byte[] readbuf = (byte[])msg.obj;
String readmessage = new String(readbuf, 0, msg.arg1);
mConversationAdapter.add(mConnectedServiceName+":  "+readmessage);

break;
case MESSAGE_TOAST:
//这个好像没用到
Toast.makeText(getApplicationContext(), msg.getData().getString(TOAST), Toast.LENGTH_SHORT).show();
break;
case MESSAGE_DEVICE_NAME:
//保存链接设备的名称
mConnectedServiceName = msg.getData().getString(DEVICE_NAME);
Toast.makeText(getApplicationContext(), "connect to "+mConnectedServiceName, Toast.LENGTH_SHORT).show();
break;

}
}

};

//请求码的处理
@Override
public void onActivityResult(int requestCode,int resultCode,Intent data){

//通过请求码来判断是否与结果码一样,然后做处理
switch(requestCode){
//请求成功则链接设备
case REQUEST_CONNECT_DEVICE:
if(resultCode == Activity.RESULT_OK){
connectDevice(data);
}
break;
case REQUEST_ENABLE_BT:
if(resultCode == Activity.RESULT_OK){
//设备可用,进入setupChat()
setupChat();
}else{
Toast.makeText(getApplicationContext(), R.string.bt_not_enabled_leaving, Toast.LENGTH_SHORT).show();
finish();
}

}

}

/**
* 连接设备
* @param data
*/

public void connectDevice(Intent data) {
// TODO Auto-generated method stub
//获取Mac地址
String address = data.getExtras().
getString(DeviceListActivity.EXTRA_DEVICE_ADDRESS);

//通过地址获取设备
BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(address);

//然后连接
mBlueToothChatService.connect(device);
}

@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.connect_scan:
serverIntent = new Intent(this,DeviceListActivity.class);
startActivityForResult(serverIntent, REQUEST_CONNECT_DEVICE);

return true;

//可发现300s内
case R.id.discoverable:

ensureDiscovery();

return true;
}
return false;

}

//设置300s可被发现
private void ensureDiscovery() {
// TODO Auto-generated method stub

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

}

@Override
public synchronized void onPause(){
super.onPause();
}

@Override
public void onStop(){
super.onStop();
}

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

}


接下来是

/**
* BlueToothChatService实现的线程开启,关闭,管理以及连接
* @author micro
*
*/

public class BlueToothChatService {

private static int mState;

public static final String NAME = "BlueToothChat";

public static final UUID MY_UUID = UUID.fromString("0001101-0000-1000-8000-00805F9B34FB");

//
private final  Handler mHandler ;

//三个线程
private ConnectThread mmConnectThread ;
private ConnectedThread mmConnectedThread;
private AcceptThread mmAcceptThread;

//表示当前的连接状态
public static final int STATE_NONE = 0;
public static final int STATE_LISTEN = 1;
public static final int STATE_CONNECTING = 2;
public static final int STATE_CONNECTED = 3;

//蓝牙适配器
private BluetoothAdapter mAdapter;

//构造器初始化
public BlueToothChatService(Context context, Handler handler) {
// TODO Auto-generated constructor stub
mAdapter = BluetoothAdapter.getDefaultAdapter();
mState = STATE_NONE;
mHandler = handler;

}

//设置当前状态
public synchronized void setState(int state){

mState = state;

//UI线程处理
mHandler.obtainMessage(BlueToothChat.MESSAGE_STATE_CHANGE, state, -1).sendToTarget();

}

/**
* Return the current connection state.
*/
public synchronized int getState() {
return mState;
}

/**
* 开启AcceptThread线程
*/

public synchronized void start() {
// TODO Auto-generated method stub

if(mmConnectedThread!=null){
mmConnectedThread.cancel();
mmConnectedThread = null;
}

if(mmConnectThread!=null){
mmConnectThread.cancel();
mmConnectThread=null;
}

//服务端线程开启
if(mmAcceptThread == null){

mmAcceptThread = new AcceptThread();
mmAcceptThread.start();

}

//设置为监听状态
setState(STATE_LISTEN);

}

/**
* 开启一个设备连接线程
* @param device
*/

public synchronized void connect(BluetoothDevice device) {
// TODO Auto-generated method stub

if(mState == STATE_CONNECTING){

if(mmConnectThread!=null){
mmConnectThread.cancel();
mmConnectThread = null;
}
}

if(mmConnectedThread!=null){
mmConnectedThread.cancel();
mmConnectedThread = null;
}

//开启
mmConnectThread = new ConnectThread(device);
mmConnectThread.start();

setState(STATE_CONNECTING);

}

/**
* 开启一个已经连接的线程来管理蓝牙连接
* Start the ConnectedThread to begin managing a Bluetooth connection
* @param socket
* @param device
* @param socketType
*/
public synchronized void connected(BluetoothSocket socket,
BluetoothDevice device, final String socketType){

if(mmConnectedThread!=null){
mmConnectedThread.cancel();
mmConnectedThread = null;
}

if(mmConnectThread!=null){
mmConnectThread.cancel();
mmConnectThread = null;
}

if(mmAcceptThread!=null){
mmAcceptThread.cancel();
mmAcceptThread = null;
}

mmConnectedThread = new ConnectedThread(socket, socketType);
mmConnectedThread.start();

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

Message message = mHandler.obtainMessage(BlueToothChat.MESSAGE_DEVICE_NAME);

Bundle bundle = new Bundle();
bundle.putString(BlueToothChat.DEVICE_NAME, device.getName());

message.setData(bundle);

mHandler.sendMessage(message);

setState(STATE_CONNECTED);
}

/**
* 停止所有的线程
*/

public synchronized void stop() {
// TODO Auto-generated method stub

if(mmConnectedThread!=null){
mmConnectedThread.cancel();
mmConnectedThread = null;
}

if(mmConnectThread!=null){
mmConnectThread.cancel();
mmConnectThread = null;
}

if(mmAcceptThread!=null){
mmAcceptThread.cancel();
mmAcceptThread = 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 = mmConnectedThread;
}
// Perform the write unsynchronized
//线程调用写入方法
r.write(out);
}

/**
* failed处理
* @author micro
*
*/
public void connectionFailed(){

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

Bundle bundle = new Bundle();
bundle.putString(BlueToothChat.TOAST, "Device connection failed to connect");
msg.setData(bundle);

mHandler.sendMessage(msg);

//重启对Socket的监听线程,即服务端的线程
BlueToothChatService.this.start();

}

/**
*
* @author micro
*
*/

public void connectionLost(){

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

//重启对Socket的监听线程,即服务端的线程
BlueToothChatService.this.start();

}

//ServerSocket
private class AcceptThread extends Thread{

private final BluetoothServerSocket serverSocket;
private String socketType;

public AcceptThread(){

BluetoothServerSocket temp =null;

try {

temp = mAdapter.
listenUsingRfcommWithServiceRecord(NAME, MY_UUID);

} catch (Exception e) {
// TODO: handle exception
Log.e("listen Thread", "failed to get the temp thread");
}

serverSocket = temp;

}

@Override
public void run(){

setName("AcceptThread" + socketType);

BluetoothSocket socket = null;

//如果设备没有连接

while(mState!=STATE_CONNECTED){

try {

socket = serverSocket.accept();
Log.e("success", "success");

} catch (IOException e) {
// TODO Auto-generated catch block
Log.e("socket", "couldn't accept the socket sending");
break;
}

//如果Socket.accpt()成功
if(socket!=null){

//异步线程加载
synchronized (BlueToothChatService.this) {

switch(mState){

case STATE_LISTEN:
case STATE_CONNECTING:
Log.e("connectting or Listen", "start");
connected(socket,socket.getRemoteDevice(),socketType);
Log.e("connectting or Listen", "success");
break;

//None或者连接上的时候关闭socket
case STATE_NONE:
case STATE_CONNECTED:
try {
socket.close();
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}

break;

}

}
}

}

}

public void cancel(){
try {
serverSocket.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}

//连接线程connectThread,用于连接

private class ConnectThread extends Thread{

private BluetoothSocket mmSocket;
private BluetoothDevice mmDevice;

private String mSocketTye;

public ConnectThread(BluetoothDevice device){

mmDevice = device;

BluetoothSocket temp = null;

try {

temp = device.createRfcommSocketToServiceRecord(MY_UUID);

} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}

mmSocket = temp;

}

@Override
public void run(){

setName("ConnectThread"+mSocketTye);

//关闭扫描发现,否则会影响socket之间的连接
mAdapter.cancelDiscovery();

try {
Log.e("mmSocket", "mmSocket.connect()");
mmSocket.connect();
Log.e("mmSocket", "mmSocket.connect success");

} catch (Exception e) {
// TODO: handle exception
try {
mmSocket.close();
} catch (Exception e2) {
// TODO: handle exception

}
//连接失败
connectionFailed();
return;
}

//重置
synchronized (BlueToothChatService.this) {

mmConnectThread = null;
}

//已连接的线程Start the ConnectedThread to begin managing a Bluetooth connection
connected(mmSocket,mmDevice,mSocketTye);
}

public void cancel(){
try {
mmSocket.close();
} catch (Exception e) {
// TODO: handle exception
}
}

}

//这是一个在两个设备之间进行数据交换的线程,前提是已经连接上

private class ConnectedThread extends Thread{

private  BluetoothSocket mmSocket ;
private  InputStream mmInput ;
private  OutputStream mmOuput ;

public ConnectedThread(BluetoothSocket socket,String socketType){

mmSocket = socket;

InputStream tmpInput = null;
OutputStream tmpOutput = null;

try {

tmpInput = socket.getInputStream();
tmpOutput = socket.getOutputStream();

} catch (Exception e) {
// TODO: handle exception
}

mmInput = tmpInput;
mmOuput = tmpOutput;

}

@Override
public void run(){

byte[]  buff  =  new byte[1024];

int bytes;

while (true) {

try {
//读取
bytes = mmInput.read(buff);

//发送到UI线程处理
mHandler.obtainMessage(BlueToothChat.MESSAGE_READ,
bytes, -1, buff).sendToTarget();

} catch (IOException e) {
// TODO Auto-generated catch block
connectionLost();
BlueToothChatService.this.start();
break;
}

}

}

//写入
public void write(byte[] buff){

try {

mmOuput.write(buff);

mHandler.obtainMessage(BlueToothChat.MESSAGE_WRITE,
-1, -1, buff).sendToTarget();

} catch (Exception e) {
// TODO: handle exception
}

}

public void cancel(){
try {
mmSocket.close();
} catch (Exception e) {
// TODO: handle exception
}
}

}

}

/*关于客户端和服务端:
首先每一部设备都有服务线程和连接线程,当一部设备(A)对另一部设备(B)发起连接的时候,那么A将作为客户端,而B作为服务端,B的服务端线程的serverSocket将不断监听来自客户端的socket
即就是:socket = serverSocket.accept();
这个实现之后,才能实现彼此的聊天数据线程的连接和交换*/


接下来实现的是:

已配对列表和发现新设备的列表和开启300s蓝牙可被发现的功能

/**
* 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.
* 这个活动将以dialog的形式显示,主要通过主题设置实现
* 包含的功能有:已配对的设备列表和发现的设备列表
* 当选择任何一个选项的时候,将返回一些信息给BlueToothChat
*
*/

public class DeviceListActivity extends Activity {

public static final String EXTRA_DEVICE_ADDRESS = "device_name";

//蓝牙必备
private BluetoothAdapter mBtAdapter;
private ArrayAdapter<String> mPairDeviceArrayAdapter;         //已配对的适配器
private ArrayAdapter<String> mNewDevicesArrayAdapter;         //发现的新设备适配器

@Override
protected void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.device_list);

Button scanBtn = (Button)findViewById(R.id.button_scan);
scanBtn.setOnClickListener(new OnClickListener() {

@Override
public void onClick(View v) {
//点击之后开始扫描发现,按钮隐藏不可见
// TODO Auto-generated method stub
doDiscovery();
v.setVisibility(View.GONE);

}
});

//初始化适配器
mPairDeviceArrayAdapter = new ArrayAdapter<String>(this, R.layout.device_name);

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

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

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

pairedList.setAdapter(mPairDeviceArrayAdapter);
newList.setAdapter(mNewDevicesArrayAdapter);

pairedList.setOnItemClickListener(mDeviceClickListener);
newList.setOnItemClickListener(mDeviceClickListener);

//注册广播及状态
IntentFilter intentFilter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
this.registerReceiver(reciver, intentFilter);

intentFilter = new IntentFilter(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
this.registerReceiver(reciver, intentFilter);

//

mBtAdapter = BluetoothAdapter.getDefaultAdapter();

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

if(pairedDevices.size()>0){

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

for(BluetoothDevice device:pairedDevices){
mPairDeviceArrayAdapter.add(device.getName()+"\n"+device.getAddress());
}

}else{

String noDevice = getResources().getText(R.string.none_paired).toString();

mPairDeviceArrayAdapter.add(noDevice);
}

}

@Override
public void onDestroy(){
super.onDestroy();

if(mBtAdapter!=null){
mBtAdapter.cancelDiscovery();
}

this.unregisterReceiver(reciver);
}

private OnItemClickListener mDeviceClickListener = new OnItemClickListener() {

@Override
public void onItemClick(AdapterView<?> av, View v, int arg2,
long arg3) {
// TODO Auto-generated method stub
//停止扫描发现
mBtAdapter.cancelDiscovery();

//截取后面17位字符也就是Mac地址
String info = ((TextView)v).getText().toString();

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

Intent intent = new Intent();
intent.putExtra(EXTRA_DEVICE_ADDRESS, address);//返回了一个地址
setResult(RESULT_OK, intent);

finish();//关闭界面
}
};

public void doDiscovery() {
// TODO Auto-generated method stub

setProgressBarVisibility(true);
setTitle(R.string.scanning);
findViewById(R.id.title_new_devices).setVisibility(View.VISIBLE);

if(mBtAdapter.isDiscovering()){
mBtAdapter.cancelDiscovery();
}

mBtAdapter.startDiscovery(); //开始扫描发现

}

// The BroadcastReceiver that listens for discovered devices and
// changes the title when discovery is finished
//通过广播对扫描的设备做处理

private final BroadcastReceiver reciver = new BroadcastReceiver() {

@Override
public void onReceive(Context context, Intent intent) {
// TODO Auto-generated method stub

//获取当前的Action即就是其状态
String action = intent.getAction();

//same and then
if(BluetoothDevice.ACTION_FOUND.equals(action)){

//获取设备对象
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);

//判断该设备是否已配对
if(device.getBondState()!=BluetoothDevice.BOND_BONDED){

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

}

}else if(BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)){
//扫描结束
setProgressBarVisibility(false);
setTitle(R.string.select_device);

if(mNewDevicesArrayAdapter.getCount()==0){
String noDevice = getResources().getText(R.string.none_found).toString();
mNewDevicesArrayAdapter.add(noDevice);
}
}

}
};

}


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

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


以下是一些布局文件

device_list.xml:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<TextView android:id="@+id/title_paired_devices"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/title_paired_devices"
android:visibility="gone"
android:background="#666"
android:textColor="#fff"
android:paddingLeft="5dp"
/>
<ListView android:id="@+id/paired_devices"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:stackFromBottom="true"
android:layout_weight="1"
/>
<TextView android:id="@+id/title_new_devices"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/title_other_devices"
android:visibility="gone"
android:background="#666"
android:textColor="#fff"
android:paddingLeft="5dp"
/>
<ListView android:id="@+id/new_devices"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:stackFromBottom="true"
android:layout_weight="2"
/>
<Button android:id="@+id/button_scan"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/button_scan"
/>
</LinearLayout>

device_name.xml:
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="18sp"
android:padding="5dp"
/>

message.xml:
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="18sp"
android:padding="5dp"
/>

main.xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >

<ListView
android:id="@+id/chat_list"
android:layout_width="match_parent"
android:layout_height="0dp"
android:stackFromBottom="true"
android:transcriptMode="alwaysScroll"
android:layout_weight="1">

</ListView>

<LinearLayout
android:layout_gravity="bottom"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">

<EditText
android:id="@+id/edit_text"
android:layout_height="wrap_content"
android:layout_width="0dp"
android:layout_weight="1"
/>

<Button
android:id="@+id/send_btn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/send"/>

</LinearLayout>

</LinearLayout>

strings.xml:
<resources>

<string name="app_name">BlueToothChat</string>
<string name="send">Send</string>
<string name="not_connected">You are not connected to a device</string>
<string name="title_connecting">connecting...</string>
<string name="title_not_connected">not connected</string>

<string name="bt_not_enabled_leaving">Bluetooth was not enabled. Leaving Bluetooth Chat.</string>

<!-- Options Menu -->
<string name="connect">Connect a device</string>
<string name="discoverable">Make discoverable</string>

<!--  DeviceListActivity -->
<string name="scanning">scanning for devices...</string>
<string name="select_device">select a device to connect</string>
<string name="none_paired">No devices have been paired</string>
<string name="none_found">No devices found</string>
<string name="title_paired_devices">Paired Devices</string>
<string name="title_other_devices">Other Available Devices</string>
<string name="button_scan">Scan for devices</string>

</resources>

option_menu.xml:
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="@+id/connect_scan"
android:icon="@android:drawable/ic_menu_search"
android:title="@string/connect"
android:showAsAction="ifRoom|withText" />
<item android:id="@+id/discoverable"
android:icon="@android:drawable/ic_menu_mylocation"
android:title="@string/discoverable"
android:showAsAction="ifRoom|withText" />
</menu>

AndroidManifest.xml的Apllication部分:
<application
android:allowBackup="true"
android:icon="@drawable/app_icon"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity android:name=".BlueToothChat"
android:configChanges="orientation|keyboardHidden">
<intent-filter >
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>

<activity
android:name="DeviceListActivity"
android:label="@string/select_device"
android:theme="@android:style/Theme.Holo.Dialog"
android:configChanges="orientation|keyboardHidden"></activity>
</application>
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  蓝牙 聊天 线程