android 多个蓝牙连接电脑,android多个蓝牙装置实现连接

android多个蓝牙设备实现连接

这是主界面,分别跳动服务器界面和客户端界面

package com.hao.activity;

import android.app.Activity;

import android.app.ActivityManager;

import android.content.Context;

import android.content.Intent;

import android.os.Build;

import android.os.Bundle;

import android.view.KeyEvent;

import android.view.View;

import android.view.View.OnClickListener;

import android.widget.Button;

public class GroupChatActivity extends Activity {

/** Called when the activity is first created. */

//我是服务器按钮

Button buttonServer;

//我是客户端按钮

Button buttonClient;

//当前类跳转到聊天界面时的一个标记,用来说明是从buttonServer或者buttonClient里面进入的

public static final int clientFlag = 1;

public static final int serverFlag = 2;

public static final String FROM = "from";

int pid =Build.VERSION.SDK_INT;

@Override

public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.main);

buttonClient = (Button) findViewById(R.id.client);

buttonClient.setOnClickListener(clickListener);

buttonServer = (Button) findViewById(R.id.server);

buttonServer.setOnClickListener(clickListener);

}

OnClickListener clickListener = new OnClickListener() {

@Override

public void onClick(View v) {

// TODO Auto-generated method stub

Intent intent = null;

switch (v.getId()) {

case R.id.client:

intent = new Intent(GroupChatActivity.this, ChatAClientActivity.class);

startActivity(intent);

break;

case R.id.server:

intent = new Intent(GroupChatActivity.this, ChatServerActivity.class);

startActivity(intent);

break;

default:

break;

}

}

};

/**

* 完全退出程序

*/

public boolean onKeyDown(int keyCode, KeyEvent event) {

if (keyCode == KeyEvent.KEYCODE_BACK && event.getRepeatCount() == 0) {

if(pid<=7)

{

ActivityManager activityManager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);

activityManager.restartPackage(getPackageName());

}

else {

android.os.Process.killProcess(pid);

System.exit(0);

finish();

}

return true;

}

return super.onKeyDown(keyCode, event);

}

}

客户端界面

package com.hao.activity;

import com.hao.activity.server.Connection;

import com.hao.activity.server.Connection.OnConnectionLostListener;

import com.hao.activity.server.Connection.OnConnectionServiceReadyListener;

import com.hao.activity.server.Connection.OnMessageReceivedListener;

import android.app.Activity;

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.View;

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;

public class ChatAClientActivity extends Activity {

private Connection mConnection;

private ChatAClientActivity self;

private static final int SERVER_LIST_RESULT_CODE = 42;

// Layout Views

private TextView mTitle;

private ListView mConversationView;

private EditText mOutEditText;

private Button mSendButton;

String deviceString;

// Name of the connected device

private String mConnectedDeviceName = null;

// Array adapter for the conversation thread

private ArrayAdapter mConversationArrayAdapter;

private static final String MAC = "FB:DB:7F:D2:AA:B5";

// private static final String MAC ="D8:B3:77:9A:6A:9A";

/**

* 开启蓝牙服务器端的服务

*/

private OnConnectionServiceReadyListener serviceReadyListener = new OnConnectionServiceReadyListener() {

@Override

public void OnConnectionServiceReady() {

// TODO Auto-generated method stub

Intent serverListIntent = new Intent(self, ServerListActivity.class);

startActivityForResult(serverListIntent, SERVER_LIST_RESULT_CODE);

};

};

@Override

protected void onCreate(Bundle savedInstanceState) {

// TODO Auto-generated method stub

super.onCreate(savedInstanceState);

setContentView(R.layout.clientchat);

self = this;

mConnection = new Connection(this, serviceReadyListener);

}

@Override

protected void onStart() {

// TODO Auto-generated method stub

super.onStart();

mConversationArrayAdapter = new ArrayAdapter(this,

R.layout.message);

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

mConversationView.setAdapter(mConversationArrayAdapter);

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

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

mOutEditText.setOnEditorActionListener(mWriteListener);

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

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

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

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

sendMessage(message);

}

});

}

@Override

protected void onDestroy() {

// TODO Auto-generated method stub

super.onDestroy();

if (mConnection != null) {

mConnection.shutdown();

}

mConversationArrayAdapter.clear();

}

// The action listener for the 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;

}

};

@Override

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

if ((resultCode == Activity.RESULT_OK)

&& (requestCode == SERVER_LIST_RESULT_CODE)) {

String device = data

.getStringExtra(ServerListActivity.EXTRA_SELECTED_ADDRESS);

Toast.makeText(getApplicationContext(), device, Toast.LENGTH_SHORT)

.show();

Log.i("dds", device);

int connectionStatus = mConnection.connect(device,

dataReceivedListener, disconnectedListener);

Log.w("connectionStatus", "" + connectionStatus);

if (connectionStatus != Connection.SUCCESS) {

Toast.makeText(self, "Unable to connect; please try again.", 1)

.show();

}

return;

}

}

protected void sendMessage(String message) {

// TODO Auto-generated method stub

if (message.length() > 0) {

mConnection.sendMessage(deviceString, message);

mConversationArrayAdapter.add("我" + message);

mConversationArrayAdapter.notifyDataSetChanged();

}

}

