在应用到应用的通信中,应用使用蓝牙发现另一播发该应用想要访问的服务的应用。如果应用找到范围内的提供此服务的另一应用,则发起连接请求。当两个应用均接受连接时,将在两者之间打开流套接字,应用通过它进行通讯。(应用应该是相同)
蓝牙API,windows phone 8扩展:
PeerFinder
提供发现附近设备上的另一应用实例的能力,并在这些对等方应用之间建立套接字连接。对等方应用是运行在另一设备上的另一应用实例。
包含标识对等应用或设备的信息。
StreamSocket
支持使用 TCP 流套接字的网络通信。
支持使用 TCP 流套接字的网络通信。
ConnectionRequestedEventArgs
包含通过 ConnectionRequested 事件传递给应用的属性。
在WMAppManifest.xml 中指定:
应用到应用
ID_CAP_PROXIMITY
应用到设备
ID_CAP_PROXIMITY、ID_CAP_NETWORKING
一下代码是综合这两个资料自己写的,林政的代码有点问题,msdn上有个地方有不同意见。
定义全局变量
StreamSocket
_socket;
//socket数据流对象
DataWriter
_dataWriter;
//数据写入对象,将数据写入到输出流
DataReader
_dataReader;
//数据读取对象,从输入流中读取数据
protected
override
void
OnNavigatedTo(
NavigationEventArgs
e)
{
base
.OnNavigatedTo(e);
//一定要在FindAllPeersAsync之前调用,显示自己的蓝牙,让别人能发现
PeerFinder
.Start();
//远程对等类使用ConnectAsync时发生
PeerFinder
.ConnectionRequested+=PeerFinder_ConnectionRequested;
}
protected
override
void
OnNavigatedFrom(
NavigationEventArgs
e)
{
base
.OnNavigatedFrom(e);
PeerFinder
.ConnectionRequested -= PeerFinder_ConnectionRequested;
//stop:节约电量,避免像在程序中打开蓝牙,返回键回来当前页面时能正确提示,而不会一直显示打开蓝牙
CloseConnection(
false
);
}
点击搜索的时候调用
private
async
void
Search_Click(
object
sender,
RoutedEventArgs
e)
{
try
{
//找到所有的
var
peers =
await
PeerFinder
.FindAllPeersAsync();
if
(peers.Count == 0)
{
MessageBox
.Show(
"没有可以对接的应用"
);
}
else
{
listbox.ItemsSource = peers;
if
(listbox.Items.Count == 1)
listbox.SelectedIndex = 0;
}
}
catch
(
Exception
ex)
{
if
((
uint
)ex.HResult == 0x8007048F)
{
var
result =
MessageBox
.Show(
"是否打开蓝牙开关"
,
"蓝牙"
,
MessageBoxButton
.OKCancel);
if
(result ==
MessageBoxResult
.OK)
{
//打开蓝牙设置
ConnectionSettingsTask
connectionSettingsTask =
new
ConnectionSettingsTask
();
connectionSettingsTask.ConnectionSettingsType =
ConnectionSettingsType
.Bluetooth;
connectionSettingsTask.Show();
}
}
else
{
MessageBox
.Show(ex.Message);
}
}
}
点击连接的时候调用
private
void
OnLink(
object
sender,
RoutedEventArgs
e)
{
Button
btn = sender
as
Button
;
PeerInformation
peerInfo = btn.DataContext
as
PeerInformation
;
ConnectToPeer(peerInfo);
}
创建连接套接字
private
async
void
ConnectToPeer(
PeerInformation
peer)
{
try
{
//连接到一个对等类
_socket =
await
PeerFinder
.ConnectAsync(peer);
// We can preserve battery by not advertising our presence.
PeerFinder
.Stop();
//读取信息
PeerFinder_StartReader();
}
catch
{
MessageBox
.Show(
"目标主机未开启"
);
//msdn上是false,个人觉得应该为true
CloseConnection(
true
);
}
}
在调用
ConnectAsync时会触发事件,调用该事件委托
private
void
PeerFinder_ConnectionRequested(
object
sender,
ConnectionRequestedEventArgs
args)
{
this
.Dispatcher.BeginInvoke(() =>
{
try
{
var
result =
MessageBox
.Show(
string
.Format(
"是否接受{0}的链接请求"
, args.PeerInformation.DisplayName),
"对接"
,
MessageBoxButton
.OKCancel);
if
(result ==
MessageBoxResult
.OK)
{
txtshow.Text +=
"开始chat\n"
;
ConnectToPeer(args.PeerInformation);
}
else
{
}
}
catch
(
Exception
ex)
{
MessageBox
.Show(ex.Message);
CloseConnection(
true
);
//重置
}
});
}
读取信息,时刻等待,异步
async
void
PeerFinder_StartReader()
{
try
{
var
message =
await
GetMessage();
txtshow.Text += message;
PeerFinder_StartReader();
}
catch
{
MessageBox
.Show(
"读出数据不正确"
);
CloseConnection(
true
);
txtshow.Text +=
"\nchat End!"
;
}
}
private
async
Task
<
string
> GetMessage()
{
if
(_dataReader ==
null
)
_dataReader =
new
DataReader
(_socket.InputStream);
await
_dataReader.LoadAsync(
sizeof
(
uint
));
uint
strLength = (
uint
)_dataReader.ReadInt32();
//读出消息的长度
await
_dataReader.LoadAsync(strLength);
return
_dataReader.ReadString(strLength);
//读出的字符串
}
发送信息。
private
void
SendMessage_Tap_1(
object
sender, System.Windows.Input.
GestureEventArgs
e)
{
SendMessage(txtMessage.Text);
}
private
async
void
SendMessage(
string
message)
{
if
(message.Trim().Length == 0)
{
MessageBox
.Show(
"输入为空"
);
return
;
}
if
(_socket ==
null
)
{
MessageBox
.Show(
"Socket Error"
);
return
;
}
if
(_dataWriter ==
null
)
_dataWriter =
new
DataWriter
(_socket.OutputStream);
//写入信息的长度
_dataWriter.WriteInt32(message.Length);
await
_dataWriter.StoreAsync();
//写入的字符串
_dataWriter.WriteString(message);
await
_dataWriter.StoreAsync();
}
主界面:
<
Grid
x
:
Name
="ContentPanel"
Grid.Row
="1"
Margin
="12,0,12,0">
<
StackPanel
>
<
Button
Content
="通过蓝牙查找应用设备"
HorizontalAlignment
="Center"
VerticalAlignment
="Top"
Click
="Search_Click"/>
<
ListBox
Name
="listbox">
<
ListBox.ItemTemplate
>
<
DataTemplate
>
<
StackPanel
Orientation
="Horizontal">
<
TextBlock
Text
="{
Binding
DisplayName
}"/>
<
TextBlock
Text
="{
Binding
ServiceName
}"/>
<
Button
Content
="链接"
Width
="308"
Height
="91"
VerticalAlignment
="Top"
Click
="OnLink"/>
</
StackPanel
>
</
DataTemplate
>
</
ListBox.ItemTemplate
>
</
ListBox
>
<
StackPanel
Orientation
="Horizontal">
<
TextBox
x
:
Name
="txtMessage"
Width
="350"/>
<
Button
x
:
Name
="btnSendMessage"
Content
="Send"
Tap
="SendMessage_Tap_1"/>
</
StackPanel
>
<
TextBlock
Name
="txtshow"/>
</
StackPanel
>
</
Grid
>
参考资料: