<?xml version="1.0" encoding="UTF-8"?><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>Development Archives - Mobile USTP MKL</title>
	<atom:link href="https://mobile.fhstp.ac.at/category/development/feed/" rel="self" type="application/rss+xml" />
	<link>https://mobile.fhstp.ac.at/category/development/</link>
	<description>Die &#34;Mobile Forschungsgruppe&#34; der USTP, sie  sammelt hier alles zu den Themen Design, UX und Entwicklung mobiler Applikationen</description>
	<lastBuildDate>Mon, 15 Jun 2026 09:44:24 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	

<image>
	<url>https://mobile.fhstp.ac.at/wp-content/uploads/2025/03/icon-120x120.webp</url>
	<title>Development Archives - Mobile USTP MKL</title>
	<link>https://mobile.fhstp.ac.at/category/development/</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>Microservices at the Edge: Why We Use Cloudflare Workers for swiva.app</title>
		<link>https://mobile.fhstp.ac.at/development/webdevelopment/microservices-at-the-edge-why-we-use-cloudflare-workers-for-swiva-app/</link>
		
		<dc:creator><![CDATA[Daniel Studera]]></dc:creator>
		<pubDate>Mon, 15 Jun 2026 09:40:14 +0000</pubDate>
				<category><![CDATA[Allgemein]]></category>
		<category><![CDATA[Projekte]]></category>
		<category><![CDATA[Studium]]></category>
		<category><![CDATA[Webdevelopment]]></category>
		<category><![CDATA[cloudflare]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[mobile]]></category>
		<category><![CDATA[QR-Code]]></category>
		<category><![CDATA[swiva]]></category>
		<guid isPermaLink="false">https://mobile.fhstp.ac.at/?p=15887</guid>

					<description><![CDATA[<p>When building an app, it is very easy to put everything into one big backend. At the beginning this feels simple. One server, one API, one place for all logic. But after a while, the backend starts doing things it was never really meant to do. Redirects, small integrations, tracking, webhook handling, feedback forms and <a class="read-more" href="https://mobile.fhstp.ac.at/development/webdevelopment/microservices-at-the-edge-why-we-use-cloudflare-workers-for-swiva-app/">[...]</a></p>
<p>The post <a href="https://mobile.fhstp.ac.at/development/webdevelopment/microservices-at-the-edge-why-we-use-cloudflare-workers-for-swiva-app/">Microservices at the Edge: Why We Use Cloudflare Workers for swiva.app</a> appeared first on <a href="https://mobile.fhstp.ac.at">Mobile USTP MKL</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph">When building an app, it is very easy to put everything into one big backend. At the beginning this feels simple. One server, one API, one place for all logic. But after a while, the backend starts doing things it was never really meant to do. Redirects, small integrations, tracking, webhook handling, feedback forms and other tiny helper tasks all end up in the same system.</p>



<p class="wp-block-paragraph">For Swiva, we decided to keep some of these tasks out of our main backend and move them closer to the user, to the edge. In our case, this means using Cloudflare Workers. A Worker is a small serverless function that runs on Cloudflare’s global network, close to the user. It can handle a request, run a bit of JavaScript or TypeScript and return a response without needing our main backend at all.</p>



<p class="wp-block-paragraph">That makes Workers a good fit for small features that need to be fast, but do not need a full backend route, database connection or heavy infrastructure.</p>



<h2 class="wp-block-heading">The problem with app store redirects</h2>



<p class="wp-block-paragraph">A simple example is our app download link. When someone scans a QR code on a poster, sticker or social media post, they should end up in the right place. iPhone users should go to the Apple App Store, Android users should go to Google Play and desktop users should go to our website.</p>



<p class="wp-block-paragraph">The normal solution would be to send everyone to a page on our website. The page loads, JavaScript runs in the browser, checks the device and then redirects the user. That works, but it is not ideal. The user may see a blank page or a short loading screen before the store opens. For an app download link, every small delay matters.</p>



<h2 class="wp-block-heading">A smart redirect at the edge</h2>



<p class="wp-block-paragraph">Instead of loading a full page, we use a Cloudflare Worker. The Worker runs before the request even reaches our main server. It checks the user agent from the HTTP request, decides if the user is on iOS, Android or desktop and immediately returns a 302 redirect.  So the QR code does not point to a heavy website. It points to a tiny edge function.</p>



<p class="wp-block-paragraph">A simplified version can look like this:</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: jscript; title: ; notranslate">
export default {
  async fetch(request, env, ctx) {
    const userAgent = request.headers.get(&quot;user-agent&quot;) || &quot;&quot;;

    const isIOS = /iPhone|iPad|iPod/i.test(userAgent);
    const isAndroid = /Android/i.test(userAgent);

    const targets = {
      ios: &quot;https://apps.apple.com/at/app/swiva/id6769160022&quot;,
      android: &quot;https://play.google.com/store/apps/details?id=app.swiva&quot;,
      desktop: &quot;https://swiva.app&quot;,
      fallback: &quot;https://swiva.app&quot;,
    };

    let platform = &quot;fallback&quot;;

    if (isIOS) {
      platform = &quot;ios&quot;;
    } else if (isAndroid) {
      platform = &quot;android&quot;;
    } else {
      platform = &quot;desktop&quot;;
    }

    return Response.redirect(targets&#x5B;platform], 302);
  },
};
</pre></div>


<p class="wp-block-paragraph">This is not a huge feature. But it solves a real problem in a very clean way.<br></p>



<h2 class="wp-block-heading">Tracking without a heavy analytics script</h2>



<p class="wp-block-paragraph">We also want to know where our downloads come from. A QR code on a poster, a link in a story and a link on a website should not all look the same. Instead of loading a full analytics script, the Worker can read a source parameter from the URL, add UTM parameters to the final link and count the redirect in Cloudflare KV. The important part is that this should not slow down the redirect. For that, we use <code>ctx.waitUntil()</code>.</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: jscript; title: ; notranslate">
const source =
  url.searchParams.get(&quot;src&quot;) ||
  url.searchParams.get(&quot;source&quot;) ||
  &quot;direct&quot;;

targetUrl.searchParams.set(&quot;utm_source&quot;, source);
targetUrl.searchParams.set(&quot;utm_medium&quot;, &quot;smart_redirect&quot;);
targetUrl.searchParams.set(&quot;utm_campaign&quot;, &quot;app_download&quot;);

if (env.DOWNLOAD_LINK_REDIRECT_STATS) {
  const today = new Date().toISOString().split(&quot;T&quot;)&#x5B;0];
  const key = `${today}:${source}:${platform}`;

  ctx.waitUntil(
    (async () =&gt; {
      const currentCount =
        (await env.DOWNLOAD_LINK_REDIRECT_STATS.get(key)) || &quot;0&quot;;

      await env.DOWNLOAD_LINK_REDIRECT_STATS.put(
        key,
        (parseInt(currentCount) + 1).toString()
      );
    })()
  );
}
</pre></div>


<p class="wp-block-paragraph">The redirect is sent back immediately. The statistic update happens in the background. That is exactly the kind of small task where edge functions feel perfect.</p>



<h2 class="wp-block-heading">Why this works well for Swiva</h2>



<p class="wp-block-paragraph">This setup works well because each Cloudflare product has a clear job. Our marketing website runs on Cloudflare Pages, which is made for hosting static websites and frontend projects. This is enough for a lightweight app landing page like <a href="https://swiva.app">swiva.app</a> and keeps the website separate from the redirect logic.</p>



<p class="wp-block-paragraph">The redirect itself runs as a Cloudflare Worker, because it needs to be fast and should happen before a full website loads. For simple tracking, we use Cloudflare KV. KV is a key value store, so we can save small pieces of data with a key, for example how often a specific QR code source was used on a specific day.</p>



<p class="wp-block-paragraph">This gives us lightweight redirect tracking without setting up a full database or adding a big analytics tool. For this kind of use case, the free limits are more than enough. Cloudflare Workers currently include 100,000 requests per day on the Free plan, which is a lot for a smart redirect service.</p>



<h2 class="wp-block-heading">Try it yourself</h2>



<p class="wp-block-paragraph">You can test the redirect yourself using this link or by scanning the QR code.</p>



<p class="wp-block-paragraph">If you scan it with an iPhone, it should open the Apple App Store. If you scan it with an Android device, it should open Google Play. If you click the same link on a desktop device, it should redirect you to the Swiva landing page.</p>



<p class="wp-block-paragraph">That is the nice part about this setup: one QR code can work for every platform, without loading a full website first.</p>



<p class="wp-block-paragraph"><a href="https://swiva.app/download?source=blogpost">Open the Swiva smart redirect</a></p>


<div class="wp-block-image is-style-default">
<figure class="aligncenter size-full is-resized"><img fetchpriority="high" decoding="async" width="3000" height="3000" src="https://mobile.fhstp.ac.at/wp-content/uploads/2026/06/swiva-qr-code-download.png" alt="Swiva QR Code Download Link" class="wp-image-15890" style="aspect-ratio:1;object-fit:cover;width:361px;height:auto" srcset="https://mobile.fhstp.ac.at/wp-content/uploads/2026/06/swiva-qr-code-download.png 3000w, https://mobile.fhstp.ac.at/wp-content/uploads/2026/06/swiva-qr-code-download-150x150.png 150w, https://mobile.fhstp.ac.at/wp-content/uploads/2026/06/swiva-qr-code-download-1536x1536.png 1536w, https://mobile.fhstp.ac.at/wp-content/uploads/2026/06/swiva-qr-code-download-2048x2048.png 2048w, https://mobile.fhstp.ac.at/wp-content/uploads/2026/06/swiva-qr-code-download-120x120.png 120w" sizes="(max-width: 3000px) 100vw, 3000px" /></figure>
</div><p>The post <a href="https://mobile.fhstp.ac.at/development/webdevelopment/microservices-at-the-edge-why-we-use-cloudflare-workers-for-swiva-app/">Microservices at the Edge: Why We Use Cloudflare Workers for swiva.app</a> appeared first on <a href="https://mobile.fhstp.ac.at">Mobile USTP MKL</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>PROJECT &#124; Building a New Website for RKZ Metall Design GmbH</title>
		<link>https://mobile.fhstp.ac.at/allgemein/building-a-new-website-for-rkz-metall-design-gmbh/</link>
		
		<dc:creator><![CDATA[Kevin Kraushofer]]></dc:creator>
		<pubDate>Wed, 10 Jun 2026 18:59:02 +0000</pubDate>
				<category><![CDATA[Allgemein]]></category>
		<category><![CDATA[Design]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[Projekte]]></category>
		<category><![CDATA[Studium]]></category>
		<category><![CDATA[Webdevelopment]]></category>
		<category><![CDATA[hochwasserschutz]]></category>
		<category><![CDATA[mobile]]></category>
		<category><![CDATA[rkz metall design gmbh]]></category>
		<guid isPermaLink="false">https://mobile.fhstp.ac.at/?p=15871</guid>

					<description><![CDATA[<p>For this project, I had the opportunity to create a completely new website for RKZ Metall Design GmbH. RKZ is an Austrian company based in Lower Austria that specializes in professional flood protection solutions for windows and doors, as well as custom-made solutions for special situations. This project was especially interesting for me because my <a class="read-more" href="https://mobile.fhstp.ac.at/allgemein/building-a-new-website-for-rkz-metall-design-gmbh/">[...]</a></p>
<p>The post <a href="https://mobile.fhstp.ac.at/allgemein/building-a-new-website-for-rkz-metall-design-gmbh/">PROJECT | Building a New Website for RKZ Metall Design GmbH</a> appeared first on <a href="https://mobile.fhstp.ac.at">Mobile USTP MKL</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph">For this project, I had the opportunity to create a completely new website for RKZ Metall Design GmbH. RKZ is an Austrian company based in Lower Austria that specializes in professional flood protection solutions for windows and doors, as well as custom-made solutions for special situations.</p>



<p class="wp-block-paragraph">This project was especially interesting for me because my father works at the company, which gave me a closer connection to both the business and its challenges.</p>



<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>



<h2 class="wp-block-heading">Why This Project?</h2>



<p class="wp-block-paragraph">You might be wondering why I suddenly included this project among my master&#8217;s projects.</p>



<p class="wp-block-paragraph">The answer is quite simple. The company had received very few customer inquiries in recent months. During trade fairs and exhibitions, potential customers often mentioned that they could not find the company online. After taking a closer look, it became clear why.</p>



<p class="wp-block-paragraph">The existing website had several issues. It suffered from poor performance, weak SEO, and limited accessibility. Important legal pages such as the imprint and privacy policy were also incomplete and contained errors. Overall, the website did not represent the quality of the company and its products.</p>



<p class="wp-block-paragraph">Because of this, I offered my support and took on the challenge of creating a new website from scratch.</p>



<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>



<h2 class="wp-block-heading">Project Scope</h2>



<p class="wp-block-paragraph">One of the biggest problems with the old website was that it had been developed entirely in React. While this worked from a technical perspective, it made content management almost impossible for non-technical employees.</p>



<p class="wp-block-paragraph">The company wanted a website that they could update themselves. They wanted to be able to change texts, upload images, and maintain content without needing programming knowledge every time.</p>



<p class="wp-block-paragraph">This became one of the main goals of the project.</p>



<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>



<h2 class="wp-block-heading">Core Features</h2>



<p class="wp-block-paragraph">Before starting the design and development process, I spoke with the client to understand what they needed from their new website.</p>



<p class="wp-block-paragraph">Of course, the products had to be presented clearly. Beyond that, they wanted customer reviews, information about partners, a contact form, and an overall more modern appearance.</p>



<p class="wp-block-paragraph">My personal focus was on creating a website that performs well in areas that are essential today: responsive design, SEO, and accessibility. A website should not only look good, it should also be easy to find and easy to use on all devices.</p>



<p class="wp-block-paragraph">Since the company had almost no digital presence beyond its website, I also created a Google Business Profile and set up Google Analytics to help them understand and improve their online visibility in the future.</p>



<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>



<h2 class="wp-block-heading">Design, Tools, and Technologies</h2>



<p class="wp-block-paragraph">The design process started in Figma. The client requested a visual style inspired by water and waves to reflect the company&#8217;s connection to flood protection.</p>



<p class="wp-block-paragraph">At the same time, I wanted to keep the design clean and professional. The target audience is mostly businesses and homeowners looking for reliable protection solutions, so the website needed to maintain a strong industrial and trustworthy feel.</p>



<p class="wp-block-paragraph">To make content management easier for the company, I decided to build the website with WordPress instead of creating another fully custom solution. This allows employees to manage content themselves without needing technical knowledge.</p>



<p class="wp-block-paragraph">To customize the website and provide all required functionality, I researched, installed, and configured several WordPress plugins that support performance, SEO, security, forms, and content management.</p>



<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>



<h2 class="wp-block-heading">What I Learned</h2>



<p class="wp-block-paragraph">This was the first time I created an entire website completely from scratch.</p>



<p class="wp-block-paragraph">I was involved in every step of the process, from researching hosting options and planning the structure to designing the interface, setting up WordPress, configuring plugins, creating the Google Business Profile, and integrating Google Analytics.</p>



<p class="wp-block-paragraph">On top of that, I made sure the website worked well on different screen sizes and followed SEO and accessibility best practices.</p>



<p class="wp-block-paragraph">The project was definitely time-consuming, but it taught me a lot. I gained a much better understanding of how many different areas come together when building a professional website. It was not only about design or development, but also about planning, communication, marketing, and long-term maintainability.</p>



<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>



<h2 class="wp-block-heading">Conclusion and Future Steps</h2>



<p class="wp-block-paragraph">At the moment, the project is not completely finished yet. I am currently waiting for feedback from the company, and some final content such as photos and text material is still missing.</p>



<p class="wp-block-paragraph">Once these assets are available, I will make the final adjustments, complete the remaining content, and submit the website for indexing so it can be found through search engines.</p>



<p class="wp-block-paragraph">After that, the company will finally have a modern web presence that better reflects its expertise and helps potential customers find its services online.</p>



<div style="height:20px" aria-hidden="true" class="wp-block-spacer"></div>



<h2 class="wp-block-heading">Check It Out Soon</h2>



<p class="wp-block-paragraph">The new website will soon be available at:</p>



<p class="wp-block-paragraph"><a href="https://www.rkz-design.gmbh">https://www.rkz-design.gmbh</a></p>



<p class="wp-block-paragraph">Feel free to take a look once it goes live.</p>
<p>The post <a href="https://mobile.fhstp.ac.at/allgemein/building-a-new-website-for-rkz-metall-design-gmbh/">PROJECT | Building a New Website for RKZ Metall Design GmbH</a> appeared first on <a href="https://mobile.fhstp.ac.at">Mobile USTP MKL</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Smart Import Feature for my app &#8220;Swiva&#8221;</title>
		<link>https://mobile.fhstp.ac.at/studium/studium-projekte/smart-import-feature-for-my-app-swiva/</link>
		
		<dc:creator><![CDATA[Daniel Studera]]></dc:creator>
		<pubDate>Wed, 10 Jun 2026 11:48:56 +0000</pubDate>
				<category><![CDATA[Allgemein]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[Projekte]]></category>
		<category><![CDATA[Studium]]></category>
		<category><![CDATA[User Experience]]></category>
		<category><![CDATA[AI]]></category>
		<category><![CDATA[android]]></category>
		<category><![CDATA[iOS]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[mobile]]></category>
		<guid isPermaLink="false">https://mobile.fhstp.ac.at/?p=15857</guid>

					<description><![CDATA[<p>For this project, I worked on an AI feature for Swiva, my React Native app for saving activities, places and ideas. The basic idea of Swiva is simple: users collect things they want to try, organize them in lists and later swipe through them when they do not know what to do. One feature we <a class="read-more" href="https://mobile.fhstp.ac.at/studium/studium-projekte/smart-import-feature-for-my-app-swiva/">[...]</a></p>
<p>The post <a href="https://mobile.fhstp.ac.at/studium/studium-projekte/smart-import-feature-for-my-app-swiva/">Smart Import Feature for my app &#8220;Swiva&#8221;</a> appeared first on <a href="https://mobile.fhstp.ac.at">Mobile USTP MKL</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph">For this project, I worked on an AI feature for Swiva, my React Native app for saving activities, places and ideas. The basic idea of Swiva is simple: users collect things they want to try, organize them in lists and later swipe through them when they do not know what to do.</p>



<p class="wp-block-paragraph">One feature we had planned for a longer time was sharing links directly into the app. For example, a user sees a recipe on Instagram, a restaurant on Google Maps or an activity on TikTok and shares the link to Swiva. The app should then create a useful activity from that link, with a title and a short description.</p>



<p class="wp-block-paragraph">At first, I thought the main challenge would be the AI part. But during the project I realized that a much bigger part was actually getting good information from the shared links.</p>



<h2 class="wp-block-heading">The real problem: getting the content</h2>



<p class="wp-block-paragraph">Before the AI can generate a good activity, the app needs useful input. For that, I used two general strategies and one special case.</p>



<p class="wp-block-paragraph">The first strategy is Open Graph metadata. This is the information many websites use for link previews, for example when a link is shared in WhatsApp. It often contains a title, description and image, which can already be enough to understand the basic content of a post or website.</p>



<p class="wp-block-paragraph">The second strategy is oEmbed. This is used by platforms like TikTok to provide information for embedded content. In some cases, this gives better structured data than normal page metadata.</p>



<p class="wp-block-paragraph">Google Maps was more difficult. The official APIs are based on place IDs and structured requests, not just random shared Maps links. Also, Google has strict rules around scraping. Because of that, I did not scrape the page directly. Instead, I tried to resolve the link and extract the place name from the final URL when possible.</p>



<p class="wp-block-paragraph">I also decided to send these metadata requests from the app instead of my backend. If the app scales, I do not want my server to send too many requests to platforms like Instagram or TikTok and risk rate limits or IP bans. Sending them from the app distributes this better and keeps the backend simpler.</p>



<h2 class="wp-block-heading">On-device AI and fallback</h2>



<p class="wp-block-paragraph">For iOS, I used the Callstack React Native AI package with Apple’s on-device AI capabilities. This worked well and was quite easy to use, because the API is based on the Vercel AI SDK.</p>



<p class="wp-block-paragraph">My original plan was to also use Google ML Kit GenAI for Android. But the support I wanted in the React Native AI package was not available yet, and I did not want to build a custom Expo module just for this. Since I had already proven the on-device concept with Apple, I used a cloud fallback for Android and unsupported devices.</p>



<p class="wp-block-paragraph">The fallback sends a request to my backend, which uses a Gemini Flash-Lite model to generate the activity. At first I used Gemini 2.5 Flash-Lite, where the results were comparable to Apple’s on-device model. Later I tested Gemini 3.1 Flash-Lite, and I was much happier with the generated titles and descriptions.</p>



<h2 class="wp-block-heading">What I learned</h2>



<p class="wp-block-paragraph">My original goal was to compare on-device AI and cloud AI and see if the quality could be similar. I did not fully reach that goal, because the newer cloud model gave better results for my use case.</p>



<p class="wp-block-paragraph">Still, the project was a useful experiment. I learned how to use Apple on-device AI in a React Native app, how to build a fallback strategy and how important link metadata is for this feature.</p>



<p class="wp-block-paragraph">For Swiva, I currently think that one cloud strategy is probably the easiest solution to maintain. Gemini Flash-Lite is cheap enough for this use case, the results are more consistent across devices, and the architecture is simpler than maintaining separate strategies for iOS, Android and fallback.</p>



<p class="wp-block-paragraph">On-device AI is still very interesting, especially for privacy, offline usage and reducing server costs. But in this case, the simplest and most stable solution might be the best one</p>



<p class="wp-block-paragraph"></p>



<p class="wp-block-paragraph">Check out the feature by downloading Swiva here: <a href="https://swiva.app/download">https://swiva.app/download</a></p>



<h2 class="wp-block-heading">Sources</h2>



<ul class="wp-block-list">
<li>Callstack React Native AI: <a href="https://github.com/callstackincubator/ai">https://github.com/callstackincubator/ai</a></li>



<li>Google ML Kit GenAI APIs: <a href="https://developers.google.com/ml-kit/genai">https://developers.google.com/ml-kit/genai</a></li>



<li>Open Graph Protocol: <a href="https://ogp.me/">https://ogp.me/</a></li>



<li>TikTok oEmbed / Embed Documentation: <a href="https://developers.tiktok.com/doc/embed-videos/">https://developers.tiktok.com/doc/embed-videos/</a></li>



<li>Google Maps Place Details API: <a href="https://developers.google.com/maps/documentation/places/web-service/place-details">https://developers.google.com/maps/documentation/places/web-service/place-details</a></li>



<li>Gemini API Pricing: <a href="https://ai.google.dev/gemini-api/docs/pricing">https://ai.google.dev/gemini-api/docs/pricing</a></li>
</ul>



<p class="wp-block-paragraph"></p>
<p>The post <a href="https://mobile.fhstp.ac.at/studium/studium-projekte/smart-import-feature-for-my-app-swiva/">Smart Import Feature for my app &#8220;Swiva&#8221;</a> appeared first on <a href="https://mobile.fhstp.ac.at">Mobile USTP MKL</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Automated Performance Testing for React Native with agent-device</title>
		<link>https://mobile.fhstp.ac.at/tests/automated-performance-testing-for-react-native-with-agent-device/</link>
		
		<dc:creator><![CDATA[Daniel Studera]]></dc:creator>
		<pubDate>Wed, 10 Jun 2026 09:58:45 +0000</pubDate>
				<category><![CDATA[Allgemein]]></category>
		<category><![CDATA[Cross Plattform]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[Native Development]]></category>
		<category><![CDATA[Projekte]]></category>
		<category><![CDATA[Software]]></category>
		<category><![CDATA[Studium]]></category>
		<category><![CDATA[Tests]]></category>
		<category><![CDATA[AI]]></category>
		<category><![CDATA[AI Agents]]></category>
		<category><![CDATA[android]]></category>
		<category><![CDATA[iOS]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[mobile]]></category>
		<category><![CDATA[Test]]></category>
		<category><![CDATA[Testing Framework]]></category>
		<guid isPermaLink="false">https://mobile.fhstp.ac.at/?p=15851</guid>

					<description><![CDATA[<p>Recently I started testing an idea I saw on X: using Agent Device from Callstack for automated performance testing. I had already seen Agent Device before, because I also use Callstack’s React Native on-device AI package and follow some of their work. But the performance testing use case really caught my attention. The idea was <a class="read-more" href="https://mobile.fhstp.ac.at/tests/automated-performance-testing-for-react-native-with-agent-device/">[...]</a></p>
<p>The post <a href="https://mobile.fhstp.ac.at/tests/automated-performance-testing-for-react-native-with-agent-device/">Automated Performance Testing for React Native with agent-device</a> appeared first on <a href="https://mobile.fhstp.ac.at">Mobile USTP MKL</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph">Recently I started testing an idea I saw on X: using Agent Device from Callstack for automated performance testing.</p>



<p class="wp-block-paragraph">I had already seen Agent Device before, because I also use Callstack’s React Native on-device AI package and follow some of their work. But the performance testing use case really caught my attention. The idea was simple but powerful: let an AI agent click through a mobile app, collect snapshots of performance numbers and check where frame drops or slow interactions happen. So I wanted to try it myself with one of my React Native builds.</p>



<h2 class="wp-block-heading">What is Agent Device?</h2>



<p class="wp-block-paragraph">Agent Device is a CLI tool that lets AI agents control mobile apps. It can work with iOS and Android apps, including React Native apps, native apps and apps running on real devices, simulators or emulators.</p>



<p class="wp-block-paragraph">Instead of only looking at code, the agent can actually interact with the app. It can inspect the UI, understand what is currently on the screen, tap elements, scroll, type into inputs, take screenshots, collect logs and repeat actions. That makes it useful for mobile testing, because the agent can behave more like a real user. It does not only follow a fixed script. It can look at the current app state and decide what to do next based on the UI.</p>



<h2 class="wp-block-heading">Why performance testing?</h2>



<p class="wp-block-paragraph">Performance problems in mobile apps are not always obvious in the code. Sometimes a screen looks completely fine, but when you use it on a real phone, it feels slow. Maybe an animation drops frames. Maybe a list scrolls badly. Maybe opening a modal causes a short freeze. </p>



<p class="wp-block-paragraph">That is why I thought Agent Device could be interesting for performance testing. My idea was not to replace proper profiling tools. You still need real profiling when you want detailed information about the JS thread, native rendering, memory usage or expensive renders. But Agent Device can help with the first layer of testing. It can go through the app automatically and collect signals about where the app feels slower or where frame drops happen.</p>



<h2 class="wp-block-heading">My setup</h2>



<p class="wp-block-paragraph">For my test, I created a build and installed it on a real Android device. Of course, this could also work with emulators. But for performance testing, I think real devices make more sense. A real device gives you more realistic performance behavior. It has real hardware limits, real touch input and real rendering conditions.</p>



<p class="wp-block-paragraph">After installing the app, I installed the Agent Device CLI. Then I used Antigravity with Gemini 3.5 Flash to control the agent. I used this model because the task was not really about deep reasoning. It mostly needed to follow instructions, use the allowed Agent Device commands and document what happened. Also, the free token limits were good enough for testing this kind of workflow.</p>



<p class="wp-block-paragraph">Then I wrote a prompt that explained the use case. The agent should open the app, navigate through all screens, interact with different UI elements and take snapshots of the performance numbers. It should also watch out for frame drops, slow transitions and screens that feel less smooth. I also allowed the agent to use all the Agent Device commands it needed, so it could inspect the UI, tap elements, scroll and move through the app without asking every time.</p>



<figure class="wp-block-video"><video height="1080" style="aspect-ratio: 1920 / 1080;" width="1920" controls src="https://mobile.fhstp.ac.at/wp-content/uploads/2026/06/0610.mp4"></video></figure>



<h2 class="wp-block-heading">Why this is useful</h2>



<p class="wp-block-paragraph">The biggest benefit for me is that the agent can do the boring part. Normally, performance testing often starts with manually opening the app, clicking around and trying to notice where something feels bad. This works, but it is easy to forget screens or to test in a different way every time.</p>



<p class="wp-block-paragraph">With Agent Device, the agent can go through a defined flow again and again. It can collect snapshots, describe problems and give a first overview of possible performance issues.</p>



<p class="wp-block-paragraph">This could be especially useful before releases. You could let the agent run through the main flows and check if there are obvious frame drops or slow interactions before shipping a new version.</p>



<h2 class="wp-block-heading">What I learned</h2>



<p class="wp-block-paragraph">The most important thing is to see this as an extra testing layer, not as a replacement for proper profiling. Agent Device can help you detect where something might be wrong. But after that, you still need to investigate why it happens. Maybe the issue is caused by too many re-renders, heavy images, expensive calculations, navigation transitions or something happening on the native side.</p>



<p class="wp-block-paragraph">Still, I think this workflow is really promising. It connects AI agents with real mobile app usage, not just code generation. The agent does not only write or review code. It actually uses the app and checks how it behaves.</p>



<p class="wp-block-paragraph">I tested this workflow with my own app, Swiva. It is a React Native app for saving activities, places and ideas, and then swiping through them when you need inspiration. If you want to check it out, you can find it here: <a href="https://swiva.app">swiva.app</a></p>



<h2 class="wp-block-heading">Final thoughts</h2>



<p class="wp-block-paragraph">I first saw the idea for performance testing with Agent Device on X/Twitter, and after trying it myself, I think it is a very practical use case. There are probably many more possibilities for this kind of mobile automation. QA flows, regression testing, onboarding checks, accessibility testing or release checks could all be interesting.</p>



<p class="wp-block-paragraph">For me, performance testing was just the first thing that made the tool click. Letting an AI agent move through a real app, collect snapshots and point out possible slow parts feels like a small but useful step towards more automated mobile testing.</p>



<p class="wp-block-paragraph"></p>
<p>The post <a href="https://mobile.fhstp.ac.at/tests/automated-performance-testing-for-react-native-with-agent-device/">Automated Performance Testing for React Native with agent-device</a> appeared first on <a href="https://mobile.fhstp.ac.at">Mobile USTP MKL</a>.</p>
]]></content:encoded>
					
		
		<enclosure url="https://mobile.fhstp.ac.at/wp-content/uploads/2026/06/0610.mp4" length="14076908" type="video/mp4" />

			</item>
		<item>
		<title>Projekt WS25 &#124; MixMatch (Fortsetzung)</title>
		<link>https://mobile.fhstp.ac.at/allgemein/projekt-ws25-mixmatch-fortsetzung/</link>
		
		<dc:creator><![CDATA[Andreas Kaiser]]></dc:creator>
		<pubDate>Sun, 01 Mar 2026 23:41:03 +0000</pubDate>
				<category><![CDATA[Allgemein]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[Native Development]]></category>
		<category><![CDATA[Projekte]]></category>
		<category><![CDATA[Studium]]></category>
		<category><![CDATA[android]]></category>
		<category><![CDATA[mobile]]></category>
		<guid isPermaLink="false">https://mobile.fhstp.ac.at/?p=15368</guid>

					<description><![CDATA[<p>Um mein Projekt &#8220;MixMatch&#8221; näher in die Richtung production-ready Zustand zu bringen wurde das 3. Semester von mir genutzt, nahtlos an den zuvor vorhandenen Stand der Entwicklung anzuschließen.Im Semester habe ich mich im wesentlichen darauf fokussiert, Community Features, wie Sterne-Bewertungen und Kommentier- bzw. Antwortfunktion, in meine Nativescript-App zu integrieren und deutlich mehr Zeit in Bugfixing <a class="read-more" href="https://mobile.fhstp.ac.at/allgemein/projekt-ws25-mixmatch-fortsetzung/">[...]</a></p>
<p>The post <a href="https://mobile.fhstp.ac.at/allgemein/projekt-ws25-mixmatch-fortsetzung/">Projekt WS25 | MixMatch (Fortsetzung)</a> appeared first on <a href="https://mobile.fhstp.ac.at">Mobile USTP MKL</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph">Um mein Projekt &#8220;MixMatch&#8221; näher in die Richtung production-ready Zustand zu bringen wurde das 3. Semester von mir genutzt, nahtlos an den zuvor vorhandenen Stand der Entwicklung anzuschließen.<br>Im Semester habe ich mich im wesentlichen darauf fokussiert, Community Features, wie Sterne-Bewertungen und Kommentier- bzw. Antwortfunktion, in meine Nativescript-App zu integrieren und deutlich mehr Zeit in Bugfixing zu investieren. Nebenbei wurde stellenweise das Design weiter optimiert, sowie das Fehlerhandling überarbeitet. Zur Abrundung wurde im Projektabschnitt eine exportierbare Einkaufliste für Zutaten, die der/die User:in braucht, um die Rezepte nachzumachen, integriert.</p>



<h2 class="wp-block-heading"><strong>Neuerungen seit dem letzten Semester</strong></h2>



<div class="wp-block-columns is-layout-flex wp-container-core-columns-is-layout-8f761849 wp-block-columns-is-layout-flex">
<div class="wp-block-column is-layout-flow wp-block-column-is-layout-flow" style="flex-basis:33.34%">
<figure class="wp-block-image size-full is-resized"><img decoding="async" width="1224" height="2570" src="https://mobile.fhstp.ac.at/wp-content/uploads/2026/03/Screenshot_20260301_232048.png" alt="" class="wp-image-15782" style="width:232px;height:auto" srcset="https://mobile.fhstp.ac.at/wp-content/uploads/2026/03/Screenshot_20260301_232048.png 1224w, https://mobile.fhstp.ac.at/wp-content/uploads/2026/03/Screenshot_20260301_232048-732x1536.png 732w, https://mobile.fhstp.ac.at/wp-content/uploads/2026/03/Screenshot_20260301_232048-975x2048.png 975w" sizes="(max-width: 1224px) 100vw, 1224px" /></figure>
</div>



<div class="wp-block-column is-layout-flow wp-block-column-is-layout-flow" style="flex-basis:33.33%">
<figure class="wp-block-image size-full is-resized"><img decoding="async" width="1224" height="2570" src="https://mobile.fhstp.ac.at/wp-content/uploads/2026/03/Screenshot_20260302_003203.png" alt="" class="wp-image-15787" style="width:231px;height:auto" srcset="https://mobile.fhstp.ac.at/wp-content/uploads/2026/03/Screenshot_20260302_003203.png 1224w, https://mobile.fhstp.ac.at/wp-content/uploads/2026/03/Screenshot_20260302_003203-732x1536.png 732w, https://mobile.fhstp.ac.at/wp-content/uploads/2026/03/Screenshot_20260302_003203-975x2048.png 975w" sizes="(max-width: 1224px) 100vw, 1224px" /></figure>
</div>



<div class="wp-block-column is-layout-flow wp-block-column-is-layout-flow" style="flex-basis:33.33%">
<figure class="wp-block-image size-full is-resized"><img loading="lazy" decoding="async" width="1224" height="2570" src="https://mobile.fhstp.ac.at/wp-content/uploads/2026/03/Screenshot_20260301_232236.png" alt="" class="wp-image-15784" style="width:234px;height:auto" srcset="https://mobile.fhstp.ac.at/wp-content/uploads/2026/03/Screenshot_20260301_232236.png 1224w, https://mobile.fhstp.ac.at/wp-content/uploads/2026/03/Screenshot_20260301_232236-732x1536.png 732w, https://mobile.fhstp.ac.at/wp-content/uploads/2026/03/Screenshot_20260301_232236-975x2048.png 975w" sizes="auto, (max-width: 1224px) 100vw, 1224px" /></figure>
</div>
</div>



<ul class="wp-block-list">
<li><strong>Filteroptionen in der Rezeptliste</strong></li>
</ul>



<p class="wp-block-paragraph">Der größte strukturelle Umbau fand in der Rezeptliste statt. Bisher wurden die Rezepte einfach als rohe Liste angezeigt, ohne Möglichkeit zur Filterung. Jetzt gibt es eine eigene Suchleiste mit Autocomplete-Vorschlägen der gefilterten Drinks, eine alphabetische Sortierung mit Drink-Nummer pro Karte, sowie einen Toggle-Filter für Signature Drinks.</p>



<ul class="wp-block-list">
<li><strong>Kommentar-Sektion bei den Recipes</strong></li>
</ul>



<p class="wp-block-paragraph">Das Herzstück des Projektes war die Erweiterung, dass jedes Rezept nun eine vollwertige Community-Section hat. User:innen können Kommentare mit Sternebewertung hinterlassen, auf Kommentare anderer antworten und eigene Kommentare wieder löschen. Die Bewertungen fließen in eine Durchschnittsbewertung ein, die prominent im Header der Rezeptkarte angezeigt wird. Die gesamte Kommunikation läuft in Echtzeit über WebSockets.</p>



<ul class="wp-block-list">
<li><strong>Benötigte Zutaten einer Einkaufsliste hinzufügen</strong></li>
</ul>



<p class="wp-block-paragraph">Bisher wurden alle nicht angegebenen Zutaten bei der Hauptsuche automatisch gesammelt und global in meinem Code zwischengespeichert. Das wurde grundlegend über ein Einkaufslisten-Feature überarbeitet: Pro Rezept kann der/die Nutzer:in nun selbst entscheiden, ob er/sie die fehlenden Zutaten zur Einkaufsliste hinzufügen möchte. Fehlende Zutaten werden in der Zutatenliste farblich in Orange hervorgehoben. Ein einzelner Button pro Rezept überträgt dann gezielt nur die fehlenden Zutaten in die Einkaufsliste. Die Einkaufsliste selbst unterstützt den Export als PDF über den nativen Android PrintManager sowie im CSV-Format.<br><br>Neben diesen Änderungen konnten viele Bugs behoben werden. Speziell einige Bugs, die die Funktionalität rund um die Erstellung von &#8220;Signature Drinks&#8221; (anlegen/löschen) als auch den Umgang mit gekennzeichneten Favoriten-Rezepten, eingeschränkt haben, existieren nicht mehr.</p>



<h2 class="wp-block-heading"><strong>Technischer Part</strong></h2>



<p class="wp-block-paragraph">Der Großteil an Technologien ist gleich geblieben. Im Frontend setze ich weiterhin auf NativeScript Angular bzw. Tailwind für das Design und im Backend SpringBoot. Das Backend habe ich dieses Semester erstmalig über den Online-Service Railway gehostet. Dazugekommen sind vor allem die WebSocket-Bibliothek <code>@stomp/stompjs</code> im Frontend sowie die entsprechende Spring WebSocket-Abhängigkeit im Backend.</p>



<p class="wp-block-paragraph">Für die Kommentar-Funktion war von Anfang an klar, dass klassische HTTP-Requests nicht ausreichen , sonst wäre ein ständiges manuelles Aktualisieren notwendig gewesen, um neue Kommentare zu sehen. Die Wahl fiel auf WebSockets mit STOMP, einem einfachen Messaging-Protokoll das auf WebSocket aufsetzt und ein Publish-Subscribe-Modell ermöglicht. Im Spring Boot Backend wird dabei ein Message-Broker konfiguriert der eingehende Nachrichten an alle Subscriber des jeweiligen Rezept-Topics weiterleitet. Jedes Rezept hat seinen eigenen Kanal, zum Beispiel <code>/topic/recipe/42/comments</code>. Nur Nutzer:innen die gerade dieses Rezept offen haben, empfangen die Kommentar, die zu diesem Rezept abgegeben wurden. Der Controller nimmt neue Kommentare entgegen, speichert sie und schickt sie sofort an alle aktiven Subscriber:</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: java; title: ; notranslate">
@MessageMapping(&quot;/comments/create&quot;)
public void createComment(CreateCommentRequestDto request, Principal principal) {
    User author = userRepository.findByUsername(principal.getName())...;
    CommentResponseDto saved = commentService.createComment(request, author);
    messagingTemplate.convertAndSend(
        &quot;/topic/recipe/&quot; + request.getRecipeId() + &quot;/comments&quot;, 
        saved
    );
}
</pre></div>


<p class="wp-block-paragraph">Im Frontend übernimmt ein dedizierter <code>CommentWebSocketService</code> die gesamte Verbindungslogik. Er verwendet die <code>@stomp/stompjs</code> Bibliothek, schickt den JWT-Token beim Verbindungsaufbau mit und subscribt auf den zum Rezept passenden Topic-Kanal:</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: plain; title: ; notranslate">
this.stompClient = new Client({
    webSocketFactory: () =&gt; new WebSocket(`wss://...railway.app/ws`),
    connectHeaders: { Authorization: `Bearer ${this.authToken}` },
    reconnectDelay: 5000,
});

this.stompClient.onConnect = () =&gt; {
    this.stompClient.subscribe(
        `/topic/recipe/${this.recipeId}/comments`,
        (message) =&gt; {
            const comment = JSON.parse(message.body);
            onCommentReceived(comment);
        }
    );
};
</pre></div>


<h2 class="wp-block-heading"><strong>Herausforderungen &amp; Learning(s) daraus</strong></h2>



<p class="wp-block-paragraph">Die größte Herausforderung des Semesters waren eindeutig die WebSockets. Theoretisch klingt es simpel (Verbindung öffnen und Nachrichten empfangen), jedoch in der Praxis gab es einige Hürden. Zuerst die Authentifizierung: anders als bei normalen HTTP-Requests musste der JWT-Token über die STOMP <code>connectHeaders</code> mitgeschickt und im Backend extra validiert werden. Dann das Problem mit inaktiven Verbindungen, denn ohne der sogenannten &#8220;Heartbeat-Konfiguration&#8221; auf beiden Seiten kamen Nachrichten irgendwann einfach nicht mehr an (Fehlermeldungen wurden nicht geworfen). Zu guter Letzt das Aufräumen der Verbindungen, denn ohne explizites <code>disconnect()</code> blieben im Hintergrund immer mehr aktive Verbindungen offen.</p>



<p class="wp-block-paragraph">Was das Aufräumen so schwierig gemacht hat, war der Pager, mit dem man zwischen den Rezepten swipen kann. NativeScript&#8217;s Pager-Komponente erstellt alle Rezept-Items gleichzeitig beim Laden, bei 14 Rezepten also sofort 14 WebSocket-Verbindungen und 14 HTTP-Requests, obwohl der/die Nutzer:in nur ein einziges Rezept sieht. Noch dazu wird <code>ngOnDestroy</code> beim Wischen zwischen den Items nicht zuverlässig aufgerufen, weil der Pager seine Views intern recycelt statt sie wirklich zu zerstören. Dadurch hat die Cleanup-Logik nie gefeuert.</p>



<p class="wp-block-paragraph">Die Lösung war letztlich ein Umdenken: statt auf <code>ngOnDestroy</code> zu vertrauen, steuert jetzt ein Flag, ob die Kommentar-Sektion überhaupt gerendert wird. Sobald der Nutzer wegwischt, verschwindet die Komponente via <code>*ngIf</code> aus dem DOM, damit das Cleanup zuverlässig durchläuft. Das wesentliche Learning dabei, war ein gut ausgebautes Debugging zu haben.</p>



<h2 class="wp-block-heading"><strong>Fazit und zukünftige TODOs</strong></h2>



<p class="wp-block-paragraph">In diesem Projektabschnitt konnte ich mich erstmalig herausfordernd damit befassen, wie WebSockets technisch umgesetzt werden. Das war gleichzeitig eines der interessantesten und aufwändigsten Themen des Semesters. Die vielen Debugging-Sessions haben mich aber auch am meisten weitergebracht. Rückblickend bin ich sehr zufrieden damit, was ich mir vorgenommen hatte auch tatsächlich vollständig umgesetzt zu haben. Gerade das Bugfixing war diesmal besonders aufwändig, hat aber mit großem Erfolg geendet und manche Features meiner App brauchbarer gemacht.</p>



<p class="wp-block-paragraph">An diesen Dingen sollte nun weitergearbeitet werden: Performance-seitig gibt es noch Luft nach oben, sowohl beim initialen Laden als auch bei den Screen-Wechseln merkt man stellenweise noch Verzögerungen die es zu optimieren gilt. Auch das Design ist noch nicht wirklich durchgängig einheitlich, was ich in einem nächsten Schritt konsequenter angehen möchte. Dazu kommt, dass ich bisher kaum echtes User-Feedback eingeholt habe, das soll sich ändern. Auf technischer Seite fehlen noch automatisierte Tests, die zur noch besseren Stabilität der App beitragen sollen. Schlussendlich wäre das große Ziel die App veröffentlichen zu können.</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<p class="wp-block-paragraph"><strong>Beitragsbild</strong>: dieses wurde mittels Einsatz von KI erzeugt</p>
<p>The post <a href="https://mobile.fhstp.ac.at/allgemein/projekt-ws25-mixmatch-fortsetzung/">Projekt WS25 | MixMatch (Fortsetzung)</a> appeared first on <a href="https://mobile.fhstp.ac.at">Mobile USTP MKL</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Projekt &#124; VS Code Extension</title>
		<link>https://mobile.fhstp.ac.at/studium/studium-projekte/projekt-vs-code-extension/</link>
		
		<dc:creator><![CDATA[Katharina Wurm]]></dc:creator>
		<pubDate>Thu, 26 Feb 2026 11:32:36 +0000</pubDate>
				<category><![CDATA[Allgemein]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[Projekte]]></category>
		<category><![CDATA[Studium]]></category>
		<category><![CDATA[extension]]></category>
		<category><![CDATA[IDE]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Typescript]]></category>
		<category><![CDATA[Visual Studio Code]]></category>
		<guid isPermaLink="false">https://mobile.fhstp.ac.at/?p=15534</guid>

					<description><![CDATA[<p>IDEs wie Visual Studio Code gehören zum Alltag jeder Softwareentwicklerin und jedes Softwareentwicklers – egal ob im Mobile-, Web- oder Backend-Bereich. Was VS Code besonders spannend macht, ist, dass es sich erweitern lässt. Sogenannte &#8220;Extensions&#8221; ermöglichen es, die Arbeitsumgebung individuell zu gestalten, Prozesse zu automatisieren und neue Funktionen direkt in den Editor zu integrieren. Obwohl <a class="read-more" href="https://mobile.fhstp.ac.at/studium/studium-projekte/projekt-vs-code-extension/">[...]</a></p>
<p>The post <a href="https://mobile.fhstp.ac.at/studium/studium-projekte/projekt-vs-code-extension/">Projekt | VS Code Extension</a> appeared first on <a href="https://mobile.fhstp.ac.at">Mobile USTP MKL</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph"><span style="font-size: revert; white-space: normal;">IDEs wie Visual Studio Code gehören zum Alltag jeder Softwareentwicklerin und jedes Softwareentwicklers – egal ob im Mobile-, Web- oder Backend-Bereich. </span>Was VS Code besonders spannend macht, ist, dass es sich erweitern lässt. Sogenannte &#8220;Extensions&#8221; ermöglichen es, die Arbeitsumgebung individuell zu gestalten, Prozesse zu automatisieren und neue Funktionen direkt in den Editor zu integrieren.</p>



<p class="wp-block-paragraph">Obwohl ich bereits unzählige Stunden in IDEs wie VS Code verbracht habe, um Apps und mehr zu entwickeln, hatte ich mich bisher nie damit beschäftigt, wie sich die Entwicklungsumgebung selbst erweitern lässt.</p>



<p class="wp-block-paragraph">Da ich die Idee hatte, in meiner Masterarbeit eine VS Code Extension zu entwickeln, wollte ich das Einzelprojekt im 3. Semester der Masterklasse Mobile nutzen, um erste praktische Erfahrungen mit der Entwicklung von VS Code Extensions zu sammeln, bevor ich mich an die separate Entwicklung des Masterarbeitsprojekts mache.</p>



<p class="wp-block-paragraph">Das Ergebnis dieses explorativen Projekts ist &#8220;Cute Cat&#8221;: eine süße VS Code Extension, die unterschiedliche Möglichkeiten von VS Code Extensions kombiniert.</p>



<h2 class="wp-block-heading">Features</h2>



<h3 class="wp-block-heading">Commands</h3>



<p class="wp-block-paragraph">Die Extension stellt mehrere Commands zur Verfügung, die direkt über die Command Palette in VS Code aufgerufen werden können:</p>



<ul class="wp-block-list">
<li><strong>&#8220;Meow!&#8221;</strong> zeigt eine kurze Informationsnachricht.</li>



<li>&#8220;<strong>Show me the cat“</strong>&nbsp;öffnet ein Informations-Popup, in welchem auch mehrzeiliger Text verwendet werden kann.</li>



<li>&#8220;<strong>Wake up cat“</strong>&nbsp;aktiviert die WebView im Side Panel (falls sie nicht schon angezeigt wird) und zeigt eine überraschte Katze für ein paar Sekunden. Die WebView wird weiter unten im Detail beschrieben.</li>



<li>&#8220;<strong>Wrap selection in try catch block“</strong>&nbsp;erweitert den ausgewählten Code automatisch um einen&nbsp;try-catch-Block oder gibt eine Warnung aus, falls keine Auswahl getroffen wurde.</li>
</ul>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img loading="lazy" decoding="async" width="1255" height="652" src="https://mobile.fhstp.ac.at/wp-content/uploads/2026/02/commands.png" alt="" class="wp-image-15614" srcset="https://mobile.fhstp.ac.at/wp-content/uploads/2026/02/commands.png 1255w, https://mobile.fhstp.ac.at/wp-content/uploads/2026/02/commands-770x400.png 770w" sizes="auto, (max-width: 1255px) 100vw, 1255px" /></figure>
</div>


<h3 class="wp-block-heading">Themes</h3>



<p class="wp-block-paragraph">Neben funktionalen Features wurden auch eigene Designkomponenten umgesetzt:</p>



<ul class="wp-block-list">
<li><strong>&#8220;Cute Cat Pastel Dark&#8221;</strong> Colour Theme</li>



<li><strong>&#8220;Cute Cat Pastel Icons&#8221;</strong> Icon Theme</li>
</ul>



<p class="wp-block-paragraph">Dabei lag der Fokus auf einer konsistenten visuellen Identität. Die Kombination aus sanften Pastelltönen und angepassten Icons verleiht der Extension einen klaren Wiedererkennungswert.</p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="1255" height="652" src="https://mobile.fhstp.ac.at/wp-content/uploads/2026/02/theme-demo-2.jpg" alt="" class="wp-image-15612" srcset="https://mobile.fhstp.ac.at/wp-content/uploads/2026/02/theme-demo-2.jpg 1255w, https://mobile.fhstp.ac.at/wp-content/uploads/2026/02/theme-demo-2-770x400.jpg 770w" sizes="auto, (max-width: 1255px) 100vw, 1255px" /></figure>



<h3 class="wp-block-heading"><strong>WebView Side Panel</strong></h3>



<p class="wp-block-paragraph">Ein zentrales Element der Extension ist die WebView im Side Panel. Dort wird ein animiertes Katzen-GIF angezeigt, das dynamisch auf Kontextinformationen reagiert:</p>



<ul class="wp-block-list">
<li>Anpassung an die Tageszeit (z. B. „Good Morning“)</li>



<li>Reaktion auf lange Coding-Sessions (z. B. schlägt die Katze dem*der User*in nach 4 Stunden vor, eine Kaffeepause einzulegen)</li>



<li>Anzeige der aktuellen Session-Dauer</li>



<li>Anzeige, wie lange die Extension insgesamt schon aktiv ist (&#8220;<em>Did you know we have been friends for 19h 58min?</em>&#8220;)</li>
</ul>



<p class="wp-block-paragraph">Zusätzlich kann innerhalb der WebView über ein Settings-Icon ein Modal geöffnet werden, in dem User*innen mit einem Klick die bereitgestellte Colour bzw. Icon Theme (de)aktivieren können.</p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="1255" height="652" src="https://mobile.fhstp.ac.at/wp-content/uploads/2026/02/webview.png" alt="" class="wp-image-15616" srcset="https://mobile.fhstp.ac.at/wp-content/uploads/2026/02/webview.png 1255w, https://mobile.fhstp.ac.at/wp-content/uploads/2026/02/webview-770x400.png 770w" sizes="auto, (max-width: 1255px) 100vw, 1255px" /></figure>



<h3 class="wp-block-heading">Text Decorations</h3>



<p class="wp-block-paragraph">Ein weiteres Feature der Extension sind dynamische Text Decorations. In den geöffneten Texteditoren werden Schlüsselwörter wie &#8220;cat&#8221; und &#8220;cute&#8221; mit kleinen dekorativen Elementen versehen.</p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="1255" height="652" src="https://mobile.fhstp.ac.at/wp-content/uploads/2026/02/decorations.png" alt="" class="wp-image-15618" srcset="https://mobile.fhstp.ac.at/wp-content/uploads/2026/02/decorations.png 1255w, https://mobile.fhstp.ac.at/wp-content/uploads/2026/02/decorations-770x400.png 770w" sizes="auto, (max-width: 1255px) 100vw, 1255px" /></figure>



<details class="wp-block-details is-layout-flow wp-block-details-is-layout-flow"><summary><em>Attribution</em></summary>
<ul class="wp-block-list">
<li><em>Cat&nbsp;SVG Vector (mit geänderter Farbe): bereitgestellt auf <a href="https://www.svgrepo.com/svg/522779/cat">https://www.svgrepo.com/svg/522779/cat</a> von <a href="https://www.svgrepo.com/author/Solar%20Icons/">Solar Icons</a> unter der <a href="https://www.svgrepo.com/page/licensing/#CC%20Attribution">CC Attribution Lizenz</a></em></li>



<li><em>Bow Tie Ribbon&nbsp;SVG Vector (mit geänderter Farbe): bereitgestellt auf <a href="https://www.svgrepo.com/svg/321894/bow-tie-ribbon">https://www.svgrepo.com/svg/321894/bow-tie-ribbon</a> von <a href="https://www.svgrepo.com/collection/game-interface-icons/">Game Interface Icons</a> unter der <a href="https://www.svgrepo.com/page/licensing/#CC%20Attribution">CC Attribution Lizenz</a></em></li>
</ul>
</details>



<h2 class="wp-block-heading">Projektaufbau</h2>



<p class="wp-block-paragraph">Vereinfacht dargestellt ist das Projekt wie folgt aufgebaut:</p>



<pre class="wp-block-code"><code>- media/
  - webViewScript.js
  - webViewStyles.css
  - &#91;...Bilder]
- src/
  - extension.ts (Einstiegspunkt)
  - &#91;...]
- themes/
  - color-theme.json
  - icon-theme.json
- &#91;...]
- package.json (Manifest)</code></pre>



<p class="wp-block-paragraph">Wichtig sind hierbei die <code>package.json</code> Datei, in welcher die Commands, WebView und Themes deklariert werden, und die <code>src/extension.ts</code> Datei, welche den Einstiegspunkt der Extension darstellt:</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: plain; title: ; notranslate">
import * as vscode from &#039;vscode&#039;;

export function activate(context: vscode.ExtensionContext) {
    // ...
}

export function deactivate() {}
</pre></div>


<h2 class="wp-block-heading">Challenges und Learnings</h2>



<h3 class="wp-block-heading">API-Dokumentation</h3>



<p class="wp-block-paragraph">VS Code bietet einen <a href="https://code.visualstudio.com/api/get-started/your-first-extension">&#8220;Your First Extension&#8221; Guide</a> und stellt viele Beispielprojekte zu unterschiedlichen Extension-Funktionalitäten für Entwickler*innen zur Verfügung. Trotzdem ist es manchmal nicht so leicht, das genaue Beispielprojekt, welches man sucht, zu finden. Ich würde zukünftigen Extension-Developer*innen empfehlen, direkt auf GitHub zu schauen (<a href="https://github.com/microsoft/vscode-extension-samples">https://github.com/microsoft/vscode-extension-samples</a>), anstatt nur in der <a href="https://code.visualstudio.com/api">VS Code Extension API</a> zu suchen.</p>



<p class="wp-block-paragraph">Falls man etwas Bestimmtes zur <a href="https://code.visualstudio.com/api/references/vscode-api">VS Code API</a> nachschauen will, ist diese recht gut dokumentiert. Leider funktionieren einige Links auf der Website allerdings nicht, weshalb ich mich hauptsächlich mit der Suchfunktion (STRG+F) durch die API-Dokumentation arbeiten musste.</p>



<p class="wp-block-paragraph">Von der Community gibt es eher weniger Tutorials und Online-Beiträge. Um die VS Code Extension zu entwickeln, kombinierte ich daher Informationen aus der API-Dokumentation, aus Beispielprojekten und Tutorials und erarbeitete mir die fehlenden Details eigenständig durch &#8220;Learning by Doing&#8221;.</p>



<h3 class="wp-block-heading">Text Decoration Icons</h3>



<p class="wp-block-paragraph">Man würde denken, ein Bild als Text Decoration zu setzen, wäre trivial. Doch hat es mich einige Zeit gekostet, bis ich Folgendes realisiert habe: Wenn man ein SVG Icon verwenden will, darf dieses nicht selbst &#8220;width&#8221; und &#8220;height&#8221; angeben. Obwohl man der Text Decoration sowohl width, als auch height, mitgeben kann, werden diese Angaben ignoriert, wenn das SVG seine eigene Größe vorgibt. </p>



<p class="wp-block-paragraph">Weiters werden die Icons nicht mitting in der Zeile positioniert (siehe das Bild der Text Decorations: die Icons sind etwas weiter oben positioniert als der Text). Man kann der Decoration zwar auch einen Margin mitgeben, allerdings würde z. B. ein Top-Margin (um den extra Platz unterhalb des Icons auszugleichen) nicht nur das Icon, sondern die ganze Zeile nach unten schieben.</p>



<h3 class="wp-block-heading">Kommunikation zwischen Extension und WebView</h3>



<p class="wp-block-paragraph">Eine weitere Challenge war die Kommunikation zwischen der Extension und der WebView, um insbesondere bei den &#8220;Theme Toggles&#8221; beide Seiten am gleichen Stand zu halten (wenn das Theme (extern) aktiviert wurde, sollte auch der Toggle in der WebView automatisch aktiviert werden). Dank der VS Code API können aber Nachrichten recht einfach zwischen der Extension und der WebView ausgetauscht werden.</p>



<h3 class="wp-block-heading">Debugging</h3>



<p class="wp-block-paragraph">Ich fand es sehr spannend, insbesondere die WebView zu debuggen. Über die Command Palette in VS Code lässt sich der Web Inspector öffnen (&#8220;Toggle Developer Tools&#8221;), mit welcher sowohl der Console-Output, als auch die HTML-Elemente der ganzen IDE inspiziert werden können. Innerhalb von den Sourcefiles (abgesehen von <code>webViewScript.js</code>) lassen sich allerdings auch Breakpoints setzen.</p>



<p class="wp-block-paragraph">Obwohl der sogenannte &#8220;Extension Development Host&#8221; (das separate VS Code Fenster, in welchem die Extension während der Entwicklung läuft) viel zu bieten hat, konnte ich nicht die komplette Funktionalität meiner Extension darin testen. Das Icon Theme lässt sich innerhalb des Extension Hosts zum Beispiel nicht programmatisch für den Workspace setzen (innerhalb von <code>.vscode/settings.json</code>), weshalb ich die Extension mit dem &#8220;<code>vsce package</code>&#8221; Command zuerst builden und installieren musste, um den &#8220;Icon Theme Toggle&#8221; innerhalb der WebView zu testen.</p>



<h2 class="wp-block-heading">Conclusion</h2>



<p class="wp-block-paragraph">Mit dem Projekt &#8220;Cute Cat&#8221; konnte ich einen intensiven Einblick in die Möglichkeiten und Herausforderungen von VS Code Extensions gewinnen. Besonders wertvoll war für mich dabei der explorative Charakter des Projekts: Ich konnte vieles ausprobieren und dadurch ein tiefes Verständnis für die Entwicklung von VS Code Extensions aufbauen.</p>



<p class="wp-block-paragraph">Ich bin stolz auf das, was ich erreicht habe, und fühle mich nun bestens vorbereitet, das nächste Projekt anzugehen: die Entwicklung meiner eigenen VS Code Extension im Rahmen der Masterarbeit.</p>
<p>The post <a href="https://mobile.fhstp.ac.at/studium/studium-projekte/projekt-vs-code-extension/">Projekt | VS Code Extension</a> appeared first on <a href="https://mobile.fhstp.ac.at">Mobile USTP MKL</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Projekt &#124; Timelapse Android App</title>
		<link>https://mobile.fhstp.ac.at/studium/studium-projekte/projekt-timelapse-android-app/</link>
		
		<dc:creator><![CDATA[David Grünberger]]></dc:creator>
		<pubDate>Thu, 26 Feb 2026 10:19:46 +0000</pubDate>
				<category><![CDATA[Design]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[Dokumentation]]></category>
		<category><![CDATA[Native Development]]></category>
		<category><![CDATA[Projekte]]></category>
		<category><![CDATA[Studium]]></category>
		<category><![CDATA[Trends]]></category>
		<category><![CDATA[User Experience]]></category>
		<category><![CDATA[android]]></category>
		<category><![CDATA[design systems]]></category>
		<category><![CDATA[Jetpack Compose]]></category>
		<category><![CDATA[Material Design]]></category>
		<category><![CDATA[mobile]]></category>
		<category><![CDATA[Semesterprojekt]]></category>
		<guid isPermaLink="false">https://mobile.fhstp.ac.at/?p=15691</guid>

					<description><![CDATA[<p>Im Rahmen des Semesterprojekts im 3. Semester der Masterklasse Mobile habe ich die Android-App &#8220;Timelapse&#8221; entwickelt. Die Idee dahinter: Aus vielen einzelnen Momentaufnahmen wird automatisch ein visueller Zeitstrahl – als Video, das langfristige Veränderungen sichtbar macht. Egal ob Bartwachstum, Fitness-Progress oder das Wachstum einer Zimmerpflanze: Timelapse hilft dabei, diese Reise festzuhalten. Ziel des Projekts war ein alltagstauglicher MVP, der den kompletten Ablauf abdeckt: vom Erstellen <a class="read-more" href="https://mobile.fhstp.ac.at/studium/studium-projekte/projekt-timelapse-android-app/">[...]</a></p>
<p>The post <a href="https://mobile.fhstp.ac.at/studium/studium-projekte/projekt-timelapse-android-app/">Projekt | Timelapse Android App</a> appeared first on <a href="https://mobile.fhstp.ac.at">Mobile USTP MKL</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph">Im Rahmen des Semesterprojekts im 3. Semester der Masterklasse Mobile habe ich die Android-App &#8220;Timelapse&#8221; entwickelt. Die Idee dahinter: Aus vielen einzelnen Momentaufnahmen wird automatisch ein visueller Zeitstrahl – als Video, das langfristige Veränderungen sichtbar macht. Egal ob Bartwachstum, Fitness-Progress oder das Wachstum einer Zimmerpflanze: Timelapse hilft dabei, diese Reise festzuhalten. Ziel des Projekts war ein alltagstauglicher MVP, der den kompletten Ablauf abdeckt: vom Erstellen eines Projekts über tägliche Erinnerungen und eine übersichtliche Tage-Ansicht bis hin zur fertigen Video-Montage, die sich teilen oder archivieren lässt.</p>



<h2 class="wp-block-heading">Worum es in der&nbsp;App geht</h2>



<p class="wp-block-paragraph">Im Kern funktioniert Timelapse wie ein&nbsp;visuelles&nbsp;Tagebuch:</p>



<ul class="wp-block-list">
<li>Nutzer:innen legen Projekte an (z. B. „Daily Selfie“ oder „Zimmerpflanze“).</li>



<li>Die App erinnert regelmäßig daran, neue Fotos aufzunehmen.</li>



<li>Alle Bilder werden zeitlich geordnet, mit Datum und optionalen Kommentaren gespeichert.</li>



<li>Auf einer kompakten Übersicht sieht man, wann man etwas aufgenommen hat, welche Tage besonders wichtig waren und wie sich das Projekt über Wochen und Monate entwickelt.</li>



<li>Aus dieser Sammlung erzeugt Timelapse auf Knopfdruck ein Zeitraffervideo, das die Geschichte des Projekts in wenigen Sekunden erzählt.</li>
</ul>



<h2 class="wp-block-heading">Zentrale&nbsp;Funktionen&nbsp;in&nbsp;Kürze</h2>



<ul class="wp-block-list">
<li><strong>Projektorganisation:</strong> Mehrere parallele Timelapse-Projekte mit Titel, Beschreibung und individuellen Einstellungen.</li>



<li><strong>Visuelle Timeline:</strong> Eine kombinierte Wochen- und Listenansicht zeigt, welche Tage schon dokumentiert sind und welche Lücken es noch gibt.</li>



<li><strong>Erinnerungen:</strong> Konfigurierbare Benachrichtigungen, damit die tägliche Aufnahme zur Routine wird und die Timeline nicht abreißt.</li>



<li>F<strong>avoriten &amp; Notizen:</strong> Einzelne Tage können hervorgehoben und mit kurzen Kommentaren versehen werden – etwa um Meilensteine oder besondere Momente zu markieren.</li>



<li><strong>Automatische Video-Montage:</strong> Die App erstellt aus den Bildern ein Video, berücksichtigt Ausrichtung, Datum, optionales Wasserzeichen und Kommentare und bietet Konfigurationsmöglichkeiten für Qualität oder Textstil.</li>
</ul>



<figure class="wp-block-gallery has-nested-images columns-4 wp-block-gallery-1 is-layout-flex wp-block-gallery-is-layout-flex">
<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="1080" height="2400" data-id="15763" src="https://mobile.fhstp.ac.at/wp-content/uploads/2026/02/Screenshot_20260226_122653_Timelapse.jpg" alt="" class="wp-image-15763" srcset="https://mobile.fhstp.ac.at/wp-content/uploads/2026/02/Screenshot_20260226_122653_Timelapse.jpg 1080w, https://mobile.fhstp.ac.at/wp-content/uploads/2026/02/Screenshot_20260226_122653_Timelapse-691x1536.jpg 691w, https://mobile.fhstp.ac.at/wp-content/uploads/2026/02/Screenshot_20260226_122653_Timelapse-922x2048.jpg 922w" sizes="auto, (max-width: 1080px) 100vw, 1080px" /></figure>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="1080" height="2400" data-id="15765" src="https://mobile.fhstp.ac.at/wp-content/uploads/2026/02/Screenshot_20260226_122559_Timelapse.jpg" alt="" class="wp-image-15765" srcset="https://mobile.fhstp.ac.at/wp-content/uploads/2026/02/Screenshot_20260226_122559_Timelapse.jpg 1080w, https://mobile.fhstp.ac.at/wp-content/uploads/2026/02/Screenshot_20260226_122559_Timelapse-691x1536.jpg 691w, https://mobile.fhstp.ac.at/wp-content/uploads/2026/02/Screenshot_20260226_122559_Timelapse-922x2048.jpg 922w" sizes="auto, (max-width: 1080px) 100vw, 1080px" /></figure>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="1080" height="2400" data-id="15764" src="https://mobile.fhstp.ac.at/wp-content/uploads/2026/02/Screenshot_20260226_122619_Timelapse.jpg" alt="" class="wp-image-15764" srcset="https://mobile.fhstp.ac.at/wp-content/uploads/2026/02/Screenshot_20260226_122619_Timelapse.jpg 1080w, https://mobile.fhstp.ac.at/wp-content/uploads/2026/02/Screenshot_20260226_122619_Timelapse-691x1536.jpg 691w, https://mobile.fhstp.ac.at/wp-content/uploads/2026/02/Screenshot_20260226_122619_Timelapse-922x2048.jpg 922w" sizes="auto, (max-width: 1080px) 100vw, 1080px" /></figure>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="1080" height="2400" data-id="15766" src="https://mobile.fhstp.ac.at/wp-content/uploads/2026/02/Screenshot_20260226_122700_Timelapse.jpg" alt="" class="wp-image-15766" srcset="https://mobile.fhstp.ac.at/wp-content/uploads/2026/02/Screenshot_20260226_122700_Timelapse.jpg 1080w, https://mobile.fhstp.ac.at/wp-content/uploads/2026/02/Screenshot_20260226_122700_Timelapse-691x1536.jpg 691w, https://mobile.fhstp.ac.at/wp-content/uploads/2026/02/Screenshot_20260226_122700_Timelapse-922x2048.jpg 922w" sizes="auto, (max-width: 1080px) 100vw, 1080px" /></figure>
<figcaption class="blocks-gallery-caption wp-element-caption"><strong>Abb. 1: App Screenshots</strong></figcaption></figure>



<h2 class="wp-block-heading">Technologie-Stack</h2>



<p class="wp-block-paragraph">Die&nbsp;App ist&nbsp;als&nbsp;native&nbsp;Android-Anwendung mit Jetpack Compose&nbsp;umgesetzt und&nbsp;nutzt&nbsp;moderne&nbsp;Android-APIs sowie eine&nbsp;klare&nbsp;Schichtung&nbsp;zwischen&nbsp;UI, Logik&nbsp;und Medienverarbeitung.</p>



<ul class="wp-block-list">
<li><strong>UI: Jetpack Compose + Material 3</strong>
<ul class="wp-block-list">
<li>Alle Screens (Projektliste, Details, Dialoge, Konfiguration) sind vollständig in Compose realisiert.</li>



<li>Material-3-Komponenten wie LargeFlexibleTopAppBar, Listen, Cards und Dialoge sorgen für ein konsistentes Look &amp; Feel.</li>



<li>Ein zentrales TimelapseTheme verwaltet App-Theme (Light/Dark), Seed-Farbe und den Palette-Stil.</li>
</ul>
</li>



<li><strong>Material 3 Expressive &amp; Material You</strong>
<ul class="wp-block-list">
<li>Die App nutzt Material 3 Expressive, um eine lebendige, charakterstarke Farb- und Typografie-Sprache umzusetzen – passend zu einer App, die persönliche Veränderungen dokumentiert.</li>



<li>Über einen integrierten Color Picker wählen Nutzer:innen eine eigene Akzentfarbe.</li>



<li>Aus dieser Seed-Farbe wird mit Material You ein komplettes Farbschema generiert, das sich konsistent über die gesamte App zieht.</li>



<li>Dadurch wirkt Timelapse auf jedem Gerät persönlich, bleibt aber immer klar strukturiert und gut lesbar – unabhängig davon, ob Light- oder Dark-Mode aktiv ist.</li>
</ul>
</li>



<li><strong>Video-Montage &amp; Bildverarbeitung</strong>
<ul class="wp-block-list">
<li>Die Montage-Logik läuft in einem eigenen Modul:</li>



<li>Bilder werden anhand ihrer EXIF-Daten korrekt ausgerichtet.</li>



<li>Ein Canvas setzt die Frames zusammen, ergänzt Texte (Datum, Kommentare, Wasserzeichen) und kümmert sich um Hintergrundfarbe und Zensurflächen.</li>



<li>Ein Muxer erzeugt daraus ein MP4-Video, gesteuert über Kotlin Flows, die den Fortschritt an die UI melden.</li>



<li>So entsteht aus einer losen Sammlung von Bildern ein stimmiges Timelapse-Video, ohne dass externe Tools nötig sind.</li>
</ul>
</li>
</ul>



<h2 class="wp-block-heading">Material&nbsp;3 Expressive&nbsp;&amp; Material You im&nbsp;Einsatz</h2>



<p class="wp-block-paragraph">Ein großer&nbsp;Fokus&nbsp;des&nbsp;Projekts lag&nbsp;auf einer&nbsp;modernen, adaptiven&nbsp;UI, die sich&nbsp;nach&nbsp;den&nbsp;Nutzer:innen richtet:</p>



<ul class="wp-block-list">
<li><strong>Dynamische Farbwelten</strong>
<ul class="wp-block-list">
<li>Durch den Seed-Color-Ansatz wirkt die App nicht wie ein statisch durchgestyltes Produkt, sondern wie ein Rahmen, der sich der jeweiligen Geschichte anpasst.</li>



<li>Projekte mit emotionalem Kontext (z. B. Schwangerschaft, Beziehungen, erste Wohnung) profitieren von den kräftigen, expressiven Paletten, die Material 3 bereitstellt.</li>
</ul>
</li>



<li><strong>Einheitliche, weiche Formsprache</strong>
<ul class="wp-block-list">
<li>Großzügige Rundungen (z. B. extra große Card-Shapes in Dialogen), expressive Typografie und bewusst eingesetzte Icons unterstützen den Tagebuch-Charakter der App.</li>



<li>Die App verzichtet auf überladene UI-Elemente und setzt auf Ruhe, Klarheit und Fokus – wichtig, wenn man sich über Monate immer wieder mit derselben Oberfläche beschäftigt.</li>
</ul>
</li>



<li><strong>Konsistentes Theming</strong>
<ul class="wp-block-list">
<li>Alle Bausteine – von Erfassungsdialogs über Erinnerungs-Settings bis hin zu Fortschrittsanzeigen bei Scans und Montage – hängen am gleichen Theme.</li>



<li>Änderungen an Theme, Palette oder Seed-Farbe greifen sofort durch, ohne dass einzelne Screens speziell angepasst werden müssen.</li>
</ul>
</li>
</ul>



<h2 class="wp-block-heading">Herausforderungen&nbsp;&amp; Learnings</h2>



<ul class="wp-block-list">
<li><strong>Balance zwischen Einfachheit und Kontrolle</strong>
<ul class="wp-block-list">
<li>Nutzer:innen sollen einerseits „einfach nur“ ein Timelapse-Video erstellen können, andererseits genug Einstellmöglichkeiten für Qualität, Text, Stabilisierung und Privatsphäre haben.</li>



<li>Ein wichtiger Lernpunkt war, die Komplexität hinter klaren Dialogen und wenigen, gut erklärten Optionen zu verstecken.</li>
</ul>
</li>



<li><strong>Stabile, angenehme Timelapse-Videos</strong>
<ul class="wp-block-list">
<li>Kleine Fehler bei Skalierung oder Matrix-Transformation führen schnell zu Sprüngen oder abgeschnittenen Bereichen – hier war viel Feintuning nötig.</li>
</ul>
</li>



<li><strong>Durchgängiges Theming mit Material 3 / Material You</strong>
<ul class="wp-block-list">
<li>Seed-Farben, dynamische Paletten und unterschiedliche Palettenstile (z. B. Expressive) lassen sich mächtig kombinieren – aber nur, wenn das Theming-Konzept von Anfang an klar definiert ist.</li>



<li>Die wichtigste Erkenntnis: Ein zentrales Theme-Objekt vereinfacht langfristig alle Entscheidungen rund um Farben, Typografie und Component-Styling.</li>
</ul>
</li>
</ul>



<h2 class="wp-block-heading">Fazit</h2>



<p class="wp-block-paragraph">Timelapse war für mich ein Projekt, in dem sich User Experience, modernes Android-Design und Medienverarbeitung sehr gut ergänzt haben. Die App zeigt, wie sich mit Jetpack Compose, Material 3 Expressive und Material You eine Oberfläche bauen lässt, die technisch anspruchsvolle Abläufe (zB. Videomontage) hinter einem einfachen, persönlichen Nutzungserlebnis versteckt. Besonders spannend war zu sehen, wie stark sich die Wahrnehmung der App ändert, wenn man eine eigene Farbwelt definieren kann und diese sich konsequent durch alle Screens zieht. In zukünftigen Schritten möchte ich die App um Themen wie Musik, Export-Presets und umfangreichere Sharing-Optionen erweitern – immer mit dem Ziel, den Kern beizubehalten: Veränderung sichtbar machen, ohne dass sich der Aufwand danach anfühlt.</p>
<p>The post <a href="https://mobile.fhstp.ac.at/studium/studium-projekte/projekt-timelapse-android-app/">Projekt | Timelapse Android App</a> appeared first on <a href="https://mobile.fhstp.ac.at">Mobile USTP MKL</a>.</p>
]]></content:encoded>
					
		
		
			</item>
	</channel>
</rss>
