<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet href="https://shkspr.mobi/blog/wp-content/themes/edent-wordpress-theme/rss-style.xsl" type="text/xsl"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	    xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	     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/"
	  xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>
<channel>
	<title>Kotlin &#8211; Terence Eden’s Blog</title>
	<atom:link href="https://shkspr.mobi/blog/tag/kotlin/feed/" rel="self" type="application/rss+xml" />
	<link>https://shkspr.mobi/blog</link>
	<description>Regular nonsense about tech and its effects 🙃</description>
	<lastBuildDate>Wed, 26 Feb 2025 23:06:13 +0000</lastBuildDate>
	<language>en-GB</language>
	<copyright>© Terence Eden. 🄯 CC BY-SA. See https://shkspr.mobi/blog/copyright-and-copyleft/</copyright>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>https://wordpress.org/?v=7.1.3</generator>

<image>
	<url>https://shkspr.mobi/blog/wp-content/uploads/2023/07/cropped-avatar-32x32.jpeg</url>
	<title>Kotlin &#8211; Terence Eden’s Blog</title>
	<link>https://shkspr.mobi/blog</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title><![CDATA[ManyTag Colour eInk Badge SDK - Minimum Viable Example for Android]]></title>
		<link>https://shkspr.mobi/blog/2025/02/manytag-colour-eink-badge-sdk-minimum-viable-example-for-android/</link>
					<comments>https://shkspr.mobi/blog/2025/02/manytag-colour-eink-badge-sdk-minimum-viable-example-for-android/#respond</comments>
				<dc:creator><![CDATA[Terence Eden]]></dc:creator>
		<pubDate>Fri, 28 Feb 2025 12:34:30 +0000</pubDate>
		<category><![CDATA[android]]></category><category><![CDATA[app]]></category><category><![CDATA[eink]]></category><category><![CDATA[HowTo]]></category><category><![CDATA[Kotlin]]></category>		<guid isPermaLink="false">https://shkspr.mobi/blog/?p=58487</guid>

					<description><![CDATA[Last year, I reviewed a Four-Colour eInk Name Badge - the ManyTag HSN371. The hardware itself is perfectly fine, but the Android app isn&#039;t great. It is complicated, crash-prone, and not available in the app-store.  After some back-and-forth with the manufacturer, they agreed to send me their Android SDK and documentation. Sadly, the PDF they sent me was riddled with errors and the software…]]></description>
										<content:encoded>&lt;p&gt;Last year, I reviewed a &lt;a href="https://shkspr.mobi/blog/2024/11/review-four-colour-eink-name-badge-hsn371-plus-linux-and-android-tips/"&gt;Four-Colour eInk Name Badge&lt;/a&gt; - the ManyTag HSN371. The hardware itself is perfectly fine, but the Android app isn't great. It is complicated, crash-prone, and not available in the app-store.&lt;/p&gt;

&lt;p&gt;After some back-and-forth with the manufacturer, they agreed to send me their Android SDK and documentation. Sadly, the PDF they sent me was riddled with errors and the software library is also a bit dodgy. So, with the help of &lt;a href="https://hades.omg.lol/"&gt;Edward Toroshchyn&lt;/a&gt; and a hefty amount of automated boiler-plate, I managed to get it working.&lt;/p&gt;

&lt;p&gt;The &lt;a href="https://codeberg.org/edent/eInk-SDK/"&gt;full code is open source&lt;/a&gt;, but here's a quick walk-through of the important bits.&lt;/p&gt;

&lt;p&gt;First, the AAR library needs to be imported into the project. Place it in &lt;code&gt;app/libs&lt;/code&gt; and then include it in the Gradle build file:&lt;/p&gt;

&lt;pre&gt;&lt;code class="language-java"&gt;dependencies {
    implementation(files("libs/badge_nfc_api-release.aar"))
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The key to getting it working is in the Android permissions. It needs Bluetooth, NFC, and location. So the manifest has to contain:&lt;/p&gt;

&lt;pre&gt;&lt;code class="language-xml"&gt;&amp;lt;uses-permission android:name="android.permission.BLUETOOTH"/&amp;gt;
&amp;lt;uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/&amp;gt;
&amp;lt;uses-permission android:name="android.permission.BLUETOOTH_SCAN"/&amp;gt;
&amp;lt;uses-permission android:name="android.permission.BLUETOOTH_CONNECT"/&amp;gt;
&amp;lt;uses-permission android:name="android.permission.NFC"/&amp;gt;
&amp;lt;uses-permission android:name="android.permission.NFC_TRANSACTION_EVENT"/&amp;gt;
&amp;lt;uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/&amp;gt;
&amp;lt;uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The following imports are needed from the Android Archive library:&lt;/p&gt;

&lt;pre&gt;&lt;code class="language-java"&gt;import cn.manytag.badge_nfc_api.manager.BadgeWriteManager
import cn.manytag.badge_nfc_api.manager.OnNFCReaderCallback
import cn.manytag.badge_nfc_api.manager.OnBluetoothCallBack
import cn.manytag.badge_nfc_api.manager.OnSendImageCallback
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The library needs to be initialised with:&lt;/p&gt;

&lt;pre&gt;&lt;code class="language-java"&gt;val state = BadgeWriteManager.getInstance().init(this)
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;When the phone reads the NFC tag, it gets a bunch of information:&lt;/p&gt;

&lt;pre&gt;&lt;code class="language-java"&gt;BadgeWriteManager.getInstance().setOnNFCReaderCallback(object : OnNFCReaderCallback {
    override fun onReaderMessage(i: Int, tag: Tag) {
        if (i == 0) {
            BadgeWriteManager.getInstance().readNFC(tag)
        }
    }

    //  Get the data from the badge
    override fun onReaderType(tag: Tag, isodep: IsoDep, i: Int, type: String, size: String, color: String) {
        if (i == 0) {
            nfcData = """
                NFC Tag Detected!!!
                Tag: $tag
                IsoDep: $isodep
                Type: $type
                Size: $size
                Color: $color
            """.trimIndent()
            colorFromNFC = color
            tagObject = tag
            isoDepObject = isodep
            badgeType = type
            badgeSize = size
        }
    }
})
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The &lt;code&gt;color&lt;/code&gt; is most important right now. It says whether the badge is black and white, or black and white and red, or black and white and red and yellow.&lt;/p&gt;

&lt;p&gt;After picking an image from the filesystem, it needs to be dithered into the correct colour format:&lt;/p&gt;

&lt;pre&gt;&lt;code class="language-java"&gt;processedBitmap = originalBitmap?.let { bitmap -&amp;gt;
    colorFromNFC?.let { color -&amp;gt;
        BadgeWriteManager.getInstance().processImage(bitmap, color)
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Finally, the processed image needs to be converted to bytes and then sent to the badge via Bluetooth:&lt;/p&gt;

&lt;pre&gt;&lt;code class="language-java"&gt;if (processedBitmap != null &amp;amp;&amp;amp; badgeType != null &amp;amp;&amp;amp; badgeSize != null &amp;amp;&amp;amp; colorFromNFC != null) {
    val imgData = BadgeWriteManager.getInstance().getImageData(processedBitmap!!, colorFromNFC!!)

    BadgeWriteManager.getInstance().sentImageResource(
        tagObject!!, isoDepObject!!, imgData, badgeType!!, badgeSize!!, colorFromNFC!!
    )
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;I realise this is a bit "&lt;a href="https://knowyourmeme.com/memes/how-to-draw-an-owl"&gt;draw the rest of the owl&lt;/a&gt;" but that should be enough to get you started on building an app which can communicate with these badges.&lt;/p&gt;

&lt;p&gt;The app I've built isn't the prettiest in the world but at least it works. It scans a badge, gets its info, picks an image, dithers it, then sends it to the badge.&lt;/p&gt;

&lt;img src="https://shkspr.mobi/blog/wp-content/uploads/2025/02/badge-app-fs8.png" alt="Screenshot of an app." width="504" height="957" class="aligncenter size-full wp-image-58494"&gt;

&lt;p&gt;You can &lt;a href="https://codeberg.org/edent/eInk-SDK/"&gt;play with the code on CodeBerg&lt;/a&gt;.&lt;/p&gt;
&lt;img src="https://shkspr.mobi/blog/wp-content/themes/edent-wordpress-theme/info/okgo.php?ID=58487&amp;amp;HTTP_REFERER=RSS" alt="" width="1" height="1" loading="eager"&gt;</content:encoded>
					
					<wfw:commentRss>https://shkspr.mobi/blog/2025/02/manytag-colour-eink-badge-sdk-minimum-viable-example-for-android/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
	</channel>
</rss>
