Home » Uncategorized » A Login template for App Inventor (part 2)

A Login template for App Inventor (part 2)


Code blocks

NOTE:

This post was initially published for AppInventor classic. Currently sources are available also for AI2 but unless explicitly noted comments and images correspond still to classic version since the app is roughly the same.

This post completes the tutorial for creating a login template. In part 1 we designed the user interface. Now we’re going to add the code necessary for it to work!

The following image depicts the blocks for all the functionalities:

logintutorial_31

The blocks editor layout intends to be organized in a way that facilitates its comprehension:

  • Constants: Variables with an initial value that does not change. According to the standard programming convention their name is fully written with capital letters and the character “_” is used to separate words.
  • Variables: Variables that change over time. They are typically initialized in the initializations functions (see below). By convention they have a prefix indicating their type (s: text, i: number, lst: list, b: boolean)
  • Auxiliary functions: General purpose procedures shared by different functionalities
  • General events: Events captured during the screen execution

  • One column for each of the functionalities: Login dialog, Register dialog, Send password dialog, Goggle login interface, Menu

Constants

logintutorial_32

  • C_BLUE, C_CYAN, C_ORANGE, C_GREEN, C_RED: Some customized colors for the menu. For example:

logintutorial_33

NOTE: These colors are taken from the palette defined in the google style guide for android

  • C_BLUE_SEL, C_CYAN_SEL, C_ORANGE_SEL, C_GREEN_SEL, C_RED_SEL: Some more colors, slightly lighter than the previous ones. They’re used to change the menu option color when pressed.
  • CLIENT_ID, CLIENT_SECRET, RESPONSE_OK, RESPONSE_DENIED: Constant values for the Google Login functionality explained in the tutorial How to redirect to the Google login.
  • SCR_LOGIN, SCR_REG, SCR_SEND, SCR_HELP, SCR_GOOGLE, SCR_MAIN: We associate a numeric value to each window. This is used in the screen management tutorial to make code more readable (e.g. the sentence “CurrentScreen = SCR_MAIN” is much easier to understand than “CurrentScreen = 1
  • DATA_PWD, DATA_MAIL, DATA_SENDMAIL: We associate a numeric value to the fields stored in the database. This is used to make the code more readable (e.g. when this information is stored in a list we can obtain “SELECT LIST ITEM list DATA_MAIL” which is easier to understand than “SELECT LIST ITEM list 2”). This way, to add a new field to the database we simply need to create a new constant with a significant name and assign to it the first available number.
  • ALPHANUMERIC_CHARS: This string contains all the valid characters for both username and password. It’s used for validating the entered values and also in the encryption algorithm explained in the post A simple way to encrypt texts with App Inventor.
  • APPENGINE_ADDRESS, AUTH_KEY: The authenticator key and address for the mail sending service. They MUST be informed with the right value as explained in the post How to send direct mails
  • CRYPTO_KEY: A key used to encrypt passwords. You should change it to a value that only you know

Variables

logintutorial_34

  • lstStack, lstScreens, iStackPointer: Variables used to control the back navigation (see the post An “optimal” way to manage multiple screens)
  • lstUserInfo: A list containing all the information from a user: password, email, sendmail
  • iScreenHeight, iScreenWidth, iHeight, iWidth: Variables that store the screen size. They are used to calculate dynamically the dimension of some components (for example when changing the screen orientation as explained in tutorial How to adapt controls appearance depending on the screen orientation)
  • sCode, sResponse, sToken, lstResponse: Used in the Google Login window
  • sEncrypterKey: A string used by the encrypter algorithm. It’s calculated at initialization time by merging the constants ALPHANUMERIC_CHARS and CRYPTO_KEY
  • sUser: Stores the user that’s currently logged in
  • bLogged: Indicator of whether the user is already logged. It’s used to decide the behaviour in some places (e.g. make visible the User label at the header screen)
  • iIndex, iVal, sVal: Auxiliary variables used in several places
  • sRet_checkPassword, sRet_isAlphanumeric, sRet_xor: Return values for functions

NOTE: The latter variables are not necessary anymore in the version for AI2 since return value is solved by means of local variables (see below the code for the checkUsername function)

Auxiliary functions

logintutorial_36

  • initMenuSize: Used to set the height and width of menu options depending in the screen size. It’s called when initializing the screen and also when changing the screen orientation. The code is explained in the post How to adapt controls appearance depending on the screen orientation
  • popScreen, pushScreen, getCurrentScreen, showScreen, showMain: Functions used to manage the screens. They are explained in the tutorial An ‘optimal’ way to manage multiple screens
  • initCrypto, encrypt, decrypt, pseudoXOR: Functions used to encrypt/decrypt passwords. They are explained in the tutorial A simple way to encrypt texts with App Inventor
  • initColors: Used to apply the customized colors to the components. It simply sets the right Backgroundcolor attribute to each component
  • initScreens: Initializes the variable lstScreens with the list of existing windows

logintutorial_35

  • initHelpLabels: This function is called every time the help button is pressed. It sets the text labels of the screen buttons according to the currently selected window (which is received as an input parameter)

logintutorial_37

  • checkUsername, checkPassword: Validation functions that enforce some rules regarding the username and password format. The code is self-explanatory
  • isAlphanumeric: Auxiliary function that returns true if all the characters of the string received are alphanumeric (i.e. exist in the ALPHANUMERIC_CHARS constant)

In this case let’s see the checkUsername function both in AI classic and AI2, since it’s a simple example that demonstrates how to make our code cleaner and safer thanks to local variables:

logintutorial_90 logintutorial_91

General events

logintutorial_41

  • BackPressed: Manages the behaviour of the “back” button in order to simulate the window closing, as explained in the post  An ‘optimal’ way to manage multiple screens
  • ScreenOrientationChanged: Resizes controls according to the current screen height and width, as explained in the post How to adapt to screen orientation
  • OtherScreenClosed: Restores the components’ colors since they may have changed to improve user feedback.

NOTE: AI does not provide visual feedback when a button is pressed. This is annoying specially if the action associated to the button takes some time to initiate because the user may not be sure of whether he’s really pressed the button. That’s why we improve his experience by playing a sound and changing the color of the pressed button

  • Initialize: Calls the initialization functions, shows the login window, obtains default values for some fields (username and password) and redirects to Google Login if this is the default option

Login window

logintutorial_42

  • ButtonLogin.Click: Queries TinyWebDB to verify that the username/password exist in the database.
  • TinyWebDB_LOGIN.GotValue: Obtains the information about the user by means of the getUserInformation function (explained below). If password is correct shows the menu window calling the ShowMain function explained in the tutorial  An ‘optimal’ way to manage multiple screens. Additionally, if “Remember” is checked, stores the values entered in the TinyDB so that they become the default options for the device.
  • ButtonGuest.Click: shows the menu window calling the ShowMain function explained in the tutorial An ‘optimal’ way to manage multiple screens. This function receives the user as a parameter, which in this case is informed with the special value “_guest”. In further places a comparison with this value is used to limit the available options (e.g. disable the option to modify the profile)

Register window

This window is used both for the initial register and to modify the profile. In the second case the username textbox is disabled. The code uses this condition to skip some controls in case we’re just modifying information.

logintutorial_43

  • ButtonRegister.Click: Shows the Register window using the PushScreen function explained in the post  An ‘optimal’ way to manage multiple screens.
  • ButtonOk_REG.Click: Validates that username and password format and queries TinyWebDB to verify the username does not already exist in the database
  • TinyWebDB_REG.GotValue: After some validations stores the information in the database and closes the window using the popscreen function explained in the post  An ‘optimal’ way to manage multiple screens.

logintutorial_44

  • GetUserInformation: Auxiliary function that receives as input parameter a string of data separated by the characters “|||” (i.e. the way it’s stored in the database) and returns a list with an element for each piece encountered (e.g. the input string “myPwd|||myMail|||1” would return a list of 3 elements: [myPwd] [myMail] [1] ). Additionally, this function decrypts the password
  • SetUserInformation: As opposite to the previous function, this one receives the information fields as parameters and returns a string in the format required to store the information in the database. It also encrypts the password

Forgot password window

logintutorial_45

  • ButtonForgetPWD.Click: Shows the Forgot Password window using the PushScreen function explained in the post  An ‘optimal’ way to manage multiple screens
  • ButtonOk_SEND.Click: Queries TinyWebDB to obtain the information about the username from the database
  • TinyWebDB_SEND.GotValue: Stores the information read into some hidden fields and calls the sendMail function. Finally closes the window using the PopScreen function
  • sendMail: This is the function that performs the actual job. It’s explained in the post How to send direct mails

Menu window

logintutorial_46

  • Button_1.Click, Button_2.Click, Button_3.Click, Button_4.Click: Open the second window passing as a parameter the logged user. It also changes the button to a somewhat lighter color
  • ButtonProfile.Click: Opens the Register window initializing previously the username textbox and disabling it. It also queries TinyWebDB to obtain the information about the username
  • TinyWebDB_Profile.GotValue: Calls the GetUserInformation function in order to convert the information read into a list, and then initializes the fields with this information.
Advertisements

15 Comments

  1. How would i change this to be used with a one or two fusion tables

    • eixerits says:

      Do you mean that usernames and passwords be stored in fusiontables rathen than in TinyWebDB? It looks extremely interesting since it would make it much easier for an administrator to maintain users. I’ll try to implement it in a new version when I have the time.
      Changes required would be:
      Fusiontable.DoQuery instead of TinyWebDB.GetValue
      Fustiontable.GotResult instead of TinyWebDB.GotValue (and a slight adaptation to parse the result)
      Fusiontable.DoQuery with an INSERT statement instead of TinyWebDB.StoreValue
      Changes do not appear to be hard but there are quite a few places to adapt.
      One consideration to take into account is security, since the AI fusiontables component require the fusiontable to be public (see the post https://eixerits.wordpress.com/2013/05/25/fast-and-safe-fusiontables-with-app-inventor/). You can use the solution from the same post to overcome the issue. By the way, another alternative to implement your idea would be to modify the python service so that the TinyWebDB reads and stores data in a fusiontable. This way it would not be necessary to modify the AppInventor template. Yes, I think it could work and would be the simplest solution.

      • Richard says:

        Yes that is exactly what I was going for, thanks for responding and giving the equivalent commands and such to do so.

      • eixerits says:

        That’s great. If you want to share the results I’ll be pleased to reference your solution in this post.

        I assume you’re working in the solution of adapting the App Inventor template, which is the smart way to go. In the meantime I’ve been working in the alternative solution and it also works! i.e. I’ve modified the python service so that when it receives a tag starting by “usr:” it stores or retrieves data from a fusiontable (indicated in the settings). I intend to write a tutorial about this because I think it’s an interesting approach for future projects, but in this case I’d prefer to adapt the App Inventor as I understand you’re doing. Anyway, here is the adapted service in case anyone is interested:

        https://docs.google.com/file/d/0B1e4mf9UAhC0U29JMGg0Nk1ZRnc/edit?usp=sharing

        Installation is simple: just replace the main.py with this new version, modify the settings as explained in the comments and deploy it again.

  2. Thank you so much, I am just still learning how to use AI. This will help a ton.

  3. Martha says:

    At the initHelpLabes appears for the first time the component labelHead where does this defined?

    • eixerits says:

      You’re right! There was a mistake in the tutorial first part (). In the explanation for the TableArrangementHelp there were two labels called LabelCab and LabelCab2 which are really called LabelHead and LabelSpacer.

      I’ve just fixed the tutorial. I hope this helps you. Thanks for the comment.

  4. KENIGBOLO MEYA STEPHEN says:

    Please how do I convert this to AI2? I used this tutorial perfectly on AI classic but now I have a project I am working on with AI2 and I would love to make use of this template. The problem now is that I can’t seem to convert this to AI2. Would love a little help

    • eixerits says:

      Well, I was waiting for the translating tool but it seems it won’t be able until past summer and without much guarantees of success. So I think I’m going to translate it manually when I have a moment. I can’t promise a date but it will hopefully be ready by summer.

  5. rafli says:

    eixerits u’r amazing.. this is what Im looking for so loong.. your articles is very help full. I love it.. thanks a lot.. I’m now trying to combine with facebook login form..

  6. jyoung says:

    Thanks so much this is what I really want! I downloaded the template for ai2. and i don’t know how to treat the message which was ‘text’ in ai classic… thanks a lot

  7. Darren says:

    Thanks for the tutorial. Is there an updated tutorial for AI2 as yet though?

  8. mikeattackyt says:

    Hola, estic fent el Treball de Recerca sobre una aplicació i la estic creant per App Inventor. Per la base de l’aplicació necessito aquest sistema de login/register, però al descarregar i pujarlo al App Inventor em dóna error, i no em carga tots els screens. A més voldría que s’emmagatzemés en Fusiontables ja que vull que es pugui buscar dintre d’aquesta base de dades.
    T’explico una mica la ideia i així saps de què parlo: Bàsicament vull fer una aplicació que sigui com un banc d’hores on hi ha alumnes que ofereixin hores d’estudi, segons matèria, curs i temps. I altres alumnes que demanin una matèria, una quantitat d’hores i el curs. Sabries alguna forma que al buscar , entri a la Fusiontable i trobès aquestes dades, per què si ho poso a TinyWebDB dubto que es pugui accedir.

    Em seria de gran ajuda que em contestèssis, moltes gràcies.

  9. AJ says:

    Can I download this project?

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: