Google Nearby - Connections API - обнаружение не работает - PullRequest
0 голосов
/ 20 января 2020

недавно мои друзья и я подумали о создании приложения, которое позволит в некоторой степени осуществлять связь между подключенными устройствами в режиме реального времени без использования веб-сервера. Более конкретно, это должно быть приложение, в котором одно устройство (главное устройство / хост) создает игру / сеанс, и несколько устройств (ведомые устройства / клиенты) могут присоединиться. после установления всех необходимых соединений (4-5 клиентов) хост должен иметь возможность транслировать данные клиентам. Поэтому я немного исследовал, и если я правильно понимаю, лучшим предположением для android является либо прямое подключение к WiFi, либо соединение с Google, расположенное поблизости.

Q1 . Это самый простой подход к желаемой цели? или это уже слишком глубоко?

Так что я немного поигрался с API-интерфейсом соединений, я сделал простое приложение и просто использовал код из Ближайшей документации . Поскольку я новичок в Kotlin, это также может быть довольно простой ошибкой, однако через 2 часа я вернулся к java с той же ошибкой. когда клиенты пытаются обнаружить хост, они запускают свой OnFailureListener. Я пытался найти решение онлайн (включая SO), но не смог найти никакой полезной информации.

Я тестирую приложение на HT C ONE M8 и Samsung Galaxy S7. Чтобы убедиться, что функции API-интерфейса Nearby Connection должны работать, я также скачал 2 примера приложений , и они работали просто отлично. Я попробовал, как они справились с использованием API, но не смог найти важную часть.

Q2 . Где я использую API неправильно? Или это действительно просто ошибка в кодировании?

MainActivity.kt

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")
            }
        }
}

}

Android Manifest

<?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>

1 Ответ

0 голосов
/ 20 января 2020

Хорошо, после выяснения, как правильно настроить Слушатели, используя Kotlin, я обнаружил, что получил исключение из-за пропущенного разрешения, 01-20 21: 11: 14.269 1058-1058 / com.example.testapplication I / 16843649 / Фильтр: 8034: MISSING_PERMISSION_ACCESS_COARSE_LOCATION, что, на мой взгляд, было странным, поскольку оно в манифесте. Однако я перешел к обычным настройкам приложения и включил разрешения вручную, и теперь это работает.

...