Category Archives: Mobile Apps

BC TechTalk TODAY!

Finally, it is here! Another conference about Business Central is here and due to COVID-19, it’s online and totally free.

Check all amazing sessions from best speakers from the Business Central world. The agenda is on the web HERE.

And if you are interested in mobile development for Business Central, definitely come to my session on Friday 04/12/2020 at 17:00 (track 1)!

Session on BC TechTalk about Business Central mobile development

I have a session on the upcoming online conference BC Tech Talks about an exciting topic – Build your own mobile app for Business Central!

Event for the Technical BC People

BC TechTalk is a 2 day FREE online summit for the technical Business Central people: developers, technical decision makers, projects managers, IT managers, working for Microsoft partners or customers, freelancers, trainers. It‘s a technical content driven event, a place where technical people exchange ideas, where MVP and BC professionals will deliver latest content and findings. For anyone around the world passionate about Microsoft Business Central.

Each day will have 2 tracks and 8-10 sessions, for different level technical people. We will have 16 speakers and we aim for up to 1,200 attendees. There will be a networking platform to share your ideas, questions and experience.

https://bctechtalk.com/

Dart & Flutter: Use of REST GET method

This chapter we will continue with the project that we created before. The project could be found on GitHub.

Now when we have a runnable app with homepage and standardized navigation, we can look on how to load data using REST. We will start with the basic example of GET method and, in the next chapter, we will move to a more advance example.

Firstly, we need to allow using an HTTP package. To do that, we have to add one line in pubspec.yaml in the root directory. You can add a newer version if exists (check here).

 http: ^0.12.2

Then we need to allow access for the app to the Internet using uses-permission in AndroidManifest.xml.

 <uses-permission android:name="android.permission.INTERNET" />

Now we can start. Our goal is to download email from this REST API. To process a request, we have to use some new keywords in Dart – Future, async and await.

Future, async & await

The Future is an object that represents a (potential) value, that will be obtained somehow in the future. In other words, this object promise (yes, I used this term because it is very similar construction) to our app that sometimes in the future, there will be an object of this specific type. Which object will be available is specified using structure Future where the T is the type of the object.

Async and await are special constructions (keywords) define how to create and use asynchronous functions. If we want to create an asynchronous function, we have to add async keyword before the function body. In the same way, if we want to call function asynchronously (that is only possible from functions declared as async) we add a keyword await before the function call.

 Future<int> loadData() async {
   return await sleepAndLoadData();
 }

Example

Now, as we know all necessities, we can go directly to our example. We create an async function fetchRESTTestData using Future where T will be a model class using which we store downloaded data.

As you see, the REST call is straightforward. We just use async get function from HTTP package.

 import 'dart:convert' as JSON;
 import 'package:http/http.dart' as http;

 Future<RESTTestData> fetchRESTTestData() async {

   final response =
       await http.get('https://jsonplaceholder.typicode.com/comments/1');

   if (response.statusCode == 200) {
     return RESTTestData.fromJson(JSON.jsonDecode(response.body));
   } else {
     throw Exception('Failed to load album');
   }
 }

 class RESTTestData {
   final int postId;
   final int id;
   final String name;
   final String email;
   final String body;

   RESTTestData({
     this.postId,
     this.id,
     this.name,
     this.email,
     this.body,
   });

   factory RESTTestData.fromJson(Map<String, dynamic> json) {
     return RESTTestData(
       postId: json['postId'],
       id: json['id'],
       name: json['name'],
       email: json['email'],
       body: json['body'],
     );
   }
 }

Then we have to add our new functionality to the UI. We will use our home page that we made earlier for a start. Firstly, we need to obtain data using our function that we just created and store them in a class variable. To achieve that we use function initState on our HomePage. This method is called only once when the state is initialized (in our example, when we open the app or open the home page from the menu).

   @override
   void initState() {
     super.initState();
     futureRESTTestData = fetchRESTTestData();
   }

It is done in the same way as any other element using the Builder class. As we are working with Future object (that hold our REST data), we need to work with FutureBuilder.

             FutureBuilder<RESTTestData>(
               future: futureRESTTestData,
               builder: (context, snapshot) {
                 if (snapshot.hasData) {
                   return Text("Data from REST: " + snapshot.data.email);
                 }
                 return CircularProgressIndicator();
               },
             ),

And that’s all! We can build the app and upload it on our Android device or run it using the emulator. You can see the final result on the emulator picture below.

