Note:

If you want to create a new page for developers, you should create it on the Moodle Developer Resource site.

Moodle Mobile remote add-on tutorial

From MoodleDocs

Introduction

This tutorial tells you how to set up to develop a Moodle Mobile remote add-on for the Moodle mobile app. That's what you need to do if you've written a custom plugin and you want it to work in the mobile app.

  • This is an unofficial tutorial. There is plenty of official documentation, which is linked throughout this tutorial; this tutorial just pulls together the necessary information for this specific task.

This page assumes that you know how to develop for Moodle and are already set up for that, but you know nothing about developing mobile apps in general or the Moodle on specifically. Some of the detailed instructions might assume you are using Windows but it should work on other platforms too.

  • Note: The mobile app is about to change significantly (with Moodle 3.5) so you might not want to do this yet!

Overview

This overview describes the steps which will be covered in detail below.

You will first need to:

  • 1 Configure your developer Moodle to allow mobile access.

There is some additional configuration you can do in Moodle, which is covered under this heading, although you probably want to do it later.

You should then:

  • 2 Set up an emulator and install the real app from the Play Store so you can try it out.

(You can skip this step and use a real device if you prefer, provided you are connected to a wi-fi network that can access your Moodle developer server.)

At this point, you can try out the real app:

  • 3 In the app, connect to your dev server.

You will need to set up the Moodle mobile app development:

  • 4 Check out the Moodle mobile app project and run it using Ionic.

You can then access the app using an ordinary Chrome browser window.

Once the development environment is set up and working, you can create a custom plugin (add-on).

  • 5 Create an add-on within the Moodle Mobile app.

When your add-on is finished and working, you can package it in a zip file within the main Moodle plugin repository.

  • 6 Package your add-on as a 'remote add-on' within a Moodle plugin.

Step 1 - Moodle setup

  • Under mobile app / mobile settings, turn on the 'enablemobilewebservice' option.
  • If your Moodle site uses a non-standard authentication plugin, you will need to make it possible to log in using standard Moodle manual authentication, and you'll need a manual account to log in with. (In time, you will probably want to sort out the authentication, but best to leave that until later.)

Customisation

Some customisation options are available in the Moodle settings. These are generally more relevant to administrators than when implementing a single plugin, but here's a quick summary.

Language strings

You can customise app language strings under Mobile app / Mobile features. There is a full list of lang strings for the app. This seems to work as expected.

CSS

You can customise app CSS by providing a URL to a CSS file on the mobile features page.

Turning things off

You can turn off parts of the app using the settings page. This allows almost everything to be turned off. It also allows any custom plugins to be turned off as well.

Step 2 - Emulator setup

To simplify networking, it may be easiest to use an emulator running on your PC (you can also use a real device, provided that it can connect to your developer server).

Android emulator installation and setup

