enhost Blogs

Global Reader

Welcome to the Global Reader, your window into the vibrant community of enhost BLOGS! Here, you'll find a dynamic feed of the latest posts from all our users, showcasing the diverse voices and perspectives within our Fediverse network. Explore fresh ideas, discover new writers, and engage with content that sparks your curiosity. Dive in and see what the enhost BLOGS community is creating today!

from The Pragmatic Pixel

Hey everyone, Jamie here.

As developers, we tend to build our “homes” in certain frameworks and ecosystems. For me, and for much of this blog, that home has been Laravel. I appreciate its elegant syntax, its “batteries-included” philosophy, and the sheer speed at which you can build robust, modern applications. It's a fantastic tool that I know and love.

Recently, however, I had the opportunity to dive deep into a project built purely on Symfony. It wasn't just about using a few Symfony components under the hood (which Laravel does extensively), but about working within the complete Symfony framework, with its own conventions, structure, and mindset.

It was a fascinating experience that felt like visiting a well-designed, but very different, city. It made me appreciate not only what Symfony does so well but also gave me a fresh perspective on why Laravel works the way it does.


The Initial Shock: “Where's the Magic?”

My first few hours with the Symfony project were a lesson in humility. As a Laravel developer, you get used to a certain amount of “magic” and convention. Things just work.

  • Eloquent vs. Doctrine: I found myself missing the simplicity of Eloquent. In Symfony, the default ORM is Doctrine. It's incredibly powerful and robust, but it's also more verbose. Defining entities, repositories, and mappings felt more deliberate and required more boilerplate than simply creating a new Laravel model.
  • Configuration Over Convention: Laravel famously favors convention over configuration. In Symfony, the opposite is often true. I spent a good amount of time in YAML files (services.yaml), explicitly defining services and their dependencies. My first reaction was, “Why do I have to wire all this up myself?”
  • No Facades, Just Services: There are no global helpers like auth() or cache(). There are no facades providing a simple, static-like interface to underlying services. Everything is a service, and if you want to use it, you must explicitly inject it into your class's constructor.

It felt like the framework was forcing me to be incredibly explicit about every single thing I was doing.


The Slow Appreciation: The Power of Explicitness

After the initial friction, something started to click. The very things that felt like hurdles at first began to reveal their purpose and power.

  • Dependency Injection is a First-Class Citizen: Because you have to inject every dependency, your code becomes incredibly clear. You can look at any class's constructor and know exactly what its dependencies are. This makes the code highly predictable, decoupled, and exceptionally easy to test. You're not guessing where a service comes from; it's right there.
  • Unmatched Flexibility: Symfony feels less like a framework you build inside of, and more like a set of high-quality components you build your application with. You have complete control. You can swap out almost any part of the system with your own implementation. This level of flexibility is fantastic for large, complex, or long-lived enterprise applications where requirements are unique and evolving.
  • Stability and Predictability: The lack of “magic” means there are fewer surprises. The call stack is often easier to trace. You can follow the path from configuration to instantiation to execution without the framework doing things behind a curtain. This can be a huge advantage when debugging complex issues.

What I Missed From Laravel: The Joy of Convention

As I grew to appreciate Symfony's architecture, I also found myself missing the sheer developer experience and rapid development cycle that Laravel provides.

  • Eloquent's Elegance: For all of Doctrine's power, I missed the beauty of defining a hasMany relationship in a single line and chaining query builder methods with such ease. For 90% of standard CRUD and API tasks, Eloquent's speed and readability are hard to beat.
  • The “Batteries-Included” Ecosystem: Laravel's first-party packages like Sanctum, Telescope, and Sail create a seamless, cohesive development experience. Setting up API authentication with Sanctum, for example, is a beautifully simple process. In Symfony, you're more likely to be assembling and configuring different bundles to achieve the same result.
  • Artisan and the make Commands: I missed the convenience of php artisan make:model -mcr. Laravel's command-line tools are tailored for rapid scaffolding and reducing boilerplate, which keeps you in the creative flow.

The Right Tool for the Job

My time with Symfony didn't make me think Laravel is “better” or vice-versa. It solidified my belief that they are two different tools with different philosophies, both built on the same excellent foundation of modern PHP.

  • Symfony feels like a meticulously organized workshop full of high-end, individual power tools. It gives you the power and flexibility to build anything, but it expects you to be a skilled craftsperson who knows how to assemble them. It shines for complex, bespoke, long-term projects.
  • Laravel feels like a state-of-the-art, all-in-one workstation. It has pre-configured tools, sensible defaults, and clever jigs that let you build common things incredibly quickly and elegantly. It shines for rapid application development, APIs, and a huge range of web applications.

