Introduction

The Intent Interface is one of two main methods of showing custom content on the ST1. It uses Android’s Broadcast Intents to receive an Intent from your application. This interface is designed to send informational text with some formatting to the HUD.

Its design is intentionally limited to simplify the interface and content it generates.

Start Service

The intent interface runs in a foreground service and must be started before it can be used. This can be done via the toggle in one of the Six15 Service apps, ADB, or code.

Service App

The Intent Interface can be manually started using the toggle switch in the “Six15 ST1” app.

Code

Ideally, the service could be started with context.startService() (context.startForegroundService() on newer version of Android). Unfortunately, newer versions of Android block the Intent Interface Service from starting when the Six15 app is not running. This can happen after a reboot, after “Force Stopping” the app, or for any other reason Android decides.

To work around this issue, we have an activity in the Six15 service application which can receive start requests, forward them to the service, then closes itself. This allows the service to be started reliably in any situation. The activity is totally transparent so this sequence is not visible to the user at all. The calling application will momentarily move into the paused state, so onPause() and onResume() will be called when this happens. Note, using the AIDL interface and binding to the Six15 service will keep our app running and this problem will not occur.

The service and forwarding activity both register an intent filter action “com.six15.hudservice.ACTION_START_INTENT_SERVICE”. This makes them easy to discover with pm.queryIntentServices(...) or pm.queryIntentActivities(...) at runtime. They should however be launched as explicit intents.

Discovering these intents at runtime requires the following entry in your Android Manifest (inside the manifest tag).

<queries>
    <intent>
        <action android:name="com.six15.hudservice.ACTION_START_INTENT_SERVICE" />
    </intent>
</queries>

See the example function HudIntentInterface.startIntentInterface(Context) for how to start the Intent Interface correctly from code. It takes care of all this complexity. Using this function also requires the above queries entry.

ADB

The Intent Interface can be started with ADB. This is mostly useful for development.

adb shell am start-foreground-service \
    com.six15.st1_connect/com.six15.intent_interface.IntentInterfaceService

Unlike when starting from code, ADB has no problem starting the service when it’s in the background. This means the forwarding activity is not needed. That being said, using the forwarding activity works too.

adb shell am start -n com.six15.st1_connect/com.six15.intent_interface.IntentInterfaceActivity

No matter how it’s started, no specific Intent action string is needed to start the Intent Interface. If the intent does contain an action, that action (and it’s associated extras) are processed as if they were a broadcast. When used with action “com.six15.hudservice.ACTION_SEND_TEXT”, an initial image can be shown on the display right after the service starts. This can be useful to avoid race conditions between starting the service/activity and sending the first broadcast to it. From code this can be done when calling HudIntentInterface.startIntentInterface(context, action, args).

API Definition

Each Intent corresponds to a single image or command. The action of the Intent defines what should happen. There are currently 4 supported actions.

Clear Display

Sending an Intent with action = “com.six15.hudservice.ACTION_CLEAR_DISPLAY” clears the HMD.

adb shell am broadcast -a com.six15.hudservice.ACTION_CLEAR_DISPLAY

or use the example function.

HudIntentInterface.clearDisplay(context)

Stop Service

Sending an Intent with action = “com.six15.hudservice.ACTION_STOP_INTENT_SERVICE” stops the Intent Interface service. After this, the service must be restarted before sending another image.

adb shell am broadcast -a com.six15.hudservice.ACTION_STOP_INTENT_SERVICE

or use the example function.

HudIntentInterface.stopIntentInterface(context)

Send Text

Sending an Intent with action = “com.six15.hudservice.ACTION_SEND_TEXT” sends an image to the HMD. The various extras listed below define the text/color/background etc… of the image.

Extras are a key/value pair which are part of an Intent. Each extra has a type associated with it. For example, the extra with key:”text0” and type:”String” might have value:”This is Example Text”.

The Intent Interface can display between 1 and 4 rows of text. Extras ending with the number N (0,1,2,3) define properties for row N. For example, color2 defines the text color for row 2. If no text is given for a specific row, that row is skipped and the other rows expand to take its space. To draw an empty row set textN to ” ” <space> for that row.

Within each row, there can be between 1 and 4 evenly split columns of text.

Text size is calculated automatically. The largest size possible is used, after accounting for the specified weighting and padding. All text on the same row is the same size. The font is Roboto and cannot be changed. All leading or trailing spaces are automatically trimmed.

Extras: Purpose, Type, and Default Value

Extra

Purpose

Type

Default Value

textN

Text on row N.

String or String[]

<empty-string>

colorN

The color of the text or row N.

String or String[]

“white”

bg_colorN

The background color for row N.

String or String[]

“black”

padding_horizontalN

Adds extra space between text elements, likely making text smaller.

int

10

padding_verticalN

Adds extra space between text elements, likely making text smaller.

int

5

gravityN

Defines the text alignment for text on row N.

String

“center”

weightN

Defines the relative height of row N compared to other rows.

String

“1”

max_linesN

