Communication and Deeplinks
Exchange data between your streamed Android app running in the cloud and the local client using intents, URLs, and deeplinks.
Overview
N2I provides two communication channels between the streamed app (running in the cloud) and the local client (your website or native app):
- App → Client: The streamed app sends data to the local client via Android Intent broadcast or by opening a URL.
- Client → App: The local client sends data to the streamed app via the N2I JavaScript API (
sendDeeplink,sendCustomPacket).
App → Client: Using Android Intents (Recommended)
The preferred method for sending data from the streamed app to the local client is a broadcast Intent targeting the N2I receiver. This approach does not spawn a new Activity, so it does not interrupt the running app.
The N2I frontend receives the broadcast and fires an n2i_data event on the client side, carrying the URL and extras as a data dictionary.
Unity (C#)
public void SendData(string url = null, Dictionary<string, string> extras = null)
{
#if UNITY_ANDROID && !UNITY_EDITOR
using (var unityPlayer = new AndroidJavaClass("com.unity3d.player.UnityPlayer"))
{
var activity = unityPlayer.GetStatic<AndroidJavaObject>("currentActivity");
using (var intent = new AndroidJavaObject("android.content.Intent"))
{
using (var componentName = new AndroidJavaObject(
"android.content.ComponentName",
"com.n2i.urlhandler",
"com.n2i.urlhandler.Receiver"
))
{
intent.Call<AndroidJavaObject>("setComponent", componentName);
}
if (!string.IsNullOrEmpty(url))
{
using (var uriClass = new AndroidJavaClass("android.net.Uri"))
{
var uri = uriClass.CallStatic<AndroidJavaObject>("parse", url);
intent.Call<AndroidJavaObject>("setData", uri);
}
}
if (extras != null && extras.Count > 0)
{
using (var bundle = new AndroidJavaObject("android.os.Bundle"))
{
foreach (var kvp in extras)
bundle.Call("putString", kvp.Key, kvp.Value);
intent.Call<AndroidJavaObject>("putExtras", bundle);
}
}
activity.Call("sendBroadcast", intent);
}
}
#endif
}
Native Android (Java)
public static void sendData(Context context, String url, Bundle extras) {
if (context == null) return;
Intent intent = new Intent();
intent.setComponent(new ComponentName(
"com.n2i.urlhandler",
"com.n2i.urlhandler.Receiver"
));
if (url != null && !url.isEmpty())
intent.setData(Uri.parse(url));
if (extras != null && !extras.isEmpty())
intent.putExtras(extras);
context.sendBroadcast(intent);
}
The client receives the n2i_data event with the following payload:
{ "data": "<url>", "extras": { "<key>": "<value>" } }
App → Client: Using URLs
Any URL opened by the streamed app with an http:, https:, or n2i-send: scheme is intercepted by N2I and forwarded to the client as an n2i_open_url_notify event (instead of opening a browser window in the cloud).
Use the n2i-send: scheme for custom signals that should never open a real browser:
// Unity
Application.OpenURL("n2i-send://payment-complete");
// Native Android
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse("n2i-send://payment-complete"));
startActivity(intent);
The client receives:
{ "type": "n2i_open_url_notify", "detail": "n2i-send://payment-complete" }
URL-based communication is not available when embedding via iframe — use the Intent method or sendCustomPacket instead.
Handling the event on the client (iframe)
<iframe id="n2i-iframe" src="https://mygame.n2i-cloud.com/"></iframe>
<script>
window.addEventListener("message", (event) => {
if (event.data?.type === "n2i_open_url_notify") {
const url = event.data.detail;
if (url === "n2i-send://payment-complete") {
// handle the signal
}
}
});
</script>
App → Client: Opening a Web Page
The streamed app can open a URL in the user's local browser (for example, a payment page hosted on your infrastructure). N2I intercepts the URL and opens it on the client side rather than in the cloud.
This is the recommended approach for IAP flows when your payment provider uses cloud-hosted accounts.
Use standard Android Intent or Unity Application.OpenURL() to open http:// or https:// URLs. Contact N2I to enable this feature — it is off by default.
Client → App: Sending Deeplinks
Use the sendDeeplink API to send a deeplink from your client to the streamed app:
// iframe
iframe.contentWindow.postMessage(
{ type: "sendDeeplink", detail: ["com.example.mygame", "mygame://level/5"] },
"https://your-domain.com"
);
// WebView (Android)
myWebView.loadUrl("javascript:n2i.sendDeeplink('com.example.mygame', 'mygame://level/5')");
Handling deeplinks inside the app:
- Unity: Use
Application.deepLinkActivated. - Native Android: Declare an
intent-filteron the target Activity.
Client → App: Custom Packets
For structured binary or string messages, use sendCustomPacket. See Events and API for the full API reference and the Pip3D Support Library for low-level custom packet integration.