Ultimately, working with Symfony made me a better PHP developer. It forced me to engage with concepts like the service container and dependency injection on a much deeper level. And when I returned to a Laravel project, I had a newfound appreciation for the thoughtful conventions and the “magic” that lets me focus on building features so quickly.

What are your experiences moving between the two frameworks? I'd love to hear your thoughts in the comments.

Cheers,

Jamie C

 
Read more...

from The Pragmatic Pixel

Hey everyone, Jamie here.

Following on from my last post, I've been really touched by the messages of support and the shared stories about navigating the tech job market. There's a huge amount of excitement that comes with accepting a verbal offer for a new role. It’s the culmination of weeks, sometimes months, of interviews, technical tasks, and conversations. The natural instinct is to rush to your current boss, hand in your notice, and start the countdown to your next chapter.

But I want to talk about the most critical, and often overlooked, step in this entire process: the pause. The deliberate, professional, and absolutely essential moment between the “Yes, I'd love to accept!” and “Dear Boss, please accept this letter as my formal resignation.”

I'm talking about waiting for the signed contract.


A Verbal Agreement is Built on Good Faith. A Contract is Built on Certainty.

Let's be clear: in the vast majority of cases, a verbal offer is made in good faith. The company wants you, you want them, and everyone is excited. But good faith doesn't protect you if things go wrong.

A verbal offer is not a legally binding employment contract. It's a statement of intent. Until you have a written document, signed by both you and an authorized person at the new company, you are in a professional no-man's-land.

Here’s why that’s a risk you should never take:

  • Details Get Lost in Translation: Was the salary £X, or was that the “total compensation package” including a potential bonus? Is the start date flexible? What's the exact job title? Details discussed over a phone call can be easily misremembered or misinterpreted by either side. The contract solidifies these details in black and white.
  • Internal Situations Change: This is the big one. Between a verbal offer and your start date, anything can happen. Budgets can be unexpectedly frozen, the project you were hired for can be de-prioritized, the hiring manager might leave, or a last-minute internal candidate might emerge. A verbal offer can be rescinded with a difficult phone call. A signed contract makes this significantly more complicated and less likely.
  • It's Your Only Safety Net: Imagine resigning from your stable job, only to have the new offer withdrawn a week later. You're left with no job and no recourse. It's a nightmare scenario, and while it's not common, it happens. The contract is your safety net.

What to Check Before You Sign (and Resign)

When that PDF lands in your inbox, don't just skim to the signature line. Read it carefully. You're checking that it matches your discussions.

  • The Core Details: Salary, job title, start date, and your primary place of work.
  • Notice Period: What's required from you if you leave, and what's required from them? Does this change after a probationary period?
  • Restrictive Covenants: Pay close attention to these. Are there non-compete clauses that could limit your future employment? Non-solicitation clauses? Understand what you're agreeing to.
  • Benefits: Check that key benefits like holiday entitlement, pension contributions, and any mentioned health or insurance plans are documented.
  • Job Description: Does the summary of your role and responsibilities align with what you discussed in the interviews?

If there are any discrepancies, now is the time to raise them politely. It's much easier to clarify a detail before you've signed than to dispute it later.


The Golden Rule

It's so simple, yet so important that it's worth stating plainly:

Never, ever resign from your current position until you have a signed, written employment contract from your new employer.

Chasing for it isn't being pushy; it's being professional. A simple, polite email is all it takes:

“Hi [Hiring Manager/HR Contact], I'm incredibly excited to have accepted the offer and am really looking forward to joining the team. Just checking in on the written contract so I can get that signed and then hand in my notice at my current role. Please let me know if you need anything else from me in the meantime.”

This shows you're organised and diligent—qualities they hired you for in the first place. Any reasonable employer will understand and respect this completely. If they pressure you to resign before providing a contract, that itself is a major red flag.

Taking that small pause to ensure your next step is secure doesn't diminish the excitement of a new role. It protects it. It allows you to hand in your notice not with a leap of faith, but with the confidence and certainty that you deserve.

Cheers,

Jamie C

 
Read more...

from The Pragmatic Pixel

Hey everyone, Jamie here.

This is a bit of a different post from me today—less about code, more about career. After a period of reflection and some interesting conversations, I'm thrilled to share that I've accepted a new role and will be starting a new chapter in my professional journey.

Making this move has been an eye-opening experience, and it gave me a front-row seat to the current state of the UK tech job market. It feels very different from the hiring frenzy of a few years ago, and I wanted to share some thoughts for anyone else out there who might be thinking of making a change.


The Temperature Check: A Market Correction

Let's be honest: the market right now is not what it was in 2021. The “great resignation” and the subsequent hiring boom have given way to a more cautious, measured approach from companies. Layoffs in big tech have had a ripple effect, and while there are still plenty of roles available, the process feels more deliberate and competitive.

