The Sending.Network Android SDK provides a messaging framework that enables you to integrate chatroom and notification services within your mobile applications.
This quickstart will walk you through a simple demo that makes basic API calls like user registration, room creation, etc. Please refer to the SDK demo for the completed code.
Prerequisites
Components
Requirements
OS
Android 6.0 or above
Software
Android Studio 4.0 or above
Configure your build
Gradle
Add the following code to the top-level build.gradle configuration file:
Your application should at least contain the provider InitializationProvider to remove the initialization of the WorkManager as below:
<applicationandroid: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 <providerandroid:name="androidx.startup.InitializationProvider"android:authorities="${applicationId}.androidx-startup"android:exported="false"tools:ignore="MissingClass"tools:node="merge"> <meta-dataandroid:name="androidx.work.WorkManagerInitializer"android:value="androidx.startup"tools:node="remove" /> </provider> // Declare the RadixService only when running a local P2P node <serviceandroid:name="org.sdn.android.sdk.server.RadixService"android:enabled="true"/> </application>
Initialization and DID login
Application initialization
Create SDNClient instance from the onCreate() method of the child class of Application.
overridefunonCreate() {super.onCreate() Timber.plant(Timber.DebugTree())// Initialize the Client instance client =Client( context =this, clientConfiguration =ClientConfiguration( roomDisplayNameFallbackProvider =RoomDisplayNameFallbackProviderImpl() ) )// If there has been a session then starts syncing messages.// Otherwise complete the login process on the login page.val lastSession = client.authenticationService().getLastAuthenticatedSession()if (lastSession !=null) { SessionHolder.currentSession = lastSession lastSession.open() lastSession.syncService().startSync(true) } }
Network configuration
There are two ways to join the SDN network. You can create a local P2P service to communicate with the SDN network. Or, you may connect to an existing Edge Node and enjoy the P2P messaging.
To connect to a remote Edge Node:
Please contact developer@sending.network for a test server URL and set it as the nodeUrl.
// Connect to a remote Edge Nodeval nodeUrl ="https://node-domain"val nodeConnectionConfig = nodeConnectionConfig.Builder() .withNodeUri(Uri.parse(node)) .build()
To run a local P2P node:
// Start the node serviceval intent =Intent(context, RadixService::class.java)context.startService(intent)// Connect to local P2P serviceval nodeUrl ="http://localhost:65432"val nodeConnectionConfig = NodeConnectionConfig.Builder() .withNodeUri(Uri.parse(node)) .build()
DID login
You will need a developer key to access the Edge Network. To request and utilize a developer key, please refer to the guide provided here.
The client calls the login-related APIs through AuthenticationService:
Query for existing DIDs associated with current wallet address.
Obtain login message by using one of the DIDs or the wallet address if no DID exists.
Request for a message signature with the developer key.
Request for a message signature with the user's wallet account.
Login by passing the two signatures to the edge node.
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 walletval token =signMessage(ecKeyPair, loginDidMsg.message)// sign with developer key from server sideval 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()}
Your developer key server needs to perform the signing operation. Below is an example code for the client to request a signature from the server:"
Invite a user to a private chat room with the user id.
val session = SessionHolder.currentSessionval otherUserId ="@sdn_0829932f18b936f9c878bf1332b53214c11380cb:0829932f18b936f9c878bf1332b53214c11380cb"// Create a private chat roomval roomId = session.roomService().createDirectRoom(otherUserId)val room? = session.getRoom(roomId)// Display the room informationroom?.getRoomSummaryLive()?.observe(viewLifecycleOwner) { roomSummary ->// display room summary on application UI}
Send and receive messages
// Send a messageroom?.sendService()?.sendTextMessage("Hello!")// Set timeline listenerval timelineSettings =TimelineSettings(initialSize =30)val timeline = room?.timelineService()?.createTimeline(null, timelineSettings)?.also { it.addListener(this) it.start()}// set callback function in the listeneroverridefunonTimelineUpdated(snapshot: List<TimelineEvent>) {// call this method to process the timeline event// when there's an update in timeline}