Labels

Wednesday, April 2, 2014

Native looking Android App with Qt

This article is part of my Qt on Android series. In the previous article I show you how to get started developing Qt for Android: Tutorial: Qt for Android - set up SDK and Hello World

Qt Quick vs. Qt Widgets

First we need to discuss the goal of your app. If you have a complex UI with many different standard widgets (e.g. Checkbox, Radiobutton, Text-Input Fields, etc.) you may want to use Qt Widgets. There are many different Widgets and all of them are usable on Android. But unfortunately they will look not native and not only that - they could look strange thus they are designed to be used on Desktop with a simple Pixel-based screen. So you have to test it very properly.

On the other hand we have Qt Quick, which is really great for rapid prototyping and creating custom UIs. The big point is that there are no build-in standard widgets available and it's also completely theme-less. So you have to design and construct your all your UI elements.

So let's get started...

Native looking Qt Widgets on Android

The first important point is to create a correctly scaling layout.

  • Set the basis widget to vertical layout (Lay out vertically-Button in the top toolbar)
  • Place a LineEdit and a PushButton into it
  • Use Vertical Spacers to align the Textbox and Button to the middle of the screen


layout graph

The very important point is to set the Vertical Size Policy to Minimum (or Expanding if it makes sense). Do not use fixed size at all, because then the real size on the mobile screen can be very different!

LineEdit properties



Run it on your Android phone. It will look like this:

It's the Qt look and not the Android theme (called Holo). So your App will feel like a foreign body.  The trick is to use Ministro.

  • Switch to Projects mode
  • Select the Run Settings for Android
  • Open Deploy configurations Details
  • Select Use Ministro service to install Qt




Now the Qt Widgets will have a native Android look. But there is a big drawback: Your App has now a dependency to the Ministro App. The App will check on startup if Ministro is installed on your device. If it is not installed the user is forced to install it over the Android Play Store.





When all dependencies are installed, your app will look like this:



Native looking widgets based on Qt Quick

In the version of 5.2 Qt Quick has no high-level ui components. There are only the base elements to create your own ui components. I will show you a strategy how to create Android-looking custom UI widgets.
As example we will create a Holo-themed button.

In the first step, find and download the button images from the Android Style Guide:

To get nice images you have to edit the images you have caught from the Android Style Guide and remove the text on them.
Create the two important buttons states as image: normal, pressed



Create a new directory for the images in your project path: HelloAndroid/qml/HelloAndroid/images
Save the two images in the new images directory.

Create new QML file: HelloWorld/qml/HelloAndroid/HoloButton.qml

import QtQuick 2.0

Rectangle {
    width: 100
    height: 62

    state: "normal"
    property alias text: text1.text

    BorderImage {
        id: borderImage1
        x: 0
        y: 0
        width: parent.width
        height: parent.height
        border.top: 6
        border.left: 6
        border.right: 6
        border.bottom: 6
        source: "images/button-normal.png"

        Text {
            id: text1
            anchors.centerIn: parent
            text: qsTr("Text")
        }
    }
    MouseArea {
        id: mouseArea1
        x: 0
        y: 0
        width: parent.width
        height: parent.height
        onPressed: parent.state = "pressed"
        onReleased: parent.state = "normal"
    }

    states: [
        State {
            name: "normal"
            PropertyChanges {
                target: borderImage1
                source: "images/button-normal.png"
            }
        },
        State {
            name: "pressed"
            PropertyChanges {
                target: borderImage1
                source: "images/button-pressed.png"
            }

        }
    ]
}


Now you can use the HoloButton in your main.qml file:

import QtQuick 2.0

Rectangle {
    id: rectangle1
    width: 360
    height: 360


    HoloButton {
        id: textInput1
        height: parent.height * 0.1
        width: parent.width * 0.8
        text: qsTr("Text Input")
        anchors.centerIn: parent
    }

}

This is the result on the Android phone:


You can find this project at github: https://github.com/jjoe64/qt-android-helloworld

Wednesday, March 12, 2014

Tutorial: Qt for Android - set up SDK and Hello World

This article is part of my Qt on Android series. Stay tuned to see more articles about developing apps for Android based on Qt.

Qt on Android? Wait ... what?