It's not all doom and gloom, but it's certainly what I'd call “choppy waters.” Companies are taking longer to hire, interview processes are often more rigorous, and the days of juggling multiple, no-strings-attached offers seem to have cooled off for many. This isn't necessarily a bad thing; it feels like a return to a more sustainable, intentional hiring environment.

The Interview Gauntlet: What to Expect

The process of finding the right fit was a marathon, not a sprint. Here are a few patterns I noticed:

  • Multi-Stage Interviews are Standard: A quick chat is rarely enough. I consistently found a 3-to-5 stage process was the norm: an initial screening call, a technical chat with a senior dev or lead, a take-home task or live coding session, and finally a “cultural fit” or team meeting.
  • Take-Home Tasks are Prevalent: This is a divisive topic, I know. My take is that a well-scoped, respectful take-home task (i.e., one that takes a few hours, not a few days) can be a great way for both sides to see if there's a good fit. It allowed me to showcase my practical skills beyond just talking about them.
  • The “Why” Matters More: At a certain level of experience, companies assume you have the technical chops. What they really wanted to dig into was my thinking. Why did I choose a certain architectural pattern? How do I approach technical debt? How do I communicate complex ideas to non-technical stakeholders? The soft skills and the “why” behind my technical decisions were just as important as the code itself.

My Pragmatic Takeaways for Job Seekers

If you're currently navigating this market, here's some advice based on my recent journey.

  1. Your CV is a Story, Not a List: Don't just list technologies. Tell a story of impact. Instead of “Worked on a Laravel API,” try “Developed and maintained a Laravel API that handled X requests per day, leading to a Y% improvement in response times.” Quantify your achievements where you can. As someone with both backend (PHP/Laravel) and frontend (Flutter) skills, I made sure to highlight projects where I successfully bridged that gap.
  2. Specialization is Your Anchor, Versatility is Your Sail: My deep knowledge of Laravel was my anchor—it got me in the door. But my experience with Flutter was my sail—it showed I was adaptable, curious, and could bring a broader perspective. If you have a “T-shaped” skill set, lean into it. It's a significant advantage in a world of full-stack product teams.
  3. Patience is a Strategic Asset: The process will likely take longer than you expect. Rejections, and even “ghosting” after an interview, are part of the game. It's frustrating, but it's not personal. Stay resilient, keep refining your approach, and don't get discouraged.
  4. Know Your Worth, But Be Realistic: Do your research on salaries, but also understand that the leverage has shifted slightly back towards employers. Be prepared to articulate your value clearly to justify your expectations.

What's Next?

I'm incredibly excited about my new role. It's a fantastic opportunity to tackle some new challenges, work with a great team, and dive deep into some interesting technical problems.

And don't worry, The Pragmatic Pixel isn't going anywhere. My passion for exploring the intersection of robust backends and fluid frontends remains, and I'll continue to share my learnings and experiences here.

For anyone else on their own job hunt right now, I wish you the very best of luck. It's a challenging market, but good people with solid skills are always in demand. Be patient, be strategic, and be confident in the value you bring.

Cheers,

Jamie C

 
Read more...

from The Pragmatic Pixel

Hey everyone, Jamie here.

Writing this from my office, which, despite my best efforts, is starting to feel a bit like a greenhouse. It's officially the hottest day of the year so far here in the UK, and you can almost feel the collective groan of the country's infrastructure. Trains run slower, the power grid is under strain, and everyone's looking for a bit of shade.

It's a perfect real-world analogy for what happens to our applications under stress. A sudden spike in traffic from a marketing campaign or a viral moment is the digital equivalent of a heatwave. If your application isn't prepared, it will slow down, buckle, and potentially crash, leading to a poor user experience.

So, while I'm trying to keep my laptop from melting, let's talk about how we can build our Laravel and Flutter apps to handle the heat and perform gracefully under pressure.


The Backend: Your Server's Air Conditioning (Laravel)

When your app gets popular, your Laravel backend takes the first hit. Every user action, every data fetch, adds to the server load. Here are some fundamental ways to keep it cool.

1. Caching is Your Best Friend

Caching is the most effective way to reduce server load. It's like having a cold drink ready instead of having to make it from scratch every single time someone asks.

  • Application Cache: Use Cache::remember() to store the results of expensive operations, like complex database queries or calculations. For data that doesn't change every second (e.g., a list of product categories, a user's profile data), this is a game-changer.
  • Query Caching: Avoid re-running the same database queries over and over. If you have a query that fetches a site-wide settings table, cache it.
  • Configuration & Route Caching: In production, always run php artisan config:cache and php artisan route:cache. This gives Laravel pre-compiled files to work with, saving it from parsing multiple files on every single request.

2. Offload Heavy Lifting to Queues

