/whiteboard_androidClient

Whiteboard Android Client for use with the whiteboard_server; distributed whiteboard drawing app

Primary LanguageJava

4995 Industries Presents: Whiteboard

What is it?

"Whiteboard" is a real-time collaborative whiteboard application developed by CS 4995 students at the University of Minnesota-Duluth.

Setup

  1. Download and set up the NodeJS whiteboard server
  2. Change the values in app/src/main/res/values/strings.xml to match your server address
    • Change "hostname" to your server hostname
    • Change rtc_port to your RTC signalling port (3001 by default)
    • If your server is NOT running over HTTPS (most people):
      • Change "secure" to false
      • Change "port" to your server port (3000 by default)
    • Otherwise, if you ARE running over HTTPS:
      • Change "secure_port" to your HTTPS port
  3. Build and run the Android application (we use Android Studio)

Nodejs Development Information

The server is written in Javascript using Nodejs, and most of the client-server communication uses Socket.IO. This means that most of the communication is asynchronous, so you need to write your code in a way that can be executed asynchronously without problems. There are good examples of this in JoinBoardFragment.java.

Building messages

Message data needs to be packaged in a JSONObject or JSONArray in order to be sent via socketio. This is pretty easy to do:

JSONObject jsonData = new JSONObject();
jsonData.put("name", "testBoard");

Sometimes it helps to think about JSONObjects is as HashMap<String,Object> and JSONArrays as List (though technically speaking, this isn't totally correct).

Sending and receiving a message

In order to send or receive a message, your class needs to have access to the global SocketService. You can access this through the Globals singleton:

final SocketService socket = Globals.getInstance().getSocketService();

Sending a message can be done through the sendMessage method, which takes a string and either a string, JSONObject, or JSONArray. Message types are stored in a "struct" called Messages within SocketService.

socket.sendMessage(SocketService.Messages.CREATE_WHITEBOARD, jsonData);

SendMessage will throw an error if it does not have a connection to the server, so make sure to check for that.

To receive a message, you need to set up a listener, which is usually an anonymous function that will get called when the server send s message back with the given message type (such as createWhiteboard).

For example, to set up a listener to for a createWhiteboard message,

socket.addListener(SocketService.Messages.CREATE_WHITEBOARD, new Emitter.Listener() {
    @Override
    public void call(Object... args) {
        
        // args[0] is a string containing the server's response, which we parse into a JSONObject
        JSONObject recvd = (JSONObject) args[0];
        
        try {
            Log.i("createWhiteboard", "received message: " + recvd.getString("message"));
        } catch (JSONException e) {
            Log.e("createWhiteboard", "error parsing received message");
        }
        
        // After we have successfully processed the response, 
        // remove the listener so it doesn't get called again.
        socket.clearListener(SocketService.Messages.CREATE_WHITEBOARD);
    }
});

Debugging messages

You can see a live log of the public server at https://lempo.d.umn.edu:4995/log.html

Additionally, you can simulate a real client and test sending messages at https://lempo.d.umn.edu:4995/console.html

Server message types

Name Purpose Arguments Returns
createWhiteboard Creates a whiteboard. name A success or error message
joinWhiteboard Joins a whiteboard. name A success or error message
deleteWhiteboard Deleted a whiteboard. name A success or error message
me Allows user to get information about themselves none A JSONObject with 'whiteboard' property containing user's current whiteboard
chat message Blast a message to all users message The message
drawevent Sends a drawevent to users in the current whiteboard drawevent object generated by DrawProtocol none

Getting Google Sign-In and Google Drive Services to Function

Before you can build the app with OAuth2.0 Google Sign-in enabled and Googe Drive functionality you will need to authenticate your client with their services as well as create a Google Developers Console Project.

Before you will be able to begin integrating Google Sign-In however, you must configure a Google Developers Console project and configure the Android Studio project.

  1. First, add the Google Play Services SDK if it is not added already: a. In Android Studio, select Tools > Android > SDK Manager. b. At the bottom of the package list select Extras > Google Play services.

  2. Obtain your configuration file which contains service-specific information for your application.

    a. Go to the Google Developers Console and scroll down to the middle of the page and select the button that says "GET A CONFIGURATION FILE"

    b. You will need to create a new project and provide the package name for the application. You will also need to provide the SHA-1 hash of your signing certificate. c. To obtain your SHA-1 hash: ` Go to a terminal and enter this command to obtain your SHA-1 certificate

             keytool -exportcert -list -v -alias <your-key-name> -keystore <path-to-production-keystore>
    
         Replace "your-key-name" and "path-to-production-keystore" appropriately. For example, on OSX:
    
             keytool -exportcert -list -v -alias androiddebugkey -keystore ~/.android/debug.keystore
    
         Your key name should probably be unique, so you can use something like 'rysau001debugkey' instead.
    
         This command will output your SHA-1 key fingerprint. Save this!
    
  3. Add the google-services.json file to your project: a. Copy the google-services.json file you just downloaded into the app/ directory of your Android Studio project. b. Open the Android Studio Terminal pane and enter the following command, replacing path-to-download with the actual path:

     For MAC/LINUX: $ mv path-to-download/google-services.json app/
    
     For WINDOWS: $ move path-to-download/google-services.json app/
    
  4. Add the Google Services plugin by updating your top-level build.gradle and your app-level build.gradle files as follows if they are not already added: a. Add the following dependency to your project-level build.gradle by copying/pasting the following line into your dependencies section:

     classpath 'com.google.gms:google-services:2.0.0-alpha5'
    

    b. Add the plugin to the app-level build.gradle:

     apply plugin: 'com.google.gms.google-services'
    
  5. Add Google Play Services if it is not already added to the app-level build.gradle:

    a. in the app-level build.gradle file add the following line under dependencies:

     compile 'com.google.android.gms:play-services-auth:8.4.0'
    
  6. It is possible that you will also have to create a Google Developers Project: a. You can create a new project for free by selecting "Create a new project" from the project drop-down at the Google Developers Console Web site.

    b. From the "API Manager" sidebar, select Credentials, followed by the OAuth consent screen tab. a. Select an email address, specify the product name (Whiteboard in this case, or a test project name if you do so choose), and select Save.

    c. In the Credentials tab, select the New Credentials drop-down list, and select OAuth Client ID, then follow the rest of the steps to create the client ID.

Contributors

Put your name and email/website here! Leave a blank line between names.

Mitchell Rysavy (rysau001@d.umn.edu)

Laura J. Krebs (krebs148@d.umn.edu)