Yes, since Qt version 5.1 the Qt developers focuses the their development at the integration to Android and other mobile platforms. Since 5.2 the Android port is fully production-ready and it's very easy to start developing for it (as you will see below).

I will take a closer look into this topic and share my experience here. I'm sure that Qt is a good alternative to a cross platform mobile app written in HTML5/Cordova. There are many pros:

  • Very good tooling (Qt Creator)
  • Solid and nice language (Qt / C++)
  • Nearly native performance since using Android JNI
  • Cross-Platform

Read more about the Android port at the official Qt page.

Set up Development Environment


Prerequisites

Ensure that you have this 2 packages installed:
  • Java SE Development Kit (JDK) v6 or later. You can also use OpenJDK on Linux.
  • Apache Ant v1.8 or later
  • (Windows Users have also to install MinGW)

Install Android SDK+NDK

Now you have to download and install (extract) the Android SDK and NDK. You get them at the Android developer page:
After you have unpacked the Android SDK, open a terminal and change into the tools directory. Then update the Android SDK to get the API and tools packages required for development:
cd android-sdk-linux_86/tools/
./android update sdk
Ensure that the latest platform is checked (in my case it was API 19.) and then click the update button.


At least you have to set the global environment variable ANDROID_NDK_ROOT to the path of the Android NDK.
Under Linux you typically have to add this line into your .bashrc in your home directory (change the path to your needs):
export ANDROID_NDK_ROOT=/home/jonas/projects/android/sdk/android-ndk-r9d

Install Qt SDK

Download the Qt Online installer for your OS. In my case I downloaded Qt Online Installer for Linux 32-bit. You get the files from the download page at qt-project.org.
http://qt-project.org/downloads

Execute the installer. Linux users: You may have to set the file as executable to run it:
chmod +x qt-opensource-linux-x86-1.5.0-2-online.run
./qt-opensource-linux-x86-1.5.0-2-online.run

In the installer leave the components selected that are default.

After the installation has finished, you should be able to start Qt Creator. In Linux the binary is in the installation folder, typically HOME_DIR/Qt/Tools/QtCreator/bin/qtcreator.

Configure Qt Creator

  1. Start Qt Creator and open the Android Options (Tools > Options > Android).
  2. Set the path to Android SDK and NDK that you have downloaded and extracted before.
  3. Select the Automatically create kits for Android tool chains check box to allow Qt Creator to create the kits for you. Qt Creator displays a warning if it cannot find a suitable Qt version.

    note about mips architecture support

    Qt versions for architecture mips is missing. To add the Qt versions, select Options > Build & Run >Qt versions.

    Note: If you are getting the warning, that mips platform is missing, you can normally ignore that. If you need MIPS you have to note this:

    Because of missing support for MIPS in the JavaScript engine used in QtQuick 2, there is no binary package for that architecture.

    If your app does not require Qt Quick 2, you can build Qt manually for MIPS. If you require Qt Quick 2 for MIPS, unfortunately the only solution right now is to build from the dev repository (which is under active development and not as stable) or wait for Qt 5.2, where this problem should be fixed.

    If your app does not require MIPS support, you can safely ignore the warning in Qt Creator.
  4. Select the Ant location if it is not automatically found. Typically /usr/bin/ant for Linux.
  5. Select the JavaJDK location if is not automatically found. If you are not sure where your JDK is located you can find out that way:

    $ which javac
    /usr/bin/javac
    $ ls -l /usr/bin/javac
    lrwxrwxrwx 1 root root 23 May  2 10:02 /usr/bin/javac -> /etc/alternatives/javac
    $ ls -l /etc/alternatives/javac
    lrwxrwxrwx 1 root root 43 May  2 10:02 /etc/alternatives/javac -> /usr/lib/jvm/java-7-openjdk-amd64/bin/javac
    $ ls -l /usr/lib/jvm/java-7-openjdk-amd64/bin/javac
    -rwxr-xr-x 1 root root 6352 Apr 13 04:00 /usr/lib/jvm/java-7-openjdk-amd64/bin/javac

    So your JDK location is in that case under /usr/lib/jvm/java-7-openjdk-amd64.
Qt Creator Android Configuration


Now you are ready to start developing Qt for Android.

Create a Qt Project for Android / Hello World


  1. Open Qt Creator and select New Project
  2. Select Qt Quick Application template
  3. Choose a project name. I recommend HelloAndroid
  4. Leave the Qt quick component set Qt quick 2.0 selected.
  5. In the Kit Selection step ensure that the checkbox for Desktop and Android armeabi-v7a is checked.
  6. Confirm the project creation in the last step.

Run it on your Android device

Note: You need a device with at least Android 2.3 (API Level 9) running.

First you have to activate USD Debugging on your target device. Do to that, you need to enable developer settings. It depends on your device how to enable the developer settings. In the most cases on newer devices you have to do a simple trick to make the developer menu visible:
  1. Go to the settings menu, and scroll down to "About phone." Tap it.
  2. Scroll down to the bottom again, where you see "Build number."
  3. Tap it seven (7) times. After the third tap, you'll see a playful dialog that says you're four taps away from being a developer. (If only it were that simple, eh?) Keep on tapping, and *poof*, you've got the developer settings back.
Then you can find the developer settings. Open, activate them and check the USB-Debugging checkbox.

  1. Connect your smartphone with your PC via USB.
  2. In Qt Creator select the target for Android

  3. After a few seconds, you can click on the Run button, the green triangle.
  4. Select your connected device and there you go!



Enjoy Qt on Android :-)



Do you like Qt on Android? You know some disadvantages? Let me know in the comments!


Official documentation
http://qt-project.org/doc/qt-5/androidgs.html
http://qt-project.org/doc/qtcreator-3.0/creator-developing-android.html


This could be interesting for you:

Saturday, January 25, 2014

Apache Shiro with Hibernate/SQL - full tutorial

Apache Shiro is a powerful and easy-to-use Java security framework that performs authentication, authorization, cryptography, and session management. With Shiro’s easy-to-understand API, you can quickly and easily secure any application – from the smallest mobile applications to the largest web and enterprise applications.
I will show you have to integrate Apache Shiro into a Java application based on Hibernate/MySQL. The authentication will be use a SHA256 hash and a salt for password storing. I will also show how to use roles and permissions in Shiro.

How Authentication works

Authentication is the mechanism that checks if the user that is going to access the website is really the user that he says he is. Typically this is checked by a personal password but there are other ways how the authentication can be executed.
In our case we check the E-Mail and password. The password will not be stored in plaintext but as a sha1 hash as you will see later.

A full description about that topic can be found here at the official documentation.

How Authorization works

Authorization is the mechanism that checks if the specific user that is going to access a feature of the website has the permission to access that part or is allowed to do a specific action on a specific object.

Permissions in Apache Shiro represent the most atomic element of a security policy. They are fundamentally statements about behavior and represent explicitly what can be done in an application. A well-formed permission statement essentially describes resources and what actions are possible when a Subject interacts with those resources.
Some examples of permission statements:
  • Open a file
  • View the '/user/list' web page
  • Print documents
  • Delete the 'jsmith' user

Performing authorization in Shiro can be done in 3 ways:

  • Programmatically - You can perform authorization checks in your java code with structures like if and else blocks.
  • JDK annotations - You can attach an authorization annotation to your Java methods
  • JSP/GSP TagLibs - You can control JSP or GSP page output based on roles and permissions

I will show you in this tutorial how to use them programmatically.

A full description about that topic can be found here at the official documentation.

Add dependency

First you have to include the .jar to classpath or if you use maven add the dependency to your pom.xml.
<!-- apache shiro -->
<dependency>
  <groupId>org.apache.shiro</groupId>
  <artifactId>shiro-all</artifactId>
  <version>1.2.2</version>
</dependency>
<dependency>
  <groupId>org.slf4j</groupId>
  <artifactId>slf4j-simple</artifactId>
  <version>1.6.1</version>
</dependency>
<dependency>
  <groupId>commons-logging</groupId>
  <artifactId>commons-logging</artifactId>
  <version>1.1.1</version>
</dependency>

Create database tables

Shiro needs at least 3 tables: User, UserRole and RolesPermission.
Table: User
Columns:
id int(11) PK AI
username varchar(45)
email varchar(128)
password varchar(128)
salt varchar(128)
CREATE TABLE `User` (
 `id` int(11) NOT NULL AUTO_INCREMENT,
 `username` varchar(45) DEFAULT NULL,
 `email` varchar(128) DEFAULT NULL,
 `password` varchar(128) DEFAULT NULL,
 `salt` varchar(128) DEFAULT NULL,
 PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1
Table: UserRole
Columns:
id int(11) PK AI
roleName varchar(45)
email varchar(128)
CREATE TABLE `UserRole` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `roleName` varchar(45) DEFAULT NULL,
  `email` varchar(128) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1
Table: RolesPermission
Columns:
id int(11) PK AI
permission varchar(80)
roleName varchar(128) 
CREATE TABLE `RolesPermission` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `permission` varchar(80) DEFAULT NULL,
  `roleName` varchar(128) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1

Create models

Create corresponding classes.
@Entity
@Table
public class User implements Serializable {

  /**
   * 
   */
  private static final long serialVersionUID = -4656759219348212715L;

  @Id
  @GeneratedValue
  private Integer id;
  
  @Column
  private String username;
  
  @Column
  private String email;
  
  @Column
  private String password;
  
  @Column
  private String salt;

  // ... getters and setters ...

}
@Entity
@Table
public class UserRole implements Serializable {
  /**
   * 
   */
  private static final long serialVersionUID = 8432414340180447723L;

  @Id
  @GeneratedValue
  private Integer id;
  
  @Column
  private String roleName;
  
  @Column
  private String email;

  // ... getters and setters ...

}
@Entity
@Table
public class RolesPermission implements Serializable {
  /**
   * 
   */
  private static final long serialVersionUID = -2070357513686679164L;

  @Id
  @GeneratedValue
  private Integer id;
  
  @Column
  private String permission;

  @Column
  private String roleName;

  // ... getters and setters ...
  
}

Create DAOs

Next you have to define the DAOs to query the database for the data.
public class UserDAO {

  public static User getUserByEmail(String email) {
    Session session = HibernateUtil.getCurrentSession();
    session.beginTransaction();
    User user = (User) session.createQuery("from User where email=?").setString(0, email).uniqueResult();
    session.getTransaction().commit();
    return user;
  }
}
public class UserRoleDAO {
  public static List<UserRole> getUserRolesByEmail(String email) {
    Session session = HibernateUtil.getCurrentSession();
    session.beginTransaction();
    @SuppressWarnings("unchecked")
    List<UserRole> roles = session.createQuery("from UserRole where email=?").setString(0, email).list();
    session.getTransaction().commit();
    return roles;
  }

  public static void insert(UserRole r) {
    Session session = HibernateUtil.getCurrentSession();
    session.beginTransaction();
    session.persist(r);
    session.getTransaction().commit();
  }

}

Create SaltedAuthenticationInfo

In cryptography, a salt is random data that is used as an additional input to a one-way function that hashes a password or passphrase. The primary function of salts is to defend against dictionary attacks and pre-computed rainbow table attacks.
A new salt is randomly generated for each password. In a typical setting, the salt and the password are concatenated and processed with a cryptographic hash function, and the resulting output (but not the original password) is stored with the salt in a database. Hashing allows for later authentication while defending against compromise of the plaintext password in the event that the database is somehow compromised.
from Wikipedia 
public class MySaltedAuthentificationInfo implements SaltedAuthenticationInfo {
  private static final long serialVersionUID = -5467967895187234984L;

  private final String username;
  private final String password;
  private final String salt;

  public MySaltedAuthentificationInfo(String username, String password, String salt) {
    this.username = username;
    this.password = password;
    this.salt = salt;
  }

  @Override
  public PrincipalCollection getPrincipals() {
    PrincipalCollection coll = new SimplePrincipalCollection(username, username);
    return coll;
  }

  @Override
  public Object getCredentials() {
    return password;
  }

  @Override
  public ByteSource getCredentialsSalt() {
    return  new SimpleByteSource(Base64.decode(salt)); 
  }

}

Create your realm

A Realm abstracts your user, permission and role metadata for Shiro. You make this data available to Shiro by implementing a realm and plugging it into Shiro. Typical realms use either a relational database or LDAP to store user data.
Realms are responsible for authentication and authorization. Any time user wants to log in to the application, authentication information is collected and passed to realm. Realm verifies supplied data and decides whether user should be allowed to log in, have access to resource or own specific role.
We need to create our own Realm to use Shiro with salted passwords.
public class MyCustomRealm extends JdbcRealm {
  @Override
  protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
    // identify account to log to
    UsernamePasswordToken userPassToken = (UsernamePasswordToken) token;
    final String username = userPassToken.getUsername();

    if (username == null) {
      System.out.println("Username is null.");
      return null;
    }

    // read password hash and salt from db
    final User user = UserDAO.getUserByEmail(username);

    if (user == null) {
      System.out.println("No account found for user [" + username + "]");
      return null;
    }

    // return salted credentials
    SaltedAuthenticationInfo info = new MySaltedAuthentificationInfo(username, user.getPassword(), user.getSalt());

    return info;
  }
}

Create Shiro configuration file

Next we have to create Shiro's config file. Here you have to set your full classname of your own realm, provide the database information and set the URLs, optionally with permissions.
The config file must be located at WEB-INF/shiro.ini
[main]
authc.loginUrl = /Login.html
authc.successUrl  = /ExampleApp.html
logout.redirectUrl = /ExampleApp.html

# ------------------------
# Database

# Own Realm
jdbcRealm = com.example.MyCustomRealm

# Sha256
sha256Matcher = org.apache.shiro.authc.credential.Sha256CredentialsMatcher
# base64 encoding, not hex in this example:
sha256Matcher.storedCredentialsHexEncoded = false
sha256Matcher.hashIterations = 1024

jdbcRealm.credentialsMatcher = $sha256Matcher

# User Query
# default is "select password from users where username = ?"
jdbcRealm.authenticationQuery = SELECT password, salt FROM User WHERE email = ?

# permissions
jdbcRealm.permissionsLookupEnabled = true
jdbcRealm.userRolesQuery = select roleName from UserRole where email = ?
jdbcRealm.permissionsQuery = select permission from RolesPermission where roleName = ?

# Connection 
ds = com.mysql.jdbc.jdbc2.optional.MysqlDataSource
ds.serverName = localhost
ds.user = root
#ds.password = 
ds.databaseName = exampleapp
jdbcRealm.dataSource=$ds

authc.usernameParam = email
authc.passwordParam = password
authc.failureKeyAttribute = shiroLoginFailure

# Use Built-in Chache Manager
builtInCacheManager = org.apache.shiro.cache.MemoryConstrainedCacheManager
securityManager.cacheManager = $builtInCacheManager

securityManager.realms = $jdbcRealm

# -----------------------------------------------------------------------------
[urls]
/ExampleApp.html = authc, perms["portal:read"]
/Admin.html = authc, perms["admin:access"]

Modity web.xml

Configure web.xml to call IniShiroFilter before each request. This filter must be defined before the <servlet> and <servlet-mapping> tags.
<!-- Apache Shiro -->
<listener>
  <listener-class>org.apache.shiro.web.env.EnvironmentLoaderListener</listener-class>
</listener>
<filter>
  <filter-name>ShiroFilter</filter-name>
  <filter-class>org.apache.shiro.web.servlet.ShiroFilter</filter-class>