/**

* 接收到对方发送过来的消息

*/

private OnMessageReceivedListener dataReceivedListener = new OnMessageReceivedListener() {

@Override

public void OnMessageReceived(String device, String message) {

// TODO Auto-generated method stub

deviceString = device;

Message mMessage = new Message();

mMessage.obj = message;

handler.sendMessage(mMessage);

}

};

Handler handler = new Handler() {

public void handleMessage(android.os.Message msg) {

mConversationArrayAdapter.add("她" + msg.obj);

mConversationArrayAdapter.notifyDataSetChanged();

};

};

private OnConnectionLostListener disconnectedListener = new OnConnectionLostListener() {

@Override

public void OnConnectionLost(String device) {

// TODO Auto-generated method stub

deviceString = "";

}

};

}

//服务器界面

package com.hao.activity;

import java.io.File;

import java.io.FileNotFoundException;

import java.io.FileOutputStream;

import java.io.IOException;

import java.io.Serializable;

import java.util.ArrayList;

import java.util.List;

import com.hao.activity.server.Connection;

import com.hao.activity.server.Connection.OnConnectionLostListener;

import com.hao.activity.server.Connection.OnConnectionServiceReadyListener;

import com.hao.activity.server.Connection.OnIncomingConnectionListener;

import com.hao.activity.server.Connection.OnMaxConnectionsReachedListener;

import com.hao.activity.server.Connection.OnMessageReceivedListener;

import android.R.integer;

import android.app.Activity;

import android.os.Bundle;

import android.os.Environment;

import android.os.Handler;

import android.os.Message;

import android.util.Log;

import android.view.KeyEvent;

import android.view.View;

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;

