<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
xmlns:content="http://purl.org/rss/1.0/modules/content/"
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:atom="http://www.w3.org/2005/Atom"
xmlns:sy="http://purl.org/rss/1.0/modules/syndication/">
	<channel>
		<title>Author at Infinum</title>
		<atom:link href="https://infinum.com/blog/author/asim-ribo/feed/" rel="self" type="application/rss+xml" />
		<link></link>
		<description>Building digital products</description>
		<lastBuildDate>Fri, 17 Apr 2026 13:59:15 +0000</lastBuildDate>
		<sy:updatePeriod>hourly</sy:updatePeriod>
		<sy:updateFrequency>1</sy:updateFrequency>

					<item>
				<image>
					<url>19255805https://infinum.com/uploads/2024/07/Sentinel_–_the_Android_take-hero.webp</url>
				</image>
				<title>Sentinel – The All-in-One Testing Tool for Your Android Device</title>
				<link>https://infinum.com/blog/sentinel-testing-tool-android/</link>
				<pubDate>Wed, 17 Jul 2024 11:54:00 +0000</pubDate>
				<dc:creator>Asim Ribo</dc:creator>
				<guid isPermaLink="false">https://infinum.com/?p=19255805</guid>
				<description>
					<![CDATA[<p>Our open-source library Sentinel provides easy access to all the testing tools you need directly on the device you're using.</p>
<p>The post <a href="https://infinum.com/blog/sentinel-testing-tool-android/">Sentinel – The All-in-One Testing Tool for Your Android Device</a> appeared first on <a href="https://infinum.com">Infinum</a>.</p>
]]>
				</description>
				<content:encoded>
					<![CDATA[<div
	class="wrapper"
	data-id="es-118"
	 data-animation-target='inner-items'>
		
			<div class="wrapper__inner">
			<div class="block-blog-content js-block-blog-content">
	
<div class="block-blog-content-sidebar" data-id="es-92">
	</div>

<div class="block-blog-content-main">
	
<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-95"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-93">
	<p	class='typography typography--size-36-text js-typography block-paragraph__paragraph'
	data-id='es-94'
	>
	<strong>Have you ever been frustrated by some unusual app behavior when you&#8217;re away from your computer and can&#8217;t access logs? With our open-source library Sentinel, you can have all your testing tools in one place, accessible directly from your device.</strong></p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-98"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-96">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-97'
	>
	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.&nbsp;</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-101"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-99">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-100'
	>
	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.&nbsp;</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-104"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-102">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-103'
	>
	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?</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-107"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-105">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-106'
	>
	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 <a href="https://infinum.com/blog/sentinel-develeper-qa-library/" target="_blank" rel="noreferrer noopener">this article</a>, and if you&#8217;re interested in the QA perspective, <a href="https://infinum.com/blog/sentinel-software-testing/" target="_blank" rel="noreferrer noopener">this is your resource</a>. </p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-110"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-108">
	<h2	class='typography typography--size-52-default js-typography block-heading__heading'
	data-id='es-109'
	>
	What Sentinel brings to the table</h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-113"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-111">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-112'
	>
	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.&nbsp;</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-116"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-114">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-115'
	>
	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.</p></div>	</div>
</div>
</div>		</div>
	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-129"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="wrapper__inner">
			<div class="grid block-grid__grid" data-id="es-128">
	
<div class="block-grid-item" data-id="es-121">
	
<div class="block-media">
	<div	class="media block-media__media media__border--none media__align--center-center"
	data-id="es-119"
	 data-media-type='image'>

	<figure class="image block-media__image-figure image--size-stretch" data-id="es-120">
	<picture class="image__picture block-media__image-picture">
												<img
					src="https://infinum.com/uploads/2024/07/Sentinel_aa.webp"
					class="image__img block-media__image-img"
					alt=""
										height="2275"
															width="1080"
										loading="lazy"
					 />
					</picture>

	</figure></div></div>
</div>

<div class="block-grid-item" data-id="es-124">
	
<div class="block-media">
	<div	class="media block-media__media media__border--none media__align--center-center"
	data-id="es-122"
	 data-media-type='image'>

	<figure class="image block-media__image-figure image--size-stretch" data-id="es-123">
	<picture class="image__picture block-media__image-picture">
												<img
					src="https://infinum.com/uploads/2024/07/Sentinel_b.webp"
					class="image__img block-media__image-img"
					alt=""
										height="2275"
															width="1080"
										loading="lazy"
					 />
					</picture>

	</figure></div></div>
</div>

<div class="block-grid-item" data-id="es-127">
	
<div class="block-media">
	<div	class="media block-media__media media__border--none media__align--center-center"
	data-id="es-125"
	 data-media-type='image'>

	<figure class="image block-media__image-figure image--size-stretch" data-id="es-126">
	<picture class="image__picture block-media__image-picture">
												<img
					src="https://infinum.com/uploads/2024/07/Sentinel_c.webp"
					class="image__img block-media__image-img"
					alt=""
										height="2275"
															width="1080"
										loading="lazy"
					 />
					</picture>

	</figure></div></div>
</div>
</div>		</div>
	</div>

<div
	class="wrapper"
	data-id="es-185"
	 data-animation-target='inner-items'>
		
			<div class="wrapper__inner">
			<div class="block-blog-content js-block-blog-content">
	
<div class="block-blog-content-sidebar" data-id="es-130">
	</div>

<div class="block-blog-content-main">
	
<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-133"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-131">
	<h2	class='typography typography--size-52-default js-typography block-heading__heading'
	data-id='es-132'
	>
	How to implement Sentinel</h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-136"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-134">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-135'
	>
	We’ll start with the basic implementation, which is very straightforward and can be done in a couple of minutes.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-139"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-137">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-138'
	>
	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:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-143"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="bullet bullet--left bullet__type--dot bullet__color--infinum block-bullet__bullet" data-id="es-140">
			<div class="bullet__dot"></div>
		<div class="bullet__content">
		<p	class='typography typography--size-20-text js-typography bullet__heading'
	data-id='es-141'
	>
	ChuckerTool</p><p	class='typography typography--size-20-text-roman js-typography bullet__paragraph'
	data-id='es-142'
	>
	A wrapper class that opens the <a href="https://github.com/ChuckerTeam/chucker" target="_blank" rel="noreferrer noopener">Chucker</a> network monitor.</p>	</div>
</div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-147"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="bullet bullet--left bullet__type--dot bullet__color--infinum block-bullet__bullet" data-id="es-144">
			<div class="bullet__dot"></div>
		<div class="bullet__content">
		<p	class='typography typography--size-20-text js-typography bullet__heading'
	data-id='es-145'
	>
	CollarTool</p><p	class='typography typography--size-20-text-roman js-typography bullet__paragraph'
	data-id='es-146'
	>
	A wrapper class that opens the <a href="https://github.com/infinum/android-collar" target="_blank" rel="noreferrer noopener">Collar</a> analytics tracker.</p>	</div>
</div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-151"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="bullet bullet--left bullet__type--dot bullet__color--infinum block-bullet__bullet" data-id="es-148">
			<div class="bullet__dot"></div>
		<div class="bullet__content">
		<p	class='typography typography--size-20-text js-typography bullet__heading'
	data-id='es-149'
	>
	DbInspectorTool</p><p	class='typography typography--size-20-text-roman js-typography bullet__paragraph'
	data-id='es-150'
	>
	A wrapper class that opens <a href="https://github.com/infinum/android_dbinspector" target="_blank" rel="noreferrer noopener">DbInspector</a>.</p>	</div>
</div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-155"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="bullet bullet--left bullet__type--dot bullet__color--infinum block-bullet__bullet" data-id="es-152">
			<div class="bullet__dot"></div>
		<div class="bullet__content">
		<p	class='typography typography--size-20-text js-typography bullet__heading'
	data-id='es-153'
	>
	LeakCanaryTool</p><p	class='typography typography--size-20-text-roman js-typography bullet__paragraph'
	data-id='es-154'
	>
	A wrapper class that opens the <a href="https://github.com/square/leakcanary" target="_blank" rel="noreferrer noopener">LeakCanary</a> tool for memory leak detection.</p>	</div>
</div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-159"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="bullet bullet--left bullet__type--dot bullet__color--infinum block-bullet__bullet" data-id="es-156">
			<div class="bullet__dot"></div>
		<div class="bullet__content">
		<p	class='typography typography--size-20-text js-typography bullet__heading'
	data-id='es-157'
	>
	TimberTool</p><p	class='typography typography--size-20-text-roman js-typography bullet__paragraph'
	data-id='es-158'
	>
	A wrapper class that opens the <a href="https://github.com/JakeWharton/timber" target="_blank" rel="noreferrer noopener">Timber</a> logger.</p>	</div>
</div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-163"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="bullet bullet--left bullet__type--dot bullet__color--infinum block-bullet__bullet" data-id="es-160">
			<div class="bullet__dot"></div>
		<div class="bullet__content">
		<p	class='typography typography--size-20-text js-typography bullet__heading'
	data-id='es-161'
	>
	AppGalleryTool</p><p	class='typography typography--size-20-text-roman js-typography bullet__paragraph'
	data-id='es-162'
	>
	A wrapper class that opens the Huawei AppGallery listing for published applications or the app’s web page if the listing is not found.</p>	</div>
</div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-167"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="bullet bullet--left bullet__type--dot bullet__color--infinum block-bullet__bullet" data-id="es-164">
			<div class="bullet__dot"></div>
		<div class="bullet__content">
		<p	class='typography typography--size-20-text js-typography bullet__heading'
	data-id='es-165'
	>
	GooglePlayTool</p><p	class='typography typography--size-20-text-roman js-typography bullet__paragraph'
	data-id='es-166'
	>
	A wrapper class that opens the Google Play listing for published applications or the app’s web page if the listing is not found.</p>	</div>
</div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-170"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-168">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-169'
	>
	Now it is time to include the appropriate dependencies in your <code>build.gradle</code> file. The dependencies are listed in the GitHub repository’s Readme section, which makes this a lot easier. For demonstration purposes, let&#8217;s include Chucker and DbInspector.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-172"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-kotlin github-light" data-language="kotlin" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token">val </span><span class="token">sentinelVersion </span><span class="token" style="color: #d73a49;">=</span><span class="token"> </span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #032f62;">1.4.0</span><span class="token" style="color: #032f62;">&quot;</span><span class="token">
</span></span><span class="line"><span class="token">debugImplementation</span><span class="token">(</span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #032f62;">com.infinum.sentinel:sentinel:</span><span class="token" style="color: #005cc5;">$sentinelVersion</span><span class="token" style="color: #032f62;">&quot;</span><span class="token">)
</span></span><span class="line"><span class="token">releaseImplementation</span><span class="token">(</span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #032f62;">com.infinum.sentinel:sentinel-no-op:</span><span class="token" style="color: #005cc5;">$sentinelVersion</span><span class="token" style="color: #032f62;">&quot;</span><span class="token">)
</span></span><span class="line"><span class="token">debugImplementation</span><span class="token">(</span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #032f62;">com.infinum.sentinel:tool-chucker:</span><span class="token" style="color: #005cc5;">$sentinelVersion</span><span class="token" style="color: #032f62;">&quot;</span><span class="token">)
</span></span><span class="line"><span class="token">debugImplementation</span><span class="token">(</span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #032f62;">com.infinum.sentinel:tool-dbinspector:</span><span class="token" style="color: #005cc5;">$sentinelVersion</span><span class="token" style="color: #032f62;">&quot;</span><span class="token">)
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-175"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-173">
	<p	class='typography typography--size-20-text-roman js-typography block-paragraph__paragraph'
	data-id='es-174'
	>
	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.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-178"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-176">
	<p	class='typography typography--size-20-text-roman js-typography block-paragraph__paragraph'
	data-id='es-177'
	>
	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 <code>onCreate</code> callback.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-180"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-kotlin github-light" data-language="kotlin" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token" style="color: #d73a49;">override</span><span class="token"> </span><span class="token">fun onCreate</span><span class="token">(){
</span></span><span class="line"><span class="token">        </span><span class="token" style="color: #005cc5;">super</span><span class="token">.onCreate</span><span class="token">()
</span></span><span class="line"><span class="token">        Sentinel</span><span class="token">.watch</span><span class="token">(
</span></span><span class="line"><span class="token">               </span><span class="token">setOf</span><span class="token">(
</span></span><span class="line"><span class="token">                   </span><span class="token">ChuckerTool</span><span class="token">(),
</span></span><span class="line"><span class="token">                   </span><span class="token">DbInspectorTool</span><span class="token">()
</span></span><span class="line"><span class="token">               )
</span></span><span class="line"><span class="token">        )
</span></span><span class="line"><span class="token">}
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-183"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-181">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-182'
	>
	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.</p></div>	</div>
</div>
</div>		</div>
	</div>

<div
	class="wrapper"
	data-id="es-188"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="wrapper__inner">
			<div class="block-media">
	<div	class="media block-media__media media__border--none media__align--center-center"
	data-id="es-186"
	 data-media-type='video'>

	<div class="video__wrapper" data-id="es-187">
		<video
		class="video block-media__video js-video js-block-media-video video--cursor-takeover-use"
		 loop autoplay playsinline muted preload='metadata'>
		<source  src='https://infinum.com/uploads/2024/07/SentinelProvidedTools_optimized.mp4' type='video/mp4' />	</video>
	</div></div></div>		</div>
	</div>

<div
	class="wrapper"
	data-id="es-220"
	 data-animation-target='inner-items'>
		
			<div class="wrapper__inner">
			<div class="block-blog-content js-block-blog-content">
	
<div class="block-blog-content-sidebar" data-id="es-189">
	</div>

<div class="block-blog-content-main">
	
<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-192"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-190">
	<h2	class='typography typography--size-52-default js-typography block-heading__heading'
	data-id='es-191'
	>
	Pre-packaged tools not enough?</h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-195"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-193">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-194'
	>
	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 <code>Sentinel.Tool</code> interface and provide the implementation details for your tool.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-198"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-196">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-197'
	>
	To demonstrate this in an example, let&#8217;s quickly make a tool for monitoring the battery percentage. The first step is to create a separate <code>Activity</code> class where we can access battery data. To access battery data in <code>Activity</code>, we can use this code.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-200"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-kotlin github-light" data-language="kotlin" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token">class BatteryInfoActivity </span><span class="token">: </span><span class="token" style="color: #6f42c1;">ComponentActivity</span><span class="token">() {
</span></span><span class="line"><span class="token">    </span><span class="token" style="color: #d73a49;">private</span><span class="token"> </span><span class="token" style="color: #d73a49;">lateinit</span><span class="token"> </span><span class="token">var </span><span class="token">batteryReceiver</span><span class="token">: </span><span class="token" style="color: #6f42c1;">BroadcastReceiver</span><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token" style="color: #d73a49;">private</span><span class="token"> </span><span class="token">var </span><span class="token">batteryPercentage </span><span class="token" style="color: #d73a49;">=</span><span class="token"> </span><span class="token">mutableIntStateOf</span><span class="token">(</span><span class="token" style="color: #005cc5;">0</span><span class="token">)
</span></span><span class="line"><span class="token">
</span></span><span class="line"><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token" style="color: #d73a49;">override</span><span class="token"> </span><span class="token">fun onCreate</span><span class="token">(savedInstanceState</span><span class="token">: </span><span class="token" style="color: #6f42c1;">Bundle</span><span class="token">?) {
</span></span><span class="line"><span class="token">        </span><span class="token" style="color: #005cc5;">super</span><span class="token">.onCreate</span><span class="token">(savedInstanceState)
</span></span><span class="line"><span class="token">
</span></span><span class="line"><span class="token">
</span></span><span class="line"><span class="token">        batteryReceiver </span><span class="token" style="color: #d73a49;">=</span><span class="token"> </span><span class="token" style="color: #d73a49;">object</span><span class="token"> </span><span class="token">: </span><span class="token" style="color: #6f42c1;">BroadcastReceiver</span><span class="token">() {
</span></span><span class="line"><span class="token">            </span><span class="token" style="color: #d73a49;">override</span><span class="token"> </span><span class="token">fun onReceive</span><span class="token">(context</span><span class="token">: </span><span class="token" style="color: #6f42c1;">Context</span><span class="token">, </span><span class="token" style="color: #6f42c1;">intent</span><span class="token">: </span><span class="token" style="color: #6f42c1;">In</span><span class="token" style="color: #6f42c1;">tent</span><span class="token">) {
</span></span><span class="line"><span class="token">                </span><span class="token">val </span><span class="token">level </span><span class="token" style="color: #d73a49;">=</span><span class="token"> intent</span><span class="token">.getIntExtra</span><span class="token">(BatteryManager.EXTRA_LEVEL, </span><span class="token" style="color: #d73a49;">-</span><span class="token" style="color: #005cc5;">1</span><span class="token">)
</span></span><span class="line"><span class="token">                </span><span class="token">val </span><span class="token">scale </span><span class="token" style="color: #d73a49;">=</span><span class="token"> intent</span><span class="token">.getIntExtra</span><span class="token">(BatteryManager.EXTRA_SCALE, </span><span class="token" style="color: #d73a49;">-</span><span class="token" style="color: #005cc5;">1</span><span class="token">)
</span></span><span class="line"><span class="token">                </span><span class="token">val </span><span class="token">batteryPct </span><span class="token" style="color: #d73a49;">=</span><span class="token"> level </span><span class="token" style="color: #d73a49;">/</span><span class="token"> scale</span><span class="token">.toFloat</span><span class="token">() </span><span class="token" style="color: #d73a49;">*</span><span class="token"> </span><span class="token" style="color: #005cc5;">100</span><span class="token">
</span></span><span class="line"><span class="token">                batteryPercentage.intValue </span><span class="token" style="color: #d73a49;">=</span><span class="token"> batteryPct</span><span class="token">.toInt</span><span class="token">()
</span></span><span class="line"><span class="token">            }
</span></span><span class="line"><span class="token">        }
</span></span><span class="line"><span class="token">
</span></span><span class="line"><span class="token">
</span></span><span class="line"><span class="token">        </span><span class="token">val </span><span class="token">filter </span><span class="token" style="color: #d73a49;">=</span><span class="token"> </span><span class="token">IntentFilter</span><span class="token">(Intent.ACTION_BATTERY_CHANGED)
</span></span><span class="line"><span class="token">        </span><span class="token">registerReceiver</span><span class="token">(batteryReceiver, filter)
</span></span><span class="line"><span class="token">
</span></span><span class="line"><span class="token">
</span></span><span class="line"><span class="token">        </span><span class="token">setContent </span><span class="token">{
</span></span><span class="line"><span class="token">            </span><span class="token">BatteryInfoScreen</span><span class="token">(batteryPercentage.intValue)
</span></span><span class="line"><span class="token">        }
</span></span><span class="line"><span class="token">    }
</span></span><span class="line"><span class="token">
</span></span><span class="line"><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token" style="color: #d73a49;">override</span><span class="token"> </span><span class="token">fun onDestroy</span><span class="token">() {
</span></span><span class="line"><span class="token">        </span><span class="token" style="color: #005cc5;">super</span><span class="token">.onDestroy</span><span class="token">()
</span></span><span class="line"><span class="token">        </span><span class="token">unregisterReceiver</span><span class="token">(batteryReceiver)
</span></span><span class="line"><span class="token">    }
</span></span><span class="line"><span class="token">}
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-203"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-201">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-202'
	>
	<code>BatteryInfoScreen</code> is just a simple <code>Column</code> with two <code>Texts</code>.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-205"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-kotlin github-light" data-language="kotlin" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token" style="color: #6f42c1;">@Composable</span><span class="token">
</span></span><span class="line"><span class="token">fun BatteryInfoScreen</span><span class="token">(batteryPercentage</span><span class="token">: </span><span class="token" style="color: #6f42c1;">Int</span><span class="token">) {
</span></span><span class="line"><span class="token">    </span><span class="token">Column</span><span class="token">(
</span></span><span class="line"><span class="token">        modifier </span><span class="token" style="color: #d73a49;">=</span><span class="token"> Modifier</span><span class="token">.fillMaxSize</span><span class="token">(),
</span></span><span class="line"><span class="token">        verticalArrangement </span><span class="token" style="color: #d73a49;">=</span><span class="token"> Arrangement.Center,
</span></span><span class="line"><span class="token">        horizontalAlignment </span><span class="token" style="color: #d73a49;">=</span><span class="token"> Alignment.CenterHorizontally
</span></span><span class="line"><span class="token">    ) {
</span></span><span class="line"><span class="token">        </span><span class="token">Text</span><span class="token">(text </span><span class="token" style="color: #d73a49;">=</span><span class="token"> </span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #032f62;">Battery Percentage</span><span class="token" style="color: #032f62;">&quot;</span><span class="token">, style </span><span class="token" style="color: #d73a49;">=</span><span class="token"> MaterialTheme.typography.headlineMedium)
</span></span><span class="line"><span class="token">        </span><span class="token">Text</span><span class="token">(text </span><span class="token" style="color: #d73a49;">=</span><span class="token"> </span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #005cc5;">$batteryPercentage</span><span class="token" style="color: #032f62;">%</span><span class="token" style="color: #032f62;">&quot;</span><span class="token">, style </span><span class="token" style="color: #d73a49;">=</span><span class="token"> MaterialTheme.typography.displayLarge)
</span></span><span class="line"><span class="token">    }
</span></span><span class="line"><span class="token">}
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-208"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-206">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-207'
	>
	Now that we have our <code>Activity</code>, we can simply wrap it as a Sentinel tool by providing the implementation of two functions.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-210"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-kotlin github-light" data-language="kotlin" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token">class BatteryViewerTool </span><span class="token">: </span><span class="token" style="color: #6f42c1;">Sentinel</span><span class="token">.Tool </span><span class="token">{
</span></span><span class="line"><span class="token">    </span><span class="token" style="color: #d73a49;">override</span><span class="token"> </span><span class="token">fun listener</span><span class="token">()</span><span class="token">: </span><span class="token" style="color: #6f42c1;">View</span><span class="token">.</span><span class="token" style="color: #6f42c1;">OnC</span><span class="token">lickListener </span><span class="token">{
</span></span><span class="line"><span class="token">        </span><span class="token" style="color: #d73a49;">return</span><span class="token"> View</span><span class="token">.OnClickListener </span><span class="token">{ view </span><span class="token" style="color: #d73a49;">-&gt;</span><span class="token">
</span></span><span class="line"><span class="token">            </span><span class="token">val </span><span class="token">context </span><span class="token" style="color: #d73a49;">=</span><span class="token"> view.context
</span></span><span class="line"><span class="token">            </span><span class="token">val </span><span class="token">intent </span><span class="token" style="color: #d73a49;">=</span><span class="token"> </span><span class="token">Intent</span><span class="token">(context, BatteryInfoActivity</span><span class="token" style="color: #6f42c1;">::cla</span><span class="token">ss</span><span class="token">.java)
</span></span><span class="line"><span class="token">            </span><span class="token">startActivity</span><span class="token">(context, intent, </span><span class="token" style="color: #005cc5;">null</span><span class="token">)
</span></span><span class="line"><span class="token">        }
</span></span><span class="line"><span class="token">    }
</span></span><span class="line"><span class="token">    </span><span class="token" style="color: #d73a49;">override</span><span class="token"> </span><span class="token">fun name</span><span class="token">()</span><span class="token">: </span><span class="token" style="color: #6f42c1;">Int</span><span class="token"> = </span><span class="token" style="color: #6f42c1;">R</span><span class="token">.</span><span class="token">string.battery_info
</span></span><span class="line"><span class="token">}
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-213"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-211">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-212'
	>
	Don’t forget to add this new tool to <code>Sentinel.watch</code>, which should now look like this:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-215"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-kotlin github-light" data-language="kotlin" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token">Sentinel</span><span class="token">.watch</span><span class="token">(
</span></span><span class="line"><span class="token">    </span><span class="token">setOf</span><span class="token">(
</span></span><span class="line"><span class="token">        </span><span class="token">ChuckerTool</span><span class="token">(), 
</span></span><span class="line"><span class="token">        </span><span class="token">DbInspectorTool</span><span class="token">(), 
</span></span><span class="line"><span class="token">        </span><span class="token">BatteryViewerTool</span><span class="token">()
</span></span><span class="line"><span class="token">    )
</span></span><span class="line"><span class="token">)
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-218"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-216">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-217'
	>
	Next step: enjoy your new tool!</p></div>	</div>
</div>
</div>		</div>
	</div>

<div
	class="wrapper"
	data-id="es-223"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="wrapper__inner">
			<div class="block-media">
	<div	class="media block-media__media media__border--none media__align--center-center"
	data-id="es-221"
	 data-media-type='video'>

	<div class="video__wrapper" data-id="es-222">
		<video
		class="video block-media__video js-video js-block-media-video video--cursor-takeover-use"
		 loop autoplay playsinline muted preload='metadata'>
		<source  src='https://infinum.com/uploads/2024/07/BatteryTool_optimized.mp4' type='video/mp4' />	</video>
	</div></div></div>		</div>
	</div>

<div
	class="wrapper"
	data-id="es-235"
	 data-animation-target='inner-items'>
		
			<div class="wrapper__inner">
			<div class="block-blog-content js-block-blog-content">
	
<div class="block-blog-content-sidebar" data-id="es-224">
	</div>

<div class="block-blog-content-main">
	
<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-227"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-225">
	<h2	class='typography typography--size-52-default js-typography block-heading__heading'
	data-id='es-226'
	>
	Working with Sentinel</h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-230"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-228">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-229'
	>
	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.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-233"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-231">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-232'
	>
	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.</p></div>	</div>
</div>
</div>		</div>
	</div>

<div
	class="wrapper"
	data-id="es-238"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="wrapper__inner">
			<div class="block-media">
	<div	class="media block-media__media media__border--none media__align--center-center"
	data-id="es-236"
	 data-media-type='image'>

	<figure class="image block-media__image-figure image--size-stretch" data-id="es-237">
	<picture class="image__picture block-media__image-picture">
												<img
					src="https://infinum.com/uploads/2024/07/SentinelTriggers.webp"
					class="image__img block-media__image-img"
					alt=""
										height="1100"
															width="1080"
										loading="lazy"
					 />
					</picture>

	</figure></div></div>		</div>
	</div>

<div
	class="wrapper"
	data-id="es-261"
	 data-animation-target='inner-items'>
		
			<div class="wrapper__inner">
			<div class="block-blog-content js-block-blog-content">
	
<div class="block-blog-content-sidebar" data-id="es-239">
	</div>

<div class="block-blog-content-main">
	
<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-242"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-240">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-241'
	>
	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 <code>AndroidManifest</code> 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.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-244"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-xml github-light" data-language="xml" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token">&lt;</span><span class="token" style="color: #22863a;">meta-data</span><span class="token">
</span></span><span class="line"><span class="token">  </span><span class="token" style="color: #6f42c1;">  and</span><span class="token" style="color: #6f42c1;">r</span><span class="token" style="color: #6f42c1;">oid:</span><span class="token">name=</span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #032f62;">com.infinum.sentinel.trigger.foreground</span><span class="token" style="color: #032f62;">&quot;</span><span class="token">
</span></span><span class="line"><span class="token">  </span><span class="token" style="color: #6f42c1;">  and</span><span class="token" style="color: #6f42c1;">r</span><span class="token" style="color: #6f42c1;">oid:v</span><span class="token">alue=</span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #032f62;">0</span><span class="token" style="color: #032f62;">&quot;</span><span class="token"> </span><span class="token">/&gt;</span><span class="token">
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-247"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-245">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-246'
	>
	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.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-250"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-248">
	<h2	class='typography typography--size-52-default js-typography block-heading__heading'
	data-id='es-249'
	>
	Simplify your testing process</h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-253"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-251">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-252'
	>
	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.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-256"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-254">
	<p	class='typography typography--size-20-text-roman js-typography block-paragraph__paragraph'
	data-id='es-255'
	>
	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. </p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-259"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-257">
	<p	class='typography typography--size-20-text-roman js-typography block-paragraph__paragraph'
	data-id='es-258'
	>
	<em>To check the repository and open any PRs or leave suggestions, head on to </em><a href="https://github.com/infinum/android-sentinel"><em>our GitHub page</em></a><em>. </em></p></div>	</div>
</div>
</div>		</div>
	</div><p>The post <a href="https://infinum.com/blog/sentinel-testing-tool-android/">Sentinel – The All-in-One Testing Tool for Your Android Device</a> appeared first on <a href="https://infinum.com">Infinum</a>.</p>
]]>
				</content:encoded>
			</item>
		
	</channel>
</rss>