Android 谷歌附近-连接API-发现不工作
因此,最近我和我的朋友考虑创建一个应用程序,允许连接设备之间的实时通信,而不需要Web服务器。更明确地说,它应该是一个应用程序,其中一个设备(主设备/主机)创建一个游戏/会话,多个设备(从设备/客户端)可以加入。建立所有必要的连接(4-5个客户端)后,主机应能够向客户端广播数据。因此,我做了一些研究,如果我理解正确的话,android的最佳猜测是WiFi直接或谷歌附近的连接api Q1。这是实现预期目标的最简单方法吗?还是这已经太深了 因此,我对connections api进行了一些研究,制作了一个简单的应用程序,并使用了。由于我是Kotlin的新手,这也可能是一个相当简单的错误,但是在两个小时后,我换回了java,出现了相同的错误。当客户端试图发现主机时,它们触发了OnFailureListener。我试图在网上搜索解决方案(包括SO),但找不到任何有用的信息 我正在HTC ONE M8和三星Galaxy S7上测试该应用程序。为了确保附近的连接API功能正常工作,我还下载了2个,这些功能工作得很好。我尝试了这些如何处理api的使用,但没有找到重要的部分 Q2。我在哪里使用了错误的API?或者这真的只是编码中的一个错误 MainActivity.ktAndroid 谷歌附近-连接API-发现不工作,android,wifip2p,google-nearby-connections,Android,Wifip2p,Google Nearby Connections,因此,最近我和我的朋友考虑创建一个应用程序,允许连接设备之间的实时通信,而不需要Web服务器。更明确地说,它应该是一个应用程序,其中一个设备(主设备/主机)创建一个游戏/会话,多个设备(从设备/客户端)可以加入。建立所有必要的连接(4-5个客户端)后,主机应能够向客户端广播数据。因此,我做了一些研究,如果我理解正确的话,android的最佳猜测是WiFi直接或谷歌附近的连接api Q1。这是实现预期目标的最简单方法吗?还是这已经太深了 因此,我对connections api进行了一些研究,制作
private const val TAG = android.R.attr.packageNames.toString() + "/Filter"
class MainActivity : AppCompatActivity() {
private lateinit var connectionClient : ConnectionsClient
private val payloadCallback = object : PayloadCallback() {
override fun onPayloadReceived(p0: String, p1: Payload) {
Toast.makeText(applicationContext, "Payload Received", Toast.LENGTH_SHORT).show()
}
override fun onPayloadTransferUpdate(p0: String, p1: PayloadTransferUpdate) {
Toast.makeText(applicationContext, "Payload Transfer Update", Toast.LENGTH_SHORT).show()
}
}
private val connPoint = object : ConnectionLifecycleCallback() {
override fun onConnectionInitiated(p0: String, p1: ConnectionInfo) {
connectionClient.acceptConnection(p0, payloadCallback)
Log.i(TAG, "OnConnectionInitiated")
}
override fun onConnectionResult(p0: String, p1: ConnectionResolution) {
when(p1.status.statusCode){
ConnectionsStatusCodes.STATUS_OK -> Log.i(TAG, "ConnectionsStatusCodes STATUS_OK")
ConnectionsStatusCodes.STATUS_CONNECTION_REJECTED -> Log.i(TAG, "ConnectionsStatusCodes STATUS_CONNECTION_REJECTED")
ConnectionsStatusCodes.STATUS_ERROR -> Log.i(TAG, "ConnectionsStatusCodes STATUS_ERROR")
else -> Log.i(TAG, "ConnectionsStatusCodes STATUS_UNKNOWN")
}
}
override fun onDisconnected(p0: String) {
Log.i(TAG, "onDisconnected $p0")
}
}
private val endPoint = object : EndpointDiscoveryCallback() {
override fun onEndpointFound(p0: String, p1: DiscoveredEndpointInfo) {
Log.i(TAG, "onEndpointFound ID: $p0 Name: ${p1.endpointName} ")
connectionClient.requestConnection(p1.endpointName, p0, connPoint)
.addOnSuccessListener {
Log.i(TAG, "OnSuccessListener requestConnection")
}
.addOnFailureListener {
Log.i(TAG, "OnFailureListener requestConnection")
}
}
override fun onEndpointLost(p0: String) {
Log.i(TAG, "$p0 disconnected")
}
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
connectionClient = Nearby.getConnectionsClient(this.applicationContext)
//Toast.makeText(applicationContext, connectionClient.instanceId, Toast.LENGTH_SHORT).show()
setButtonOnClick()
}
override fun onStop() {
connectionClient.stopAllEndpoints()
connectionClient.stopAdvertising()
connectionClient.stopDiscovery()
super.onStop()
}
private fun setButtonOnClick(){
val create = findViewById<Button>(R.id.create_btn)
val join = findViewById<Button>(R.id.join_btn)
create.setOnClickListener{ _ -> CreateGroup()}
join.setOnClickListener{ _ -> JoinGroup()}
Log.i(TAG, "On Click Listener set")
}
private fun CreateGroup(){
Log.i(TAG, "Starting Advertising")
connectionClient
.startAdvertising(android.os.Build.MODEL,
packageName.toString(),
connPoint,
AdvertisingOptions.Builder().apply{
setStrategy(Strategy.P2P_CLUSTER)
}.build())
.addOnSuccessListener {
OnSuccessListener<Void> {
Log.i(TAG, "OnSuccessListener CreateGroup() was triggered")
}
}
.addOnFailureListener {
OnFailureListener {
Log.i(TAG, "OnFailureListener CreateGroup() was triggered")
}
}
}
private fun JoinGroup(){
Log.i(TAG, "Starting Discovering")
connectionClient.startDiscovery(packageName.toString(),
endPoint,
DiscoveryOptions.Builder().apply{
setStrategy(Strategy.P2P_CLUSTER)
}.build())
.addOnSuccessListener {
OnSuccessListener<Void> {
Log.i(TAG, "OnSuccessListener JoinGroup() was triggered")
}
}
.addOnFailureListener {
OnFailureListener {
Log.i(TAG, "OnSuccessListener JoinGroup() was triggered")
}
}
}
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.testapplication">
<!-- Required for Nearby Connections -->
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<!-- Optional: only required for FILE payloads -->
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
private const val TAG=android.R.attr.packageNames.toString()+“/Filter”
类MainActivity:AppCompatActivity(){
私有lateinit var connectionClient:connectionClient
private val payloadCallback=对象:payloadCallback(){
覆盖收到的有效载荷(p0:字符串,p1:有效载荷){
Toast.makeText(applicationContext,“收到的有效负载”,Toast.LENGTH\u SHORT.show())
}
重写PayloadTransferUpdate(p0:String,p1:PayloadTransferUpdate){
makeText(applicationContext,“有效负载传输更新”,Toast.LENGTH\u SHORT.show())
}
}
private val connPoint=object:ConnectionLifecycleCallback(){
覆盖已启动的连接(p0:String,p1:ConnectionInfo){
connectionClient.acceptConnection(p0,payloadCallback)
Log.i(标记“OnConnectionInitiated”)
}
覆盖连接结果(p0:String,p1:ConnectionResolution){
何时(p1.状态.状态代码){
ConnectionStatusCodes.STATUS\u OK->Log.i(标记“ConnectionStatusCodes STATUS\u OK”)
ConnectionStatusCodes.STATUS\u CONNECTION\u REJECTED->Log.i(标记“ConnectionStatusCodes STATUS\u CONNECTION\u REJECTED”)
ConnectionStatusCodes.STATUS\u ERROR->Log.i(标记“ConnectionStatusCodes STATUS\u ERROR”)
else->Log.i(标记“ConnectionStatusCodes状态\未知”)
}
}
已断开连接(p0:字符串){
Log.i(标记“onDisconnected$p0”)
}
}
private val endPoint=object:EndpointDiscoveryCallback(){
覆盖已找到的OnEndPointInfo(p0:String,p1:DiscoveredEndpointInfo){
Log.i(标记“onEndpointFound ID:$p0 Name:${p1.endpointName}”)
connectionClient.requestConnection(p1.endpointName,p0,connPoint)
.addOnSuccessListener{
Log.i(标记“OnSuccessListener请求连接”)
}
.addOnFailureListener{
Log.i(标记“OnFailureListener请求连接”)
}
}
覆盖onEndpointLost(p0:字符串){
Log.i(标记“$p0已断开”)
}
}
重写创建时的乐趣(savedInstanceState:Bundle?){
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
connectionClient=nearear.GetConnectionClient(this.applicationContext)
//Toast.makeText(applicationContext,connectionClient.instanceId,Toast.LENGTH\u SHORT.show())
setButtonConclick()
}
覆盖桌面上的乐趣(){
connectionClient.stopAllEndpoints()
connectionClient.stopAdvertising()
connectionClient.stopDiscovery()
super.onStop()
}
私人娱乐设置按钮包含(){
val create=findviewbyd(R.id.create\u btn)
val join=findviewbyd(R.id.join\u btn)
create.setOnClickListener{{{->CreateGroup()}
join.setOnClickListener{{u0->JoinGroup()}
Log.i(标记“单击侦听器集”)
}
私人娱乐集团(){
Log.i(标签“开始广告”)
连接客户
.startAvertising(android.os.Build.MODEL,
packageName.toString(),
康波因特,
advisingoptions.Builder().apply{
setStrategy(Strategy.P2P_集群)
}.build())
.addOnSuccessListener{
OnSuccessListener{
Log.i(标记“OnSuccessListener CreateGroup()已触发”)
}
}
.addOnFailureListener{
OnFailureListener{
Log.i(标记“OnFailureListener CreateGroup()已触发”)
}
}
}
私人娱乐集团(){
Log.i(标记“开始发现”)
connectionClient.startDiscovery(packageName.toString(),
终点,
DiscoveryOptions.Builder().apply{
setStrategy(Strategy.P2P_集群)
}.build())
.addOnSuccessListener{
OnSuccessListener{
Log.i(标记“OnSuccessListener JoinGroup()已触发”)
}
}
.addOnFailureListener{
OnFailureListener{
Log.i(标记“OnSuccessListener JoinGroup()已触发”)
}
}
}
}
Android清单
private const val TAG = android.R.attr.packageNames.toString() + "/Filter"
class MainActivity : AppCompatActivity() {
private lateinit var connectionClient : ConnectionsClient
private val payloadCallback = object : PayloadCallback() {
override fun onPayloadReceived(p0: String, p1: Payload) {
Toast.makeText(applicationContext, "Payload Received", Toast.LENGTH_SHORT).show()
}
override fun onPayloadTransferUpdate(p0: String, p1: PayloadTransferUpdate) {
Toast.makeText(applicationContext, "Payload Transfer Update", Toast.LENGTH_SHORT).show()
}
}
private val connPoint = object : ConnectionLifecycleCallback() {
override fun onConnectionInitiated(p0: String, p1: ConnectionInfo) {
connectionClient.acceptConnection(p0, payloadCallback)
Log.i(TAG, "OnConnectionInitiated")
}
override fun onConnectionResult(p0: String, p1: ConnectionResolution) {
when(p1.status.statusCode){
ConnectionsStatusCodes.STATUS_OK -> Log.i(TAG, "ConnectionsStatusCodes STATUS_OK")
ConnectionsStatusCodes.STATUS_CONNECTION_REJECTED -> Log.i(TAG, "ConnectionsStatusCodes STATUS_CONNECTION_REJECTED")
ConnectionsStatusCodes.STATUS_ERROR -> Log.i(TAG, "ConnectionsStatusCodes STATUS_ERROR")
else -> Log.i(TAG, "ConnectionsStatusCodes STATUS_UNKNOWN")
}
}
override fun onDisconnected(p0: String) {
Log.i(TAG, "onDisconnected $p0")
}
}
private val endPoint = object : EndpointDiscoveryCallback() {
override fun onEndpointFound(p0: String, p1: DiscoveredEndpointInfo) {
Log.i(TAG, "onEndpointFound ID: $p0 Name: ${p1.endpointName} ")
connectionClient.requestConnection(p1.endpointName, p0, connPoint)
.addOnSuccessListener {
Log.i(TAG, "OnSuccessListener requestConnection")
}
.addOnFailureListener {
Log.i(TAG, "OnFailureListener requestConnection")
}
}
override fun onEndpointLost(p0: String) {
Log.i(TAG, "$p0 disconnected")
}
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
connectionClient = Nearby.getConnectionsClient(this.applicationContext)
//Toast.makeText(applicationContext, connectionClient.instanceId, Toast.LENGTH_SHORT).show()
setButtonOnClick()
}
override fun onStop() {
connectionClient.stopAllEndpoints()
connectionClient.stopAdvertising()
connectionClient.stopDiscovery()
super.onStop()
}
private fun setButtonOnClick(){
val create = findViewById<Button>(R.id.create_btn)
val join = findViewById<Button>(R.id.join_btn)
create.setOnClickListener{ _ -> CreateGroup()}
join.setOnClickListener{ _ -> JoinGroup()}
Log.i(TAG, "On Click Listener set")
}
private fun CreateGroup(){
Log.i(TAG, "Starting Advertising")
connectionClient
.startAdvertising(android.os.Build.MODEL,
packageName.toString(),
connPoint,
AdvertisingOptions.Builder().apply{
setStrategy(Strategy.P2P_CLUSTER)
}.build())
.addOnSuccessListener {
OnSuccessListener<Void> {
Log.i(TAG, "OnSuccessListener CreateGroup() was triggered")
}
}
.addOnFailureListener {
OnFailureListener {
Log.i(TAG, "OnFailureListener CreateGroup() was triggered")
}
}
}
private fun JoinGroup(){
Log.i(TAG, "Starting Discovering")
connectionClient.startDiscovery(packageName.toString(),
endPoint,
DiscoveryOptions.Builder().apply{
setStrategy(Strategy.P2P_CLUSTER)
}.build())
.addOnSuccessListener {
OnSuccessListener<Void> {
Log.i(TAG, "OnSuccessListener JoinGroup() was triggered")
}
}
.addOnFailureListener {
OnFailureListener {
Log.i(TAG, "OnSuccessListener JoinGroup() was triggered")
}
}
}
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.testapplication">
<!-- Required for Nearby Connections -->
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<!-- Optional: only required for FILE payloads -->
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
好的,在弄清楚如何使用Kotlin正确设置侦听器后,我发现我得到了一个缺少权限的例外,01-20 21:11:14.269 1058-1058/com.example.t