Does your app send a welcome email, process an uploaded image, or generate a report after a user takes an action? Don't make the user wait for that to finish.

  • Use Laravel Queues: Push these long-running tasks onto a queue. Your controller can then return a response to the user instantly, while a separate queue worker process handles the heavy lifting in the background. This keeps your main application threads free and your app feeling snappy.

3. Database Optimization

A slow database is a boat anchor for your application's performance.

  • Tackle N+1 Problems: This is a classic performance killer. If you have a loop that performs a database query on each iteration, you have an N+1 problem. Use Laravel's Eager Loading (->with('relation')) to fetch all the necessary data in one or two queries instead of dozens. Tools like Laravel Telescope or the Laravel Debugbar are fantastic for spotting these.
  • Add Indexes: Ensure your database tables have indexes on columns that are frequently used in WHERE clauses, joins, or ordering. This is like having a well-organized filing cabinet instead of a giant pile of papers.

The Frontend: A Smooth Experience, Not a Stuttering Mess (Flutter)

A fast backend is great, but if the Flutter app itself is janky or slow to render, the user experience still suffers.

1. Build for Release, Test for Real

Never judge your app's performance based on a debug build. The debug build includes extra checks and assertions that slow things down.

  • Use Release Mode: To get a true sense of performance, run your app in release mode: flutter run --release. This uses AOT (Ahead-Of-Time) compilation and creates a highly optimized build that's representative of what your users will experience.

2. Master the Build Method

The build() method in your widgets is called frequently. Keeping it fast is critical to avoiding “jank” (stuttering animations).

  • Keep build() Methods Pure & Small: The build() method should be free of side effects and focus only on returning a widget tree based on the current state. Break down large build() methods into smaller, dedicated widgets.
  • Use const Widgets: If a part of your widget tree doesn't change, declare it as a const. This tells Flutter it doesn't need to rebuild that widget, saving valuable processing time.

3. Optimize Your Assets

Large images are one of the most common causes of slow-loading screens and high memory usage.

  • Right-Size Your Images: Don't use a massive 4000x3000 pixel image for a 100x100 pixel avatar. Resize images to the maximum size they'll be displayed at.
  • Use Efficient Formats: Consider modern formats like WebP, which often provide better compression than JPEG or PNG.
  • Cache Network Images: Use packages like cached_network_image to cache images fetched from your API, preventing them from being re-downloaded every time they're needed.

Performance isn't an afterthought; it's a feature. Just like you wouldn't build a house in a hot climate without thinking about ventilation, you shouldn't build an app without thinking about how it will perform under stress. By implementing these practices, you're building a more robust, scalable, and professional application that can handle the heat when its moment in the sun arrives.

Right, I think it's time for an ice cream. Stay cool out there!

Cheers,

Jamie C

 
Read more...

from The Pragmatic Pixel

Hey everyone, Jamie here.

We spend a lot of time focusing on building great features, crafting beautiful UIs, and optimizing performance. But beneath all that lies an unseen foundation that's arguably the most critical part of your application: security. A single vulnerability can undermine all of your hard work, compromise user data, and destroy trust.

When you're building a full-stack application with a Laravel API and a Flutter mobile app, security isn't just a backend problem or a frontend problem—it's a shared responsibility across the entire stack. You have to secure the server, the client, and the communication between them.

Let's walk through some pragmatic, essential security practices for our Laravel and Flutter projects.


Securing the Backend (Laravel)

Your Laravel API is the gatekeeper to your data. Protecting it is paramount.

1. Robust Authentication & Authorization

We've talked about using Laravel Sanctum for authenticating our Flutter app, which is a great start. But authentication (who you are) is only half the battle. Authorization (what you're allowed to do) is just as important.

  • Laravel Policies: Use Policies to organize your authorization logic around a particular model or resource. For example, a PostPolicy might have a update method that checks if the currently authenticated user is the author of the post they're trying to edit. This keeps complex permission logic out of your controllers.
  • Don't Trust User IDs from the Request: Never assume user_id in a request body is correct. Always use the authenticated user from the request context: auth()->user() or $request->user().

2. Rigorous Validation is Non-Negotiable

This is your first and most important line of defense. Never, ever trust data coming from the client. Validate everything.

  • Use Form Requests: Encapsulate your validation logic in dedicated Form Request classes. This cleans up your controllers and makes the rules reusable.
  • Be Specific: Don't just validate that a field exists. Validate its type (string, integer), its format (email, date), its size (max:255), and that it's a valid value (e.g., using the Rule::in(['active', 'pending']) rule).

3. Prevent Mass Assignment Vulnerabilities

Mass assignment is when you use Model::create($request->all()) to create a new model. If a malicious user adds an extra field to their request (e.g., "is_admin": true), they could potentially change data you never intended.

  • Use $fillable or $guarded: On your Eloquent models, always define a $fillable array of fields that are safe for mass assignment, or a $guarded array (often ['*'] by default in new projects) to block all fields unless explicitly allowed. protected $fillable = ['title', 'body', 'author_id']; is much safer.

