Skip to content

Commit d45a8d5

Browse files
committed
The hardware scan keys now trigger the capture process.
Added a "About' entry in the menu with dependencies informations and license
1 parent 4448f21 commit d45a8d5

File tree

11 files changed

+583
-0
lines changed

11 files changed

+583
-0
lines changed

AI_MultiBarcodes_Capture/src/main/AndroidManifest.xml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,10 @@
3838
android:name=".settings.SettingsActivity"
3939
android:exported="false"
4040
android:screenOrientation="portrait" />
41+
<activity
42+
android:name=".AboutActivity"
43+
android:exported="false"
44+
android:screenOrientation="portrait" />
4145
<activity
4246
android:name=".SplashActivity"
4347
android:exported="true"
Binary file not shown.
Lines changed: 203 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,203 @@
1+
// Copyright 2025 Zebra Technologies Corporation and/or its affiliates. All rights reserved.
2+
package com.zebra.ai_multibarcodes_capture;
3+
4+
import android.content.Context;
5+
import android.content.Intent;
6+
import android.net.Uri;
7+
import android.os.Bundle;
8+
import android.view.View;
9+
import android.widget.Button;
10+
import android.widget.ImageView;
11+
import android.widget.TextView;
12+
import android.widget.Toast;
13+
14+
import androidx.appcompat.app.AppCompatActivity;
15+
import androidx.core.content.FileProvider;
16+
17+
import com.zebra.ai_multibarcodes_capture.helpers.LocaleHelper;
18+
import com.zebra.ai_multibarcodes_capture.helpers.LogUtils;
19+
20+
import java.io.File;
21+
import java.io.FileOutputStream;
22+
import java.io.IOException;
23+
import java.io.InputStream;
24+
import java.io.OutputStream;
25+
26+
/**
27+
* AboutActivity displays information about the application and its dependencies.
28+
* Shows the app version and versions of key libraries used in the project.
29+
*/
30+
public class AboutActivity extends AppCompatActivity {
31+
32+
private static final String TAG = "AboutActivity";
33+
34+
@Override
35+
protected void onCreate(Bundle savedInstanceState) {
36+
super.onCreate(savedInstanceState);
37+
setContentView(R.layout.activity_about);
38+
39+
// Set up the toolbar and back button
40+
ImageView backButton = findViewById(R.id.back_button);
41+
backButton.setOnClickListener(new View.OnClickListener() {
42+
@Override
43+
public void onClick(View v) {
44+
finish();
45+
}
46+
});
47+
48+
// Set title
49+
TextView titleText = findViewById(R.id.title_text);
50+
titleText.setText(R.string.activity_about);
51+
52+
// Display app version
53+
TextView appVersionValue = findViewById(R.id.app_version_value);
54+
String versionInfo = BuildConfig.VERSION_NAME + " (" + BuildConfig.VERSION_CODE + ")";
55+
appVersionValue.setText(versionInfo);
56+
57+
// Display Zebra AI Vision SDK version
58+
TextView zebraAiVersionValue = findViewById(R.id.zebra_ai_vision_sdk_value);
59+
zebraAiVersionValue.setText(getVersionString("zebraAIVisionSdk"));
60+
61+
// Display Barcode Localizer version
62+
TextView barcodeLocalizerValue = findViewById(R.id.barcode_localizer_value);
63+
barcodeLocalizerValue.setText(getVersionString("barcodeLocalizer"));
64+
65+
// Display Critical Permission Helper version
66+
TextView criticalPermissionHelperValue = findViewById(R.id.critical_permission_helper_value);
67+
criticalPermissionHelperValue.setText(getVersionString("criticalpermissionhelper"));
68+
69+
// Display DataWedge Intent Wrapper version
70+
TextView datawedgeIntentWrapperValue = findViewById(R.id.datawedge_intent_wrapper_value);
71+
datawedgeIntentWrapperValue.setText(getVersionString("datawedgeintentwrapper"));
72+
73+
// Set up GitHub repository link
74+
TextView repositoryLink = findViewById(R.id.repository_link);
75+
repositoryLink.setOnClickListener(new View.OnClickListener() {
76+
@Override
77+
public void onClick(View v) {
78+
openGitHubRepository();
79+
}
80+
});
81+
82+
// Set up license view button
83+
Button viewLicenseButton = findViewById(R.id.view_license_button);
84+
viewLicenseButton.setOnClickListener(new View.OnClickListener() {
85+
@Override
86+
public void onClick(View v) {
87+
openLicensePdf();
88+
}
89+
});
90+
}
91+
92+
/**
93+
* Opens the GitHub repository in a web browser
94+
*/
95+
private void openGitHubRepository() {
96+
String url = getString(R.string.about_repository_url);
97+
Intent intent = new Intent(Intent.ACTION_VIEW);
98+
intent.setData(Uri.parse(url));
99+
startActivity(intent);
100+
}
101+
102+
/**
103+
* Opens the license PDF file using an external PDF viewer
104+
*/
105+
private void openLicensePdf() {
106+
try {
107+
LogUtils.d(TAG, "Opening license PDF");
108+
109+
// Copy PDF from assets to cache directory if needed
110+
File pdfFile = new File(getCacheDir(), "Zebra_Development_Tool_License.pdf");
111+
LogUtils.d(TAG, "PDF file path: " + pdfFile.getAbsolutePath());
112+
113+
if (!pdfFile.exists()) {
114+
LogUtils.d(TAG, "PDF file doesn't exist in cache, copying from assets");
115+
copyAssetToCache("Zebra_Development_Tool_License.pdf", pdfFile);
116+
LogUtils.d(TAG, "PDF copied successfully, file size: " + pdfFile.length());
117+
} else {
118+
LogUtils.d(TAG, "PDF already exists in cache, file size: " + pdfFile.length());
119+
}
120+
121+
// Get URI using FileProvider
122+
Uri pdfUri = FileProvider.getUriForFile(
123+
this,
124+
"com.zebra.ai_multibarcodes_capture.dev.fileprovider",
125+
pdfFile
126+
);
127+
LogUtils.d(TAG, "FileProvider URI: " + pdfUri.toString());
128+
129+
// Create intent to view PDF
130+
Intent intent = new Intent(Intent.ACTION_VIEW);
131+
intent.setDataAndType(pdfUri, "application/pdf");
132+
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
133+
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
134+
135+
// Try to start the activity with a chooser to ensure it works
136+
try {
137+
startActivity(Intent.createChooser(intent, "Open License PDF"));
138+
LogUtils.d(TAG, "PDF viewer intent started successfully");
139+
} catch (Exception e) {
140+
LogUtils.e(TAG, "Failed to open PDF with chooser", e);
141+
Toast.makeText(this, "No PDF viewer app found. Please install a PDF reader.", Toast.LENGTH_LONG).show();
142+
}
143+
} catch (Exception e) {
144+
LogUtils.e(TAG, "Error opening license PDF", e);
145+
Toast.makeText(this, "Error opening license: " + e.getMessage(), Toast.LENGTH_LONG).show();
146+
}
147+
}
148+
149+
/**
150+
* Copies a file from assets to the cache directory
151+
*/
152+
private void copyAssetToCache(String assetName, File outputFile) throws IOException {
153+
InputStream in = null;
154+
OutputStream out = null;
155+
try {
156+
in = getAssets().open(assetName);
157+
out = new FileOutputStream(outputFile);
158+
159+
byte[] buffer = new byte[1024];
160+
int read;
161+
while ((read = in.read(buffer)) != -1) {
162+
out.write(buffer, 0, read);
163+
}
164+
} finally {
165+
if (in != null) {
166+
in.close();
167+
}
168+
if (out != null) {
169+
out.close();
170+
}
171+
}
172+
}
173+
174+
/**
175+
* Gets version string for a dependency from gradle version catalog.
176+
* This is a placeholder that returns the version from the libs.versions.toml
177+
*
178+
* @param dependencyName Name of the dependency
179+
* @return Version string
180+
*/
181+
private String getVersionString(String dependencyName) {
182+
// Version strings from gradle/libs.versions.toml
183+
switch (dependencyName) {
184+
case "zebraAIVisionSdk":
185+
return "3.0.2";
186+
case "barcodeLocalizer":
187+
return "5.0.1";
188+
case "criticalpermissionhelper":
189+
return "0.8.1";
190+
case "datawedgeintentwrapper":
191+
return "14.10";
192+
default:
193+
return "Unknown";
194+
}
195+
}
196+
197+
@Override
198+
protected void attachBaseContext(Context newBase) {
199+
String languageCode = LocaleHelper.getCurrentLanguageCode(newBase);
200+
Context context = LocaleHelper.setLocale(newBase, languageCode);
201+
super.attachBaseContext(context);
202+
}
203+
}