</filter>
<!-- Make sure any request you want accessible to Shiro is filtered. /* 
  catches all -->
<!-- requests. Usually this filter mapping is defined first (before all 
  others) to -->
<!-- ensure that Shiro works in subsequent filters in the filter chain: -->
<filter-mapping>
  <filter-name>ShiroFilter</filter-name>
  <url-pattern>/*</url-pattern>
  <dispatcher>REQUEST</dispatcher>
  <dispatcher>FORWARD</dispatcher>
  <dispatcher>INCLUDE</dispatcher>
  <dispatcher>ERROR</dispatcher>
</filter-mapping>

Register new user / generate password hash and salt

When we want to register a new user, we have to build the sha1 hash and a salt for the password. I show you how it goes:
public void registrate(String email, String plainTextPassword) {
  User user = new User();
  user.setUsername(email);
  user.setEmail(email);

  generatePassword(user, plainTextPassword);

  Session session = HibernateUtil.getCurrentSession();
  Transaction tx = session.beginTransaction();
  session.save(user);
  tx.commit();

  System.err.println("User with email:" + user.getEmail() + " hashedPassword:"+ user.getPassword() + " salt:" + user.getSalt());
}

private void generatePassword(User user, String plainTextPassword) {
  RandomNumberGenerator rng = new SecureRandomNumberGenerator();
  Object salt = rng.nextBytes();

  // Now hash the plain-text password with the random salt and multiple
  // iterations and then Base64-encode the value (requires less space than Hex):
  String hashedPasswordBase64 = new Sha256Hash(plainTextPassword, salt,1024).toBase64();

  user.setPassword(hashedPasswordBase64);
  user.setSalt(salt.toString());
}

Do login

This is how you can check the password and log in the user.
// init shiro - place this e.g. in the constructor
Factory<org.apache.shiro.mgt.SecurityManager> factory = new IniSecurityManagerFactory();
org.apache.shiro.mgt.SecurityManager securityManager = factory.getInstance();
  SecurityUtils.setSecurityManager(securityManager);


// login
public boolean tryLogin(String username, String password, Boolean rememberMe) {
  // get the currently executing user:
  org.apache.shiro.subject.Subject currentUser = SecurityUtils.getSubject();

  if (!currentUser.isAuthenticated()) {
    //collect user principals and credentials in a gui specific manner
    //such as username/password html form, X509 certificate, OpenID, etc.
    //We'll use the username/password example here since it is the most common.
    UsernamePasswordToken token = new UsernamePasswordToken(username,password);
     //this is all you have to do to support 'remember me' (no config - built in!):
    token.setRememberMe(rememberMe);

    try {
        currentUser.login(token);
        System.out.println("User [" + currentUser.getPrincipal().toString() + "] logged in successfully.");
        
        // save current username in the session, so we have access to our User model
        currentUser.getSession().setAttribute("username", username);
        return true;
    } catch (UnknownAccountException uae) {
      System.out.println("There is no user with username of "
                + token.getPrincipal());
    } catch (IncorrectCredentialsException ice) {
      System.out.println("Password for account " + token.getPrincipal()
                + " was incorrect!");
    } catch (LockedAccountException lae) {
      System.out.println("The account for username " + token.getPrincipal()
                + " is locked.  "
                + "Please contact your administrator to unlock it.");
    }
  } else {
    return true; // already logged in
  }

  return false;
}

Get current user

Because we have stored the username / email of the user in the session during the login progress, we can now access the User model via our UserDAO.
public User getCurrentUser() {
  org.apache.shiro.subject.Subject currentUser = SecurityUtils.getSubject();

  if (currentUser.isAuthenticated()) {
    String mail = (String) currentUser.getSession().getAttribute("username");
    User user = getUserByEmail(mail);
    return user;
  } else {
    return null;
  }
}

Check for Permission

In our case the permission system works like this:
  • Every user has n roles.
  • Every role has n permissions.
  • If we have to authorize an action (e.g. delete operation, view a page), we do not check for the username nor the role the user have, but the permission.
There are mainly two methods to check the permission. The one throws an exception and the other returns a boolean value.
org.apache.shiro.subject.Subject currentUser = SecurityUtils.getSubject();

// throws UnauthorizedException if the user has no permission
currentUser.checkPermission("admin:access");

// returns false if the user has no permission
currentUser.isPermitted("admin:access");

Insert permissions and roles manually to the database

This is just to show you how the data have to look like. Insert this data to your database manually.
Table: UserRole
roleName: admin
email: test@test.test

Table: RolesPermission
permission: admin:access
roleName: admin
The result is now that the user with the mail address test@test.test has the permission to access the admin area.

Logout

Do a logout is very easy:
public void logout() {
  org.apache.shiro.subject.Subject currentUser = SecurityUtils.getSubject();
  currentUser.logout();
}

Example Project 

I have created an working example project on github to demonstrate this code. Check it out at github.
Please read the README to get it to work on your machine.


Friday, January 24, 2014

send email via SMTP/SSL with javax mail

This shit took me too long to get it to work, and I didn't found a working solution on the web, so I post the complete solution how to send a email in java with the standard javax mail class via a SMTP server with SSL!!

Create a helper class:

import java.util.Properties;

import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;

public class MailHelper {
  public static void sendMail(String recipient, String subject, String content) {
    // config
    // Sender's email ID needs to be mentioned
    String from = "PLACE YOUR SENDER ADDRESS HERE";
    
    // Get system properties
    Properties properties = System.getProperties();
    // Setup mail server
    properties.setProperty("mail.smtps.host", "PLACE YOUR SERVER DOMAIN e.g. smtps.example.com");
    properties.setProperty("mail.smtps.port", "465");
    properties.setProperty("mail.smtps.auth", "true");
    properties.setProperty("mail.user", "PLACE YOUR SMTP USERNAME");
    properties.setProperty("mail.password", "PLACE YOUR SMTP PASSWORD");
    //properties.put("mail.debug", "true");

    // Get the default Session object.
    Session session = Session.getDefaultInstance(properties);

    try{
      MimeMessage message = new MimeMessage(session);

      // Set From: header field of the header.
      message.setFrom(new InternetAddress(from));

      // Set To: header field of the header.
      message.addRecipient(Message.RecipientType.TO,
          new InternetAddress(recipient));

      message.setSubject(subject);
      message.setText(content);

      Transport trnsport;
      trnsport = session.getTransport("smtps");
      trnsport.connect(null, properties.getProperty("mail.password"));
      message.saveChanges();
      trnsport.sendMessage(message, message.getAllRecipients());
      trnsport.close();
      System.out.println("Sent message successfully....");
    }catch (MessagingException mex) {
      mex.printStackTrace();
    }
  }
}


Then you can send an email easily:

String to = "test@example.com";
String subject = "Yessss";
String content = "foo bar foo bar....";
MailHelper.sendMail(to, subject, content);

There you go!

Friday, December 6, 2013

GraphView 3.1.1

New release of GraphView 3.1.1 published!

Bugfixes

  • no text overlapping in legend
  • no white text in holo theme
  • [BarGraphView] fixed bar chart width calculation and labels position
  • scaling works also without manual viewport size
  • scaling is more stable. no jumping anymore after releasing

Features

  • more legend styles (legendBorder, legendSpacing, legendWidth)
  • LineGraphView better background rendering. support for semi-transparent colors
  • use text colors from current theme
  • vertical labels alignment (left, center, right)
  • [BarGraphView] draw values on top of bars
  • [LineGraphView] draw datapoints for linegraph

Checkout the project homepage at http://android-graphview.org

Download .jar direct from here: https://github.com/jjoe64/GraphView/blob/master/public/GraphView-3.1.1.jar?raw=true

Wednesday, August 7, 2013

GraphView 3.1 released

Good news for GraphView users: GraphView 3.1 is out!

There were many changes done. The best way to get involved is to check out the GraphView-Demos project.

Checkout GraphView-Demos
https://github.com/jjoe64/GraphView-Demos

Download as jar: GraphView 3.1
https://github.com/jjoe64/GraphView/raw/master/public/graphview-3.1.jar

Changelog


  • javadoc available at http://jjoe64.github.io/GraphView/
  • series style
  • Realtime: append data with limit
  • Realtime with multiple series
  • GraphViewDataInterface: use your own models as data
  • LineGraph: Custom Background Color
  • Full customizable label width and label count
  • Custom Label Formatter as Interface
  • Manual Y Axis bounds
  • GraphViewStyle with many options
  • BarGraphView: Value dependent color
  • ... fixed many bugs


Saturday, July 13, 2013

physijs and three.js on node.js

For my project I need to run the game physic also on the server side (node.js). It's not possible to use physijs out of the box on node, because it uses WebWorker which is not available on node.

So I decided to patch physijs. I had to do these steps:
  • patch files, so that they can be used as node modules via require()
  • replaced WebWorker communication with simple Handler functions (from webworker-js to scene-js and vice-versa).
  • patch ammo.js, so it can be required as node-module.
  • you need the three.js build for node.js.

I pushed my changes to my phyijs branch on github:
https://github.com/jjoe64/Physijs


It's now pretty simple to use my patched version of physi.js on a nodejs application. Ensure, that physi.js, physijs_worker.js and ammo.js are in the same directoy.

var THREE = require('./libs/three.js');
var Ammo = require('./libs/ammo.js');
var Physijs = require('./libs/physi.js')(THREE, Ammo);

Now you can simply create your Scene and phsical objects. One more important point is, that you can not use requestAnimationFrame, so you have to run the physic with setTimeout().

// create scene ...
scene = new Physijs.Scene;
// ...
render = function() {
 scene.simulate(); // run physics
 setTimeout( render, 200 );
};


I published a complete standalone example, where you can compare the browser version and the server-side (node) version:
https://github.com/jjoe64/nodejs-physijs