All related changes described above are on my GitHub.

Dart & Flutter: Project Initialization

We have already prepared development environment and Android Emulators in previous articles. In this chapter, we will look at how to create a new project and on the generated files.

To start with, open Visual Studio Code (or any other support development environment) and run the command “Flutter: New Project”. Once we have created a new project, we should see something simulator to the picture below.

There are many files in the root directory in the newly generated project. Some of the files are generally known (like .gitignore, I will skip them) some are specific to Flutter.

Subdirectories

  • android
    • This directory contains all the Android related files. The most important things to know is that in this directory (directories), the resources like icons or images are stored.
    • From the configuration files, the most important is “AndroidManifest.xml” that specifies everything related just to Android (for example system permissions that to the app requires to run)
  • ios
    • Similar to the android directory. As these articles are focus on the Android app, I will skip the directory.
  • lib
    • The main folder where we should write the application code. There are some patterns of how the files should be structured in this directory on which we will look in some of the next articles.
  • test
    • This folder is used to store and manage testing code for the application.

Files in the root directory

  • .metadata
    • This file tracks properties of the Flutter project and should not be changed manually.
  • .packages
    • This file is generated automatically by Pub (Flutter package manager), and like the previous file, it should not be changed manually.
  • pubspec.lock
    • Similar file to .packages, used by Pub to get the concrete versions for every used package or dependency.
  • pubspec.yaml
    • This is probably the only file we will sometimes change in the future. The file specifies all flutter packages we have available. If we need to add a new third-party package (for example HTTP), we should do it in this file.
  • tka_demo.iml
    • Auto-Generated file specifying internal project properties.

main.dart file

 import 'package:flutter/material.dart';

 void main() {
   runApp(MyApp());
 }

 class MyApp extends StatelessWidget {
   @override
   Widget build(BuildContext context) {
     return MaterialApp(
       title: 'Flutter Demo',
       theme: ThemeData(
         primarySwatch: Colors.blue,
         visualDensity: VisualDensity.adaptivePlatformDensity,
       ),
       home: MyHomePage(title: 'Flutter Demo Home Page'),
     );
   }
 }

 class MyHomePage extends StatefulWidget {
   MyHomePage({Key key, this.title}) : super(key: key);

   final String title;

   @override
   _MyHomePageState createState() => _MyHomePageState();
 }

 class _MyHomePageState extends State<MyHomePage> {
   int _counter = 0;

   void _incrementCounter() {
     setState(() {
       _counter++;
     });
   }

   @override
   Widget build(BuildContext context) {
     return Scaffold(
       appBar: AppBar(
         title: Text(widget.title),
       ),
       body: Center(
         child: Column(
           mainAxisAlignment: MainAxisAlignment.center,
           children: <Widget>[
             Text(
               'You have pushed the button this many times:',
             ),
             Text(
               '$_counter',
               style: Theme.of(context).textTheme.headline4,
             ),
           ],
         ),
       ),
       floatingActionButton: FloatingActionButton(
         onPressed: _incrementCounter,
         tooltip: 'Increment',
         child: Icon(Icons.add),
       ),
     );
   }
 }

Dart & Flutter: Setup Android emulator and Android device

Application development is not possible without testing. For mobile development there are two primary possibilities – test the application on a mobile device with Android or using Android emulator.

If you have an Android device (especially the one for which you are developing) it’s usually better to work with this device; however, in many cases, we do not have such opportunity hence we use emulators.

Using Android Mobile Device

To use your own device you have to allow USB debugging (https://developer.android.com/studio/debug/dev-options), connect the device to the computer and authorize your computer to access the device.

Using Android Emulator

Android emulator is a great tool for developing mobile apps; however, the most problematic part is that, like any other emulator, needs a lot of system resources.

How to set up

  1. Enable VM acceleration on your machine (if possible).
  2. Open “Android Studio”, click on the “AVD Manager” (under “Configure”) and select “Create Virtual Device…”.
  3. Choose a device that you want (or that is the most similar to the one you want). In case you need a different device setting, you can use “New Hardware profile” that allows defining configuration manually. For example, as I’m currently working with two devices (Honeywell ScanPal EDA51 and CipherLab RK25) which both have a different configuration from all presets, I had to configure emulators manually.
  4. Choose a system image for the Android version you want to emulate.
  5. Verify setting and continue with “Finish”.