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 a message from your application. The information included inside the Intent is used to generate a screen which is shown on the HUD.
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.
Explicitly starting the Intent Interface is required due to Android limitations on background operations.
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.
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 SEND_TEXT action 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.
Extra |
Purpose |
Type |
Default Value |
---|---|---|---|
|
Text on row N. |
String or String[] |
<empty-string> |
|
The color of the text or row N. |
String or String[] |
“white” |
|
The background color for row N. |
String or String[] |
“black” |
|
Adds extra space between text elements, likely making text smaller. |
int |
10 |
|
Adds extra space between text elements, likely making text smaller. |
int |
5 |
|
Defines the text alignment for text on row N. |
String |
“center” |
|
Defines the relative height of row N compared to other rows. |
String |
“1” |
|
Defines the maximum number of rows of text on row N. |
int |
1 |
Extra |
Description |
---|---|
|
Empty string causes row N to not be shown. If |
|
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 |
|
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 |
|
Units are in dp. On the HMD, 3.5px=1dp. Must be between 0 and 30 inclusively. |
|
Units are in dp. On the HMD, 3.5px=1dp. Must be between 0 and 10 inclusively. |
|
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” |
|
A floating point number parsed by Java’s |
|
Fewer lines may be used if it results in larger text. Manual new-lines can be placed using “\n” within 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.
Send Screen¶
Sending an Intent with action = “com.six15.hudservice.ACTION_SEND_SCREEN” sends an image to the HMD. Send Screen can be used as a simpler version of Send Text where formatting is left up to the Six15 Service.
The extra value lines
should be set to an array of strings, or a string with each line separated by a “\n” character.
These lines represent a series of textual information, likely the entire contents of a terminal screen application.
The Intent Interface will process the lines and automatically convert them into an image to show on the HUD. Exactly how this processing is done is determined by the Six15 Service application.
The processing steps can be partially configured through the Six15 Service app’s settings option “Smart Configurator”. These settings also apply to the “Picking Test Drive” demo which uses optical character recognition (OCR) to read text from the screen.
Send Screen is used to implement Smart Velocity through a generic Velocity script.
Examples¶
Make sure the service is started, when trying these examples.
ADB Shell¶
The following command sends a SEND_TEXT action 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.
A similar, but less customized, image can be sent using the SEND_SCREEN action.
adb shell am broadcast -a com.six15.hudservice.ACTION_SEND_SCREEN --esa lines "Scan\ Location,Aisle:M58,Shelf:F10,Level:2"
Note
When run using adb shell, ” ” <space> characters in extras must be escaped. Otherwise the command will fail and no image will be shown on the HMD.
Java Code¶
The following Java code snippet sends a Send Text action to the Intent Interface. The Intent Interface will draw the corresponding image on the HMD. 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);
A similar, but less customized, image can be sent using the SEND_SCREEN action.
Intent intent = new Intent("com.six15.hudservice.ACTION_SEND_SCREEN");
intent.putExtra("lines", new String[]{"Scan Location", "Aisle:M58","Shelf:F10", "Level:2"});
sendBroadcast(intent);
See the Intent Interface examples for more, and for examples starting and stopping the service.