<?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" xmlns:cc="http://cyber.law.harvard.edu/rss/creativeCommonsRssModule.html">
    <channel>
        <title><![CDATA[Stories by Ashish yadav on Medium]]></title>
        <description><![CDATA[Stories by Ashish yadav on Medium]]></description>
        <link>https://medium.com/@ya0285981?source=rss-e0f2eeac768c------2</link>
        <image>
            <url>https://cdn-images-1.medium.com/fit/c/150/150/0*_O78gmWrmllMr3Gb</url>
            <title>Stories by Ashish yadav on Medium</title>
            <link>https://medium.com/@ya0285981?source=rss-e0f2eeac768c------2</link>
        </image>
        <generator>Medium</generator>
        <lastBuildDate>Sun, 15 Nov 2026 10:16:17 GMT</lastBuildDate>
        <atom:link href="https://medium.com/@ya0285981/feed" rel="self" type="application/rss+xml"/>
        <webMaster><![CDATA[yourfriends@medium.com]]></webMaster>
        <atom:link href="http://medium.superfeedr.com/" rel="hub"/>
        <item>
            <title><![CDATA[How to Send Firebase Push Notifications Without Writing a Single Line of Code — Using FCM Deck?]]></title>
            <link>https://medium.com/@ya0285981/how-to-send-firebase-push-notifications-without-writing-a-single-line-of-code-using-fcm-deck-0027e58c5277?source=rss-e0f2eeac768c------2</link>
            <guid isPermaLink="false">https://medium.com/p/0027e58c5277</guid>
            <category><![CDATA[google-cloud-platform]]></category>
            <category><![CDATA[android]]></category>
            <category><![CDATA[backend-development]]></category>
            <category><![CDATA[firebase]]></category>
            <category><![CDATA[backend]]></category>
            <dc:creator><![CDATA[Ashish yadav]]></dc:creator>
            <pubDate>Mon, 04 May 2026 03:38:54 GMT</pubDate>
            <atom:updated>2026-05-04T03:38:54.759Z</atom:updated>
            <content:encoded><![CDATA[<p>So you want to send Firebase push notifications without writing any code. I totally get it. Testing Firebase Cloud Messaging can be a pain. You have to use Postman, find your service account JSON, figure out the API endpoint and craft the JSON payload. It is a lot of work to send a simple test notification.</p><p>That is where FCM Deck comes in. FCM Deck is a tool that you can use in your browser to send Firebase push notifications. You do not need to write any code or set up any backend. Whether you are a developer testing a feature or a product manager doing a quick test FCM Deck makes the whole process a lot easier.</p><p>So what is FCM Deck? FCM Deck is a web console for sending Firebase Cloud Messaging notifications. It is like the Firebase Consoles notification composer. It is faster and more flexible. The best part is that your keys never leave your browser. Your Firebase service account JSON is stored locally in your browser only. It is never uploaded to any server, never logged, never shared.</p><p>To get started with FCM Deck you need two things. First you need a Firebase Service Account JSON file. You can get this by going to your Firebase project then Project Settings, Service Accounts and finally Generate new private key. Download the JSON file. Second you need a device token or topic name. This is the FCM registration token of the device you want to send the notification to.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*AHBmxxrtMrCRWLfe-mvhgg.png" /></figure><p>Once you have these two things you can start using FCM Deck. Here is how you do it.</p><ul><li>First go to <a href="https://fcmdeck.web.app/">fcmdeck.web.app</a>. Click Add Project.</li><li>You will be asked for a Project Display Name and your Service Account JSON.</li><li>Hit Save. Your project will appear in the sidebar.</li></ul><p>Now you can compose your notification. FCM Deck gives you two modes: Simple Mode and Custom Payload Mode. Simple Mode is perfect for tests. You just need to fill in the Target Type, Priority, Title, Body, Image URL and Data Payload. This mode covers everyday use cases.</p><p>Custom Payload Mode is for power users. You can write a raw FCM message JSON yourself giving you control over every field. FCM Deck even provides to-use templates. You can. Format your JSON right in the editor before sending.</p><p>Once your message is composed, hit Send Notification. FCM Deck will show you the result away. Every notification you send is logged in the History tab so you can review past sends without retyping everything.</p><p>FCM Deck is better than the alternatives. The Firebase Console has a built-in notification composer. It is limited in flexibility and does not support sending to a raw device token easily.. Curl work fine, but they require you to manually construct the Authorization header and manage OAuth tokens.</p><p>FCM Deck is simple, flexible and private. It is free. You do not need to sign up for an account. You can clear your history anytime if you are working with tokens.</p><p>So who is FCM Deck for? It is for developers who are testing push notification flows during feature development. It is for QA engineers who are verifying notification behavior across device types. It is for product managers who need to trigger a test notification without asking a developer. It is for teams that do not want to build an internal notification tool from scratch.</p><p>FCM Deck is an useful tool that makes sending Firebase push notifications easy. It is free. It respects your privacy. Give it a try at <a href="https://fcmdeck.web.app/">fcmdeck.web.app</a>. You will probably have your notification sent within five minutes.</p><p>Have you used FCM Deck or a similar tool, in your workflow? I would love to hear how you are handling push notification testing.</p><h3>Open Source &amp; Contributions</h3><p>FCM Deck is also an open-source project. If you want to improve it, suggest features, or contribute, you can check out the code on GitHub:<br><a href="https://github.com/praveenkumarytc/fcmDeck"> https://github.com/praveenkumarytc/fcmDeck</a></p><p>Contributions, issues, and feedback are always welcome</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=0027e58c5277" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[ Setting Up GitHub Actions for Flutter CI/CD with Firebase App Distribution]]></title>
            <link>https://medium.com/@ya0285981/setting-up-github-actions-for-flutter-ci-cd-with-firebase-app-distribution-9a3650871a24?source=rss-e0f2eeac768c------2</link>
            <guid isPermaLink="false">https://medium.com/p/9a3650871a24</guid>
            <category><![CDATA[mobile-destribution]]></category>
            <category><![CDATA[flutter]]></category>
            <category><![CDATA[firebase]]></category>
            <category><![CDATA[cicd]]></category>
            <dc:creator><![CDATA[Ashish yadav]]></dc:creator>
            <pubDate>Thu, 30 Apr 2026 18:02:56 GMT</pubDate>
            <atom:updated>2026-04-30T18:02:56.949Z</atom:updated>
            <content:encoded><![CDATA[<p>If you’re building a Flutter app, automating your build and distribution process can save tons of time and reduce manual errors. In this guide, I’ll walk you through how to set up <strong>CI/CD using GitHub Actions</strong> to automatically build your Flutter app and distribute it via <strong>Firebase App Distribution</strong>.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/822/1*F5nLbx3GINTHkzDNAOEgzg.png" /></figure><h3>📌 Why CI/CD for Flutter?</h3><p>CI/CD (Continuous Integration / Continuous Deployment) helps you:</p><ul><li>Automatically build your app on every push</li><li>Run tests and ensure code quality</li><li>Distribute builds to testers without manual effort</li><li>Speed up your development workflow</li></ul><h3>🧰 Prerequisites</h3><p>Before starting, make sure you have:</p><ul><li>A Flutter project pushed to GitHub</li><li>Firebase project created</li><li>Firebase App Distribution enabled</li><li>Firebase CLI installed locally</li></ul><pre>npm install -g firebase-tools</pre><ul><li>Logged in to Firebase:</li></ul><pre>firebase login</pre><h3>🔥 Step 1: Setup Firebase App Distribution</h3><ol><li>Go to Firebase Console</li><li>Select your project</li><li>Navigate to <strong>App Distribution</strong></li><li>Add your Android/iOS app</li><li>Download google-services.json (for Android)</li></ol><h3>🔑 Step 2: Generate Firebase Token</h3><p>Run the following command:</p><pre>firebase login:ci</pre><p>This will generate a <strong>CI token</strong>.</p><p>👉 Copy this token — we’ll use it in GitHub Secrets.</p><h3>🔐 Step 3: Add GitHub Secrets</h3><p>Go to your GitHub repo:</p><p>👉 Settings → Secrets → Actions → New Repository Secret</p><p>Add the following:</p><ul><li>FIREBASE_TOKEN → paste your Firebase CI token</li><li>APP_ID → Firebase App ID (from Firebase Console)</li></ul><h3>⚙️ Step 4: Create GitHub Action Workflow</h3><p>Create a file:</p><pre>.github/workflows/flutter_ci_cd.yml</pre><p>Add the following configuration:</p><pre>name: Flutter CI/CD</pre><pre>on:<br>  push:<br>    branches:<br>      - main</pre><pre>jobs:<br>  build:<br>    name: Build &amp; Distribute<br>    runs-on: ubuntu-latest</pre><pre>    steps:<br>      - name: Checkout Repo<br>        uses: actions/checkout@v3</pre><pre>      - name: Setup Flutter<br>        uses: subosito/flutter-action@v2<br>        with:<br>          flutter-version: &#39;3.22.0&#39;</pre><pre>      - name: Install Dependencies<br>        run: flutter pub get</pre><pre>      - name: Run Tests<br>        run: flutter test</pre><pre>      - name: Build APK<br>        run: flutter build apk --release</pre><pre>      - name: Install Firebase CLI<br>        run: npm install -g firebase-tools</pre><pre>      - name: Distribute to Firebase<br>        run: |<br>          firebase appdistribution:distribute build/app/outputs/flutter-apk/app-release.apk \<br>          --app ${{ secrets.APP_ID }} \<br>          --groups &quot;testers&quot; \<br>          --token ${{ secrets.FIREBASE_TOKEN }}</pre><h3>📦 Step 5: Push and Trigger CI/CD</h3><p>Now just push your code:</p><pre>git add .<br>git commit -m &quot;Setup CI/CD&quot;<br>git push origin main</pre><p>🎉 GitHub Actions will automatically:</p><ul><li>Install Flutter</li><li>Run tests</li><li>Build APK</li><li>Upload to Firebase App Distribution</li></ul><h3>👥 Managing Testers</h3><p>In Firebase Console:</p><ul><li>Add testers (emails)</li><li>Create groups (e.g., testers, qa-team)</li><li>Use --groups flag in workflow</li></ul><h3>🛠 Optional Enhancements</h3><p>You can improve your pipeline by:</p><ul><li>Adding <strong>Flutter analyze</strong>:</li></ul><pre>- run: flutter analyze</pre><ul><li>Building <strong>AAB instead of APK</strong>:</li></ul><pre>flutter build appbundle</pre><ul><li>Adding <strong>iOS build support (macOS runner)</strong></li></ul><h3>🚨 Common Issues</h3><p>IssueSolutionFirebase auth errorRegenerate tokenBuild failsCheck Flutter versionApp not uploadedVerify App ID</p><h3>🎯 Conclusion</h3><p>With GitHub Actions + Firebase App Distribution, you now have a fully automated CI/CD pipeline for your Flutter app. This setup ensures faster releases, better testing, and a smoother development workflow.</p><h3>💬 Final Thoughts</h3><p>CI/CD is not just for big teams — even solo developers can benefit massively. Once you set this up, you’ll never want to go back to manual builds again.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=9a3650871a24" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[How to Get Background Location Updates in Flutter on Android & iOS using flutter_bg_location]]></title>
            <link>https://medium.com/@ya0285981/how-to-get-background-location-updates-in-flutter-on-android-ios-using-flutter-bg-location-d16f6f2eb5d4?source=rss-e0f2eeac768c------2</link>
            <guid isPermaLink="false">https://medium.com/p/d16f6f2eb5d4</guid>
            <dc:creator><![CDATA[Ashish yadav]]></dc:creator>
            <pubDate>Sat, 03 Jan 2026 10:53:45 GMT</pubDate>
            <atom:updated>2026-01-03T10:53:45.088Z</atom:updated>
            <content:encoded><![CDATA[<p>Background location tracking is a critical requirement for apps such as <strong>fitness trackers, delivery apps, attendance systems, ride-sharing, and safety applications</strong>.<br> While Flutter makes UI development easy, handling <strong>reliable background location updates on both Android and iOS</strong> requires careful implementation and platform-specific configuration.</p><p>In this article, you’ll learn how to use the <strong>flutter_bg_location plugin</strong> to track location <strong>continuously in foreground and background</strong> on <strong>Android and iOS</strong>.</p><h3>✨ Why Use flutter_bg_location?</h3><p>This plugin is built with a <strong>developer-first mindset</strong>, focusing on:</p><ul><li>Reliable background execution on Android &amp; iOS</li><li>Battery-efficient tracking</li><li>Clean and minimal Flutter API</li><li>Platform-compliant implementation</li></ul><p>Ideal for <strong>production-grade Flutter apps</strong> that need dependable location updates even when the app is not visible.</p><h3>📦 Step 1: Add the Plugin</h3><p>Add the dependency to your pubspec.yaml:</p><pre>dependencies:<br>  flutter_bg_location: ^1.0.0</pre><p>Run:</p><pre>flutter pub get</pre><h3>🔐 Step 2: Platform Configuration</h3><h3>🤖 Android Setup</h3><p>Open android/app/src/main/AndroidManifest.xml and add:</p><pre>&lt;uses-permission android:name=&quot;android.permission.ACCESS_FINE_LOCATION&quot;/&gt;<br>&lt;uses-permission android:name=&quot;android.permission.ACCESS_COARSE_LOCATION&quot;/&gt;<br>&lt;uses-permission android:name=&quot;android.permission.ACCESS_BACKGROUND_LOCATION&quot;/&gt;<br>&lt;uses-permission android:name=&quot;android.permission.FOREGROUND_SERVICE&quot;/&gt;</pre><p>🔹 Notes:</p><ul><li>Background location requires <strong>explicit user approval</strong> on Android 10+</li><li>The plugin uses a <strong>foreground service</strong> to ensure reliability</li><li>Do not forget to request runtime permissions</li></ul><h3>🍎 iOS Setup</h3><h4>Enable Background Modes</h4><p>In Xcode:</p><ul><li>Select <strong>Runner</strong></li><li>Go to <strong>Signing &amp; Capabilities</strong></li><li>Enable <strong>Background Modes</strong></li><li>Check <strong>Location updates</strong></li></ul><h4>Update Info.plist</h4><pre>&lt;key&gt;NSLocationWhenInUseUsageDescription&lt;/key&gt;<br>&lt;string&gt;This app requires location access to track user activity.&lt;/string&gt;</pre><pre>&lt;key&gt;NSLocationAlwaysAndWhenInUseUsageDescription&lt;/key&gt;<br>&lt;string&gt;This app requires background location access.&lt;/string&gt;</pre><pre>&lt;key&gt;UIBackgroundModes&lt;/key&gt;<br>&lt;array&gt;<br>  &lt;string&gt;location&lt;/string&gt;<br>&lt;/array&gt;</pre><p>🔹 Notes:</p><ul><li>Apple reviews background location usage carefully</li><li>Always explain <strong>why</strong> background access is needed</li></ul><h3>🚀 Step 3: Start Background Location Tracking</h3><pre>import &#39;package:flutter_bg_location/flutter_bg_location.dart&#39;;</pre><pre>void startTracking() {<br>  FlutterBgLocation.startLocationService(<br>    distanceFilter: 10,     // meters<br>    updateInterval: 5000,   // milliseconds<br>  );</pre><pre>  FlutterBgLocation.onLocation((location) {<br>    print(&#39;Latitude: ${location.latitude}&#39;);<br>    print(&#39;Longitude: ${location.longitude}&#39;);<br>    print(&#39;Accuracy: ${location.accuracy}&#39;);<br>    print(&#39;Altitude: ${location.altitude}&#39;);<br>  });<br>}</pre><p>✅ Works in:</p><ul><li>Foreground</li><li>Background</li><li>Screen-locked state <em>(platform dependent)</em></li></ul><h3>🛑 Step 4: Stop Location Tracking</h3><p>Always stop tracking when not required:</p><pre>void stopTracking() {<br>  FlutterBgLocation.stopLocationService();<br>}</pre><p>This helps conserve battery and aligns with platform best practices.</p><h3>⚙️ Configuration Options</h3><p>You can fine-tune tracking behavior:</p><ul><li><strong>Update Interval</strong> — control how often updates are received</li><li><strong>Distance Filter</strong> — receive updates only after movement</li><li><strong>Accuracy Settings</strong> — balance precision vs battery usage</li></ul><p>This flexibility makes the plugin suitable for both <strong>high-precision</strong> and <strong>low-power</strong> use cases.</p><h3>🔋 Battery Optimization Tips</h3><ul><li>Increase update interval when high accuracy is not required</li><li>Stop tracking when the user logs out or completes a task</li><li>Avoid unnecessary background listeners</li></ul><p>The plugin is optimized for long-running sessions, but smart configuration is key.</p><h3>🧪 Common Use Cases</h3><ul><li>Fitness &amp; health tracking</li><li>Delivery &amp; logistics</li><li>Attendance &amp; workforce tracking</li><li>Ride-sharing apps</li><li>Safety &amp; emergency tracking</li></ul><h3>🧠 Final Thoughts</h3><p>Handling background location in Flutter doesn’t need to be complex.</p><p>With <strong>flutter_bg_location</strong>, you get:</p><ul><li>A clean Flutter API</li><li>Android &amp; iOS-compliant background execution</li><li>Reliable performance for real-world production apps</li></ul><p>👉 <strong>View the plugin on pub.dev:</strong><br> <a href="https://pub.dev/packages/flutter_bg_location">https://pub.dev/packages/flutter_bg_location</a></p><p>Feedback, suggestions, and contributions are always welcome 💙<br> Happy building with Flutter 🚀</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=d16f6f2eb5d4" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[ Securing API Keys & Endpoints in Flutter — A Complete Guide]]></title>
            <link>https://medium.com/@ya0285981/securing-api-keys-endpoints-in-flutter-a-complete-guide-5279aa449872?source=rss-e0f2eeac768c------2</link>
            <guid isPermaLink="false">https://medium.com/p/5279aa449872</guid>
            <dc:creator><![CDATA[Ashish yadav]]></dc:creator>
            <pubDate>Sat, 29 Nov 2025 18:50:42 GMT</pubDate>
            <atom:updated>2025-11-29T18:50:42.631Z</atom:updated>
            <content:encoded><![CDATA[<h3>🔐 Securing API Keys &amp; Endpoints in Flutter — A Complete Guide</h3><p>If you’ve ever shared a Flutter app publicly — whether on Play Store, App Store, or GitHub — you’ve probably wondered:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*XAR2xgxRdk8RAhn2YlJGYw.png" /></figure><blockquote><strong><em>“How do I secure my API keys and endpoints so nobody can misuse them?”</em></strong></blockquote><p>This is an important question because Flutter apps are client-side, meaning <strong>any code shipped inside your APK/IPA can be reverse-engineered</strong>. Hardcoding secrets directly inside your Dart files can expose APIs, private endpoints, and paid services.</p><p>The truth is:<br> <strong>You cannot fully hide secrets in a Flutter client.</strong><br> But you <em>can</em> make it extremely hard to extract them — and more importantly, design your architecture so leaking keys doesn’t expose anything harmful.</p><p>This guide covers <strong>everything you need to know to secure API keys and endpoints in Flutter</strong>, including recommended patterns for 2025.</p><h3>🧨 Why You Should Never Hardcode API Keys in Flutter</h3><p>APK/IPA files can be decompiled using tools like:</p><ul><li><strong>jadx</strong> (for Android)</li><li><strong>Hopper</strong> or <strong>Ghidra</strong> (for iOS)</li><li><strong>Flutter Decompiler tools</strong></li></ul><p>If your API key is in your code like this:</p><pre>const apiKey = &quot;ABCD-12345-SECRET&quot;;</pre><p>Anyone can extract it in minutes.</p><p>This can lead to:</p><ul><li>Unauthorized API usage</li><li>Exhausted API quotas</li><li>Billing charges</li><li>Compromised backend security</li></ul><p>So let’s explore safer ways.</p><h3>✅ Option 1: Use a Backend Proxy (Best &amp; Recommended)</h3><p>This is the <strong>only real secure method</strong>.</p><p>Instead of calling the external API directly from Flutter:</p><pre>Flutter App → Your Backend → Third-party API</pre><h3>Benefits</h3><p>✔ API key lives on server only<br> ✔ You can enforce authentication (JWT sessions, OAuth, Firebase Auth)<br> ✔ You can rate-limit &amp; block suspicious activity<br> ✔ Allows rotating API keys easily</p><h3>Example Setup</h3><h4>1. Flutter calls your backend</h4><pre>final response =<br>    await http.get(Uri.parse(&quot;https://yourserver.com/weather?city=Delhi&quot;));</pre><h4>2. Backend adds API key internally</h4><pre>const result = await axios.get(<br>  `https://api.openweathermap.org/data/2.5/weather?q=${city}&amp;appid=${process.env.API_KEY}`<br>);</pre><p>With this approach, <strong>your API key is never shipped inside the app</strong>.</p><h3>🔐 Option 2: Use Flutter Environment Variables (obfuscation only)</h3><p>Flutter supports <em>flavors</em> &amp; <em>env variables</em>.</p><h3>Add .env file (do NOT commit)</h3><pre>API_URL=https://example.com<br>API_KEY=xxxxxx</pre><h3>Use flutter_dotenv</h3><pre>dependencies:<br>  flutter_dotenv: ^5.1.0</pre><p>Load it:</p><pre>await dotenv.load();</pre><pre>final key = dotenv.env[&quot;API_KEY&quot;];</pre><h3>⚠ Warning</h3><p>This is <em>not secure</em>.<br> Env variables still get bundled inside your build → can be extracted.</p><p>Use this only for:</p><ul><li>Non-sensitive constants</li><li>Dev/staging flags</li></ul><h3>🔐 Option 3: Platform-specific Secret Storage (better but not perfect)</h3><p>Store secrets in:</p><h3>Android — local.properties + NDK</h3><h3>iOS — Config.xcconfig</h3><p>Example:</p><h4>android/local.properties</h4><pre>API_KEY=xxxxx</pre><p>Access using BuildConfig:</p><pre>String key = BuildConfig.API_KEY;</pre><h3>Pros</h3><p>✔ Harder to extract than Dart code<br> ✔ Obfuscation + Native layers</p><h3>Cons</h3><p>❌ Still extractable via reverse engineering<br> ❌ Maintenance overhead</p><p>Use this only when backend proxy is not possible.</p><h3>🔐 Option 4: Flutter Code Obfuscation</h3><p>Helps hide string literals and method names.</p><p>Enable obfuscation:</p><pre>flutter build apk --obfuscate --split-debug-info=build/debug-info</pre><h3>Pros</h3><p>✔ Makes reverse engineering harder<br> ✔ Removes readable names</p><h3>Cons</h3><p>❌ Does NOT hide secrets<br> ❌ Only slows attackers</p><p>Use it as an <strong>additional layer</strong>, not the main solution.</p><h3>🛑 What You Should Never Do</h3><p>❌ Put API keys inside Dart files<br> ❌ Commit API keys to GitHub<br> ❌ Store Firebase service account credentials inside Flutter<br> ❌ Ship private endpoints inside the app<br> ❌ Assume obfuscation = security</p><h3>🛡 Best Architecture for API Security (Recommended Setup)</h3><h3>Final Stack:</h3><pre>Flutter → Your Secure Backend → Third-Party API<br>            ↑<br>         Auth (JWT / Firebase Auth)</pre><h3>Must-have security rules:</h3><ol><li>Use backend proxy for any private API</li><li>Apply rate limiting (Cloudflare / Nginx / API Gateway)</li><li>Validate user tokens on the backend</li><li>Store secrets in environment variables on server</li><li>Rotate API keys every few months</li></ol><h3>💡 Example: Secure Weather API in Flutter</h3><h3>❌ Bad (direct, exposed)</h3><pre>const apiKey = &quot;12345-ABCDE&quot;;<br>final url = &quot;https://api.weather.com?apikey=$apiKey&quot;;</pre><h3>✅ Good (indirect, protected)</h3><p><strong>Flutter call</strong></p><pre>final res = await http.get(Uri.parse(&quot;https://myapp.com/weather?c=Delhi&quot;));</pre><p><strong>Your server</strong></p><pre>app.get(&quot;/weather&quot;, async (req, res) =&gt; {<br>  const city = req.query.c;<br>  const data = await weatherService.fetchWeather(city); // uses API_KEY internally<br>  res.json(data);<br>});</pre><h3>🧿 Protecting Endpoints Used by the App</h3><p>Even your own backend endpoints should be secured.</p><h3>Use JWT</h3><pre>final token = await FirebaseAuth.instance.currentUser?.getIdToken();</pre><p>Send with every request:</p><pre>headers: {&quot;Authorization&quot;: &quot;Bearer $token&quot;}</pre><p>Server verifies token before responding.</p><h3>Add rate limiting</h3><ul><li>Cloudflare Rules</li><li>Nginx limit_req</li><li>Express express-rate-limit</li></ul><h3>No endpoint should respond without authentication</h3><p>Especially:</p><ul><li>/getUserData</li><li>/updateProfile</li><li>/admin/**</li><li>/payment/**</li></ul><h3>🧵 Conclusion</h3><p>Securing API keys in Flutter isn’t about hiding them — it’s about <strong>architecting your app correctly</strong>.</p><h3>✔ What actually works</h3><ul><li>Use your own backend</li><li>Store secrets server-side</li><li>Add authentication &amp; rate limiting</li></ul><h3>✔ What helps but is not full security</h3><ul><li>Dotenv</li><li>Obfuscation</li><li>Native secret storage</li></ul><h3>❌ What never works</h3><ul><li>Hardcoding keys inside Flutter</li></ul><p>If you follow the recommended structure, you can safely scale your Flutter app without fearing API abuse or key leakage.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=5279aa449872" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Token-Oriented Object Notation (TOON) — a compact human-friendly data format]]></title>
            <link>https://medium.com/@ya0285981/token-oriented-object-notation-toon-a-compact-human-friendly-data-format-63907198664b?source=rss-e0f2eeac768c------2</link>
            <guid isPermaLink="false">https://medium.com/p/63907198664b</guid>
            <category><![CDATA[backend]]></category>
            <category><![CDATA[json]]></category>
            <category><![CDATA[technology]]></category>
            <category><![CDATA[data-science]]></category>
            <category><![CDATA[android]]></category>
            <dc:creator><![CDATA[Ashish yadav]]></dc:creator>
            <pubDate>Sun, 16 Nov 2025 07:13:18 GMT</pubDate>
            <atom:updated>2025-12-05T18:49:48.023Z</atom:updated>
            <content:encoded><![CDATA[<p><strong>Subtitle:</strong> Meet TOON — a small, token-first data notation designed for predictable streaming, tiny parsers, and easy human inspection.</p><p>TOON is a lightweight, line-oriented serialization format that exposes a token stream as the primary structure. Each value is represented by a token header followed by optional payload fields. It aims to be easy to parse in streaming environments (low memory), friendly to line-oriented tools, and explicit about types so small embedded systems or simple shell scripts can read and produce it reliably.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*LMnPYiQg2R2OWvN2i46j_g.png" /></figure><h3>Motivation</h3><p>JSON is great for nested structures but requires full-tree parsing for some operations and can be verbose for typed data. YAML is flexible but has complex parsing edge-cases. Binary formats (CBOR, MessagePack) are compact but harder to debug.</p><p>TOON sits between human-readable and tokenized/binary formats:</p><ul><li>predictable token-per-line structure for streaming/parsing</li><li>explicit, simple typing (no guessing)</li><li>easy to append to logs or pipes (line-oriented)</li><li>small parser (handwritten) fits tiny runtimes</li></ul><p>Think: system logs that carry structured data, CLI tools that emit typed events, or embedded devices that must stream telemetry with minimal CPU.</p><h3>Syntax overview (short)</h3><ul><li>File is a sequence of <em>entries</em> (one per line). Blank lines ignored.</li><li>Each entry begins with an ASCII token name (uppercase letters, digits, _) followed by a colon :.</li><li>After the token header, optional fields separated by pipes | (pipe characters).</li><li>Fields can be:</li><li>k=v pairs (string key with typed value),</li><li>positional values (no key),</li><li>or JSON payload (when the last field starts with { or [).</li><li>Types are indicated with suffixes in values or by token semantics; common scalar types are: s (string), i (integer), f (float), b (boolean), t (timestamp/ISO8601), j (JSON blob), B64 (base64).</li><li>Comments: start with # as first non-space char on a line.</li></ul><p>Example single-line entry:</p><pre>EVT:time=t:2025-11-16T07:18:00Z|level=s:info|msg=s:User logged in|user_id=i:1234</pre><h3>Formalized example and grammar</h3><h3>Token header</h3><pre>&lt;TOKEN&gt; := [A-Z0-9_]+<br>Entry := TOKEN &#39;:&#39; FieldList?<br>FieldList := Field ( &#39;|&#39; Field )*<br>Field := Keyed | Positional | JsonBlob<br>Keyed := Key &#39;:&#39; TypeTag? Value<br>Key := [a-zA-Z_][a-zA-Z0-9_-]*<br>TypeTag := [a-zA-Z0-9]+    # optional, like i, f, b, t, j, B64<br>Value := &lt;string-with-escaping&gt;<br>Positional := TypeTag? Value<br>JsonBlob := &#39;j:&#39; &#39;{&#39; ... &#39;}&#39; | &#39;j:&#39; &#39;[&#39; ... &#39;]&#39;</pre><h3>Value encoding rules</h3><ul><li>: separates a key/type tag block from the value. Example: age:i:42</li><li>If no TypeTag is given, s (string) is assumed.</li><li>Strings may contain escaped \| (escaped pipe), \\, and \n sequences. Single-line entries are recommended.</li><li>Base64 for binary: photo:B64:/9j/4AAQSkZJRgABAQAAAQABAAD...</li></ul><h3>Examples</h3><h3>Simple event log</h3><pre>EVT:time:t:2025-11-16T07:18:00Z|level:s:info|msg:s:Connected to server|lat:f:28.6139|lon:f:77.2090</pre><h3>Key-value record</h3><pre>USER:create|id:i:9876|name:s:Ashish Patel|email:s:ashish@example.com|active:b:true</pre><h3>Positional tokens (compact telemetry)</h3><pre>TMP:28.4|23.1|27.9   # interpreted as three floats (if schema known)</pre><h3>Embedded JSON (for complex nested object)</h3><pre>SCHED:j:{&quot;match&quot;:&quot;RR vs CSK&quot;,&quot;start&quot;:&quot;2026-04-10T14:30:00Z&quot;,&quot;venue&quot;:&quot;Chennai&quot;}</pre><h3>Binary data (base64)</h3><pre>PHOTO:user_id:i:9876|image:B64:/9j/4AAQSkZJRgABAQAAAQABAAD...</pre><h3>Parsing model &amp; streaming benefits</h3><p>Because each entry is a token plus a short, parseable set of fields, parsers can:</p><ol><li>Read line-by-line (no need to buffer nested braces).</li><li>Switch on TOKEN and decide how to interpret remaining fields.</li><li>Use minimal lookahead — perfect for embedded devices or streaming log processors.</li></ol><p>A tiny pseudo-parser (conceptual):</p><pre>for each line:<br>    skip blank/comments<br>    token, rest = split_at_first(&#39;:&#39;)<br>    fields = split_escaped(rest, &#39;|&#39;)<br>    for field in fields:<br>        if looks_like_json(field): parse_json(field)<br>        else if has_two_colons(field): key, typ, val = split_first_two(&#39;:&#39;)<br>        else if has_one_colon(field): key, val = split_first(&#39;:&#39;); typ=&#39;s&#39;<br>        else: treat as positional with optional type prefix<br>    emit object(token, fields_map, positional_list)</pre><p>This approach avoids full-document tree building and is straightforward to implement in ≤50 lines in C, Go, Rust, or Python.</p><h3>Comparison: TOON vs JSON, YAML, MessagePack</h3><ul><li><strong>Human readability</strong>: JSON &gt; TOON &gt; MessagePack; TOON is intentionally compact and tokenized for humans who read logs.</li><li><strong>Streaming</strong>: TOON &gt;&gt; JSON (for nested objects) because TOON is line-oriented.</li><li><strong>Typed values</strong>: TOON has explicit simple typing (i, f, b, t, B64) which is friendlier than JSON&#39;s implicit typing.</li><li><strong>Binary compactness</strong>: MessagePack/CBOR win. TOON is text-first, trading size for readability.</li><li><strong>Parser complexity</strong>: TOON parsers are trivial compared to YAML and robust JSON libraries.</li></ul><h3>Use-cases</h3><ul><li>Telemetry and event logging where you want typed, append-only lines.</li><li>CLI tools that produce structured events consumable by awk, jq-like filters (with a lightweight pre-parser).</li><li>Embedded devices that need structured output, but cannot afford a full JSON stack.</li><li>Audit trails where token semantics (e.g., AUTH_SUCCESS, PAYMENT) should be easily grep-able.</li></ul><h3>Example toolchain: convert TOON → JSON (one-liner idea)</h3><p>A small script can convert TOON to JSON objects — useful for piping to downstream systems:</p><ul><li>Read line, parse fields into dict, map typed values, print JSON object per line.</li><li>Because TOON is token-first, you can route tokens to different consumers easily.</li></ul><h3>Pros &amp; Cons</h3><p><strong>Pros</strong></p><ul><li>Extremely predictable, good for streaming.</li><li>Small parser implementation effort.</li><li>Explicit typing reduces ambiguity.</li><li>Line-oriented — appendable and easy to grep/sed/awk.</li></ul><p><strong>Cons</strong></p><ul><li>Not optimized for deeply nested structures (JSON wins there).</li><li>Slightly more verbose than compact binary formats.</li><li>Requires consumers to know type-tags and token semantics (schema).</li></ul><h3>Suggested Standard Practices</h3><ul><li>Use UTC ISO8601 for timestamps and t tag.</li><li>Keep entries one line if you rely on line-oriented tools.</li><li>Define a small token registry for your application domain (token descriptions, field names and types).</li><li>Include a header token (optional) at file start to declare schema version:</li><li>META:ver:s:1.0|created:t:2025-11-16T07:00:00Z</li></ul><h3>Quick reference (cheat sheet)</h3><pre>TOKEN: &lt;name&gt;  # uppercase<br>FIELDS: key:TYPE:VALUE  OR  TYPE:VALUE  OR  raw-json -&gt; j:{...}<br>TYPES: s (string), i (int), f (float), b (bool), t (timestamp), j (json), B64 (binary)<br>SEPARATOR: |  # escape as \|<br>COMMENTS: # at start of line</pre><h3>Closing thoughts</h3><p>TOON is intentionally pragmatic: not a replacement for JSON in every case, but an alternative for scenarios where streaming, tiny parsers, and human-inspectable typed logs matter. If you care about appendable telemetry, low-memory parsing, and readable auditing, TOON might be a fit.</p><p>If you like this idea, next steps could include:</p><ul><li>A short reference implementation in Go/Python/C.</li><li>A tiny toon2json CLI that streams conversion.</li><li>A schema registry format (optional) to describe tokens and allowed fields.</li></ul><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=63907198664b" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[How I Built a Reliable Background Location Service in Flutter using Kotlin.(Even]]></title>
            <link>https://medium.com/@ya0285981/how-i-built-a-reliable-background-location-service-in-flutter-using-kotlin-even-8ce01f193dd8?source=rss-e0f2eeac768c------2</link>
            <guid isPermaLink="false">https://medium.com/p/8ce01f193dd8</guid>
            <category><![CDATA[flutter]]></category>
            <category><![CDATA[flutter-app-development]]></category>
            <category><![CDATA[background-service]]></category>
            <category><![CDATA[gps-tracking-system]]></category>
            <category><![CDATA[kotlin]]></category>
            <dc:creator><![CDATA[Ashish yadav]]></dc:creator>
            <pubDate>Thu, 13 Nov 2025 15:13:56 GMT</pubDate>
            <atom:updated>2025-11-13T15:13:56.840Z</atom:updated>
            <content:encoded><![CDATA[<h3>How I Built a Reliable Background Location Service in Flutter using Kotlin.(Even When the App is Killed)</h3><p>Learn how to build a reliable Flutter background location tracking system using a native Kotlin Foreground Service, EventChannel, and AlarmManager — works even when the app is closed or the device restarts.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*NkKWalRgAvIaCk0Gya_rGw.png" /></figure><h3>🧩 Table of Contents</h3><ol><li><strong>Introduction</strong></li><li><strong>Project Overview</strong></li><li><strong>Architecture: How it Works</strong></li><li><strong>Android Setup</strong></li><li><strong>Flutter → Android Communication (Channels)</strong></li><li><strong>Foreground Location Service (Kotlin)</strong></li><li><strong>Flutter Side: Listening to Events</strong></li><li><strong>Testing the Setup</strong></li><li><strong>Final Notes and Limitations</strong></li><li><strong>Full Source</strong></li></ol><h3>🪐 1. Introduction</h3><blockquote><em>Flutter’s built-in location plugins can track your position when the app is open — but when you close or kill the app, updates stop.</em></blockquote><blockquote><em>In this article, I’ll show you how to create a </em><strong><em>custom background location system</em></strong><em> in Flutter using:</em></blockquote><ul><li>Native <strong>Android Foreground Service</strong></li><li><strong>AlarmManager</strong> for restart</li><li><strong>BootCompletedReceiver</strong> for reboot persistence</li><li><strong>EventChannel &amp; MethodChannel</strong> for communication</li></ul><blockquote><em>It updates your location continuously in background — even if Flutter is not running.</em></blockquote><h3>⚙️ 2. Project Overview</h3><p>We’ll build a small system with:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*_JD672IRzyO10WEH1vb6yw.png" /></figure><p>🧠 3. Architecture: How It Works</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*ADwqQ6nWxWEM556StE_-2w.png" /></figure><h3>🛠️ 4. Android Setup</h3><h3>4.1 Permissions in AndroidManifest.xml</h3><p>Add these <strong>above </strong><strong>&lt;application&gt;</strong>:</p><pre>&lt;uses-permission android:name=&quot;android.permission.FOREGROUND_SERVICE&quot; /&gt;<br>&lt;uses-permission android:name=&quot;android.permission.ACCESS_FINE_LOCATION&quot; /&gt;<br>&lt;uses-permission android:name=&quot;android.permission.ACCESS_COARSE_LOCATION&quot; /&gt;<br>&lt;uses-permission android:name=&quot;android.permission.ACCESS_BACKGROUND_LOCATION&quot; /&gt;<br>&lt;uses-permission android:name=&quot;android.permission.RECEIVE_BOOT_COMPLETED&quot; /&gt;</pre><h3>4.2 Inside &lt;application&gt;...&lt;/application&gt;</h3><pre>&lt;service<br>    android:name=&quot;.LocationService&quot;<br>    android:exported=&quot;false&quot;<br>    android:foregroundServiceType=&quot;location&quot; /&gt;</pre><pre>&lt;receiver<br>    android:name=&quot;.RestartReceiver&quot;<br>    android:exported=&quot;false&quot; /&gt;</pre><pre>&lt;receiver<br>    android:name=&quot;.BootCompletedReceiver&quot;<br>    android:enabled=&quot;true&quot;<br>    android:exported=&quot;true&quot;&gt;<br>    &lt;intent-filter&gt;<br>        &lt;action android:name=&quot;android.intent.action.BOOT_COMPLETED&quot; /&gt;<br>    &lt;/intent-filter&gt;<br>&lt;/receiver&gt;</pre><h3>💡 5. Flutter ↔ Android Communication</h3><h3>MainActivity.kt</h3><p>This connects your Flutter side to the native service.</p><pre>package com.example.background_location</pre><pre>import android.content.Intent<br>import android.os.Build<br>import android.os.Bundle<br>import android.util.Log<br>import io.flutter.embedding.android.FlutterActivity<br>import io.flutter.embedding.engine.FlutterEngine<br>import io.flutter.plugin.common.EventChannel<br>import io.flutter.plugin.common.MethodChannel</pre><pre>class MainActivity : FlutterActivity() {</pre><pre>    private val METHOD_CHANNEL = &quot;background_location/methods&quot;<br>    private val EVENT_CHANNEL = &quot;background_location/events&quot;<br>    private var eventSink: EventChannel.EventSink? = null</pre><pre>    override fun configureFlutterEngine(flutterEngine: FlutterEngine) {<br>        super.configureFlutterEngine(flutterEngine)</pre><pre>        // 🔧 Method Channel<br>        MethodChannel(flutterEngine.dartExecutor.binaryMessenger, METHOD_CHANNEL)<br>            .setMethodCallHandler { call, result -&gt;<br>                when (call.method) {<br>                    &quot;startService&quot; -&gt; {<br>                        startService()<br>                        result.success(true)<br>                    }<br>                    &quot;stopService&quot; -&gt; {<br>                        val stopIntent = Intent(this, LocationService::class.java)<br>                        stopService(stopIntent)<br>                        result.success(true)<br>                    }<br>                    &quot;checkServiceAlive&quot; -&gt; {<br>                        result.success(LocationService.isRunning)<br>                    }<br>                    else -&gt; result.notImplemented()<br>                }<br>            }</pre><pre>        // 📡 Event Channel<br>        EventChannel(flutterEngine.dartExecutor.binaryMessenger, EVENT_CHANNEL)<br>            .setStreamHandler(object : EventChannel.StreamHandler {<br>                override fun onListen(arguments: Any?, events: EventChannel.EventSink?) {<br>                    eventSink = events<br>                    LocationService.setEventSinkStatic(events)<br>                }</pre><pre>                override fun onCancel(arguments: Any?) {<br>                    eventSink = null<br>                    LocationService.setEventSinkStatic(null)<br>                }<br>            })<br>    }</pre><pre>    private fun startService() {<br>        val intent = Intent(this, LocationService::class.java)<br>        if (Build.VERSION.SDK_INT &gt;= Build.VERSION_CODES.O)<br>            startForegroundService(intent)<br>        else<br>            startService(intent)<br>    }<br>}</pre><h3>🚀 6. Foreground Location Service (LocationService.kt)</h3><pre>package com.example.background_location</pre><pre>import android.app.*<br>import android.content.Context<br>import android.content.Intent<br>import android.location.Location<br>import android.os.Build<br>import android.os.IBinder<br>import android.os.Looper<br>import android.util.Log<br>import androidx.core.app.NotificationCompat<br>import com.google.android.gms.location.*<br>import io.flutter.plugin.common.EventChannel</pre><pre>class LocationService : Service() {</pre><pre>    companion object {<br>        var isRunning = false<br>        private var staticSink: EventChannel.EventSink? = null</pre><pre>        fun setEventSinkStatic(sink: EventChannel.EventSink?) {<br>            staticSink = sink<br>        }<br>    }</pre><pre>    private lateinit var fusedClient: FusedLocationProviderClient<br>    private lateinit var locationRequest: LocationRequest<br>    private var callback: LocationCallback? = null</pre><pre>    override fun onCreate() {<br>        super.onCreate()<br>        fusedClient = LocationServices.getFusedLocationProviderClient(this)<br>        locationRequest = LocationRequest.Builder(<br>            Priority.PRIORITY_HIGH_ACCURACY, 10_000L<br>        ).setMinUpdateIntervalMillis(5_000L).build()<br>        createChannel()<br>    }</pre><pre>    private fun createChannel() {<br>        if (Build.VERSION.SDK_INT &gt;= Build.VERSION_CODES.O) {<br>            val channel = NotificationChannel(<br>                &quot;loc_service&quot;, &quot;Background Location&quot;,<br>                NotificationManager.IMPORTANCE_LOW<br>            )<br>            getSystemService(NotificationManager::class.java).createNotificationChannel(channel)<br>        }<br>    }</pre><pre>    private fun startForegroundNotification() {<br>        val notification = NotificationCompat.Builder(this, &quot;loc_service&quot;)<br>            .setContentTitle(&quot;Location Tracking&quot;)<br>            .setContentText(&quot;Tracking location in background&quot;)<br>            .setSmallIcon(android.R.drawable.ic_menu_mylocation)<br>            .build()<br>        startForeground(1, notification)<br>    }</pre><pre>    private fun sendUpdate(loc: Location) {<br>        val map = mapOf(<br>            &quot;latitude&quot; to loc.latitude,<br>            &quot;longitude&quot; to loc.longitude,<br>            &quot;accuracy&quot; to loc.accuracy,<br>            &quot;timestamp&quot; to System.currentTimeMillis()<br>        )<br>        staticSink?.success(map)<br>        Log.d(&quot;LocationService&quot;, &quot;📍 $map&quot;)<br>    }</pre><pre>    override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {<br>        startForegroundNotification()<br>        isRunning = true<br>        callback = object : LocationCallback() {<br>            override fun onLocationResult(result: LocationResult) {<br>                for (loc in result.locations) sendUpdate(loc)<br>            }<br>        }<br>        fusedClient.requestLocationUpdates(locationRequest, callback!!, Looper.getMainLooper())<br>        return START_STICKY<br>    }</pre><pre>    override fun onDestroy() {<br>        super.onDestroy()<br>        callback?.let { fusedClient.removeLocationUpdates(it) }<br>        isRunning = false<br>        staticSink?.endOfStream()<br>    }</pre><pre>    override fun onBind(intent: Intent?): IBinder? = null<br>}</pre><h3>🔁 7. Auto Restart After Kill or Reboot</h3><h3>RestartReceiver.kt</h3><pre>package com.example.background_location</pre><pre>import android.content.*<br>import android.os.Build<br>import android.util.Log</pre><pre>class RestartReceiver : BroadcastReceiver() {<br>    override fun onReceive(context: Context, intent: Intent) {<br>        Log.d(&quot;RestartReceiver&quot;, &quot;⏰ Restart alarm triggered&quot;)<br>        val service = Intent(context, LocationService::class.java)<br>        if (Build.VERSION.SDK_INT &gt;= Build.VERSION_CODES.O)<br>            context.startForegroundService(service)<br>        else<br>            context.startService(service)<br>    }<br>}</pre><h3>BootCompletedReceiver.kt</h3><pre>package com.example.background_location</pre><pre>import android.content.*<br>import android.os.Build<br>import android.util.Log</pre><pre>class BootCompletedReceiver : BroadcastReceiver() {<br>    override fun onReceive(context: Context, intent: Intent) {<br>        if (intent.action == Intent.ACTION_BOOT_COMPLETED) {<br>            Log.d(&quot;BootReceiver&quot;, &quot;✅ Device rebooted — starting service&quot;)<br>            val service = Intent(context, LocationService::class.java)<br>            if (Build.VERSION.SDK_INT &gt;= Build.VERSION_CODES.O)<br>                context.startForegroundService(service)<br>            else<br>                context.startService(service)<br>        }<br>    }<br>}</pre><h3>🧩 8. Flutter Side — location_service.dart</h3><pre>import &#39;dart:async&#39;;<br>import &#39;package:flutter/services.dart&#39;;<br>import &#39;package:flutter/foundation.dart&#39;;</pre><pre>class LocationService {<br>  static const _method = MethodChannel(&#39;background_location/methods&#39;);<br>  static const _events = EventChannel(&#39;background_location/events&#39;);</pre><pre>  Stream&lt;Map&lt;String, dynamic&gt;&gt;? _stream;</pre><pre>  Stream&lt;Map&lt;String, dynamic&gt;&gt; get locationStream {<br>    _stream ??= _events.receiveBroadcastStream().map((e) {<br>      final map = Map&lt;String, dynamic&gt;.from(e);<br>      debugPrint(&#39;📍 $map&#39;);<br>      return map;<br>    });<br>    return _stream!;<br>  }</pre><pre>  Future&lt;void&gt; start() async {<br>    await _method.invokeMethod(&#39;startService&#39;);<br>  }</pre><pre>  Future&lt;void&gt; stop() async {<br>    await _method.invokeMethod(&#39;stopService&#39;);<br>  }</pre><pre>  Future&lt;bool&gt; isRunning() async {<br>    return await _method.invokeMethod(&#39;checkServiceAlive&#39;);<br>  }<br>}</pre><h3>Usage Example:</h3><pre>final locationService = LocationService();</pre><pre>await locationService.start();</pre><pre>locationService.locationStream.listen((loc) {<br>  print(&quot;Location: ${loc[&#39;latitude&#39;]}, ${loc[&#39;longitude&#39;]}&quot;);<br>});</pre><h3>🧪 9. Testing Checklist</h3><p>✅ Start service and check logs:</p><pre>🚀 startLocationService() called<br>Started location updates<br>📍 Location update: {latitude: ..., longitude: ...}</pre><p>✅ Close Flutter app → logs continue</p><p>✅ Restart phone → logs show:</p><pre>✅ Device rebooted — starting service<br>📍 Location update: ...</pre><p>✅ Stop manually → no auto restart</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*PrRrY7ArWEChIlDtT4SLmA.png" /></figure><h3>📦 11. Full Source Code</h3><p>👉 <a href="https://github.com/ashish8381/custom_location_tracking">https://github.com/ashish8381/custom_location_tracking</a><br> (You can upload your final version there.)</p><h3>✨ 12. Bonus Improvements (optional)</h3><ul><li>Store last location in SharedPreferences</li><li>Upload to Firebase in background via WorkManager</li><li>Add iOS support via background_fetch or flutter_background_geolocation</li></ul><h3>✅ Closing</h3><blockquote><em>That’s it! You now have a </em><strong><em>complete Flutter + Android hybrid background location tracker</em></strong><em> that works reliably across foreground, background, and reboot.</em></blockquote><p>If you found this useful, share it with your team or star ⭐ the <a href="https://github.com/ashish8381/custom_location_tracking">[GitHub repo]</a>!</p><p>Tags: flutter, kotlin, android-development, background-services, location-tracking, mobile-development</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=8ce01f193dd8" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[ Console Plus — The Floating In-App Debug Console for Flutter Developers]]></title>
            <link>https://medium.com/@ya0285981/console-plus-the-floating-in-app-debug-console-for-flutter-developers-ea1f6a2d1bdf?source=rss-e0f2eeac768c------2</link>
            <guid isPermaLink="false">https://medium.com/p/ea1f6a2d1bdf</guid>
            <dc:creator><![CDATA[Ashish yadav]]></dc:creator>
            <pubDate>Sat, 08 Nov 2025 09:20:11 GMT</pubDate>
            <atom:updated>2025-11-08T17:26:34.506Z</atom:updated>
            <content:encoded><![CDATA[<h3>🐞 Console Plus — The Floating In-App Debug Console for Flutter Developers</h3><blockquote><em>Tired of switching between terminal logs and emulator screens?<br> Meet </em><strong><em>Console Plus</em></strong><em>, your floating in-app debug console — built </em>for developers, by a developer<em>.</em></blockquote><blockquote><em>💡 Instantly view, filter, copy, and export logs without leaving your Flutter app.</em></blockquote><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*ZlMEMkINOUhcQmE5yOb3Vg.png" /><figcaption>Console+</figcaption></figure><h3>🎯 Why Console Plus?</h3><p>Debugging a Flutter app can be frustrating when you have to:</p><ul><li>Keep the emulator and IDE console side by side</li><li>Scroll endlessly to find relevant logs</li><li>Re-run the app to view debug outputs</li></ul><p>That’s why I built <strong>Console Plus</strong> — a lightweight, non-intrusive, floating console overlay that brings your app logs <strong>right inside the UI</strong>.</p><h3>⚡ Features</h3><p>✅ Floating 🪶 Debug Button (draggable)<br> ✅ Real-time Log Updates<br> ✅ Auto-Scroll (smart — only when near bottom)<br> ✅ Filter Logs by Type (Info, Warning, Error)<br> ✅ Keyword Search<br> ✅ Copy / Export Logs (JSON or text)<br> ✅ Adjustable size (resize and drag anywhere)<br> ✅ Works across Android, iOS, and Web<br> ✅ Open-source &amp; developer-friendly</p><h3>🚀 Installation</h3><p>Add this line to your pubspec.yaml:</p><pre>dependencies:<br>  console_plus: ^1.1.1</pre><p>Then run:</p><pre>flutter pub get</pre><h3>🧩 How to Use</h3><h3>1️⃣ Initialize and Show Floating Button</h3><pre>import &#39;package:console_plus/console_plus.dart&#39;;</pre><pre>void main() {<br>  runApp(const MyApp());<br>  WidgetsBinding.instance.addPostFrameCallback((_) {<br>    FloatingDebugButton.show(context);<br>  });<br>}</pre><h3>2️⃣ Add Logs</h3><pre>DebugLogConsole.log(&quot;App started successfully!&quot;);<br>DebugLogConsole.log(&quot;Warning: Missing config file&quot;, type: LogType.warning);<br>DebugLogConsole.log(&quot;Error: Invalid API key&quot;, type: LogType.error);</pre><h3>3️⃣ Floating Console View</h3><p>Tap the 🐞 icon on your app, and voilà!<br> You’ll see a draggable, resizable console window — <br> with filters, search bar, and export options.</p><h3>🧠 Example Output</h3><p>🟢 <strong>INFO</strong> → Normal logs<br> 🟡 <strong>WARN</strong> → Potential issues<br> 🔴 <strong>ERROR</strong> → Critical problems</p><pre>[10:45:21.341] [INFO] App started successfully<br>[10:45:22.892] [WARN] Missing config file<br>[10:45:23.041] [ERROR] Invalid API key</pre><h3>📦 Export &amp; Copy Logs</h3><p>Want to share logs with your QA team?<br> Simply tap <strong>📋 Copy</strong> or <strong>⬇️ Export JSON</strong> — the console will save your logs as a .json file automatically.</p><h3>🧰 Under the Hood</h3><p>Console Plus is built with:</p><ul><li>Flutter’s OverlayEntry for floating UI</li><li>ValueNotifier for efficient log updates</li><li>file_saver for cross-platform file exports</li><li>SelectableText for multi-line text selection</li><li>dropdown_button2 for enhanced filter UI</li></ul><h3>💻 Code Snippet — Minimal Setup Example</h3><pre>FloatingActionButton(<br>  onPressed: () {<br>    FloatingDebugButton.show(context);<br>  },<br>  child: const Icon(Icons.bug_report),<br>);</pre><p>Once you open the floating panel, all logs you emit via DebugLogConsole.log() will appear instantly.</p><h3>🖼️ Screenshot Preview <em>:</em></h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*oL9JAmSZxhSAh3w0QOd8FQ.png" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*fag832R_SMofeYzVUj1nmw.png" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*yKJV5DJNJrlE_8qM6oABZw.png" /></figure><h3>🧑‍💻 Who Is It For?</h3><ul><li>Flutter developers working on complex UIs</li><li>QA testers debugging user-reported issues</li><li>Developers building internal dev tools</li><li>Teams needing <strong>in-app</strong> debug visibility</li></ul><h3>🏗️ Roadmap</h3><p>🔹 Log persistence between sessions<br> 🔹 Collapsible log groups<br> 🔹 Network request tracing<br> 🔹 Remote log streaming</p><p>Have a feature idea?<br> → Open an issue or PR on GitHub:<br> <a href="https://github.com/ashish8381/console_plus">github.com/ashish8381/console_plus</a></p><h3>📜 License</h3><p>MIT License © 2025 <a href="https://github.com/ashish8381">Ashish</a><br> See the full <a href="https://github.com/ashish8381/console_plus/blob/main/LICENSE">LICENSE</a> file for details.</p><h3>❤️ Support &amp; Feedback</h3><p>If you love <strong>Console Plus</strong>, please:</p><ul><li>⭐ Star the repo → <a href="https://github.com/ashish8381/console_plus">GitHub Link</a></li><li>🗣️ Comment your feedback on pub.dev</li><li>🔄 Share this article with your Flutter dev friends!</li></ul><h3>✨ Built with ❤️ by <a href="https://github.com/ashish8381">Ashish</a></h3><blockquote><em>“Logs shouldn’t live in the terminal — they should live in your app.”</em></blockquote><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=ea1f6a2d1bdf" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[ Optimizing Flutter Apps for Speed, Security & Scalability in 2025]]></title>
            <link>https://medium.com/@ya0285981/optimizing-flutter-apps-for-speed-security-scalability-in-2025-c23fae121e8b?source=rss-e0f2eeac768c------2</link>
            <guid isPermaLink="false">https://medium.com/p/c23fae121e8b</guid>
            <dc:creator><![CDATA[Ashish yadav]]></dc:creator>
            <pubDate>Wed, 15 Oct 2025 15:38:37 GMT</pubDate>
            <atom:updated>2025-12-05T18:52:56.716Z</atom:updated>
            <content:encoded><![CDATA[<p>Learn how to supercharge your Flutter apps in 2025 with advanced speed optimization, airtight security practices, and scalable architecture — from caching and isolates to API encryption and CI/CD automation.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*fz1yBoFSVOFSdqQM5xNiLg.png" /></figure><h3>🧩 Introduction</h3><p>Flutter is no longer just for hobby projects — it powers production apps used by millions worldwide.<br> But as your app scales, you’ll quickly run into three challenges: <strong>speed</strong>, <strong>security</strong>, and <strong>scalability</strong>.</p><p>In this guide, you’ll learn <strong>practical, developer-tested techniques</strong> to optimize Flutter apps for 2025 — ensuring your product remains fast, secure, and ready for growth.</p><h3>⚡ Speed Optimization: Make Your App Feel Native</h3><h3>1. Use Isolates and compute() for Heavy Tasks</h3><p>Flutter runs UI code on a single thread.<br> Move CPU-heavy work (like JSON parsing or image processing) to an isolate:</p><pre>final result = await compute(parseLargeJson, jsonString);</pre><p>💡 <em>In Flutter 3.24+, isolates have lower memory overhead and faster message passing.</em></p><h3>2. Reduce Widget Rebuilds</h3><ul><li>Use const constructors wherever possible.</li><li>Use Selector, Consumer, or ValueListenableBuilder to rebuild only what’s needed.</li></ul><pre>Selector&lt;UserProvider, String&gt;(<br>  selector: (_, provider) =&gt; provider.username,<br>  builder: (_, username, __) =&gt; Text(username),<br>)</pre><h3>3. Smart Caching = Instant Performance</h3><ul><li><strong>Images:</strong> cached_network_image</li><li><strong>APIs:</strong> dio_cache_interceptor</li><li><strong>Files:</strong> flutter_cache_manager</li></ul><p>Offline-first apps feel faster <em>and</em> reduce server load.</p><h3>4. Profile Regularly</h3><p>Don’t guess. Measure:</p><ul><li>🧰 Flutter DevTools → Performance tab</li><li>🔍 flutter run --profile</li><li>🧹 flutter analyze &amp; dart fix</li></ul><h3>🔒 Security Optimization: Protect Your Users and APIs</h3><h3>1. Use HTTPS + Certificate Pinning</h3><p>Add SSL pinning to prevent man-in-the-middle attacks:</p><pre>final dio = Dio();<br>(dio.httpClientAdapter as DefaultHttpClientAdapter).onHttpClientCreate = (client) {<br>  client.badCertificateCallback = (cert, host, port) =&gt;<br>      cert.pem == myServerCert;<br>  return client;<br>};</pre><h3>2. Store Sensitive Data Securely</h3><p>Use flutter_secure_storage for:</p><ul><li>Access tokens</li><li>API keys</li><li>Session data</li></ul><p>Encrypt local databases with sqflite_sqlcipher or Drift.</p><h3>3. Obfuscate and Shrink Code</h3><p>Protect your app logic with:</p><pre>flutter build apk --obfuscate --split-debug-info=build/debug_info/</pre><h3>4. Keep Dependencies Up-to-Date</h3><p>Outdated packages = security risk.</p><pre>flutter pub outdated<br>flutter pub upgrade</pre><p>Use GitHub Dependabot or Renovate for automated checks.</p><h3>☁️ Scalability: Build for Growth</h3><h3>1. Modular &amp; Clean Architecture</h3><p>Structure by features, not screens.</p><p><strong>Recommended pattern:</strong></p><ul><li>data/ — API, DB, repositories</li><li>domain/ — use cases</li><li>presentation/ — UI, providers</li></ul><p>Use dependency injection via get_it or riverpod for clean scaling.</p><h3>2. Scalable Backends</h3><p>For growing apps:</p><ul><li>☁️ <strong>Firebase Functions</strong> or <strong>Supabase Edge Functions</strong></li><li>🔗 <strong>GraphQL (Hasura/Apollo)</strong> for efficient querying</li><li>🧵 <strong>Pub/Sub or RabbitMQ</strong> for background processing</li></ul><h3>3. CI/CD Automation</h3><p>Continuous delivery = faster updates and safer releases.</p><p><strong>GitHub Actions Example:</strong></p><pre>name: Flutter CI<br>on: [push]<br>jobs:<br>  build:<br>    runs-on: ubuntu-latest<br>    steps:<br>      - uses: actions/checkout@v4<br>      - uses: subosito/flutter-action@v2<br>      - run: flutter pub get<br>      - run: flutter test<br>      - run: flutter build apk --release</pre><h3>4. Monitor Everything</h3><p>Integrate:</p><ul><li>🔥 Firebase Crashlytics — crash reports</li><li>🧠 Sentry — error tracking</li><li>🧰 Firebase Performance — real user metrics</li><li>🧾 App Check — prevent abuse and fake traffic</li></ul><h3>🌟 Bonus: 2025 Flutter Trends to Watch</h3><ul><li>🤖 <strong>AI-driven personalization</strong> using MLKit and TensorFlow Lite</li><li>⚡ <strong>Flutter Web with WASM rendering</strong> for blazing-fast performance</li><li>🔐 <strong>Passkey authentication</strong> replacing traditional logins</li><li>🌍 <strong>Edge-deployed APIs</strong> for low-latency global access</li></ul><h3>💡 Final Thoughts</h3><p>The Flutter ecosystem in 2025 is mature, stable, and production-ready — but only optimized apps survive.<br> Make your app:</p><p>✅ <strong>Fast</strong> — through isolates, caching, and profiling<br> ✅ <strong>Secure</strong> — with encryption and obfuscation<br> ✅ <strong>Scalable</strong> — with clean architecture and CI/CD</p><blockquote><em>“Don’t just build Flutter apps. Build future-proof digital experiences.”</em></blockquote><h3>👨‍💻 About the Author</h3><p><strong>Ashish</strong> — Android &amp; Flutter Developer<br> Helping teams build efficient, secure, and scalable mobile applications.<br>📱 Follow me for more Flutter, Firebase, and DevOps insights!</p><p>#Flutter #MobileDevelopment #AppOptimization #FlutterDev #Performance #Security #Scalability #CleanArchitecture #Firebase #DartLang #MobileAppSecurity #Flutter2025</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=c23fae121e8b" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[ Migrating Your Android App to Support 16 KB Page Size (Java/Kotlin)]]></title>
            <link>https://medium.com/@ya0285981/migrating-your-android-app-to-support-16-kb-page-size-java-kotlin-ea04cb1d8931?source=rss-e0f2eeac768c------2</link>
            <guid isPermaLink="false">https://medium.com/p/ea04cb1d8931</guid>
            <dc:creator><![CDATA[Ashish yadav]]></dc:creator>
            <pubDate>Sat, 11 Oct 2025 15:20:01 GMT</pubDate>
            <atom:updated>2025-10-11T15:20:01.178Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*4noDqCZ1DGF_zFEgQha59A.png" /></figure><p>Starting November 1, 2025, all new apps and updates targeting Android 15 (API level 35) must support 16 KB memory page sizes. If your app is written entirely in Java or Kotlin and doesn’t include native code, you’re already compliant. However, it’s essential to test your app in a 16 KB environment to ensure optimal performance and compatibility.</p><h3>📌 What Is a 16 KB Memory Page?</h3><p>A memory page is the smallest unit of data for memory management in an operating system. Traditionally, Android has used 4 KB pages. With Android 15, support for 16 KB pages is introduced, offering potential performance improvements, especially on devices with larger RAM. <a href="https://android-developers.googleblog.com/2025/07/transition-to-16-kb-page-sizes-android-apps-games-android-studio.html?utm_source=chatgpt.com">Android Developers Blog</a></p><h3>✅ Who Needs to Migrate?</h3><ul><li><strong>Java/Kotlin-Only Apps:</strong> If your app uses only Java or Kotlin and doesn’t include native code (C/C++), you’re already compatible with 16 KB page sizes.</li><li><strong>Apps with Native Code:</strong> If your app includes native code (e.g., via the Android NDK or third-party SDKs), you’ll need to recompile and align your native libraries to support 16 KB pages. <a href="https://developer.android.com/guide/practices/page-sizes?utm_source=chatgpt.com">Android Developers</a></li></ul><h3>🔧 Steps to Ensure 16 KB Compatibility</h3><h3>1. Update Your Development Environment</h3><ul><li><strong>Android Gradle Plugin (AGP):</strong> Ensure you’re using AGP 8.5.1 or higher.</li><li><strong>Target SDK Version:</strong> Set your targetSdkVersion to 35 or higher in your build.gradle file.</li><li><strong>Android NDK:</strong> If your app uses native code, update to NDK r28 or higher, which supports 16 KB alignment by default. <a href="https://android-developers.googleblog.com/2025/07/transition-to-16-kb-page-sizes-android-apps-games-android-studio.html?utm_source=chatgpt.com">Android Developers Blog</a></li></ul><h3>2. Check for Native Code Dependencies</h3><p>Use Android Studio’s APK Analyzer to inspect your APK or AAB:</p><ul><li>Navigate to Build &gt; Analyze APK....</li><li>Open the lib/ folder and check for .so files.</li><li>If present, these are native libraries that may require alignment. <a href="https://developer.android.com/guide/practices/page-sizes?utm_source=chatgpt.com">Android Developers</a></li></ul><h3>3. Recompile Native Libraries for 16 KB Alignment</h3><p>If your app includes native code:</p><ul><li><strong>Rebuild Native Code:</strong> Recompile your native libraries using the updated NDK and ensure they are aligned to 16 KB.</li><li><strong>Update Dependencies:</strong> Ensure all third-party SDKs and libraries are compatible with 16 KB page sizes.</li></ul><h3>4. Remove Hard-Coded PAGE_SIZE Assumptions</h3><p>Avoid using hard-coded values like 4096 (4 KB) for memory operations. Instead, use system calls to determine the page size:</p><ul><li><strong>Java:</strong> int pageSize = sun.misc.VM.getPageSize();</li><li><strong>Kotlin:</strong> val pageSize = sun.misc.VM.getPageSize()</li></ul><p>This ensures your app dynamically adapts to the system’s page size. <a href="https://developer.android.com/guide/practices/page-sizes?utm_source=chatgpt.com">Android Developers</a></p><h3>5. Test in a 16 KB Environment</h3><p>To verify your app’s compatibility:</p><ul><li><strong>Use Android Emulator:</strong> Set up an emulator with an Android 15 system image that supports 16 KB page sizes.</li><li><strong>On-Device Testing:</strong> For real-device testing, use devices like Pixel 8 or 8 Pro running Android 15 QPR1 or higher. Enable the developer option to toggle between 4 KB and 16 KB page sizes. <a href="https://android-developers.googleblog.com/2025/07/transition-to-16-kb-page-sizes-android-apps-games-android-studio.html?utm_source=chatgpt.com">Android Developers Blog</a></li></ul><h3>🚀 Why Migrate?</h3><p>Migrating to support 16 KB page sizes can lead to:</p><ul><li><strong>Improved Performance:</strong> Faster app launch times and reduced memory overhead.</li><li><strong>Enhanced Battery Efficiency:</strong> Lower power consumption during app startup.</li><li><strong>Better System Responsiveness:</strong> Quicker camera launches and improved system boot times. <a href="https://android-developers.googleblog.com/2025/07/transition-to-16-kb-page-sizes-android-apps-games-android-studio.html?utm_source=chatgpt.com">Android Developers Blog</a></li></ul><h3>📝 Final Thoughts</h3><p>While Java and Kotlin-only apps are inherently compatible with 16 KB page sizes, it’s crucial to test your app in a 16 KB environment to ensure optimal performance. For apps with native code, following the steps outlined above will help ensure compliance with Google’s requirements and enhance your app’s performance on supported devices.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=ea04cb1d8931" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[ Migrating Your Flutter App to Support 16 KB Page Size (Android 15+)]]></title>
            <link>https://medium.com/@ya0285981/migrating-your-flutter-app-to-support-16-kb-page-size-android-15-8b4ea93c3e91?source=rss-e0f2eeac768c------2</link>
            <guid isPermaLink="false">https://medium.com/p/8b4ea93c3e91</guid>
            <dc:creator><![CDATA[Ashish yadav]]></dc:creator>
            <pubDate>Sat, 11 Oct 2025 13:27:57 GMT</pubDate>
            <atom:updated>2025-10-11T13:27:57.781Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*4noDqCZ1DGF_zFEgQha59A.png" /></figure><p>Starting November 1, 2025, Google Play mandates that all <strong>new apps</strong> or <strong>updates</strong> targeting Android 15 (API level 35) and above <strong>must support 16 KB memory page sizes</strong> on 64-bit devices. <a href="https://android-developers.googleblog.com/2025/05/prepare-play-apps-for-devices-with-16kb-page-size.html?utm_source=chatgpt.com">Android Developers Blog+2Android Developers+2</a></p><p>If your Flutter app (or its dependencies) still assumes 4 KB page size, you may run into Play Store rejections, runtime crashes, or alignment issues. In this guide, we’ll walk through:</p><ul><li>What this 16 KB page size change means</li><li>How to check if your app is affected</li><li>Step-by-step migration for a Flutter app</li><li>Testing and verification</li><li>Common pitfalls &amp; tips</li></ul><h3>🧠 What Is a Memory Page Size &amp; Why It Matters</h3><p>Operating systems organize memory into “pages” — contiguous blocks the kernel manages. Historically, Android (and many OSes) used <strong>4 KB</strong> pages. Starting Android 15, devices <strong>may use 16 KB pages</strong> for better performance. <a href="https://developer.android.com/guide/practices/page-sizes?utm_source=chatgpt.com">Ralfiz Technologies+3Android Developers+3Android Developers Blog+3</a></p><p><strong>Benefits</strong> of larger page size (per Android docs):</p><ul><li>Lower memory management overhead</li><li>Faster app launch times (improvements vary; in some cases up to 30%) <a href="https://developer.android.com/guide/practices/page-sizes?utm_source=chatgpt.com">Android Developers+1</a></li><li>Reduced heap fragmentation</li><li>More efficient battery / power behavior during startup <a href="https://android-developers.googleblog.com/2025/05/prepare-play-apps-for-devices-with-16kb-page-size.html?utm_source=chatgpt.com">Android Developers Blog+1</a></li></ul><p>However, if your app includes <strong>native libraries</strong> (.so files) or uses NDK-based code or native plugins, those must be built/packaged to be <strong>16 KB-aligned</strong>, otherwise your app may fail to install or run properly on such devices. <a href="https://developer.android.com/guide/practices/page-sizes?utm_source=chatgpt.com">Ralfiz Technologies+4Android Developers+4Android Developers Blog+4</a></p><p>If your app is pure Dart/Kotlin/Java without any native binaries, you may already be okay — but you still should test. <a href="https://developer.android.com/guide/practices/page-sizes?utm_source=chatgpt.com">Android Developers+2Android Developers Blog+2</a></p><h3>🕵 How to Check If Your App Is Affected</h3><h3>1. Use the Play Console / App Bundle Explorer</h3><p>In Google Play Console, check your app bundle’s “Memory page size” or compatibility warnings. It may flag missing 16 KB alignment. <a href="https://dev.to/smartterss/preparing-your-flutter-apps-for-google-plays-16kb-page-size-requirement-1g0j?utm_source=chatgpt.com">DEV Community+1</a></p><h3>2. Use Android Studio’s APK Analyzer</h3><ul><li>Build your .aab or .apk</li><li>Use <strong>Build &gt; Analyze APK</strong></li><li>In the lib/ folder, see if .so files exist</li><li>Check “Alignment” column — Android Studio will warn if native libraries aren’t aligned for 16 KB pages <a href="https://developer.android.com/guide/practices/page-sizes?utm_source=chatgpt.com">Ralfiz Technologies+3Android Developers+3Android Developers Blog+3</a></li></ul><h3>3. Use command-line tools / scripts</h3><p>Android’s docs provide check_elf_alignment.sh to validate ELF segments alignment. <a href="https://developer.android.com/guide/practices/page-sizes?utm_source=chatgpt.com">Android Developers+2Android Developers Blog+2</a></p><p>Also, use:</p><pre>adb shell getconf PAGE_SIZE</pre><p>on a device/emulator to see current page size (should return 16384 if 16 KB mode is enabled). <a href="https://developer.android.com/guide/practices/page-sizes?utm_source=chatgpt.com">Android Developers+2Android Developers Blog+2</a></p><h3>🔧 Migration Steps for a Flutter App</h3><p>Here’s your checklist and step-by-step migration:</p><h3>1. Upgrade Flutter &amp; Toolchain Versions</h3><ul><li>Use a recent Flutter version that includes 16 KB support in the engine</li><li>Update <strong>Android Gradle Plugin (AGP)</strong> to <strong>8.5.1 or higher</strong> <a href="https://developer.android.com/guide/practices/page-sizes?utm_source=chatgpt.com">DEV Community+3Android Developers+3Android Developers Blog+3</a></li><li>Use Gradle wrapper version 8.5+ (or compatible)</li><li>Use Android <strong>NDK r28 or above</strong> (NDK r28+ builds native libs aligned by default) <a href="https://developer.android.com/guide/practices/page-sizes?utm_source=chatgpt.com">Ralfiz Technologies+4Android Developers+4Android Developers Blog+4</a></li></ul><p>In android/gradle/wrapper/gradle-wrapper.properties:</p><pre>distributionUrl = https\://services.gradle.org/distributions/gradle-8.13-all.zip</pre><p>In android/app/build.gradle (or build.gradle.kts), ensure:</p><pre>plugins {<br>    id &#39;com.android.application&#39; version &#39;8.12.2&#39; apply false<br>    // etc.<br>}<br>android {<br>    ndkVersion &quot;29.0.13113456&quot;  // or a suitable r28+ variant<br>}</pre><h3>2. Ensure Native Libraries Are 16 KB Aligned</h3><ul><li>If you have custom native / C++ / JNI code, rebuild with linker flags for 16 KB alignment</li><li>If you use plugins that ship .so files, upgrade those plugins to versions that support 16 KB alignment</li></ul><p>In Android NDK r28+ this alignment is handled automatically. <a href="https://developer.android.com/guide/practices/page-sizes?utm_source=chatgpt.com">Medium+4Android Developers+4Android Developers Blog+4</a></p><p>If using older NDK or legacy libraries, you may need:</p><pre>-Wl,-z,max-page-size=16384</pre><p>or related flags (see Android docs) <a href="https://developer.android.com/guide/practices/page-sizes?utm_source=chatgpt.com">Android Developers+1</a></p><p>If your app has .so libraries that are uncompressed in the APK, ensure packaging doesn’t compress them (so zip alignment can be maintained). <a href="https://developer.android.com/guide/practices/page-sizes?utm_source=chatgpt.com">Android Developers+2Android Developers Blog+2</a></p><p>In Gradle:</p><pre>android {<br>  packagingOptions {<br>    jniLibs {<br>      useLegacyPackaging true<br>    }<br>  }<br>}</pre><p>(But using legacy packaging is a fallback — ideally move to a toolchain that automatically aligns) <a href="https://developer.android.com/guide/practices/page-sizes?utm_source=chatgpt.com">Android Developers+2Android Developers Blog+2</a></p><h3>3. Remove Hard-Coded Assumptions About Page Size</h3><p>Search your native / C / C++ / JNI code for any assumptions or constants using 4096 (the 4 KB page size). Replace with dynamic queries like getpagesize() or sysconf(_SC_PAGESIZE). <a href="https://developer.android.com/guide/practices/page-sizes?utm_source=chatgpt.com">Android Developers+1</a></p><p>Avoid passing page-size–based constants to mmap() or other memory APIs without verifying alignment. <a href="https://developer.android.com/guide/practices/page-sizes?utm_source=chatgpt.com">Android Developers+1</a></p><h3>4. Clean, Rebuild &amp; Repackage</h3><ul><li>./gradlew clean</li><li>Rebuild release AAB / APK</li><li>Use flutter build appbundle --analyze-size to inspect the result</li></ul><h3>5. Verify Alignment &amp; Testing</h3><ul><li>Run check_elf_alignment.sh (or similar) on your output AAB or APK</li><li>Use zipalign:</li></ul><pre>zipalign -v -c -P 16 -4 path/to/app.apk</pre><ul><li>to verify proper 16 KB alignment. <a href="https://developer.android.com/guide/practices/page-sizes?utm_source=chatgpt.com">Android Developers+2Android Developers Blog+2</a></li><li>Test on an emulator configured for <strong>Android 15 with 16 KB system image</strong></li><li>Test on physical devices that support toggling 16 KB mode (e.g. some Pixel devices)</li><li>Use:</li></ul><pre>adb shell getconf PAGE_SIZE</pre><ul><li>to confirm the device is running 16 KB mode. <a href="https://android-developers.googleblog.com/2025/07/transition-to-16-kb-page-sizes-android-apps-games-android-studio.html?utm_source=chatgpt.com">Android Developers Blog+1</a></li></ul><h3>⚠️ Common Pitfalls &amp; Tips</h3><ul><li><strong>Plugin binaries not updated</strong> — many 3rd-party Flutter plugins may still use 4 KB builds. You might need to wait for plugin maintainers or fork + update them. <a href="https://faheem-riaz.medium.com/preparing-your-flutter-app-for-android-15s-16-kb-page-size-requirement-b07b3dbfbdd1?utm_source=chatgpt.com">Medium+4Medium+4DEV Community+4</a></li><li><strong>Huawei / OEM SDKs</strong> — some vendor SDKs (e.g. Huawei Location) may not support 16 KB yet. <a href="https://faheem-riaz.medium.com/preparing-your-flutter-app-for-android-15s-16-kb-page-size-requirement-b07b3dbfbdd1?utm_source=chatgpt.com">Medium+2DEV Community+2</a></li><li><strong>Back-compat mode</strong> — Android supports “page size compat mode” to allow older 4 KB-libraries to run temporarily, but you should not rely on that for production stability. <a href="https://developer.android.com/guide/practices/page-sizes?utm_source=chatgpt.com">Android Developers+1</a></li><li><strong>Delayed warnings</strong> — alignment issues may only appear when publishing to Play or on certain devices, so you’ll catch surprises late unless you test early</li><li><strong>Binary size changes</strong> — aligning native libs to 16 KB may slightly increase APK/AAB size</li><li><strong>Testing coverage</strong> — carefully test features that use native code (camera, ML, platform channels) to catch runtime misbehavior</li></ul><h3>🏁 Conclusion &amp; Call to Action</h3><p>Migrating to 16 KB page size may seem daunting, especially if your app depends on native plugins. But with the right toolchain version, careful alignment, and testing, it’s entirely manageable.</p><p>To recap:</p><ol><li><strong>Upgrade</strong> your Flutter, AGP, Gradle, and NDK</li><li><strong>Rebuild</strong> native libraries with 16 KB alignment</li><li><strong>Fix code</strong> that assumes 4 KB page size</li><li><strong>Test thoroughly</strong> on 16 KB devices / emulators</li><li><strong>Monitor warnings</strong> in Play Console and APK Analyzer</li></ol><p>Don’t wait until the deadline — some plugin ecosystems may lag behind. Start auditing your dependencies today so you avoid last-minute surprises.</p><h3>📎 Further Reading / References</h3><ul><li>Android Developers: <em>Support 16 KB page sizes</em> <a href="https://developer.android.com/guide/practices/page-sizes?utm_source=chatgpt.com">Android Developers</a></li><li>Android Developers Blog: <em>Prepare your apps for Google Play’s 16 KB requirement</em> <a href="https://android-developers.googleblog.com/2025/05/prepare-play-apps-for-devices-with-16kb-page-size.html?utm_source=chatgpt.com">Android Developers Blog</a></li><li>Android Studio &amp; tooling for transition to 16 KB <a href="https://android-developers.googleblog.com/2025/07/transition-to-16-kb-page-sizes-android-apps-games-android-studio.html?utm_source=chatgpt.com">Android Developers Blog</a></li><li>Community posts about Flutter and 16 KB migration <a href="https://dev.to/smartterss/preparing-your-flutter-apps-for-google-plays-16kb-page-size-requirement-1g0j?utm_source=chatgpt.com">Medium+3DEV Community+3Medium+3</a></li></ul><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=8b4ea93c3e91" width="1" height="1" alt="">]]></content:encoded>
        </item>
    </channel>
</rss>