4. Guard Against SQL Injection

The good news is that if you're using Laravel's Eloquent ORM and Query Builder, you are already protected against SQL injection by default because they use parameter binding.

  • The Danger Zone: The risk appears when you write raw SQL queries. If you must use DB::raw() or DB::select(), always use ? placeholders for user input to ensure it's properly bound, never concatenate strings.
    • Safe: DB::select('select * from users where id = ?', [$id]);
    • Unsafe: DB::select("select * from users where id = $id");

5. API Rate Limiting

To protect against brute-force attacks (e.g., someone repeatedly trying to guess a password) or general API abuse, you must limit how many times a user or IP address can hit your endpoints in a given time frame.

  • Use the throttle Middleware: Laravel makes this incredibly easy. You can apply it to routes or route groups in your routes/api.php file.
    • Route::middleware('auth:sanctum', 'throttle:60,1')->group(function () { ... }); // 60 requests per minute

Securing the Frontend (Flutter)

Your Flutter app is in the hands of the user, which means it's in a potentially untrusted environment.

1. Securely Store API Tokens

When your user logs in, your Laravel API gives the Flutter app an API token. Where you store this is critical.

  • Don't use SharedPreferences: This is plain text storage, easily readable on rooted/jailbroken devices.
  • Use flutter_secure_storage: This package uses the Android Keystore and iOS Keychain to store data in an encrypted, hardware-backed secure location. It's the standard for storing sensitive data like API tokens, refresh tokens, or encryption keys.

2. Protect Your Client-Side Keys

What about API keys for services like Google Maps or other third-party SDKs that live in your Flutter app?

  • Minimize Exposure: First, question if the key needs to be on the client at all. For many services, it's far more secure to create a “proxy” endpoint on your Laravel backend. Your Flutter app calls your own API, and your Laravel backend then securely makes the call to the third-party service using a key that never leaves your server.
  • If You Must...: If a key must be in the app, use environment variables with --dart-define at compile time rather than hardcoding it in a committed file. This prevents it from being easily found in your public Git repository.

3. Implement SSL Pinning (For High-Security Apps)

By default, your app trusts any valid SSL certificate. SSL Pinning is an advanced technique where you “pin” the specific certificate of your server within your app. The app will then refuse to connect to any server that doesn't present that exact certificate.

  • What it Prevents: It’s a strong defense against sophisticated man-in-the-middle (MITM) attacks where an attacker might try to intercept traffic using a fraudulent (but technically valid) certificate.
  • Is it for you? This adds maintenance overhead (you must update the app if your server certificate changes). It’s generally reserved for high-security applications like banking or finance apps.

4. Obfuscate Your Code

Flutter makes it easy to obfuscate your compiled Dart code.

  • Use the --obfuscate flag: When building your release app (flutter build apk --obfuscate --split-debug-info=...), this flag scrambles class, method, and field names, making it much harder for someone to decompile your app and understand its internal logic.

Security is a Process

Security isn't a feature you add at the end; it's a mindset you apply throughout the development lifecycle. It's about creating layers of defense. A secure backend can protect a compromised client, and a secure client can be more resilient in a hostile environment. By taking these pragmatic steps, you build a much stronger, more trustworthy foundation for your entire application.

What are your go-to security practices? Let's talk in the comments.

Cheers,

Jamie

 
Read more...

from Virtus Computing

This tutorial continues from the last one in the NotePad app set Basic4Android: Notepad – Part1 (Designing). In this tutorial i am taking the design and adding code to make the app load the text from files and display it in one of the four slots.

App start up

When the app starts up we are going to load in the design with the buttons and the text box in. We are also going to put things into the menu. All of this start up code goes inside the Activity create sub.

Sub Activity_Create(FirstTime As Boolean)
    'Code to run here
End Sub

Loading the layout

First of all loading the layout, all this is done with one line of code which just loads the file we saved in the first tutorial. We made main.bal in the first tutorial and now we are displaying that.

Activity.LoadLayout("main.bal")

Adding menu items

Adding menu items is very simple, we are going to add three menu items Clear, Save, Exit. These will only appear when the menu button is pressed so it saves on screen space. It is one line of code for each menu item. We are only using text items so the line of code is this:

Activity.AddMenuItem("title", "event")

The title is what you want the menu button to say example “Clear” and the event is where you want to run the code example “clear” which would run the sub “clear_Click”. We are adding the three menu items below:

	Activity.AddMenuItem("Clear", "clear")
	Activity.AddMenuItem("Save", "save")
	Activity.AddMenuItem("Exit", "exit")

Loading the slots

