<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Molfar System]]></title><description><![CDATA[Notes from a solo Android developer building a multi-AI meeting app entirely from a phone: Python, Kivy, BYOK architecture, and no PC involved]]></description><link>https://gaiduk.hashnode.dev</link><image><url>https://cdn.hashnode.com/uploads/logos/6a8dc00b0cffe851369af6fc/665de03b-9cdd-417b-a040-5523b12f5e21.png</url><title>Molfar System</title><link>https://gaiduk.hashnode.dev</link></image><generator>RSS for Node</generator><lastBuildDate>Mon, 07 Sep 2026 08:13:44 GMT</lastBuildDate><atom:link href="https://gaiduk.hashnode.dev/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[Building an Android App Entirely From a Phone: What Actually Works]]></title><description><![CDATA[I built and shipped a Python Android app to Google Play without ever opening a laptop. Not as a stunt — I simply didn't have a PC. Here's what that setup actually looks like, where it holds up, and wh]]></description><link>https://gaiduk.hashnode.dev/android-app-from-a-phone</link><guid isPermaLink="true">https://gaiduk.hashnode.dev/android-app-from-a-phone</guid><category><![CDATA[Mobile Development]]></category><category><![CDATA[ci-cd]]></category><category><![CDATA[Android]]></category><category><![CDATA[Python]]></category><category><![CDATA[Kivy]]></category><dc:creator><![CDATA[Molfar System]]></dc:creator><pubDate>Tue, 25 Aug 2026 18:34:12 GMT</pubDate><enclosure url="https://cdn.hashnode.com/uploads/covers/6a8dc00b0cffe851369af6fc/74889ad6-4496-4198-b3cd-d5383cf9f946.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>I built and shipped a Python Android app to Google Play without ever opening a laptop. Not as a stunt — I simply didn't have a PC. Here's what that setup actually looks like, where it holds up, and where it falls apart.</p>
<h2>The stack that made it possible</h2>
<p>Python was less a choice than the only realistic option. There is no Android Studio for Android, no Gradle you can comfortably drive from a touchscreen. But there <em>is</em> a working Python environment.</p>
<ul>
<li><p><a href="https://play.google.com/store/apps/details?id=ru.iiec.pydroid3"><strong>Pydroid 3</strong></a> — a full Python 3.13 interpreter with a usable editor. This is where code gets written and tested first.</p>
</li>
<li><p><strong>Kivy 2.3.0 + KivyMD 1.2.0</strong> — the UI layer. Renders identically in Pydroid and in the final APK, which matters enormously when you can't debug on a desktop.</p>
</li>
<li><p><strong>GitHub Actions +</strong> <a href="https://buildozer.readthedocs.io/en/stable/"><strong>Buildozer</strong></a> <strong>+ python-for-android</strong> — the build pipeline. You cannot compile an APK on a phone. You push, CI builds, you download the artifact.</p>
</li>
<li><p><strong>SQLite</strong> — local storage, no server involved.</p>
</li>
</ul>
<p>The critical insight: development and build are separated. The phone writes code, GitHub compiles it. Once you accept that split, a lot becomes possible.</p>
<h2>What genuinely works better than expected</h2>
<p><strong>Iteration in Pydroid is fast.</strong> Faster than waiting on a Gradle sync, honestly. You edit, you run, you see the result. For UI work with Kivy this loop is tight.</p>
<p><strong>GitHub Actions is a complete substitute for a local build machine.</strong> A push triggers Buildozer, which runs python-for-android with the sdl2 bootstrap and produces builds for <code>arm64-v8a</code> and <code>armeabi-v7a</code>. Twenty minutes later there's an APK waiting. You never touch a terminal.</p>
<p><strong>Copy-paste is a legitimate workflow.</strong> Working with an AI assistant through a browser chat window, file by file, sounds primitive. It is primitive. It also works — the project reached 64+ files and roughly 26,600 lines this way. The constraint forces something useful: you have to actually understand the architecture, because nothing is auto-imported for you.</p>
<h2>Where it breaks</h2>
<p>Being honest about this matters more than the success story.</p>
<p><strong>Native libraries are the hard wall.</strong> When Android 15 introduced the 16 KB page size requirement, the fix lived inside python-for-android's native build layer. That is not something you resolve by pasting files into a chat window. That single problem required a proper agentic coding tool with terminal access — the one genuine exception in the whole project.</p>
<p><strong>p4a has constraints you must design around.</strong> Three that cost me real time:</p>
<ul>
<li><p><strong>SQLite ships without FTS5.</strong> No <code>MATCH</code>, no <code>bm25()</code>. Full-text search has to be built on <code>LIKE</code> and manual fragmentation.</p>
</li>
<li><p><code>requests</code> <strong>must be imported inside methods</strong>, not at module level, or the app can fail to start on some devices.</p>
</li>
<li><p><strong>File paths are restricted to</strong> <code>getExternalFilesDir</code><strong>.</strong> Writing to <code>/storage/emulated/0/</code> directly is blocked by Scoped Storage. Every path in the codebase has to respect this.</p>
</li>
</ul>
<p><strong>Two environments, one codebase.</strong> Code must run in both Pydroid (Python 3.13) and the packaged APK (Python 3.11 via p4a). Version differences surface in irritating places.</p>
<p><strong>Debugging a release build is painful.</strong> No <code>adb logcat</code> on hand, no breakpoints. You log to a file, read the file on the device, and reason backwards.</p>
<h2>Practical advice if you try this</h2>
<p><strong>Set up CI before you write real code.</strong> If the pipeline isn't proven on day one, you'll discover packaging problems weeks later with hundreds of files already written.</p>
<p><strong>Keep files small and single-purpose.</strong> When your entire code-transfer mechanism is copy-paste, a 2,000-line module is a genuine obstacle. Small modules are not a style preference here — they're a hard requirement.</p>
<p><strong>Write the constraints down and re-read them.</strong> I keep a plain-text file listing every p4a limitation, path rule, and import quirk. It gets re-read constantly. Working without an IDE means the tooling won't catch mistakes for you.</p>
<p><strong>Test on the weakest device you own.</strong> Kivy's performance ceiling is lower than native. Something smooth on a mid-range phone can stutter badly on an older one.</p>
<h2>Was it worth it?</h2>
<p>The app is on <a href="https://play.google.com/store/apps/details?id=com.nova_hata.molfar">Google Play</a>. It passed a 14-day closed beta with 19 testers. It runs on Android 7.0 and up.</p>
<p>The interesting part isn't that it's <em>possible</em> — it's that the barrier turned out to be far lower than assumed. A phone, a free CI runner, and a browser tab cover most of it. Not comfortably, and not for every kind of project. But the assumption that you need a desktop to build and ship real software is worth questioning.</p>
<p>If your only machine is the one in your pocket, that isn't automatically a dead end.</p>
]]></content:encoded></item></channel></rss>