前段时间写了个安卓蓝牙联机对战的游戏,写的也不怎么好,现在想写成个博客记录下
public class AppActivity extends Cocos2dxActivity {
public Cocos2dxGLSurfaceView onCreateView() {
Cocos2dxGLSurfaceView glSurfaceView = new Cocos2dxGLSurfaceView(this);
glSurfaceView.setEGLConfigChooser(5, 6, 5, 0, 16, 8);
return glSurfaceView;
}
// work for not static func
private static Cocos2dxActivity sContext = null;
public static Context getContext() {
return sContext;
}
//服务端和游戏端
enum ServerOrCilent {
NONE,
SERVICE,
CILENT
};
//安卓调用 c++ 向游戏中发送消息 private native void StringFromJni(ArrayList<ChatMessage> str);
public native int get();
public native void set(int i);
private native void SendTo(String msg);
private native void SendMsgForServer(String msg);
private native void SendMsgForClient(String msg);
public static AppActivity instance;
private BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
private BluetoothDevice device;
private ListView mListView;
private ArrayList<ChatMessage> list = new ArrayList<ChatMessage>();
private ServerOrCilent serverorcilent = ServerOrCilent.NONE;
private BluetoothSocket socket; // 客户端socket
private ClientThread mClientThread; // 客户端运行线程
private BluetoothServerSocket mserverSocket; // 服务端socket
private ServerThread mserverThread; // 服务端运行线程
private ReadThread mreadThread; // 读取流线程
public static final String PROTOCOL_SCHEME_L2CAP = "btl2cap";
public static final String PROTOCOL_SCHEME_RFCOMM = "btspp";
public static final String PROTOCOL_SCHEME_BT_OBEX = "btgoep";
public static final String PROTOCOL_SCHEME_TCP_OBEX = "tcpobex";
private String address;
//UUID可以看做一个端口号
private static final UUID MY_UUID =
UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");
public static Object getInstance()
{
if (instance==null){
instance = new AppActivity();
}
return instance;
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
instance = this;
Log.e("leeeee","AppActivity onCreate ------------------------");
}
@Override
protected void onDestroy() {
unregisterReceiver(mReceiver);
super.onDestroy();
}
/**
* 打开蓝牙
* 返回0 : 没有蓝牙硬件或驱动
* 返回1 : 打开了蓝牙
* 返回2 : 以打开
*/
public String openBlueToot(int type)
{
if (mBluetoothAdapter == null) {
return "0";
}
if(!mBluetoothAdapter.isEnabled())
{
//请求用户开启
//Intent intent=new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
//startActivityForResult(intent, RESULT_FIRST_USER);
//使蓝牙设备可见,方便配对
//直接开启,不经过提示
mBluetoothAdapter.enable();
if(type == 1)
{
Intent in=new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
in.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 300);
startActivity(in);
}
String name = mBluetoothAdapter.getName();
serverorcilent = ServerOrCilent.SERVICE;
return name;
}else{
if(type == 1)
{
Intent in=new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
in.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 300);
startActivity(in);
}
return mBluetoothAdapter.getName();
}
}
/* 关闭蓝牙 */
public void CloseBlueToot()
{
mBluetoothAdapter.disable();
}
/**
* JNI
* 扫描蓝牙
*/
public void findBuleToots()
{
Log.e("leeeee","findBuleToots ------------------------");
serverorcilent = ServerOrCilent.CILENT;
IntentFilter filterFound = new IntentFilter(BluetoothDevice.ACTION_FOUND);
filterFound.addAction(BluetoothDevice.ACTION_BOND_STATE_CHANGED);
filterFound.addAction(BluetoothAdapter.ACTION_DISCOVERY_STARTED);
filterFound.addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
filterFound.addAction(BluetoothAdapter.ACTION_STATE_CHANGED);
filterFound.addAction(BluetoothAdapter.ACTION_SCAN_MODE_CHANGED);
registerReceiver(mReceiver, filterFound);
mBluetoothAdapter.startDiscovery();
}
private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
Log.e("leeeee","BroadcastReceiver ------------------------");
if (BluetoothDevice.ACTION_FOUND.equals(action))
{
device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
Log.e("leeeee","BluetoothDevice addddd 2------------------------"+device.getName()+"_"+device.getAddress());
if(device.getName()!= null)
{
ChatMessage chmsg = new ChatMessage(device.getName(), device.getAddress());
if(list.indexOf(chmsg) == -1)// 防止重复添加
{
list.add(chmsg);
StringFromJni(list);
}
}
}
else if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action))
{
Log.e("leeeee","BluetoothDevice nooooooooo 2------------------------");
if(list.size() == 0){
//list.add(new ChatMessage("no_device", "00"));
//StringFromJni(list);
}
}
}
};
//搜索到所有的蓝牙设备后 选择一个服务器的地址
public void chooseBlueDevice(String addr)
{
Log.d("leeeee", "chooseBlueDevice 1..........................");
mBluetoothAdapter.cancelDiscovery(); //取消搜索
//判断给定地址下的device是否已经配对
BluetoothDevice device1 = mBluetoothAdapter.getRemoteDevice(addr);
if(device1.getBondState() == BluetoothDevice.BOND_NONE){
try{
Method createBondMethod = BluetoothDevice.class
.getMethod("createBond");
Log.d("leeeee", "chooseBlueDevice 2..........................");
Boolean returnValue = (Boolean) createBondMethod.invoke(device1);
if(returnValue)
{
device = device1;
address = addr;
Log.e("leeeee","chooseBlueDevice success------------------------"+device1.getName());
MyThread mt = new MyThread();
mt.start();
}else{
Log.e("leeeee","chooseBlueDevice failed------------------------"+device1.getName());
}
}catch(Exception e){
Log.e("leeeee","chooseBlueDevice bagin------------------------"+device1.getName());
}
} else if(device1.getBondState() == BluetoothDevice.BOND_BONDED){ //已经配对成功
Log.d("leeeee", "已经配对成功 2..........................");
device = device1;
address = addr;
buildClientConnect();
}
}
private class MyThread extends Thread {
public void run()
{
boolean istemp = true;
while(istemp)
{
Set<BluetoothDevice> set = mBluetoothAdapter.getBondedDevices();
for(BluetoothDevice dev : set)
{
if(dev.getAddress().equals(address))
{
istemp = false;
buildClientConnect();
this.interrupt();
break;
}
}
}
}
}
/**
* JNI
* 建立服务器 选择的一个用户
*/
public void buildServerConnect()
{
mserverThread = new ServerThread();
mserverThread.start();
}
/**
* JNI
* 建立客户端 选择的一个用户
*/
public void buildClientConnect()
{
mClientThread = new ClientThread();
mClientThread.start();
}
//开启服务器
private class ServerThread extends Thread {
public void run() {
try {
/* 创建一个蓝牙服务器
* 参数分别:服务器名称、UUID */
mserverSocket = mBluetoothAdapter.listenUsingRfcommWithServiceRecord(PROTOCOL_SCHEME_RFCOMM,
MY_UUID);
Log.e("leeeee", "Server wait cilent connect*************************");
/* 接受客户端的连接请求 */
socket = mserverSocket.accept();
Log.e("leeeee", "Server accept success***********************************");
//启动接受数据
mreadThread = new ReadThread();
mreadThread.start();
} catch (IOException e) {
e.printStackTrace();
}
}
};
// 开启客户端连接服务端
private class ClientThread extends Thread {
@Override
public void run() {
if (device != null) {
try {
socket = device.createRfcommSocketToServiceRecord(MY_UUID);
Log.e("leeeee", "Client loading***********************************");
// 通过socket连接服务器,这是一个阻塞过程,直到连接建立或者连接失效
if (!socket.isConnected()) {
socket.connect();
}
Log.e("leeeee", "ClientThread success***********************************");
sendMessageHandle("ClientThread_success_Server_BubbleGame");
// 可以开启读数据线程
mreadThread = new ReadThread();
mreadThread.start();
} catch (IOException e) {
Log.e("leeeee", "ClientThread error***********************************"+e.getMessage());
if(serverorcilent == ServerOrCilent.CILENT)
{
SendMsgForClient("Connect_error");
}else{
SendMsgForServer("Connect_error");
}
}
}
}
}
//发送数据
public void sendMessageHandle(String msg)
{
if (socket == null)
{
//Toast.makeText(mContext, "没有连接", Toast.LENGTH_SHORT).show();
return;
}
try {
Log.e("Leeeeee","send... ------------------------"+msg);
OutputStream os = socket.getOutputStream();
os.write(msg.getBytes());
} catch (IOException e) {
//如果断开连接 发送错误代码 -5
if(serverorcilent == ServerOrCilent.CILENT)
{
SendMsgForClient("State_-5");
}else{
SendMsgForServer("State_-5");
}
e.printStackTrace();
}
}
// 通过socket获取InputStream流
private class ReadThread extends Thread {
@Override
public void run() {
// TODO Auto-generated method stub
byte[] buffer = new byte[1024];
int bytes;
InputStream is = null;
try {
is = socket.getInputStream();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
while(true) {
try {
if ((bytes = is.read(buffer)) > 0) {
byte[] data = new byte[bytes];
for (int i = 0; i < data.length; i++) {
data[i] = buffer[i];
}
String s = new String(data);
Log.e("Leeeeee","read... ------------------------"+s);
if(serverorcilent == ServerOrCilent.CILENT)
{
if(s.equals("ClientThread_success"))
{
SendTo("ClientThread_success");
}else{
SendMsgForClient(s);
}
}else{
if(s.equals("ClientThread_success")){
SendTo("ClientThread_success");
sendMessageHandle("ClientThread_success");
}else{
SendMsgForServer(s);
}
}
}
} catch (IOException e) {
try {
is.close();
} catch (IOException e1) {
e1.printStackTrace();
}
break;
}
}
}
}
/* 停止服务器 */
private void shutdownServer() {
new Thread() {
public void run() {
if(mserverThread != null)
{
mserverThread.interrupt();
mserverThread = null;
}
if(mreadThread != null)
{
mreadThread.interrupt();
mreadThread = null;
}
try {
if(socket != null)
{
socket.close();
socket = null;
}
if (mserverSocket != null)
{
mserverSocket.close();/* 关闭服务器 */
mserverSocket = null;
}
} catch (IOException e) {
Log.e("server", "mserverSocket.close()", e);
}
};
}.start();
}
/* 停止客户端连接 */
private void shutdownClient() {
new Thread() {
public void run() {
if(mClientThread!=null)
{
mClientThread.interrupt();
mClientThread= null;
}
if(mreadThread != null)
{
mreadThread.interrupt();
mreadThread = null;
}
//modify begin ---------
if (mBluetoothAdapter != null && mBluetoothAdapter.isDiscovering()) {
mBluetoothAdapter.cancelDiscovery();
}
//modify end ---------
if (socket != null) {
try {
socket.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
socket = null;
}
};
}.start();
}
}
// 消息体
public class ChatMessage {
private String name;
private String address;
public ChatMessage(String name, String address) {
this.name = name;
this.address = address;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
}