When each slot button is pressed two things will happen.

  • The data for that slot will be loaded and displayed.
  • The strings will be changed so that when saved the data is saved to the right slot. We will do the second one first as it is the simplest to do and requires only a few lines of code. First we need to set up the variable to store which slot is open. To do this we Dim the string in the Globals sub. Inside there under the setting up of the buttons and text box add the two lines. Dim slot As String slot = "0" That line lets the program know that if slot is used that it is a bit of data. Right under that line we are going to set slot to 0. This is because we don’t want bugs when a user clicks save straight away. Now we need to put a bit of code into each button so that the slot string changes. For example the button for slot 1 will be: Sub slot1_Click slot = "1" End Sub This needs to be added to all of the other subs, they should have been generated in the first tutorial, so all you need to do is add the second line to each sub. Remember to change the number so that slot2_Click contains slot = “2″ and so on.

Now we need to load the data for each slot. This is very simple to do we just need to load a text file when each button is clicked. this is done in one line, but we are going to make sure the file is there before opening to stop any errors. So under the line above we need to check for a file like this:

If File.Exists(File.DirInternal,"notepadapp-slot" & slot & ".txt") Then
    	notepadbox.Text = File.ReadString(File.DirInternal, "notepadapp-slot" & slot & ".txt")
	ToastMessageShow("Data loaded for slot " & slot & ".", True)
Else
	notepadbox.Text = "There is no data for slot" & slot
	ToastMessageShow("No data loaded for slot " & slot & ".", True)
End If

That code checks to see if the file notepadapp-slow1.txt is there, if it is then it will load the data into the text box. If not then it will display a message. The slot can still be loaded without there being data, and when it is saved for the first time it will create that file for the next time. That code needs to be put in all the four slot buttons and does not need to be modified.

Saving the slots

saving the slots is very easy, it is again just one line of code to do so. You will need to create a new sub like below with the following code inside. It can be anywhere in the code i added it at the bottom.

Sub save_click
	File.WriteString(File.DirInternal, "notepadapp-slot" & slot & ".txt", notepadbox.Text)
	ToastMessageShow("Data saved for slot " & slot & ".", True)
End Sub

The Clear button

The clear button just resets the files to default and removes all the data from it, it is only a few lines of code. it sets the text box to having no data and then writes that to the file. A new sub is need for the clear button just like with save.

Sub clear_click
	notepadbox.Text = "There is no data for slot" & slot
	File.WriteString(File.DirInternal, "notepadapp-slot" & slot & ".txt", notepadbox.Text)
	ToastMessageShow("Data deleted for slot " & slot & ".", True)
End Sub

The exit button

The last button in the menu is the exit button, this is to fully stop the program and not leave it running in the background. I like this in my apps so i can close them and speed up my phone and save battery. The code is very simple and uses a new sub.

Sub exit_Click
	Activity.Finish
	ExitApplication
End Sub

Finishing off

The app now fully works, there is one last thing i want to do to make it work better across phones with big screens. There are many things that can be edited along with colors designs, and loading the slots in a list box. This is the trick i used to make it better on bigger phones it just makes the text box adjust to the screen size, this code goes right after the menu code near the top.

notepadbox.Width = Activity.Width
notepadbox.Height = (Activity.Height - 50)

Done

That is now the app working fully. There is many things that can be added and made better, but this is a working android program that uses files to store data.

Screenshots

notepadappscreenshot (1) notepadappscreenshot (2) notepadappscreenshot (3)

End result

The app on Google Play

Written by Zachary.

 
Read more...

from Virtus Computing

In this set of tutorials i will go through how to make a notepad app. A very simple one with 4 slots and a text box to edit the text in them slots. It will save the data on the SD card if there is one and on the phone if not. I will have settings to change fonts and colours for each slot. This tutorial will be split into 2 parts:

  • Designing
  • Saving and loading slots

After that i will go on to add more functions and explain more things that can be done in B4A and how to use them.

Application settings.

First of all open up B4A and click save, this is because you can not use the GUI designer without saving it first. I recamend making a new folder to save it in like NotepadApp. Put the file name as notepad and click save. Saving the Notepad app.

When it is saved we can start to set up the settings of the app, Like the Name, Icon and Version number. Got to Project and select Choose Icon. Then select the icon from your computer. I am going to use a simple one i found on the internet. (You can download it here)

The next thing we want to edit is Package Name, this is a unique field that identifies your app and will be different from all other apps. Most of the time Developers put this to:

*appname*.*developername*.*companyname*

That is because it has to conation at least two words with a dot between them, it must all be lowercase. In this tutorial i am going to set mine to notepad.virtuscomputing.tutorial. You may use that name as well.

The last one we are going to change today is the Application Label, This is the name of your app and the one that is displayed on the app draw, in your settings, and on the top of the app. I set mine to NotePad.

Designing.

Now we can open up the designer and start to build the GUI. It will be one big Text-box with a tab host along the top. There will be a menu with a Save, Clear and Exit buttons on it. This will be most of the app interface for now. Open up the designer and click Add View then Edit Text, Drag it around the form with the square in the corners. It needs to fit the entire screen, starting from 50 from the top going all the way down to the bottom. You can then add 4 buttons and spread them across the gap left in the top. To make our code easy to read and understand rename the buttons to slot1, slot2, slot3, slot4. And the textbox to notepadbox. This is done by selecting the item, and looking at the top of the list of propities and changing the Name field.

Notepad Design Form

You should end up with something like the form above. At this point you can move thigs around to how you want them to be. Then click File –> Save, and name it main. Once this is done there is one more thing we need to do before starting to code the app. Select Tools –> Generate Members. When the new form opens up Select all views to select all the boxes. On slot1, slot2, slot3, and slot4 open then with the little + to one side and select the box for Click. Once this is done for all of them press Generate Members.

Notepad Generating Members

This inserts all the code into the file to make all them forms appear That is the last of the designing for now. You can move things around in the designer and make them look how you want.

All the code is in Basic4Android: Notepad – Part2 (Code)

Written by Zachary.

 
Read more...

from Virtus Computing

To make the test application we are just going to do the hello world app. This just prints the words hello world on the form to prove that it works. When you clickt he text hello world it will change, just to show how events are handled.

To start when you open Basic4Android it gives you a set of code already. We will be using this code to click Save and select where you want to save the project and all its files. I recommend making a new folder just for the project. Then name the project what you want. here is it called Testing for Tutorial then click save.

After we have save the project the file is created with a .b4a on the end (as seen in the picture above). Once we have saved we can now open up the designer, Click Designer on the menu bar. Two new windows will open up like the below. One of them (The bigger one) Is the control properties window. The other is the Designer.

