Category Archives: Java

How to Build a Continuous Integration Environment for Java with Jenkins, Maven, SVN, and IntelliJ IDEA

 
Continuous Integration is a practice that does not necessarily require specialized CI server software. You know for sure some magicians, who are able to write amazing shell scripts in less than a few hours, that calls the build, makes the tests, deploys status emails with links to nicely formatted reports and run it periodically at fixed times as Cron job. But not everybody is such a shell script wizard. For the rest of us, there is CI server software like Jenkins.

Regardless what way you take, you need a build process, that can be initiated by command line. The same applies to your tests. There are several build tools; the usual suspects in the Java world being Ant, Maven and meanwhile Gradle. Sometimes there are heated debates, which is the better tool. This is certainly not the case here, although I personally have a slight tendency towards Maven for several reasons.

The next important component is a version control system, in this example Subversion is used.

The screencast is divided into the following sections:
– Some basic configuration of Jenkins
– Quick setup of SVN
– Configure quickly a very simple Maven project on the command line
– Import the Maven project into IntelliJ IDEA and link it to the SVN repository
– Create a Jenkins Job, that polls every 5 minutes the SVN repository for changes
– Let a JUnit test fail and show what happens
– Add a dependency on log4j to Maven’s pom.xml and show the interaction between Maven, IntellliJ and Subversion

The actual project is nothing fancy, just a dummy Java Swing application.

But the same principles apply to more complicated scenarios, e.g. when working with a JEE stack. IMHO these are scenarios in which Maven can play its strengths. That’s perhaps a topic for a further blog post, who knows? 😉

Creating a Beacon App for Android in Less Than 10 Minutes from Scratch

 
Before starting to create a Beacon app for Android a few words about Bluetooth.

Bluetooth Low Energy (BLE)

Compared to classic Bluetooth, Bluetooth Low Energy consumes much less power (e.g. 0.01 W instead of 1W), the BLE devices are considerable cheaper to build, but the data transfer rate is much lower (e.g. 0.27 Mbit/s).

Great applications for BLE are scenarios where the power consumption must be low and the data rate is not important, e.g. the communication with small wearables, watches and fitness equipment and so on.

So it was only logical when Apple decided to use BLE as base technology for their small passive transmitters called iBeacons®.

Beacons

Beacons are permanently sending out their unique identifier to notify nearby smartphones of their existence, hence the name beacons. A compatible app running on the smartphone then knows that it is in a close proximity. Depending on the application, this can trigger an action on the smartphone, e.g. displaying some information about nearby items.

Beacons are available in different sizes and shapes and from different vendors, e.g. one being www.beaconinside.com.

Different Beacons from different Vendors

Different Beacons from different Vendors

Bluetooth Smart

Bluetooth Low Energy is also known as Bluetooth Smart. Since Android 4.3 Jelly Bean, Android also supports Bluetooth Smart.

Android Smartphone Requirements:

  • Android > 4.3
  • Bluetooth Smart radio unit

The Android SDK has no built-in support for beacons. But there is a library from Radius Networks that can be used.

Beacon Advertisements

Beacons broadcast in regular intervals (e.g. something between 100ms and 1 second). They send out their ID.

The ID consists of three parts:

  • UUID (organization or company)
  • major (arbitrarily, e.g. specific chain store)
  • minor (e.g. location in store)

Flow Control

First you have to define a Region. A region does not mean a geographically region, it’s rather a certain types of beacons you are interested in.

After defining a monitoring and ranging callback you can start monitoring.

Pseudo Code:

region = new Region("<someUUID>")
addMonitorCallback
    ->(didEnterRegion)
        startRangingBeaconsInRegion
    ->(didExitRegion)
        stopRangingBeaconsInRegion
addRangingCallback
    ->(didRangeBeaconsInRegion)
        evalute beacon info

startMonitoring(region)     

Coarse-grained Distance Estimations

The received signal strength indicator (RSSI) together with the Transmit Power can be used to measure the distance between transmitter and smartphone. The distance is not exactly measured; it’s more a coarse-grained estimation. Therefore often the proximity is divided intoImmediate (centimeters), Near (couple of meters) and Far (> 10 meters).

The library averages the distance measurements over 20 seconds in time, therefore you will note a lag, when the distance between beacons and smartphone changes. This might exactly be the behavior you want, since the distance estimations are coarse-grained and you are most likely interested in the information, which one of the beacons is the closest one.

Screencast