public class ChatServerActivity extends Activity {

private Connection mConnection;

private ChatServerActivity self;

// 第一个发送的消息列表

private ListView mConversationView1;

// 第二个发送的消息列表

private ListView mConversationView2;

// 第一个发送消息的输入框

private EditText mOutEditText1;

// 第二个发送消息的输入框

private EditText mOutEditText2;

// 第一个发送消息的按钮

private Button mSendButton1;

// 第二个发送消息的按钮

private Button mSendButton2;

// 当前的蓝牙设备名称

String deviceString;

// Array adapter for the conversation thread

private ArrayAdapter mConversationArrayAdapter1;

private ArrayAdapter mConversationArrayAdapter2;

// 所有连接到的蓝牙设备

List devices = new ArrayList();

int status = -1;

String sendMessage = "Dstad";

// 发送消息

private static final int SENDMESSAGE = 2;

// 接收消息

private static final int RECEIVEMESSAGE = 3;

// 保存第一个蓝牙设备发过来的内容

File file1 = null;

// 保存第二个蓝牙设备发过来的内容

File file2 = null;

// 第一个蓝牙设备保存文件时对应的FileOutputStream

FileOutputStream fileOutputStream1 = null;

// 第二个蓝牙设备保存文件时对应的FileOutputStream

FileOutputStream fileOutputStream2 = null;

// 设置一个标记,用来控制写入文件操作

boolean writeFlag1 = true;

boolean writeFlag2 = true;

// 向文件写入线程1

Thread writeThread1;

//

Thread writeThread2;

/**

* 开启服务器端的服务

*/

private OnConnectionServiceReadyListener serviceReadyListener = new OnConnectionServiceReadyListener() {

@Override

public void OnConnectionServiceReady() {

// TODO Auto-generated method stub

mConnection.startServer(2, connectedListener,

maxConnectionsListener, dataReceivedListener,

disconnectedListener);

self.setTitle("MultiScreen: " + mConnection.getName() + "-"

+ mConnection.getAddress());

}

};

@Override

protected void onCreate(Bundle savedInstanceState) {

// TODO Auto-generated method stub

super.onCreate(savedInstanceState);

setContentView(R.layout.serverchat);

self = this;

// 文件操作初始化

// 将文件保存到SD卡

if (Environment.getExternalStorageState().equals(

Environment.MEDIA_MOUNTED)) {

File sdCardDir = Environment.getExternalStorageDirectory();// 获取SDCard目录,2.2的时候为:/mnt/sdcard

// 2.1的时候为:/sdcard,所以使用静态方法得到路径会好一点。

file1 = new File(sdCardDir, "abc1.txt");

// FileOutputStream outStream;

try {

fileOutputStream1 = new FileOutputStream(file1);

} catch (FileNotFoundException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

file2 = new File(sdCardDir, "abc2.txt");

// FileOutputStream outStream;

try {

fileOutputStream2 = new FileOutputStream(file2);

} catch (FileNotFoundException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

}

mConnection = new Connection(this, serviceReadyListener);

}

@Override

protected void onStart() {

// TODO Auto-generated method stub

super.onStart();

mConversationArrayAdapter1 = new ArrayAdapter(this,

R.layout.message);

mConversationView1 = (ListView) findViewById(R.id.in_server_1);

mConversationView1.setAdapter(mConversationArrayAdapter1);

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

mOutEditText1 = (EditText) findViewById(R.id.edit_text_out_server_1);

mOutEditText1.setOnEditorActionListener(mWriteListener);

mOutEditText1.setText(sendMessage);

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

mSendButton1 = (Button) findViewById(R.id.button_send_server_1);

mSendButton1.setOnClickListener(new OnClickListener() {

public void onClick(View v) {

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

deviceString = devices.get(0);

sendServerMessage(message);

}

});

mConversationArrayAdapter2 = new ArrayAdapter(this,

R.layout.message);

mConversationView2 = (ListView) findViewById(R.id.in_server_2);

mConversationView2.setAdapter(mConversationArrayAdapter2);

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

mOutEditText2 = (EditText) findViewById(R.id.edit_text_out_server_2);

mOutEditText2.setOnEditorActionListener(mWriteListener);

mOutEditText2.setText(sendMessage);

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

mSendButton2 = (Button) findViewById(R.id.button_send_server_2);

mSendButton2.setOnClickListener(new OnClickListener() {

public void onClick(View v) {

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

deviceString = devices.get(1);

sendServerMessage(message);

}

});

}

@Override

protected void onResume() {

// TODO Auto-generated method stub

super.onResume();

}

@Override

protected void onDestroy() {

// TODO Auto-generated method stub

super.onDestroy();

if (mConnection != null) {

mConnection.shutdown();

}

if (mConversationArrayAdapter2 != null) {

mConversationArrayAdapter2.clear();

mConversationArrayAdapter2 = null;

}

if (mConversationArrayAdapter1 != null) {

mConversationArrayAdapter1.clear();

mConversationArrayAdapter1 = null;

}

if (devices != null) {

devices.clear();

devices = null;

}

// 将其当前的蓝牙设备名称设为空

deviceString = null;

// 释放文件流

if (fileOutputStream1 != null) {

try {

fileOutputStream1.close();

} catch (IOException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

fileOutputStream1 = null;

}

if (fileOutputStream2 != null) {

try {

fileOutputStream2.close();

} catch (IOException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

fileOutputStream2 = null;

}

// 关闭写入线程

writeFlag1 = false;

writeFlag2 = false;

if (writeThread1 != null) {

writeThread1.stop();

}

}

private TextView.OnEditorActionListener mWriteListener = new TextView.OnEditorActionListener() {

public boolean onEditorAction(TextView view, int actionId,

KeyEvent event) {

if (actionId == EditorInfo.IME_NULL

&& event.getAction() == KeyEvent.ACTION_UP) {

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

if (view.getId() == R.id.edit_text_out_server_1) {

deviceString = devices.get(1);

}

if (view.getId() == R.id.edit_text_out_server_2) {

deviceString = devices.get(0);

}

sendServerMessage(message);

}

return true;

}

};

public void sendServerMessage(String message) {

// TODO Auto-generated method stub

if (message.length() > 0) {

mConnection.sendMessage(deviceString, message);

int id = devices.indexOf(deviceString);

if (id == 0) {

mConversationArrayAdapter1.add(message);

mConversationArrayAdapter1.notifyDataSetChanged();

} else if (id == 1) {

mConversationArrayAdapter2.add(message);

mConversationArrayAdapter2.notifyDataSetChanged();

}

}

}

private OnMessageReceivedListener dataReceivedListener = new OnMessageReceivedListener() {

@Override

public synchronized void OnMessageReceived(String device, String message) {

// TODO Auto-generated method stub

InputMessage inputMessage = new InputMessage();

inputMessage.device = device;

inputMessage.message = message;

inputMessage.type = RECEIVEMESSAGE;

Message mMessage = new Message();

mMessage.obj = inputMessage;

handler.sendMessage(mMessage);

}

};

// 接收到的消息

String message = null;

/**

* 对UI层进行更新

*/

Handler handler = new Handler() {

public synchronized void handleMessage(android.os.Message msg) {

InputMessage inputMessage = (InputMessage) msg.obj;

int type = inputMessage.type;

switch (type) {

case SENDMESSAGE:

String device = inputMessage.device;

Toast.makeText(getApplicationContext(), "连接到" + device,

Toast.LENGTH_SHORT).show();

break;

case RECEIVEMESSAGE:

message = inputMessage.message;

boolean flag = message.startsWith("aa");

if (flag) {

//writeFlag1 = inputMessage.falg;

// 在蓝牙保持连接的情况下进行以下操作

if (writeFlag1) {

mConversationArrayAdapter1.add("" + message);

mConversationArrayAdapter1.notifyDataSetChanged();

writeThread(writeThread1, fileOutputStream1, message);

/*writeThread1 = new Thread() {

public void run() {

// 将文件保存到SD卡

if (Environment.getExternalStorageState()

.equals(Environment.MEDIA_MOUNTED)) {

try {

fileOutputStream1.write(message

.getBytes());

fileOutputStream1

.write("\n".getBytes());

fileOutputStream1.flush();

} catch (FileNotFoundException e) {

// TODO Auto-generated catch block

e.printStackTrace();

} catch (IOException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

}

};

};

writeThread1.start();*/

}

} else {

//writeFlag2 = inputMessage.falg;

// 在蓝牙保持连接的情况下进行以下操作

if (writeFlag2) {

mConversationArrayAdapter2.add("" + message);

mConversationArrayAdapter2.notifyDataSetChanged();

writeThread(writeThread2, fileOutputStream2, message);

/*writeThread2 = new Thread() {

public void run() {

// 将文件保存到SD卡

if (Environment.getExternalStorageState()

.equals(Environment.MEDIA_MOUNTED)) {

try {

fileOutputStream2.write(message

.getBytes());

fileOutputStream2

.write("\n".getBytes());

fileOutputStream2.flush();

} catch (FileNotFoundException e) {

// TODO Auto-generated catch block

e.printStackTrace();

} catch (IOException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

}

};

};

writeThread2.start();*/

}

}

message = null;

break;

default:

break;

}

};

};

public void writeThread(Thread thread,FileOutputStream fileOutputStream, String messag)

{

final String mesaage1 = messag;

final FileOutputStream fileOutputStream22 = fileOutputStream;

thread = new Thread() {

public void run() {

// 将文件保存到SD卡

if (Environment.getExternalStorageState()

.equals(Environment.MEDIA_MOUNTED)) {

try {

fileOutputStream22.write(mesaage1

.getBytes());

fileOutputStream22

.write("\n".getBytes());

fileOutputStream22.flush();

} catch (FileNotFoundException e) {

// TODO Auto-generated catch block

e.printStackTrace();

} catch (IOException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

}

};

};

thread.start();

}

private OnConnectionLostListener disconnectedListener = new OnConnectionLostListener() {

@Override

public void OnConnectionLost(String device) {

// 当连接断掉,就该将相应的往listview里面显示数据和向文件里面写入数据停止

/*int index = devices.indexOf(device);

if (index == 0) {

writeFlag1 = false;

InputMessage inputMessage = new InputMessage();

inputMessage.device = device;

inputMessage.falg = writeFlag1;

inputMessage.type = RECEIVEMESSAGE;

Message mMessage = new Message();

mMessage.obj = inputMessage;

handler.sendMessage(mMessage);

} else if (index == 1) {

writeFlag2 = false;

InputMessage inputMessage = new InputMessage();

inputMessage.device = device;

inputMessage.falg = writeFlag2;

inputMessage.type = RECEIVEMESSAGE;

Message mMessage = new Message();

mMessage.obj = inputMessage;

handler.sendMessage(mMessage);

}*/

// TODO Auto-generated method stub

deviceString = "";

}

};

private OnMaxConnectionsReachedListener maxConnectionsListener = new OnMaxConnectionsReachedListener() {

public void OnMaxConnectionsReached() {

Log.e("tag", "Max connections reached!");

}

};

/**

* 蓝牙连接成功后,发送过来连接到到地址

*/

private OnIncomingConnectionListener connectedListener = new OnIncomingConnectionListener() {

@Override

public synchronized void OnIncomingConnection(String device) {

// TODO Auto-generated method stub

if (devices.size() == 0) {

devices.add(device);

} else {

for (String str : devices) {

if (str.equals(device)) {

return;

} else {

devices.add(device);

}

}

}

InputMessage inputMessage = new InputMessage();

inputMessage.type = SENDMESSAGE;

inputMessage.device = device;

Message msg = new Message();

msg.obj = inputMessage;

handler.sendMessage(msg);

}

};

// int sum=0;

class InputMessage implements Serializable {

/**

*

*/

private static final long serialVersionUID = 1L;

// 接收或者发送的消息

String message;

// 蓝牙设备的地址

String device;

// 消息类型

int type;

// 消息的相关操作是否终止

boolean falg = true;

}

}

//搜索蓝牙设备

/*

* 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.hao.activity;

import android.app.Activity;

import android.app.ListActivity;

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.os.Parcelable;

import android.view.View;

import android.widget.AdapterView;

import android.widget.ArrayAdapter;

import android.widget.ListView;

import android.widget.TextView;

import android.widget.AdapterView.OnItemClickListener;

/**

* A simple list activity that displays Bluetooth devices that are in

* discoverable mode. This can be used as a gamelobby where players can see

* available servers and pick the one they wish to connect to.

*/

public class ServerListActivity extends ListActivity {

public static String EXTRA_SELECTED_ADDRESS = "btaddress";

private BluetoothAdapter myBt;

private ServerListActivity self;

private ArrayAdapter arrayAdapter;

private BroadcastReceiver myReceiver = new BroadcastReceiver() {

@Override

public void onReceive(Context context, Intent intent) {

Parcelable btParcel = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);

BluetoothDevice btDevice = (BluetoothDevice) btParcel;

arrayAdapter.add(btDevice.getName() + " - " + btDevice.getAddress());

// BluetoothDevice.pairRequest;

}

};

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

self = this;

arrayAdapter = new ArrayAdapter(self, R.layout.text);

ListView lv = self.getListView();

lv.setAdapter(arrayAdapter);

lv.setOnItemClickListener(new OnItemClickListener() {

public void onItemClick(AdapterView> arg0, View arg1, int arg2, long arg3) {

myBt.cancelDiscovery(); // Cancel BT discovery explicitly so

// that connections can go through

String btDeviceInfo = ((TextView) arg1).getText().toString();

String btHardwareAddress = btDeviceInfo.substring(btDeviceInfo.length() - 17);

Intent i = new Intent();

i.putExtra(EXTRA_SELECTED_ADDRESS, btHardwareAddress);

self.setResult(Activity.RESULT_OK, i);

finish();

}

});

myBt = BluetoothAdapter.getDefaultAdapter();

myBt.startDiscovery();

self.setResult(Activity.RESULT_CANCELED);

}

@Override

protected void onResume() {

super.onResume();

IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);

this.registerReceiver(myReceiver, filter);

}

@Override

protected void onPause() {

super.onPause();

this.unregisterReceiver(myReceiver);

}

@Override

protected void onDestroy() {

super.onDestroy();

if (myBt != null) {

myBt.cancelDiscovery(); // Ensure that we don't leave discovery

}

}

}

//使本机蓝牙可见

/*

* 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.hao.activity;

import android.app.Activity;

import android.app.AlertDialog.Builder;

import android.bluetooth.BluetoothAdapter;

import android.content.DialogInterface;

import android.content.Intent;

import android.content.DialogInterface.OnClickListener;

import android.os.Bundle;

import android.widget.Toast;

/**

* A simple activity that displays a prompt telling users to enable discoverable

* mode for Bluetooth.

*/

public class StartDiscoverableModeActivity extends Activity {

public static final int REQUEST_DISCOVERABLE_CODE = 42;

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

Intent i = new Intent();

i.setAction(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);

startActivityForResult(i, REQUEST_DISCOVERABLE_CODE);

}

@Override

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

if (requestCode == REQUEST_DISCOVERABLE_CODE) {

if (resultCode < 0) {

showWarning();

} else {

Toast.makeText(this, "Discoverable mode enabled.", 1).show();

finish();

}

}

}

private void showWarning() {

Builder warningDialog = new Builder(this);

final Activity self = this;

warningDialog.setTitle(R.string.DISCOVERABLE_MODE_NOT_ENABLED);

warningDialog.setMessage(R.string.WARNING_MESSAGE);

warningDialog.setPositiveButton("Yes", new OnClickListener() {

public void onClick(DialogInterface dialog, int which) {

Intent i = new Intent();

i.setAction(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);

startActivityForResult(i, REQUEST_DISCOVERABLE_CODE);

}

});

warningDialog.setNegativeButton("No", new OnClickListener() {

public void onClick(DialogInterface dialog, int which) {

Toast.makeText(self, "Discoverable mode NOT enabled.", 1).show();

finish();

}

});

warningDialog.setCancelable(false);

warningDialog.show();

}

}