Defines the maximum number of rows of text on row N.

int

1

Extras: Description

Extra

Description

textN

Empty string causes row N to not be shown. If textN is an array, each element is its own equal width column within that row.

colorN

A color as parsed by Color.parseColor() i.e. #rrggbb. When passed as an array, each color applies to one of the array elements of textN. If passed as a singular color, it applies to the whole row.

bg_colorN

A color as parsed by Color.parseColor() i.e. #rrggbb. When passed as an array, each color applies to one of the array elements of textN. If passed as a singular color, it applies to the whole row.

padding_horizontalN

Units are in dp. On the HMD, 3.5px=1dp. Must be between 0 and 30 inclusively.

padding_verticalN

Units are in dp. On the HMD, 3.5px=1dp. Must be between 0 and 10 inclusively.

gravityN

An OR of any of the following: center_vertical, fill_vertical, center_horizontal, fill_horizontal, center, top, bottom, left, right, start, end.

Similar to Android’s Gravity i.e. “center_horizontal|top”

weightN

A floating point number parsed by Java’s Float.parseFloat(String).

max_linesN

Fewer lines may be used if it results in larger text. Manual new-lines can be placed using “\n” within textN. Must be between 1 and 4 inclusively.

Using this field can be useful if dynamic multi-line text rendering is needed. Manually splitting text into separate rows can cause size mismatches.

Action Send

The Intent Interface can handle Android’s standard share action Intent.ACTION_SEND (aka "android.intent.action.SEND") for any “image/*”. If your app already uses Intent.ACTION_SEND it may already work with this interface. Android has complete documentation on Send Intents.

As is standard for Intent.ACTION_SEND intents, the image must be added to the intent intent.putExtra(Intent.EXTRA_STREAM, uri). The type of data must be set with intent.setType("image/*") (or something more specific like intent.setType("image/jpeg")).

The Uri must be “local”, therefore Uri schemes like “http” are not supported. See ImageView.setImageURI(Uri).

It’s possible to explicitly target the Intent Interface Activity using Intent.setComponent(component), or share an image implicitly and use Intent.createChooser(intent, "Title") to allow the user to pick which app to use.

Intent flag Intent.FLAG_GRANT_READ_URI_PERMISSION and intent.setClipData(...) should be set as shown below.

intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
intent.setClipData(ClipData.newUri(context.getContentResolver(), null, uri));

Finally, to send the Intent, use context.startActivity(intent).

Example function HudIntentInterface.sendActionSend(Context, Uri) can be used to perform this whole process when explicitly targeting the Intent Interface.

Note

It would be very non-standard to use startService() or sendBroadcast() with an Intent.ACTION_SEND intent. Doing so is NOT recommend. Keep in mind that sendBroadcast() requires that the Intent Interface is already running, and that startService() can fail if the Six15 application isn’t running in the background.

Our example application shows 2 sample Intent.ACTION_SEND intents. One sends a resource (R.drawable.*, R.raw.*, or R.mipmap.*) from the example application to the HUD. The other creates a Bitmap, draws on it, saves it to internal storage as a JPEG file, creates a content Uri from the file, and sends the Uri to the HUD.

Both examples can be found on our GitHub.

Examples

Make sure the service is started, when trying these examples.

ADB Shell

The following command sends an Intent to the Intent Interface via ADB. The Intent Interface will draw the corresponding image on the HUD.

adb shell am broadcast -a com.six15.hudservice.ACTION_SEND_TEXT \
    --esa text0 "Scan\ Location" \
    --es bg_color0 "\#454e83" \
    --es weight0 "1" \
\
    --esa text1 "Aisle:,Shelf:,Level:" \
    --es bg_color1 "\#20e5ff" \
    --es color1 "BLACK" \
    --es weight1 "1" \
\
    --esa text2 "M58,F10,2" \
    --es weight2 "2"

--es means “extra string”

--esa means “extra string array”, where each element is separated by a comma.

Note

When run using adb shell, ” ” <space> characters in extras must be escaped. Otherwise the command will fail.

Intent Interface Example

This image would be shown on the HMD.

Java Code

The following Java code snippet sends an Intent to the Intent Interface. The Intent Interface will draw the corresponding image on the HUD. See the examples section and example repository for more.

Be sure the service is started, otherwise this will not work.

Intent intent = new Intent("com.six15.hudservice.ACTION_SEND_TEXT");

intent.putExtra("text0", new String[]{"Scan Location"});
intent.putExtra("bg_color0", "#454e83");
intent.putExtra("weight0", "1");

intent.putExtra("text1", new String[]{"Aisle", "Shelf", "Level"});
intent.putExtra("bg_color1", "#20e5ff");
intent.putExtra("color1", "BLACK");
intent.putExtra("weight1", "1");

intent.putExtra("text2", new String[]{"M58", "F10", "2"});
intent.putExtra("weight2", "2");

sendBroadcast(intent);
Intent Interface Example

This image would be shown on the HMD.

See the Intent Interface examples for more, and for examples starting and stopping the service.