AI_MultiBarcodes_Capture/src/main/java/com/zebra/ai_multibarcodes_capture/EntryChoiceActivity.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,9 @@ public boolean onMenuItemClick(MenuItem menuItem) {
181181
} else if (id == R.id.action_settings) {
182182
Intent intent = new Intent(EntryChoiceActivity.this, SettingsActivity.class);
183183
resultSettings.launch(intent);
184+
} else if (id == R.id.action_about) {
185+
Intent intent = new Intent(EntryChoiceActivity.this, AboutActivity.class);
186+
startActivity(intent);
184187
}
185188
return false;
186189
}

AI_MultiBarcodes_Capture/src/main/java/com/zebra/ai_multibarcodes_capture/helpers/Constants.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -227,4 +227,7 @@ public class Constants {
227227
public static final String SHARED_PREFERENCES_FILTERING_REGEX = "SHARED_PREFERENCES_FILTERING_REGEX";
228228
public static final String SHARED_PREFERENCES_FILTERING_REGEX_DEFAULT = "";
229229

230+
231+
public static final int KEYCODE_BUTTON_R1 = 103;
232+
public static final int KEYCODE_SCAN = 10036;
230233
}

AI_MultiBarcodes_Capture/src/main/java/com/zebra/ai_multibarcodes_capture/java/CameraXLivePreviewActivity.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -993,6 +993,15 @@ private void captureData() {
993993
}
994994
}
995995

996+
@Override
997+
public boolean onKeyDown(int keyCode, android.view.KeyEvent event) {
998+
if(keyCode == Constants.KEYCODE_BUTTON_R1 || keyCode == Constants.KEYCODE_SCAN)
999+
{
1000+
captureData();
1001+
}
1002+
return super.onKeyDown(keyCode, event);
1003+
}
1004+
9961005
@Override
9971006
protected void attachBaseContext(Context newBase) {
9981007
String languageCode = LocaleHelper.getCurrentLanguageCode(newBase);
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<vector xmlns:android="http://schemas.android.com/apk/res/android"
3+
android:width="24dp"
4+
android:height="24dp"
5+
android:viewportWidth="24"
6+
android:viewportHeight="24">
7+
<circle
8+
android:strokeColor="@color/zebra"
9+
android:strokeWidth="2"
10+
android:fillColor="@color/white"
11+
cx="12"
12+
cy="12"
13+
r="10"/>
14+
<path
15+
android:fillColor="@color/zebra"
16+
android:pathData="M11,7h2v2h-2z"/>
17+
<path
18+
android:fillColor="@color/zebra"
19+
android:pathData="M11,11h2v6h-2z"/>
20+
</vector>

0 commit comments

Comments
 (0)