//连接

/*

* 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.hao.activity.server;

import com.hao.activity.IConnection;

import com.hao.activity.IConnectionCallback;

import android.content.ComponentName;

import android.content.Context;

import android.content.Intent;

import android.content.ServiceConnection;

import android.os.IBinder;

import android.os.RemoteException;

import android.util.Log;

/**

* API for the Bluetooth Click, Link, Compete library. This library simplifies

* the process of establishing Bluetooth connections and sending data in a way

* that is geared towards multi-player games.

*/

public class Connection {

public static final String TAG = "net.clc.bt.Connection";

public static final int SUCCESS = 0;

public static final int FAILURE = 1;

public static final int MAX_SUPPORTED = 2;

public interface OnConnectionServiceReadyListener {

public void OnConnectionServiceReady();

}

public interface OnIncomingConnectionListener {

public void OnIncomingConnection(String device);

}

public interface OnMaxConnectionsReachedListener {

public void OnMaxConnectionsReached();

}

public interface OnMessageReceivedListener {

public void OnMessageReceived(String device, String message);

}

public interface OnConnectionLostListener {

public void OnConnectionLost(String device);

}

private OnConnectionServiceReadyListener mOnConnectionServiceReadyListener;

private OnIncomingConnectionListener mOnIncomingConnectionListener;

private OnMaxConnectionsReachedListener mOnMaxConnectionsReachedListener;

private OnMessageReceivedListener mOnMessageReceivedListener;

private OnConnectionLostListener mOnConnectionLostListener;

private ServiceConnection mServiceConnection;

private Context mContext;

private String mPackageName = "";

private boolean mStarted = false;

private final Object mStartLock = new Object();

private IConnection mIconnection;

private IConnectionCallback mIccb = new IConnectionCallback.Stub() {

public void incomingConnection(String device) throws RemoteException {

if (mOnIncomingConnectionListener != null) {

mOnIncomingConnectionListener.OnIncomingConnection(device);

}

}

public void connectionLost(String device) throws RemoteException {

if (mOnConnectionLostListener != null) {

mOnConnectionLostListener.OnConnectionLost(device);

}

}

public void maxConnectionsReached() throws RemoteException {

if (mOnMaxConnectionsReachedListener != null) {

mOnMaxConnectionsReachedListener.OnMaxConnectionsReached();

}

}

public void messageReceived(String device, String message)

throws RemoteException {

if (mOnMessageReceivedListener != null) {

mOnMessageReceivedListener.OnMessageReceived(device, message);

}

}

};

// TODO: Add a check to autodownload this service from Market if the user

// does not have it already.

public Connection(Context ctx, OnConnectionServiceReadyListener ocsrListener) {

mOnConnectionServiceReadyListener = ocsrListener;

mContext = ctx;

// mPackageName = ctx.getPackageName();

mPackageName = "SPP";

mServiceConnection = new ServiceConnection() {

public void onServiceConnected(ComponentName name, IBinder service) {

synchronized (mStartLock) {

mIconnection = IConnection.Stub.asInterface(service);

mStarted = true;

if (mOnConnectionServiceReadyListener != null) {

mOnConnectionServiceReadyListener

.OnConnectionServiceReady();

}

}

}

public void onServiceDisconnected(ComponentName name) {

synchronized (mStartLock) {

try {

mStarted = false;

mIconnection.unregisterCallback(mPackageName);

mIconnection.shutdown(mPackageName);

} catch (RemoteException e) {

Log.e(TAG, "RemoteException in onServiceDisconnected",

e);

}

mIconnection = null;

}

}

};

// Intent intent = new

// Intent("com.google.intent.action.BT_ClickLinkCompete_SERVICE");

Intent intent = new Intent(mContext, ConnectionService.class);

// intent.addCategory("com.google.intent.category.BT_ClickLinkCompete");

mContext.bindService(intent, mServiceConnection,

Context.BIND_AUTO_CREATE);

}

public int startServer(final int maxConnections,

OnIncomingConnectionListener oicListener,

OnMaxConnectionsReachedListener omcrListener,

OnMessageReceivedListener omrListener,

OnConnectionLostListener oclListener) {

if (!mStarted) {

return Connection.FAILURE;

}

if (maxConnections > MAX_SUPPORTED) {

Log.e(TAG, "The maximum number of allowed connections is "

+ MAX_SUPPORTED);

return Connection.FAILURE;

}

mOnIncomingConnectionListener = oicListener;

mOnMaxConnectionsReachedListener = omcrListener;

mOnMessageReceivedListener = omrListener;

mOnConnectionLostListener = oclListener;

try {

int result = mIconnection.startServer(mPackageName, maxConnections);

mIconnection.registerCallback(mPackageName, mIccb);

return result;

} catch (RemoteException e) {

Log.e(TAG, "RemoteException in startServer", e);

}

return Connection.FAILURE;

}

public int connect(String device, OnMessageReceivedListener omrListener,

OnConnectionLostListener oclListener) {

if (!mStarted) {

return Connection.FAILURE;

}

mOnMessageReceivedListener = omrListener;

mOnConnectionLostListener = oclListener;

try {

int result = mIconnection.connect(mPackageName, device);

mIconnection.registerCallback(mPackageName, mIccb);

return result;

} catch (RemoteException e) {

Log.e(TAG, "RemoteException in connect", e);

}

return Connection.FAILURE;

}

public int sendMessage(String device, String message) {

if (!mStarted) {

return Connection.FAILURE;

}

try {

return mIconnection.sendMessage(mPackageName, device, message);

} catch (RemoteException e) {

Log.e(TAG, "RemoteException in sendMessage", e);

}

return Connection.FAILURE;

}

public String getConnections() {

if (!mStarted) {

return "";

}

try {

return mIconnection.getConnections(mPackageName);

} catch (RemoteException e) {

Log.e(TAG, "RemoteException in getConnections", e);

}

return "";

}

public int getVersioxn() {

if (!mStarted) {

return Connection.FAILURE;

}

try {

return mIconnection.getVersion();

} catch (RemoteException e) {

Log.e(TAG, "RemoteException in getVersion", e);

}

return Connection.FAILURE;

}

public String getAddress() {

if (!mStarted) {

return "";

}

try {

return mIconnection.getAddress();

} catch (RemoteException e) {

Log.e(TAG, "RemoteException in getAddress", e);

}

return "";

}

public String getName() {

if (!mStarted) {

return "";

}

try {

return mIconnection.getName();

} catch (RemoteException e) {

Log.e(TAG, "RemoteException in getVersion", e);

}

return "";

}

public void shutdown() {

try {

mStarted = false;

if (mIconnection != null) {

mIconnection.shutdown(mPackageName);

}

mContext.unbindService(mServiceConnection);

} catch (RemoteException e) {

Log.e(TAG, "RemoteException in shutdown", e);

}

}

}