Set up the Android emulator as follows.

  • Download and install Android Studio: https://developer.android.com/studio/.
    • The download took about 10 minutes on my system.
    • After that, the installer takes ages to even load.
    • Accept all default options in the installer.
    • Total installation time was just over 20 minutes.
  • Run Android Studio.
    • Choose the option not to import settings.
    • It takes another minute or two to load.
  • The setup wizard then appears.
    • Choose 'Standard' and then 'Next' through it until you can Finish.
    • It now downloads even more stuff.
    • There's a fun part where your screen flashes black.
  • Click 'Start a new Android Studio project'
    • Click 'Next' through everything, leaving it default, until you can Finish.
    • This also takes a minute or two.
    • If you get a firewall prompt, click 'allow access'.
  • Click the 'AVD Manager' icon in the toolbar - it's toward the right of the toolbar, just to the right of a large grey rectangle icon.
    • Click 'Create a device'
    • Choose a device that supports the Play Store; currently there are two. I chose Nexus 5. Click Next.
    • Choose a system image that supports Google Play. I chose the latest, O (API level 26). Click Download.
    • Click both items on the left and choose 'Accept' for each, then continue. The install again takes a while (don't believe the progress bar). When it actually does finish, you can click 'Finish', and then 'Next' on the underlying screen.
    • On the 'Verify configuration' screen, just hit Finish.
    • The 'Your virtual devices' screen should now show the virtual phone you just created.

Launching the emulator

Once you have set up Android Studio, you can run it again at any time. Then, to launch the phone:

  • Click the 'AVD Manager' icon.
  • Click the green Play icon next to the virtual device you created.
  • When the 'Android Emulator' window appears, you can close Android Studio (you're going to need all the RAM you can get).

Virtual phone setup

When the phone starts up you can click into the Play Store.

  • Note: In the emulator, you can type with your computer keyboard, you don't have to use the on-screen keyboard.

You'll need a real Google account - I have one using my work email address so that I don't have to share my 'real' one, and I'd recommend you do the same. You can then search 'Moodle Mobile' (by Moodle Pty Ltd) and install it as normal. If you get prompted for a credit card, don't worry, at present you can use the 'skip' option.

Step 3 - Using the mobile app

  • When the app runs, you can type in the URL of your Moodle site, for example https://myserver.example.com/moodle/.
    • If you get an error it will be at the bottom of the screen, for example: 'Mobile Services are not enabled in your site'. (See below.)
  • You then have to type the username and password of a user account. I tried a test student account.

When you make changes to settings on your developer site, you will probably need to re-synchronise to see them. To do this, from the main menu, choose App settings, Synchronization, and click the Reload button next to your site. If you've not done this before you may need to turn off the 'Allow sync only when on Wi-Fi' option, and also exit the menu and come back, before doing it.

Step 4 - Mobile app development setup

(Instructions based on Setting up your development environment for Moodle Mobile 2.)

Component installation

Update NPM in case you're using an old version, and clear the cache (I don't know why):

npm install -g npm
npm cache clean

Install Cordova and Ionic, and then other dependencies:

npm install -g cordova@6.5.0 ionic@2.2.3
npm install -g bower
npm install -g gulp

Repository setup

Clone the repo into a new folder:

cd [your workspace root]
git clone -o upstream https://github.com/moodlehq/moodleapp.git moodleapp

Workspace setup

cd moodleapp
npm run setup

(Ignore warnings.)

Set it up in your IDE

The process will differ based on the IDE you use. In PHPstorm:

  • File / New project
  • Choose 'Angular JS'
  • Choose the workspace folder, then choose to use existing sources.

Run the app

ionic serve --address localhost --browser=chrome
  • This is how you run the app each time.
  • It will start Chrome if it isn't already running, or open a new tab in the existing one, with the app.

Step 5 - Create an add-on within the Moodle Mobile app

This is the actual development work. You're going to need to learn a bunch of stuff in order to do the development.

Useful links

The app uses Angular 1 and Ionic 1 at present. (This may change.)

Basic plugin example

Here's an example of how to set up a very basic plugin. We're going to create a completely bogus mobile app add-on in the 'tool_ouadmin' Moodle plugin. You can actually use any Moodle plugin you like, for example the one you're trying to add mobile support for. If you just want to do the tutorial on standard Moodle, pick any plugin that doesn't already have mobile app support.

  • Create a new folder inside www/addons with the same name as the plugin (tool_ouadmin).
  • Inside the folder, create subfolders with these names: controllers, lang, services, templates.
  • Create the following files (note these should also have boilerplate comments at top of each file which I've removed for brevity):

controllers/helloworld.js

angular.module('mm.addons.tool_ouadmin')

/**
 * Hello world page controller.
 *
 * @module mm.addons.tool_ouadmin
 * @ngdoc controller
 * @name mmaModForumDiscussionsCtrl
 */
.controller('mmaToolOuadminHelloWorldCtrl', function($scope, $stateParams, $translate) {
    $scope.title = $translate.instant('mma.tool_ouadmin.helloworld_title');
});

lang/en.json

{
    "helloworld_title": "Greetings earthlings",
    "helloworld": "Please take us to your leader.",
    "menuname": "Hello world"
}

services/handlers.js

angular.module('mm.addons.tool_ouadmin')

/**
 * Course completion handlers factory.
 *
 * This factory holds the different handlers used for delegates.
 *
 * @module mm.addons.tool_ouadmin
 * @ngdoc service
 * @name $mmaToolOuadminHandlers
 */
.factory('$mmaToolOuadminHandlers', function() {

    var self = {};

    /**
     * Side menu nav handler.
     *
     * @module mm.addons.tool_ouadmin
     * @ngdoc method
     * @name $mmaToolOuadminHandlers#sideMenuNav
     */
    self.sideMenuNav = function() {

        var self = {};

        /**
         * Check if handler is enabled.
         *
         * @return {Promise|Boolean} If handler is enabled returns a resolved promise. If it's not it can return a
         *                           rejected promise or false.
         */
        self.isEnabled = function() {
            return Promise.resolve(true);
        };

        /**
         * Get the controller.
         *
         * @return {Object} Controller.
         */
        self.getController = function() {

            /**
             * Side menu nav handler controller.
             *
             * @module mm.addons.tool_ouadmin
             * @ngdoc controller
             * @name $mmaToolOuadminHandlers#sideMenuNav:controller
             */
            return function($scope) {
                $scope.icon = 'ion-social-tux';
                $scope.title = 'mma.tool_ouadmin.menuname';
                $scope.state = 'site.tool_ouadmin';
                $scope.class = 'mma-tool_ouadmin-handler';
            };
        };

        return self;
    };

    return self;
});

templates/helloworld.html

<ion-view>
    <ion-nav-title><mm-format-text watch="true">{{ title }}</mm-format-text></ion-nav-title>
    <mm-split-view component="mmaToolOuadminHelloWorld">
        <ion-content mm-state-class>
            <ul class="list">
                <li class="card">
                    <article>
                        <div class="item item-body">
                            <p>{{ 'mma.tool_ouadmin.helloworld' | translate }}</p>
                        </div>
                    </article>
                </li>
            </ul>
        </ion-content>
    </mm-split-view>
</ion-view>

main.js

angular.module('mm.addons.tool_ouadmin', [])

.constant('mmaToolOuadminPriority', 900)

.config(function($stateProvider) {

    $stateProvider

    .state('site.tool_ouadmin', {
        url: '/tool_ouadmin',
        params: {
        },
        views: {
            'site': {
                controller: 'mmaToolOuadminHelloWorldCtrl',
                templateUrl: 'addons/tool_ouadmin/templates/helloworld.html'
            }
        }
    });

})

.config(function($mmSideMenuDelegateProvider, mmaToolOuadminPriority) {
    // Register side menu addon.
    $mmSideMenuDelegateProvider.registerNavHandler('mmaToolOuadmin', '$mmaToolOuadminHandlers.sideMenuNav',
            mmaToolOuadminPriority);
});

Trying the new app

If you reload the app (in the Chrome window showing your developer version from Ionic), it should now have a 'Hello world' icon in the main menu that shows the message.

What's missing?

This is a very minimal app. Your real plugin will probably need to do several other things, such as:

  • Implement web services within your Moodle plugin to provide and manipulate data for the app.
  • Attach to different parts of the UI (for example the course menu instead of the main menu) and implement a more complex UI in your add-on, using Ionic framework features.

Some of these are covered in the Moodle Mobile Developing a plugin tutorial.

Step 6 - Packaging the add-on as a remote add-on

Creating the package

You need to package the add-on into a zip file. Let's take the given example, which is in the www/admins/tool_ouadmin folder.

  • In a command prompt, change directory to the root of the moodleapp project folder.
  • Run (replacing the path with your addon's path):
gulp remoteaddon -p www/addons/tool_ouadmin
  • If you get this error:
    • Error: ENOTEMPTY: directory not empty, rmdir 'C:\Users\whoever\workspace\moodleapp\www\addons\tool_ouadmin\rapackage
  • Then delete the directory and try again.

When that works, you'll have a file called tool_ouadmin.zip in www/addons/tool_ouadmin. Including the package in Moodle

Putting the package in your Moodle installation

Create a file called db/mobile.php in your plugin, as follows:

   $addons = [
       'tool_ouadmin' => [
           'dependencies' => []
       ]
   ];
  • Place the zip file (must be called tool_ouadmin.zip, i.e. must match the value in the addons list) in a new folder called mobile inside your plugin.
  • Purge all caches, or increase the version for your plugin, and visit admin to update.

It is possible to include more than one add-on within your plugin by adding multiple entries to the array. This could be useful if you want to allow administrators to turn them on/off individually, or simply to develop in a more compartmentalised manner.

Testing the package in the real app

After putting in the zip file and purging caches, you can then re-run the real mobile app (in the emulator or on a device). It will automatically download the add-on, and you can see the 'Hello world' option in the main menu. It should work: