5.4 (Optional) Webservice Option
Use the webservice option when your Android setup should expose NIMMSTA functionality through the Web Library or the Websocket API, or when you want silent deployment without a separate websocket app.
The most important distinction is this:
NIMMSTAWebServiceConnectionstarts and binds the SDK-localWebServicethat ships with the Android Core Library.- It does not bind to an already installed NIMMSTA Android app.
If you want a helper that automatically resolves the installed app package and supports Standard App, Intent App, Webserver App, and a preferred custom package, use the Intent Library webservice connection documentation.
Choose the right setup by app type
| App type | Recommended setup | Why |
|---|---|---|
| Native Android app that only uses Core SDK APIs directly | Do not use the webservice option | NIMMSTAServiceConnection is enough for direct device access |
| Native Android app that embeds its own web UI or wants to expose a local websocket endpoint | Use NIMMSTAWebServiceConnection |
The helper starts the bundled WebService in your app and connects it to the local NIMMSTAConnectionManager |
| Separate Android app, browser app, or PWA on the same device that should talk to NIMMSTA | Bind to the installed NIMMSTA app's webservice | Your app stays decoupled from Core SDK lifecycle and updates |
| Xamarin, .NET MAUI, or other non-native mobile app where direct Android SDK integration is not ideal | Prefer the websocket integration or the Intent Library | This matches the recommended app-to-app integration path |
Approach 1: Bind to the webservice of an installed NIMMSTA app
Use this when the NIMMSTA Android app is already installed on the device and should host the webservice for your integration.
This is the better choice for:
- browser-based apps running on the device
- a second Android app that should talk to NIMMSTA without embedding the Core SDK webservice
- setups where NIMMSTA app updates should deliver webservice improvements independently of your app release
Step 1: Add package visibility to AndroidManifest.xml
Declare the installed app packages you want to query before binding to the external service.
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<queries>
<package android:name="com.nimmsta" />
<package android:name="com.nimmsta.intent" />
<!-- Optional custom package -->
<package android:name="com.nimmsta.custom" />
</queries>
<application>
<!-- Your application's components here -->
</application>
</manifest>
Step 2: Create a ServiceConnection
Define a connection object that keeps the external binder reference and reacts to connect and disconnect events:
import android.content.ComponentName
import android.content.ServiceConnection
import android.os.IBinder
class InstalledWebServiceConnection : ServiceConnection {
var binder: IBinder? = null
override fun onServiceConnected(name: ComponentName?, service: IBinder?) {
binder = service
}
override fun onServiceDisconnected(name: ComponentName?) {
binder = null
}
}
import android.content.ComponentName;
import android.content.ServiceConnection;
import android.os.IBinder;
public class InstalledWebServiceConnection implements ServiceConnection {
private IBinder binder;
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
binder = service;
}
@Override
public void onServiceDisconnected(ComponentName name) {
binder = null;
}
}
Step 3: Bind to the installed app
Try the packages in order until one bind succeeds. If you already use the Intent Library, prefer its built-in helper instead of reimplementing this loop.
Current Webserver App builds also use com.nimmsta, so there is no separate webserver package to add here.
private fun bindInstalledWebservice(customPackageName: String? = null): Boolean {
val serviceConnection = InstalledWebServiceConnection()
val packageNames = listOfNotNull(
customPackageName,
"com.nimmsta",
"com.nimmsta.intent"
).distinct()
for (packageName in packageNames) {
val intent = Intent().apply {
component = ComponentName(
packageName,
"com.nimmsta.core.android.webservice.WebService"
)
flags += Intent.FLAG_INCLUDE_STOPPED_PACKAGES
}
val didBind = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) {
applicationContext.bindService(
intent,
serviceConnection,
Context.BIND_ALLOW_ACTIVITY_STARTS or Context.BIND_AUTO_CREATE
)
} else {
applicationContext.bindService(
intent,
serviceConnection,
Context.BIND_AUTO_CREATE
)
}
if (didBind) {
return true
}
}
return false
}
private boolean bindInstalledWebservice(String customPackageName) {
InstalledWebServiceConnection serviceConnection = new InstalledWebServiceConnection();
List<String> packageNames = new ArrayList<>();
if (customPackageName != null && !customPackageName.isBlank()) {
packageNames.add(customPackageName);
}
packageNames.add("com.nimmsta");
packageNames.add("com.nimmsta.intent");
for (String packageName : new LinkedHashSet<>(packageNames)) {
Intent intent = new Intent();
intent.setComponent(new ComponentName(
packageName,
"com.nimmsta.core.android.webservice.WebService"
));
intent.setFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
boolean didBind;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) {
didBind = getApplicationContext().bindService(
intent,
serviceConnection,
Context.BIND_ALLOW_ACTIVITY_STARTS | Context.BIND_AUTO_CREATE
);
} else {
didBind = getApplicationContext().bindService(
intent,
serviceConnection,
Context.BIND_AUTO_CREATE
);
}
if (didBind) {
return true;
}
}
return false;
}
Unbind the service again when the owning component is destroyed.
Approach 2: Start the webservice inside your own Android app with NIMMSTAWebServiceConnection
Use this when your app already includes the Android Core Library and should host the webservice itself.
This is the right choice for:
- native Android apps that ship their own local HTML or Web Library frontend
- kiosk-style apps that expose a websocket endpoint locally
- single-APK solutions where Bluetooth connection management and webservice hosting should live in the same app
NIMMSTAWebServiceConnection.bindServiceToContext(...) binds to the bundled WebService, which in turn:
- binds to
NIMMSTAConnectionManagerService - enables background notifications for connected devices
- starts the websocket server once the service is ready
The helper returns immediately. Use onSuccess or onComplete before assuming that the webserver is already running.
Manifest notes for the local approach
- You do not need the
<queries>block from Approach 1, because this setup stays inside your own app. - The Android library already declares
NIMMSTAConnectionManagerServiceandWebServicein its manifest, so standard manifest merging is usually enough. - If your project does not merge library manifests, make sure those service declarations stay present in your app manifest.
Basic usage
import android.os.Bundle
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import com.nimmsta.core.android.webservice.NIMMSTAWebServiceConnection
class MainActivity : AppCompatActivity() {
private var webServiceConnection: NIMMSTAWebServiceConnection? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
webServiceConnection = NIMMSTAWebServiceConnection
.bindServiceToContext(applicationContext)
.onSuccess {
// The websocket server is ready on the default port 64693.
}
.onError { throwable ->
Toast.makeText(this, throwable.message, Toast.LENGTH_LONG).show()
}
}
override fun onDestroy() {
webServiceConnection?.close()
super.onDestroy()
}
}
import android.os.Bundle;
import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity;
import com.nimmsta.core.android.webservice.NIMMSTAWebServiceConnection;
public class MainActivity extends AppCompatActivity {
private NIMMSTAWebServiceConnection webServiceConnection;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
webServiceConnection = NIMMSTAWebServiceConnection
.bindServiceToContext(getApplicationContext())
.onSuccess(connection -> {
// The websocket server is ready on the default port 64693.
})
.onError(throwable -> {
Toast.makeText(this, throwable.getMessage(), Toast.LENGTH_LONG).show();
});
}
@Override
protected void onDestroy() {
if (webServiceConnection != null) {
webServiceConnection.close();
}
super.onDestroy();
}
}
Using a custom port
If your app should expose the server on a different local port, pass it when binding:
Lifecycle recommendations
- Prefer
applicationContextwhen binding the local webservice, because the webservice often outlives a single activity instance. - Keep the returned
NIMMSTAWebServiceConnectionreference and callclose()when your app no longer needs the webservice. - If you need to start making websocket calls immediately after startup, do that from
onSuccess, not directly afterbindServiceToContext(...).