package com.example.bluetoothtest;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.util.ArrayList;
import java.util.UUID;
import android.app.Activity;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothServerSocket;
import android.bluetooth.BluetoothSocket;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
/***
*
* @author 张章
*
*/
public class MainActivity extends Activity {
TextView t1,t2,t3;
EditText et;
Button but,but2,but3,but4,but5,but6,but7,but8,but9;
ArrayList<BluetoothDevice>deList=new ArrayList<BluetoothDevice>();
//连接后获取输出流
OutputStream outputStream;
BluetoothAdapter bluetooth;
String uuid="a60f35f0-b93a-11de-8a39-08002009c666";//服务端蓝牙设备的UUID
Handler handler=new Handler(){
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
if(msg.what==-1){
Toast.makeText(getApplicationContext(), "等待用户连接。。。。", 1).show();
}
if(msg.what==-2){
Toast.makeText(getApplicationContext(), "已与用户连接。。。。", 1).show();
}
if(msg.what==-3){
Toast.makeText(getApplicationContext(), "等待服务端接受。。。。", 1).show();
}
if(msg.what==-4){
Toast.makeText(getApplicationContext(), "服务端已接受。。。。", 1).show();
}
if(msg.what==1){
Toast.makeText(getApplicationContext(), "接收"+(String)msg.obj, 1).show();
}
if(msg.what==2){
Toast.makeText(getApplicationContext(), "发送 "+(String)msg.obj, 1).show();
}
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
t1=(TextView) findViewById(R.id.t1);
t2=(TextView) findViewById(R.id.t2);
t3=(TextView) findViewById(R.id.t3);
et=(EditText) findViewById(R.id.et);
but=(Button) findViewById(R.id.but);
but2=(Button) findViewById(R.id.but2);
but3=(Button) findViewById(R.id.but3);
but4=(Button) findViewById(R.id.but4);
but5=(Button) findViewById(R.id.but5);
but6=(Button) findViewById(R.id.but6);
but7=(Button) findViewById(R.id.but7);
but8=(Button) findViewById(R.id.but8);
but9=(Button) findViewById(R.id.but9);
//安卓手机可能有多个蓝牙适配器,目前只能使用默认蓝牙适配器,通过该方法可以获取到默认适配器
bluetooth=BluetoothAdapter.getDefaultAdapter();
//启用和禁用BluetoothAdapter是耗时的异步操作,需注册Receiver监听状态变化
registerReceiver(new MyReceiver(), new IntentFilter(BluetoothAdapter.ACTION_STATE_CHANGED));
//调用startDiscovery()方法可以开启设备扫描,注册该Receiver可以收到扫描状态变化(开始扫描还是结束扫描)
registerReceiver(new SearchReceiver(), new IntentFilter(BluetoothAdapter.ACTION_DISCOVERY_STARTED));
registerReceiver(new SearchReceiver(), new IntentFilter(BluetoothAdapter.ACTION_DISCOVERY_FINISHED));
//调用startDiscovery()方法可以开启设备扫描,注册该Receiver可以收到扫描到的设备
//通过(BluetoothDevice) intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE)
//可以获得扫描到的设备
registerReceiver(new SearchDeviceReceiver(), new IntentFilter(BluetoothDevice.ACTION_FOUND));
but.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View arg0) {
if(bluetooth.setName(et.getText().toString())){
Toast.makeText(getApplicationContext(), "设置成功", 1).show();
}else
Toast.makeText(getApplicationContext(), "设置失败", 1).show();
}
});
//加入 <uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>权限
//后可以直接使用enable()方法启动本机蓝牙适配器,并且可以修改蓝牙友好名称
but2.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View arg0) {
bluetooth.enable();
}
});
//使用下面语句可以弹出对话框提示是否开启,onActivityResult()方法可获取用户选项
but3.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View arg0) {
startActivityForResult(new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE),1);
}
});
but4.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View arg0) {
if(bluetooth.isEnabled()){
t1.setText("地址"+bluetooth.getAddress());
t2.setText("名称"+bluetooth.getName());
t3.setText("可见性"+bluetooth.getScanMode());
}else
Toast.makeText(getApplicationContext(), "蓝牙不可用", 1).show();
}
});
//修改本机蓝牙可见时间
but5.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View arg0) {
Intent intent=new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
intent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 1200);
startActivityForResult(intent, 2);
}
});
but6.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View arg0) {
if(bluetooth.isEnabled()){
deList.clear();
bluetooth.startDiscovery();
}
}
});
but7.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View arg0) {
createServer();
}
});
but8.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View arg0) {
linktoServer();
}
});
but9.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View arg0) {
send();
}
});
}
private void linktoServer() {
try {
BluetoothDevice bluetoothDevice=deList.get(0);
bluetoothDevice.getAddress();
final BluetoothSocket bluetoothSocket=bluetoothDevice.createRfcommSocketToServiceRecord(UUID.fromString(uuid));
new Thread(){
@Override
public void run() {
try {
handler.sendEmptyMessage(-3);
bluetoothSocket.connect();
handler.sendEmptyMessage(-4);
outputStream=bluetoothSocket.getOutputStream();
getInfo(bluetoothSocket);
} catch (Exception e) {
e.printStackTrace();
}
};
}.start();
} catch (Exception e) {
e.printStackTrace();
}
}
//创建服务端,类似于Socket编程
private void createServer() {
try {
final BluetoothServerSocket btserver = bluetooth.listenUsingRfcommWithServiceRecord("server", UUID.fromString(uuid));
new Thread(){
@Override
public void run() {
try {
while(true){
handler.sendEmptyMessage(-1);
final BluetoothSocket serverSocket = btserver.accept();//阻塞式方法,需开线程
handler.sendEmptyMessage(-2);
outputStream=serverSocket.getOutputStream();
new Thread(){//当有新连接时,交给新线程完成
public void run() {
getInfo(serverSocket);
};
}.start();
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
};
}.start();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
private void send() {
String ss=et.getText().toString().trim();
try {
BufferedWriter bw=new BufferedWriter(new OutputStreamWriter(outputStream));
bw.write(ss);
bw.newLine();//注意换行
bw.flush();//刷新缓存
Message msg=new Message();
msg.obj=ss;
msg.what=2;
handler.sendMessage(msg);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
private void getInfo(BluetoothSocket serverSocket) {
try {
InputStream inputStream=serverSocket.getInputStream();
BufferedReader br=new BufferedReader(new InputStreamReader(inputStream));
while(true){
String msg=br.readLine();
Message msgs=new Message();
msgs.obj=msg;
msgs.what=1;
handler.sendMessage(msgs);
}
} catch (IOException e) {
}
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if(requestCode==1&&resultCode==RESULT_OK){
Toast.makeText(getApplicationContext(), "蓝牙已启用(onActivityResult)", 1).show();
}
if(requestCode==2&&resultCode!=RESULT_CANCELED){
Toast.makeText(getApplicationContext(), "蓝牙可见时间已修改"+requestCode+"(onActivityResult)", 1).show();
}
}
private class MyReceiver extends BroadcastReceiver{
@Override
public void onReceive(Context arg0, Intent intent) {
int state=intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, -1);
if(state==BluetoothAdapter.STATE_TURNING_ON)
Toast.makeText(getApplicationContext(), "蓝牙正在开启", 1).show();
if(state==BluetoothAdapter.STATE_ON)
Toast.makeText(getApplicationContext(), "蓝牙已经开启", 1).show();
if(state==BluetoothAdapter.STATE_TURNING_OFF)
Toast.makeText(getApplicationContext(), "蓝牙正在关闭", 1).show();
if(state==BluetoothAdapter.STATE_OFF)
Toast.makeText(getApplicationContext(), "蓝牙已关闭", 1).show();
}
}
private class SearchReceiver extends BroadcastReceiver{
@Override
public void onReceive(Context arg0, Intent intent) {
if(BluetoothAdapter.ACTION_DISCOVERY_STARTED.equals(intent.getAction())){
Toast.makeText(getApplicationContext(), "启动发现。。。", 1).show();
}
if(BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(intent.getAction())){
Toast.makeText(getApplicationContext(), "发现结束。。。", 1).show();
}
}
}
private class SearchDeviceReceiver extends BroadcastReceiver{
@Override
public void onReceive(Context arg0, Intent intent) {
et.append(intent.getStringExtra(BluetoothDevice.EXTRA_NAME)+"\n");
Toast.makeText(getApplicationContext(), intent.getStringExtra(BluetoothDevice.EXTRA_NAME), 1).show();
try{
deList.add((BluetoothDevice) intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE));
Toast.makeText(getApplicationContext(), "发现设备", 1).show();
}catch(Exception e){}
}
}
}
布局文件如下
<pre name="code" class="html"><ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:orientation="vertical"
>
<TextView
android:id="@+id/t1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="t1" />
<TextView
android:id="@+id/t2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="t2" />
<TextView
android:id="@+id/t3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="t3" />
<EditText
android:id="@+id/et"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
/>
<Button
android:id="@+id/but"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="设置名称" />
<Button
android:id="@+id/but2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="自动开启" />
<Button
android:id="@+id/but3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="提示开启" />
<Button
android:id="@+id/but4"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="获取信息" />
<Button
android:id="@+id/but5"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="修改可见性" />
<Button
android:id="@+id/but6"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="查找设备" />
<Button
android:id="@+id/but7"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="创建服务端" />
<Button
android:id="@+id/but8"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="连接到服务端" />
<Button
android:id="@+id/but9"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="发送" />
</LinearLayout>
</ScrollView>
manifest文件
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.bluetoothtest"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="18" />
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name="com.example.bluetoothtest.MainActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
<uses-permission android:name="android.permission.BLUETOOTH"/>
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
</manifest>
注意:安卓手机A,安卓手机B都要安装这款软件,并都点击 提示开启(或自动开启),接着安卓手机A点击 修改可见性 并点击 创建服务端 ,安卓手机B点击查找设备,若找到的第一个设备为安卓手机A,B手机点击 链接到服务端 ,等提示 已经连接 后就可以在文本框中输入文字,然后点击 发送 了
请安装到手机上使用!
工程下载地址 http://pan.baidu.com/s/1eQ3nc3o