The following screencast shows in detail how to create a Beacon app for Android in less than 10 minutes from scratch.

Source Code

Finally here is the source code for this simple example.

package com.software7.beacon.app;

import android.os.RemoteException;
import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import org.altbeacon.beacon.*;

import java.util.Collection;


public class BeaconActivity extends ActionBarActivity implements BeaconConsumer {

    public static final String TAG = "BeaconsEverywhere";
    private BeaconManager beaconManager;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_beacon);

        beaconManager = BeaconManager.getInstanceForApplication(this);

        beaconManager.getBeaconParsers().add(new BeaconParser()
                .setBeaconLayout("m:2-3=0215,i:4-19,i:20-21,i:22-23,p:24-24,d:25-25"));

        beaconManager.bind(this);

    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        beaconManager.unbind(this);
    }

    @Override
    public void onBeaconServiceConnect() {
        final Region region = new Region("myBeaons", Identifier.parse("<replaceBySomeUIID>"), null, null);

        beaconManager.setMonitorNotifier(new MonitorNotifier() {
            @Override
            public void didEnterRegion(Region region) {
                try {
                    Log.d(TAG, "didEnterRegion");
                    beaconManager.startRangingBeaconsInRegion(region);
                } catch (RemoteException e) {
                    e.printStackTrace();
                }
            }

            @Override
            public void didExitRegion(Region region) {
                try {
                    Log.d(TAG, "didExitRegion");
                    beaconManager.stopRangingBeaconsInRegion(region);
                } catch (RemoteException e) {
                    e.printStackTrace();
                }
            }

            @Override
            public void didDetermineStateForRegion(int i, Region region) {

            }
        });

        beaconManager.setRangeNotifier(new RangeNotifier() {
            @Override
            public void didRangeBeaconsInRegion(Collection<Beacon> beacons, Region region) {
                for(Beacon oneBeacon : beacons) {
                    Log.d(TAG, "distance: " + oneBeacon.getDistance() + " id:" + oneBeacon.getId1() + "/" + oneBeacon.getId2() + "/" + oneBeacon.getId3());
                }
            }
        });

        try {
            beaconManager.startMonitoringBeaconsInRegion(region);
        } catch (RemoteException e) {
            e.printStackTrace();
        }

    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.menu_beacon, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();

        //noinspection SimplifiableIfStatement
        if (id == R.id.action_settings) {
            return true;
        }

        return super.onOptionsItemSelected(item);
    }
}


Last Famous Words

I hope that gets you started with your beacon project.

If you found this helpful, share it!

Helen 2.33 released

Bugfixes in Helen 2.33

  • To avoid losing changes, documents are now always marked ‘dirty’ for modifications done in the HTML code editor.
  • The hang during HTML export (due to multiple resources having the same name) is fixed.
  • A problem in the library s7rmtctrl.jar for the remote control of Helen via RMI (Remote Method Invocation) is fixed.
  • In exported PDF files the <sub> and <super> tags are displayed correctly.

New in Helen 2.3

Display of Invisibles (Formatting Characters)

Page breaks, Paragraphs, and sections breaks are called invsibles because you cannot see them by default. Now you can make these formatting characters visible using a new toolbar button: Paragraph

Invisibles en

Helen comes bundled now with JRE 1.6_31

Helen is available in different packages. The install packages bundled with Java Runtime
Environments (JRE) are coming now with JRE 1.6_31. There are packages for different system architectures and operating systems:

  • Windows Family (Windows 7, Vista, XP)
  • Mac OS X
  • Linux Intel

An install package without JRE is also available.

Create entries in table of contents, index, and map via context menu

In WYSIWYG design view you can add selected words to TOC, index, and map by using the context menu item ‘Add Entry…’.

AddEntry en

A dialog opens where you can control the entries for TOC, index and map.

AddEntryDlg en

In the ComboBox for the map items all entries referencing the edited HTML topic are shown. If desired, the entries can be edited in the ComboBox to create a completely new entry to the map file.

If an anchor is specified, the selected text is marked with this anchor and the map item references exact this position.

Fixed Problems

  • If the cursor was on a link during a switch from WYSIWYG design view to code view, the link was split.
  • Occasionally the preview application was not shutdown completely.
  • The CSS code editor sometimes threw an exception with specific CSS content.
  • For tables containing <colgroup> and/or <thead> tags, it was not possible in the table editor to add rows.

For more information visit: http://www.software7.biz