Skip to main content

Android Fundamentals

New to Android development? This guide covers the essential Android concepts you need to understand before integrating the AD Device Manager SDK. We won't go deep into Android development — just the key concepts that directly impact using our SDK.


Gradle Build System

Gradle is Android's build system. It compiles your code, manages dependencies (like our SDK), and packages your app.

What You Need to Know

When using the AD Device Manager SDK, you'll work with build.gradle files to:

  1. Add the SDK libraries as dependencies
  2. Configure compile and target SDK versions
  3. Manage other library dependencies

Adding SDK Dependencies

To use the AD Device Manager SDK, you add it to your app's build.gradle file:

dependencies {
implementation(files("libs/addevicemanager.aar"))
implementation(files("libs/edge.aar"))

// Logging dependencies (required)
implementation 'org.slf4j:slf4j-api:2.0.17'
implementation 'com.github.tony19:logback-android:3.0.0'
}

After modifying build.gradle, click "Sync Now" in Android Studio to apply changes.

Learn More


Activity Lifecycle

Every Android screen (Activity) goes through a lifecycle — it's created, becomes visible, goes to the background, and eventually is destroyed. Understanding this lifecycle is crucial for properly managing hardware connections.

Why It Matters for the SDK

When using Bluetooth devices like the Pathfinder Edge:

  • Connect when your Activity becomes active
  • Disconnect (or handle gracefully) when your Activity goes to the background
  • Clean up resources when your Activity is destroyed

Key Lifecycle Methods

MethodWhen It's CalledWhat to Do
onCreate()Activity is first createdInitialize the SDK, set up UI
onResume()Activity becomes visible/interactiveReconnect to device if needed
onPause()Activity is going to backgroundConsider disconnecting or pausing operations
onDestroy()Activity is being destroyedClean up resources, disconnect

Example: Managing Device Connection

public class PrintActivity extends AppCompatActivity {

private DeviceAdapter deviceAdapter;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Initialize SDK components
}

@Override
protected void onResume() {
super.onResume();
// Activity is visible — ensure device is connected
if (deviceAdapter != null && !deviceAdapter.isConnected()) {
deviceAdapter.connect();
}
}

@Override
protected void onPause() {
super.onPause();
// Activity going to background
// Decide: keep connection for quick return, or disconnect to save battery?
}

@Override
protected void onDestroy() {
super.onDestroy();
// Clean up — always disconnect when Activity is destroyed
if (deviceAdapter != null) {
deviceAdapter.disconnect();
}
}
}

Learn More


Android Permissions

Android protects sensitive device features (like Bluetooth, location, and camera) with a permission system. Your app must declare which permissions it needs and request them from the user at runtime.

Why It Matters for the SDK

The AD Device Manager SDK uses Bluetooth to communicate with Pathfinder Edge devices. Before your app can:

  • Scan for Bluetooth devices → Requires BLUETOOTH_SCAN permission
  • Connect to Bluetooth devices → Requires BLUETOOTH_CONNECT permission
  • Determine device location via Bluetooth → Requires ACCESS_FINE_LOCATION permission

Two-Step Permission Process

Step 1: Declare permissions in AndroidManifest.xml

<uses-permission android:name="android.permission.BLUETOOTH_SCAN" />
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />

Step 2: Request permissions at runtime

Starting with Android 6.0 (API 23), sensitive permissions must also be requested at runtime. The user sees a dialog asking to grant or deny each permission.

// Check if permission is already granted
if (ContextCompat.checkSelfPermission(this, Manifest.permission.BLUETOOTH_SCAN)
!= PackageManager.PERMISSION_GRANTED) {
// Permission not granted — request it
ActivityCompat.requestPermissions(this,
new String[]{Manifest.permission.BLUETOOTH_SCAN},
REQUEST_CODE);
}

Permission Best Practices

DoDon't
Request permissions just before you need themRequest all permissions at app launch
Explain why you need the permissionAssume users will grant permissions
Handle permission denial gracefullyCrash or leave features broken
Check permissions before SDK operationsAssume permissions are granted

What Happens If Permissions Are Denied?

If the user denies Bluetooth permissions:

  • startBluetoothDiscovery() will fail
  • connect() calls will fail
  • Your app should show a helpful message explaining why Bluetooth access is needed

Learn More


Asynchronous Operations

Many SDK operations take time — scanning for devices, connecting, uploading resources, printing. Android apps handle this using asynchronous programming so your app stays responsive.

CompletableFuture

The AD Device Manager SDK uses CompletableFuture for async operations. This is a Java standard for handling operations that complete in the future.

// This doesn't block — it returns immediately
deviceAdapter.connect()
.thenAccept(unused -> {
// This runs AFTER connection succeeds
Log.i("SDK", "Connected!");
})
.exceptionally(error -> {
// This runs if connection fails
Log.e("SDK", "Connection failed: " + error.getMessage());
return null;
});

// Code here runs immediately, before connection completes

Key Concepts

MethodPurpose
.thenAccept()Handle success
.exceptionally()Handle errors
.thenCompose()Chain another async operation
.thenRun()Run code after completion (no result needed)

Updating the UI from Async Callbacks

Android requires UI updates to happen on the main thread. Async callbacks may run on background threads, so use runOnUiThread():

deviceAdapter.connect()
.thenAccept(unused -> {
// Might be on a background thread — use runOnUiThread for UI updates
runOnUiThread(() -> {
statusText.setText("Connected!");
printButton.setEnabled(true);
});
});

Learn More


Next Steps

Now that you understand the fundamentals, you're ready to start integrating: