Sentinel – The All-in-One Testing Tool for Your Android Device

Have you ever been frustrated by some unusual app behavior when you’re away from your computer and can’t access logs? With our open-source library Sentinel, you can have all your testing tools in one place, accessible directly from your device.

As any developer or software tester can tell you, testing an app on a physical device can be the source of all sorts of frustration. 

Maybe you were expecting just a quick app checkup, but the app crashed. And since you weren’t connected to your computer, there are no logs available. You are desperately trying to remember the steps, but you’re unable to reproduce the crash, and you’re not really sure what happened there. 

Logs are crucial for finding the root cause of an error, and it would be really convenient if you didn’t have to connect your phone to the computer to check them every time. And what if you’re new to the project and would like to know which tools are available and used for testing the app?

Thankfully, there’s a tool that could help you in the situations above, as well as many others. Sentinel, our open-source library, offers great convenience and flexibility for checking what’s going on with your app behind the scenes. The best thing about it is that you can use it directly on your device, for free. In this article, we’ll show you what Sentinel can do for you and explain how to implement it on Android. For the iOS version, please refer to this article, and if you’re interested in the QA perspective, this is your resource

What Sentinel brings to the table

Sentinel is a great out-of-the-box solution because you get a heap of useful built-in tools just by adding it to your project. You can easily access device and application information, the list of application permissions and their values, and shared preferences where you can manipulate the values. 

These features are all great time-savers, but the true power of Sentinel lies in its flexible tool selection that developers can customize as they wish. You can choose any prepackaged tool you like and even create a custom tool with the help of a predefined interface, which makes integration a piece of cake.

How to implement Sentinel

We’ll start with the basic implementation, which is very straightforward and can be done in a couple of minutes.

The first step is to decide which tools you would like to use. Sentinel comes with seven specific tools that can be included in your app:

ChuckerTool

A wrapper class that opens the Chucker network monitor.

CollarTool

A wrapper class that opens the Collar analytics tracker.

DbInspectorTool

A wrapper class that opens DbInspector.

LeakCanaryTool

A wrapper class that opens the LeakCanary tool for memory leak detection.

TimberTool

A wrapper class that opens the Timber logger.

AppGalleryTool

A wrapper class that opens the Huawei AppGallery listing for published applications or the app’s web page if the listing is not found.

GooglePlayTool

A wrapper class that opens the Google Play listing for published applications or the app’s web page if the listing is not found.

Now it is time to include the appropriate dependencies in your build.gradle file. The dependencies are listed in the GitHub repository’s Readme section, which makes this a lot easier. For demonstration purposes, let’s include Chucker and DbInspector.

	val sentinelVersion = "1.4.0"
debugImplementation("com.infinum.sentinel:sentinel:$sentinelVersion")
releaseImplementation("com.infinum.sentinel:sentinel-no-op:$sentinelVersion")
debugImplementation("com.infinum.sentinel:tool-chucker:$sentinelVersion")
debugImplementation("com.infinum.sentinel:tool-dbinspector:$sentinelVersion")

When you’ve added the dependencies, you can go ahead and sync your project. The only thing remaining is to enable Sentinel in your app.

You can do this by creating or injecting a Sentinel instance in your application class. All you need to do is call the watch function in your onCreate callback.

	override fun onCreate(){
        super.onCreate()
        Sentinel.watch(
               setOf(
                   ChuckerTool(),
                   DbInspectorTool()
               )
        )
}

After starting the app, you can shake the device and see Sentinel in action. Pro tip: don’t forget to add the Chucker interceptor to your API module.

Pre-packaged tools not enough?

Sometimes, your project will require some special tool that is not provided in our package. Fortunately, implementing additional tools to be displayed and used in Sentinel is also quite easy. All you need to do is implement the Sentinel.Tool interface and provide the implementation details for your tool.

To demonstrate this in an example, let’s quickly make a tool for monitoring the battery percentage. The first step is to create a separate Activity class where we can access battery data. To access battery data in Activity, we can use this code.

	class BatteryInfoActivity : ComponentActivity() {
    private lateinit var batteryReceiver: BroadcastReceiver
    private var batteryPercentage = mutableIntStateOf(0)


    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)


        batteryReceiver = object : BroadcastReceiver() {
            override fun onReceive(context: Context, intent: Intent) {
                val level = intent.getIntExtra(BatteryManager.EXTRA_LEVEL, -1)
                val scale = intent.getIntExtra(BatteryManager.EXTRA_SCALE, -1)
                val batteryPct = level / scale.toFloat() * 100
                batteryPercentage.intValue = batteryPct.toInt()
            }
        }


        val filter = IntentFilter(Intent.ACTION_BATTERY_CHANGED)
        registerReceiver(batteryReceiver, filter)


        setContent {
            BatteryInfoScreen(batteryPercentage.intValue)
        }
    }


    override fun onDestroy() {
        super.onDestroy()
        unregisterReceiver(batteryReceiver)
    }
}

BatteryInfoScreen is just a simple Column with two Texts.

	@Composable
fun BatteryInfoScreen(batteryPercentage: Int) {
    Column(
        modifier = Modifier.fillMaxSize(),
        verticalArrangement = Arrangement.Center,
        horizontalAlignment = Alignment.CenterHorizontally
    ) {
        Text(text = "Battery Percentage", style = MaterialTheme.typography.headlineMedium)
        Text(text = "$batteryPercentage%", style = MaterialTheme.typography.displayLarge)
    }
}

Now that we have our Activity, we can simply wrap it as a Sentinel tool by providing the implementation of two functions.

	class BatteryViewerTool : Sentinel.Tool {
    override fun listener(): View.OnClickListener {
        return View.OnClickListener { view ->
            val context = view.context
            val intent = Intent(context, BatteryInfoActivity::class.java)
            startActivity(context, intent, null)
        }
    }
    override fun name(): Int = R.string.battery_info
}

Don’t forget to add this new tool to Sentinel.watch, which should now look like this:

	Sentinel.watch(
    setOf(
        ChuckerTool(), 
        DbInspectorTool(), 
        BatteryViewerTool()
    )
)

Next step: enjoy your new tool!

Working with Sentinel

Sentinel overlays your app and can be summoned using several different triggers. The most popular one (and my personal favorite) is the shake method. Just vigorously shake your device, and voilà, your tools become available. They tell me a gentle shake should be enough, but I still prefer my method.

The other triggers can be seen in the picture below. The trigger states are persisted between sessions and you can manage them through the Sentinel settings screen.

If you reinstall your app frequently, you might find it exhausting to turn off some trigger every time. The good news is that there is a programmatic way to solve this. Just add the metadata for disabling a trigger to your AndroidManifest file inside the application element. You’ll find the names for all triggers in the Readme file on GitHub. The 0 represents the disabled state, and 1 enables the state.

	<meta-data
    android:name="com.infinum.sentinel.trigger.foreground"
    android:value="0" />

Now you have a bunch of tools in the palm of your hand, no computer connection needed. From reading Bluetooth and network logs to changing the database and cached values in runtime, the options are limitless. Your QA colleague will be thrilled.

Simplify your testing process

Sentinel is a valuable tool both for app development and quality assurance, providing efficiency and convenience in a number of use cases. It gives you easy access to the tools you need in one place as well as important app insights, helping developers and testers manage their projects more effectively.

Also, Sentinel is open-source, so if you have any suggestions or want to contribute to the project with new ideas and implementations, you are free to do so. 

To check the repository and open any PRs or leave suggestions, head on to our GitHub page