SigNoz Cloud - This page is relevant for SigNoz Cloud editions.
Self-Host - This page is relevant for self-hosted SigNoz editions.

Android app in Java instrumentation

Overview

This document contains instructions on how to set up OpenTelemetry instrumentation in your Android mobile applications built using Java and view your application traces in SigNoz.

Prerequisites

  • Java 8 or higher.
  • Android Studio with a working Android app project.
  • Access to a SigNoz Cloud account or self-hosted SigNoz instance.

Send traces to SigNoz

📝 Note

Test the sample app for Java.

Step 1: Add OpenTelemetry dependencies

Add these dependencies to your module build.gradle:

app/build.gradle
implementation platform('io.opentelemetry:opentelemetry-bom:1.25.0')
implementation "io.opentelemetry:opentelemetry-api"
implementation "io.opentelemetry:opentelemetry-context"
implementation 'io.opentelemetry:opentelemetry-exporter-otlp'
implementation 'io.opentelemetry:opentelemetry-exporter-logging'
implementation 'io.opentelemetry:opentelemetry-extension-kotlin'
implementation 'io.opentelemetry:opentelemetry-sdk'
implementation 'io.opentelemetry:opentelemetry-semconv'

Step 2: Configure network settings

Create app/res/xml/network_security_config.xml:

app/res/xml/network_security_config.xml
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
    <domain-config cleartextTrafficPermitted="true">
        <domain includeSubdomains="true">ingest.<region>.signoz.cloud</domain>
    </domain-config>
</network-security-config>

Add network permissions and config in app/src/main/AndroidManifest.xml:

app/src/main/AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest ...>
  <uses-permission android:name="android.permission.INTERNET" />

  <application
    ...
    android:networkSecurityConfig="@xml/network_security_config">
    ...
  </application>

</manifest>

For self-hosted, replace the domain in network_security_config.xml with your collector host (for Android emulators often 10.0.2.2). Set cleartextTrafficPermitted="false" when you use HTTPS.

Step 3: Initialize OpenTelemetry

Create OpentelemetryUtil.java:

app/src/main/java/com/example/androidjavademo/OpenTelemetryUtil.java
package com.example.androidjavademo;

import io.opentelemetry.api.OpenTelemetry;
import io.opentelemetry.api.common.Attributes;
import io.opentelemetry.api.trace.Tracer;
import io.opentelemetry.api.trace.propagation.W3CTraceContextPropagator;
import io.opentelemetry.context.propagation.ContextPropagators;
import io.opentelemetry.exporter.logging.LoggingSpanExporter;
import io.opentelemetry.exporter.otlp.trace.OtlpGrpcSpanExporter;
import io.opentelemetry.sdk.OpenTelemetrySdk;
import io.opentelemetry.sdk.resources.Resource;
import io.opentelemetry.sdk.trace.SdkTracerProvider;
import io.opentelemetry.sdk.trace.export.BatchSpanProcessor;
import io.opentelemetry.sdk.trace.export.SimpleSpanProcessor;
import io.opentelemetry.semconv.resource.attributes.ResourceAttributes;

public class OpenTelemetryUtil {
    public static void init() {
        Resource otelResource = Resource.getDefault().merge(
            Resource.create(
                Attributes.of(
                    ResourceAttributes.SERVICE_NAME, "<service_name>",
                    ResourceAttributes.HOST_NAME, "<service_name>"
                )
            )
        );

        SdkTracerProvider sdkTracerProvider = SdkTracerProvider.builder()
                .addSpanProcessor(SimpleSpanProcessor.create(LoggingSpanExporter.create()))
                .addSpanProcessor(BatchSpanProcessor.builder(
                    OtlpGrpcSpanExporter.builder()
                        .setEndpoint("ingest.<region>.signoz.cloud:443/v1/traces")
                        .addHeader("signoz-ingestion-key", "<your-ingestion-key>")
                        .build()).build()
                )
                .setResource(otelResource)
                .build();

        OpenTelemetry openTelemetry = OpenTelemetrySdk.builder()
                .setTracerProvider(sdkTracerProvider)
                .setPropagators(ContextPropagators.create(W3CTraceContextPropagator.getInstance()))
                .buildAndRegisterGlobal();

        tracer = openTelemetry.getTracer("android-tracer", "1.0.0");
    }

    private static Tracer tracer;

    public static Tracer getTracer() {
        return tracer;
    }
}

Replace the placeholders:

  • <service_name>: logical name of your mobile service; this is what you will see in SigNoz.
  • <region>: your SigNoz Cloud region, for example us, eu, or in.
  • <your-ingestion-key>: ingestion key for your SigNoz Cloud organization.
Info

Using self-hosted SigNoz? Most steps are identical. Update the endpoint and remove the ingestion key header as shown in Cloud → Self-Hosted.

Initialize OpenTelemetry in MainActivity.java:

public class MainActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        OpenTelemetryUtil.init();
        ...
    }
}

Step 4: Send telemetry data

Import the APIs:

app/src/main/java/com/example/androidjavademo/MainActivity.java
import io.opentelemetry.api.common.AttributeKey;
import io.opentelemetry.api.common.Attributes;
import io.opentelemetry.api.trace.Span;
import io.opentelemetry.api.trace.StatusCode;
import io.opentelemetry.api.trace.Tracer;
import io.opentelemetry.context.Scope;

Create spans:

app/src/main/java/com/example/androidjavademo/MainActivity.java
public void parentSpan() {
    Tracer tracer = OpenTelemetryUtil.getTracer();
    Span span = tracer.spanBuilder("Parent Span").startSpan();
    try (Scope scope = span.makeCurrent()) {
        childSpan();
    } finally {
        span.end();
    }
}

public void childSpan() {
    Tracer tracer = OpenTelemetryUtil.getTracer();
    Span span = tracer.spanBuilder("Child Span").startSpan();
    try (Scope scope = span.makeCurrent()) {
        // add attributes/events as needed
    } finally {
        span.end();
    }
}

Step 5: Run the app

Run your application from Android Studio.

Validate

  • In SigNoz, go to Traces Explorer and confirm that the traces for your service (for example <service_name>) are present.
  • Open a recent trace and verify that spans from your Android app are present with the attributes you set.

Troubleshooting

  • If spans do not show up, check that the ingest.<region>.signoz.cloud or your self-hosted collector endpoint is reachable from the emulator/device and that the ingestion key (for Cloud) is correct.

Next steps

Last updated: November 22, 2025

Edit on GitHub

Was this page helpful?