//server

/*

* 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.hao.activity.server;

import android.app.Service;

import android.bluetooth.BluetoothAdapter;

import android.bluetooth.BluetoothDevice;

import android.bluetooth.BluetoothServerSocket;

import android.bluetooth.BluetoothSocket;

import android.content.Intent;

import android.content.pm.PackageInfo;

import android.content.pm.PackageManager;

import android.content.pm.PackageManager.NameNotFoundException;

import android.os.IBinder;

import android.os.RemoteException;

import android.util.Log;

import java.io.BufferedReader;

import java.io.File;

import java.io.FileOutputStream;

import java.io.IOException;

import java.io.InputStream;

import java.io.InputStreamReader;

import java.io.OutputStream;

import java.util.ArrayList;

import java.util.HashMap;

import java.util.UUID;

import com.hao.activity.IConnection;

import com.hao.activity.IConnectionCallback;

import com.hao.activity.StartDiscoverableModeActivity;

import com.hao.activity.util.FetchData;

/**

* Service for simplifying the process of establishing Bluetooth connections and

* sending data in a way that is geared towards multi-player games.

*/

public class ConnectionService extends Service {

public static final String TAG = "net.clc.bt.ConnectionService";

private ArrayList mUuid;

private ConnectionService mSelf;

private String mApp; // Assume only one app can use this at a time; may

// change this later

FetchData fd = new FetchData();

private IConnectionCallback mCallback;

private ArrayList mBtDeviceAddresses;

private HashMap mBtSockets;

private HashMap mBtStreamWatcherThreads;

private BluetoothAdapter mBtAdapter;

public ConnectionService() {

mSelf = this;

mBtAdapter = BluetoothAdapter.getDefaultAdapter();

mApp = "";

mBtSockets = new HashMap();

mBtDeviceAddresses = new ArrayList();

mBtStreamWatcherThreads = new HashMap();

mUuid = new ArrayList();

mUuid.add(UUID.fromString("00001101-0000-1000-8000-00805F9B34FB"));

mUuid.add(UUID.fromString("00001101-0000-1000-8000-00805F9B34FB"));

/*

* mUuid.add(UUID.fromString("a60f35f0-b93a-11de-8a39-08002009c666"));

* mUuid.add(UUID.fromString("503c7430-bc23-11de-8a39-0800200c9a66"));

* mUuid.add(UUID.fromString("503c7431-bc23-11de-8a39-0800200c9a66"));

* mUuid.add(UUID.fromString("503c7432-bc23-11de-8a39-0800200c9a66"));

* mUuid.add(UUID.fromString("503c7433-bc23-11de-8a39-0800200c9a66"));

* mUuid.add(UUID.fromString("503c7434-bc23-11de-8a39-0800200c9a66"));

* mUuid.add(UUID.fromString("503c7435-bc23-11de-8a39-0800200c9a66"));

*/

}

@Override

public IBinder onBind(Intent arg0) {

return mBinder;

}

private class BtStreamWatcher implements Runnable {

private String address;

public BtStreamWatcher(String deviceAddress) {

address = deviceAddress;

}

public void run() {

BluetoothSocket bSock = mBtSockets.get(address);

try {

InputStream instream = bSock.getInputStream();

String message = "";

BufferedReader bufferedReader;

while (true) {

message = "";

if (instream.available() > 0) {

bufferedReader = new BufferedReader(

new InputStreamReader(instream));

if ((message = bufferedReader.readLine()) != null) {

Thread.sleep(0);

mCallback.messageReceived(address, message);

}

}

}

} catch (IOException e) {

Log

.i(

TAG,

"IOException in BtStreamWatcher - probably caused by normal disconnection",

e);

} catch (RemoteException e) {

Log

.e(

TAG,

"RemoteException in BtStreamWatcher while reading data",

e);

} catch (InterruptedException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

// Getting out of the while loop means the connection is dead.

try {

mBtDeviceAddresses.remove(address);

mBtSockets.remove(address);

mBtStreamWatcherThreads.remove(address);

mCallback.connectionLost(address);

} catch (RemoteException e) {

Log

.e(

TAG,

"RemoteException in BtStreamWatcher while disconnecting",

e);

}

}

}

private class ConnectionWaiter implements Runnable {

private String srcApp;

private int maxConnections;

public ConnectionWaiter(String theApp, int connections) {

srcApp = theApp;

maxConnections = connections;

}

public void run() {

try {

for (int i = 0; i < Connection.MAX_SUPPORTED

&& maxConnections > 0; i++) {

BluetoothServerSocket myServerSocket = mBtAdapter

.listenUsingRfcommWithServiceRecord(srcApp, mUuid

.get(i));

BluetoothSocket myBSock = myServerSocket.accept();

myServerSocket.close(); // Close the socket now that the

// connection has been made.

String address = myBSock.getRemoteDevice().getAddress();

mBtSockets.put(address, myBSock);

mBtDeviceAddresses.add(address);

Thread mBtStreamWatcherThread = new Thread(

new BtStreamWatcher(address));

mBtStreamWatcherThread.start();

mBtStreamWatcherThreads

.put(address, mBtStreamWatcherThread);

maxConnections = maxConnections - 1;

if (mCallback != null) {

mCallback.incomingConnection(address);

}

}

if (mCallback != null) {

mCallback.maxConnectionsReached();

}

} catch (IOException e) {

Log.i(TAG, "IOException in ConnectionService:ConnectionWaiter",

e);

} catch (RemoteException e) {

Log

.e(

TAG,

"RemoteException in ConnectionService:ConnectionWaiter",

e);

}

}

}

private BluetoothSocket getConnectedSocket(BluetoothDevice myBtServer,

UUID uuidToTry) {

BluetoothSocket myBSock;

try {

myBSock = myBtServer.createRfcommSocketToServiceRecord(uuidToTry);

myBSock.connect();

return myBSock;

} catch (IOException e) {

Log.i(TAG, "IOException in getConnectedSocket", e);

}

return null;

}

private final IConnection.Stub mBinder = new IConnection.Stub() {

public int startServer(String srcApp, int maxConnections)

throws RemoteException {

if (mApp.length() > 0) {

return Connection.FAILURE;

}

mApp = srcApp;

(new Thread(new ConnectionWaiter(srcApp, maxConnections))).start();

Intent i = new Intent();

i.setClass(mSelf, StartDiscoverableModeActivity.class);

i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

startActivity(i);

return Connection.SUCCESS;

}

public int connect(String srcApp, String device) throws RemoteException {

if (mApp.length() > 0) {

return Connection.FAILURE;

}

mApp = srcApp;

BluetoothDevice myBtServer = mBtAdapter.getRemoteDevice(device);

BluetoothSocket myBSock = null;

for (int i = 0; i < Connection.MAX_SUPPORTED && myBSock == null; i++) {

for (int j = 0; j < 3 && myBSock == null; j++) {

myBSock = getConnectedSocket(myBtServer, mUuid.get(i));

if (myBSock == null) {

try {

Thread.sleep(200);

} catch (InterruptedException e) {

Log.e(TAG, "InterruptedException in connect", e);

}

}

}

}

if (myBSock == null) {

return Connection.FAILURE;

}

mBtSockets.put(device, myBSock);

mBtDeviceAddresses.add(device);

Thread mBtStreamWatcherThread = new Thread(new BtStreamWatcher(

device));

mBtStreamWatcherThread.start();

mBtStreamWatcherThreads.put(device, mBtStreamWatcherThread);

return Connection.SUCCESS;

}

public int broadcastMessage(String srcApp, String message)

throws RemoteException {

if (!mApp.equals(srcApp)) {

return Connection.FAILURE;

}

for (int i = 0; i < mBtDeviceAddresses.size(); i++) {

sendMessage(srcApp, mBtDeviceAddresses.get(i), message);

}

return Connection.SUCCESS;

}

public String getConnections(String srcApp) throws RemoteException {

if (!mApp.equals(srcApp)) {

return "";

}

String connections = "";

for (int i = 0; i < mBtDeviceAddresses.size(); i++) {

connections = connections + mBtDeviceAddresses.get(i) + ",";

}

return connections;

}

public int getVersion() throws RemoteException {

try {

PackageManager pm = mSelf.getPackageManager();

PackageInfo pInfo = pm

.getPackageInfo(mSelf.getPackageName(), 0);

return pInfo.versionCode;

} catch (NameNotFoundException e) {

Log.e(TAG, "NameNotFoundException in getVersion", e);

}

return 0;

}

public int registerCallback(String srcApp, IConnectionCallback cb)

throws RemoteException {

if (!mApp.equals(srcApp)) {

return Connection.FAILURE;

}

mCallback = cb;

return Connection.SUCCESS;

}

public int sendMessage(String srcApp, String destination, String message)

throws RemoteException {

if (!mApp.equals(srcApp)) {

return Connection.FAILURE;

}

try {

BluetoothSocket myBsock = mBtSockets.get(destination);

if (myBsock != null) {

OutputStream outStream = myBsock.getOutputStream();

byte[] stringAsBytes = (message + " ").getBytes();

stringAsBytes[stringAsBytes.length - 1] = 0; // Add a stop

// marker

outStream.write(stringAsBytes);

return Connection.SUCCESS;

}

} catch (IOException e) {

Log.i(TAG, "IOException in sendMessage - Dest:" + destination

+ ", Msg:" + message, e);

}

return Connection.FAILURE;

}

public void shutdown(String srcApp) throws RemoteException {

try {

for (int i = 0; i < mBtDeviceAddresses.size(); i++) {

BluetoothSocket myBsock = mBtSockets.get(mBtDeviceAddresses

.get(i));

myBsock.close();

}

mBtSockets = new HashMap();

mBtStreamWatcherThreads = new HashMap();

mBtDeviceAddresses = new ArrayList();

mApp = "";

} catch (IOException e) {

Log.i(TAG, "IOException in shutdown", e);

}

}

public int unregisterCallback(String srcApp) throws RemoteException {

if (!mApp.equals(srcApp)) {

return Connection.FAILURE;

}

mCallback = null;

return Connection.SUCCESS;

}

public String getAddress() throws RemoteException {

return mBtAdapter.getAddress();

}

public String getName() throws RemoteException {

return mBtAdapter.getName();

}

};

}

//两个aidl文件

/*

* 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.

*/

/**

* AIDL for the Bluetooth Connect, Link, Compete Service

* IConnection.java is autogenerated from this

*/

package com.hao.activity;

// TODO: Ideally, we would import BluetoothDevice here

// and use that instead of just a String in the connect

// method for better type safety, but this is currently

// not possible yet.

import com.hao.activity.IConnectionCallback;

// Declare the interface.

interface IConnection {

String getAddress();

String getName();

int startServer(in String srcApp, in int maxConnections);

int connect(in String srcApp, in String device);

int sendMessage(in String srcApp, in String device, in String message);

int broadcastMessage(in String srcApp, in String message);

String getConnections(in String srcApp);

int getVersion();

int registerCallback(in String srcApp, IConnectionCallback cb);

int unregisterCallback(in String srcApp);

void shutdown(in String srcApp);

}

/*

* 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.

*/

/**

* AIDL for the Bluetooth Connect, Link, Compete Service

* IConnectionCallback.java is autogenerated from this

*/

package com.hao.activity;

// Declare the interface.

oneway interface IConnectionCallback {

void incomingConnection(String device);

void maxConnectionsReached();

void messageReceived(String device, String message);

void connectionLost(String device);

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值