You can now click Add New and then Label. It inserts the label onto the form and called it Label1 You can drag this around and re size it if you want to (When the item is clicked on the properties window you can change the test font and size. You can input the text there, but we are going to do it programmatic for now. Right click on the label and hover over Generate then Dim Label1 As Label, Then do that again but select Click this time.

Once that has been done we can save the layout, Click File then Save and give the layout a name of main and click Ok. The window should look like the one below.

Once we have done that we can close the designer and begin on the code. There is not allot of code for this program. The first bit it to load the label one we start the program. And then to print text into the label.

Sub Activity_Create(FirstTime AsBoolean)
Activity.LoadLayout("main")
'The line above is to load in the layout we made, remember the name "main"
Label1.Text = "Hello World"
'The line above print the text "Hello World" onto label1
End Sub

The code above should replace the code already in the Activity_Create. The code below is to change the text when the user clicks on the label.

Sub Label1_Click
Label1.Text = "I've been clicked"
'The line above print the text "I've been clicked" onto label1
End Sub

The code above should replace whats in Label1_Click. When the activity is started it calls the first bit of code which sets up the windows and loads in the forms. It then prints the first bit of text to the label. When the label is clicked it calls the second bit of code which changes the text. Make sure to save at this point!

Testing on a android device

If you are using a physical android device then connect it to the same WiFi to the computer(this is the way i do it) Download the Program to your phone (The Basic4Android Bridge linked in the top) Then run it, it needs to configuration and should have some buttons on there. Click the button that says Start – Wireless, it should then start the service. It will say “waiting for connections” when it is ready. Then go to your computer and in basic for android go to Tools then B4A Bridge then Connect – Wireless.

It will prompt you for an IP, This is displayed on your phone and should be something like 192.168.1.68. Type it in and click connect.

If it has worked your phone will say connected.

If it has worked then you can now click the Blue Arrow on basic for android and it will compile the application. When it is done your device will prompt you to install the app automatically. But the APK file is in /objects/Testing for Tutorial.apk so you can send it to your device another way.

Installing the app on the phone. You need to click Install at the first screen, It will then install the application

After it has installed you can Open or Done, You want to open it and make sure it has worked. If you click the label the text will change.

Make sure to press Stop on B4A Bridge to save your battery when you are done.

Written by Zachary.

 
Read more...

from Virtus Computing

Basic4Android is a very useful program to write applications for the android operating system. It runs on windows and has a very similar feel to VB.net. The IDE is very clean and easy to use. And with the remote bridge software you can install the applications straight to a mobile device.

Getting all the files.

Java JDK 7 (32-bit or 64-bit)

http://www.oracle.com/technetwork/java/javase/downloads/jdk7u9-downloads-1859576.html

Android SDK

http://dl.google.com/android/installer_r20.0.3-windows.exe

Basic4Android trail setup (If you have bought it then use the setup sent in the email)

Enterprise Standard (Trial)

Basic4Android Bridge (From the market onto your phone – Optional)

https://play.google.com/store/apps/details?id=anywheresoftware.b4a.b4abridge (http://vcurl.co/?i=f2ea)

Installing

Java

Installing java first as everything needs it. To install java i find it is best to uninstall any Java things you have previously installed. That way you are starting from scratch. Once it has been uninstalled run the Java setup program and install Java to the default place. (The Java JDK development tools will still work for any other java resource. including your browser) Once the Java install has completed do not restart your computer.

Android SDK

Installing the android SDK is a little more complicated. Run the setup and follow through the instructions. Install it all to the default place after the install has completed go to your Start menu and find the “SDK Manager” run that and wait while it starts up (This can take some time). Once it has started up wait for it to refresh the package lists. One it has done select. Android 4.1 (And all that’s inside it) Then click Install packages… You will have to select Agree and Install. Then the bar at the bottom will show the progress of the installation.

Basic4Android

One everything else is installed, i recommend you have restarted before installing Basic4Android. If you are installing the trail then you need to run the file you downloaded at the top. If you have bought it then download the file from your emails and download that file to install. When running the file just install the the default places.

Configuration

When all programs are installed, it is time to configure Basic4Android to work with the Android SDK, and Java JRE. Doing this is very simple and it is only inputting two file paths. One for the javaac.exe and the other for android.jar. To do this open up Basic4Android, Once it has loaded (you will have to select Trail, unless you have a key in which case select the key). Go to Tools then Configure Paths

After you click that you are presented with the window below. You need to locate the two files it says about. It has a location of where they should be but i found that it is not there anymore. Click browse to find the files. Which for me are in these locations (Just remember to change to your username, and correct versions.)

C:\Program Files\Java\jdk1.7.0_07\bin\javac.exe

C:\Users\Zachary Claret-Scott\AppData\Local\Android\android-sdk\platforms\android-16\android.jar

The Additional Libraries folder is if you want to specify an extra folder for it to look for them. It already looks in the program files for them and that’s were we will place them. I will cover libraries in other posts but they allow you to do more stuff like tracking the usages of an app, or talk to ftp.

In the next Guide i will Talk about how to make a application. (Here)

Written by Zachary.

 
Read more...

from keleven

Hopefully this blog will chart my motorbike rides on my trusty Royal Enfield 350 Classic.

I might add other things that I find interesting, then I might not.

 
Read more...

from Zachary Claret-Scott

#music #spotify #lastfm #data

I’ve been tracking my music listening habits for decades on last.fm ever since my dad introduced me to the platform – it’s great to see what music I listened to overtime.

I used to use last.fm daily to find new music by exploring radios, in a time before streaming when ripping mp3s of disk (or online) was king it was the best way to find new music. Once Spotify took over I dumped my local music collection and exclusively listened to streamed music, I had my last.fm connected and mostly ignored it while it silently collected my data.

I’m not sure when last.fm changed but it’s a far throw from its glory days now and it’s hard to see really simple stats about my listening history without signing up for a pro membership. Recently I found an alternative which is exclusive to Spotify called YourSpotify. It is self hosted and pulls recent listening data in real time from the Spotify API but requires a data export from Spotify (which takes up to 30 days) for full historic listening data.

Cover Image

 
Read more...

from Zachary Claret-Scott

#services #selfhosted #homelab

I have wanted to host my own fediverse/activity pub compatible server for a while – however I felt running a full on Mastodon server was to heavy for my use case. And other options seemed to take a bit too much effort to host for my liking.

I had all but given up until I came across Write Freely which is a blog focused platform that just so happens to share posts via activity pub. Setting it up was super simple as a single docker container and it supports single user mode, or multi user mode with very basic permissions.

I have put it up on a spare domain which I can use as my federated username @prra.xyz because it is generic I can also use it as a social media post engine for all my company accounts.

Cover Image

 
Read more...

from Zachary Claret-Scott

#services #selfhosted #jobs #career #softwaredeveloper

I am due to start a new role next week which I am very excited for, but before I confirmed I had to go through the process of trying to find roles available in my industry and area. While sites like Indeed, and LinkedIn have vast amount of job postings I found them difficult to navigate and often out of date – or companies straight up don't post to them.

I have a list of local companies or companies in my ideal sector which I would like to work for, you could call this my list of dream jobs. It includes some interesting tech startups nearby, charities I like the mission off etc.. Most of these organisations have a careers page which I can visit to see any open roles, but it's hard work checking 15 or so job pages every few days to see if anything has opened up.

Thats where some self hosted software came into play, I setup my own instance of Change Detection and loaded in all of the companies I wanted to track. Now twice a day I get an email if any of them post new job listings, even if they don't post those roles to large job sites.

Cover Image

 
Read more...