Android SDK 接入文档 本文描述接入sendingnetwork-android-sdk的基本步骤。完成代码请参考[sdk demo](https://github.com/LinX-OpenNetwork/sendingnetwork-Android-sdk/tree/main/app) ## Prerequisites | Components | Requirements | |------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | OS | Android 6.0 or above | | Software | Android Sutdio 4.0 or above;<br/>[Sending.Network Android SDK](https://github.com/Sending-Network/sendingnetwork-android-sdk)<br/> Note: Please visit our [official website](https://sending.network/) to submit a request for the source code. | ## 一、配置文件初始化 ### Gradle 在top level build.gradle文件中添加以下配置: ```gradle buildscript { ext.kotlin_version = "1.6.0" repositories { google() jcenter() maven { url 'https://oss.sonatype.org/content/repositories/snapshots/' } } dependencies { classpath "com.android.tools.build:gradle:7.0.3" classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" } } allprojects { repositories { google() jcenter() maven { url 'https://jitpack.io' } } } ``` 在app module build.gradle文件中添加sendingnetwork-android-sdk依赖。(将`x.y.z`替换为最新版本) ```groovy // sdk依赖 implementation 'io.github.sending-network:sendingnetwork-android-sdk:x.y.z' ``` 如果需要使用本地homeserver,则添加sendingnetwork-android-service依赖。(将`x.y.z`替换为最新版本) ```groovy // 本地server依赖 implementation 'io.github.sending-network:sendingnetwork-android-service:x.y.z' ``` ## AndroidManifest.xml file Your application should at least contains the provider "InitializationProvider" to remove initialization of the WorkManager as below ```xml <application android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:name=".SampleApp" android:label="@string/app_name" android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" android:theme="@style/AppTheme"> [...] // This is required as the WorkManager is already initialized by the SDK <provider android:name="androidx.startup.InitializationProvider" android:authorities="${applicationId}.androidx-startup" android:exported="false" tools:ignore="MissingClass" tools:node="merge"> <meta-data android:name="androidx.work.WorkManagerInitializer" android:value="androidx.startup" tools:node="remove" /> </provider> // 在使用本地homeserver场景时需要声明DendriteService,否则无需声明 <service android:name="org.matrix.android.sdk.server.DendriteService" android:enabled="true"/> </application> ``` ## 二、代码初始化和DID登录 ### Application初始化 在Application子类的onCreate方法中创建Matrix对象。 ``` kotlin override fun onCreate() { super.onCreate() Timber.plant(Timber.DebugTree()) // 初始化Matrix对象 matrix = Matrix( context = this, matrixConfiguration = MatrixConfiguration( roomDisplayNameFallbackProvider = RoomDisplayNameFallbackProviderImpl() ) ) // 如果已经存在登录session,则开始sync消息;否则需要在登录页完成登录流程 val lastSession = matrix.authenticationService().getLastAuthenticatedSession() if (lastSession != null) { SessionHolder.currentSession = lastSession lastSession.open() lastSession.syncService().startSync(true) } } ``` ### HomeServer连接配置 根据使用场景,sdk支持两种方式连接homeserver。 1. 连接远程homeserver节点 ```kotlin // 连接远程homeserver val homeserverUrl = "https://homeserver-domain" val homeServerConnectionConfig = HomeServerConnectionConfig.Builder() .withHomeServerUri(Uri.parse(homeserver)) .build() ``` 2. 启动并连接本地homeserver ```kotlin // 启动homeserver服务 val intent = Intent(context, DendriteService::class.java) context.startService(intent) // 连接本地homeserver val homeserverUrl = "http://localhost:65432" val homeServerConnectionConfig = HomeServerConnectionConfig.Builder() .withHomeServerUri(Uri.parse(homeserver)) .build() ``` ### DID登录 客户端通过AuthenticationService调用登录相关接口,流程: 1. Query for existing DIDs associated with current wallet address. 2. Obtain login message by using one of the DIDs or the wallet address if no DID exists. 3. Request for a mesasge signature with the developer key. 5. Request for a message signature with user wallet account. 6. Login by passing the two signatures to SDN server. ```kotlin val address = "" val privateKey = "" val ecKeyPair: ECKeyPair = ECKeyPair.create(privateKey.decodeHex().toByteArray()) val authService = SampleApp.getSDNClient(requireContext()).authenticationService() try { val loginDidMsg = authService.didPreLogin(edgeNodeConnectionConfig, address) // sign with user wallet val token = signMessage(ecKeyPair, loginDidMsg.message) // sign with developer key from server side val appToken = signWithServerDeveloperKey((loginDidMsg.message)) authService.didLogin(edgeNodeConnectionConfig, address, loginDidMsg.did, loginDidMsg.randomServer, loginDidMsg.updated, token, appToken) } catch (failure: Throwable) { Toast.makeText(requireContext(), "Failure: $failure", Toast.LENGTH_SHORT).show() null }?.let { SessionHolder.currentSession = it it.open() it.syncService().startSync(true) displayRoomList() } ``` 服务端需使用对应语言的web3库函数完成签名操作,客户端向服务端请求签名的示例代码如下: ```kotlin suspend fun signWithServerDeveloperKey(message: String): String { val retrofit: Retrofit = Retrofit.Builder() .baseUrl("https://rewards.sending.network") .addConverterFactory(MoshiConverterFactory.create(Moshi.Builder().add(KotlinJsonAdapterFactory()).build())) .client(OkHttpClient()) .build() val signService = retrofit.create(SignService::class.java) val signResp = signService.signMessage(SignRequest(message)) return signResp.signature } ``` ## 三、创建和展示私聊房间 通过对方的UserId创建私聊房间,并获取房间详情。 ```kotlin val session = SessionHolder.currentSession val otherUserId = "@sdn_0829932f18b936f9c878bf1332b53214c11380cb:0829932f18b936f9c878bf1332b53214c11380cb" // 创建私聊房间 val roomId = session.roomService().createDirectRoom(otherUserId) val room? = session.getRoom(roomId) // 展示房间信息 room?.getRoomSummaryLive()?.observe(viewLifecycleOwner) { roomSummary -> // display room summary on application UI } ``` ## 四、发送和接受消息事件 通过对方的UserId创建私聊房间,并获取房间详情。 ```kotlin // 发送消息事件 room?.sendService()?.sendTextMessage("Hello!") // 设置timeline listener val timelineSettings = TimelineSettings(initialSize = 30) val timeline = room?.timelineService()?.createTimeline(null, timelineSettings)?.also { it.addListener(this) it.start() } // 在listener回调方法中接受消息事件 override fun onTimelineUpdated(snapshot: List<TimelineEvent>) { // timeline有更新时回调此方法 // 处理TimelineEvent事件 } ``` ## 五、打开视频聊天会议 通过房间id打开视频聊天会议。 ```kotlin import org.sdn.android.sdk.api.meet.SdnMeetActivity fun joinRoomMeeting(context: Context, roomId: String) { SdnMeetActivity.launch(context, roomId) } ```