Android手持机扫码出入库的开发详解-3.出库扫码
出库扫码界面
出库扫码程序图
flowchart TD
A[进入出库扫码界面] --> B[初始化扫码设备]
B --> C[注册扫码广播接收器]
C --> D[初始化UI面板和数据库]
D --> E[等待扫描条码]
E --> F[扫码设备扫描条码]
F --> G[mScanReceiver接收扫描结果]
G --> H[GBK解码获取条码字符串]
H --> I[parseScanCodeData解析条码类型]
I -->|长度小于21货位码| J[validationHwh验证货位号]
I -->|长度大于等于21材料码| K[validationCode验证材料码]
J -->|验证失败| L[显示错误信息]
K -->|验证失败| L
J -->|验证成功| M[显示货位信息]
K -->|验证成功| N[显示材料信息]
M --> O{是否已扫描两种码}
N --> O
O -->|否| E
O -->|是| P[CorrelationData关联数据检查]
P -->|关联失败| Q[显示关联错误]
Q --> R[重置验证面板]
R --> E
P -->|关联成功| S[启用更新按钮]
S --> T[点击更新按钮]
T --> U[updateOutData更新数据库]
U --> V[更新待出库表扫码数量]
V --> W[插入出库扫码记录]
W --> X[Refresh_ListView刷新主界面]
X --> Y{是否所有数量已扫描}
Y -->|是| R
Y -->|否| Z[保持验证面板状态]
Z --> E
出库扫码程序流程说明:
- 初始化阶段:进入界面后,程序会初始化扫码设备、注册广播接收器、加载UI面板并初始化数据库连接
- 扫码阶段:扫码设备扫描条码后,通过广播接收器接收数据并进行GBK解码
- 条码解析:根据条码长度判断是货位码(<21位)还是材料码(≥21位)
- 验证阶段:分别对货位码和材料码进行验证,验证失败则显示错误信息
- 数据关联:当两种码都扫描完成后,进行货位号和生产日期的一致性检查
- 数据更新:验证通过后,更新待出库表中的扫码数量,并将扫描记录插入出库扫码表
- UI刷新:更新操作完成后,刷新主界面列表,并根据扫描数量决定是否重置验证面板
- 循环处理:完成一次扫码流程后,继续等待下一次扫描
出库扫码源代码
1. 初始化阶段
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_out_storage_scan_code);
// 获取用户信息
Intent intent = getIntent();
Bundle bundle = intent.getExtras();
this.userName = bundle.getString("userName");
// 初始化扫码设备
sm = new ScanDevice();
sm.openScan();
// 注册扫码广播接收器
IntentFilter filter = new IntentFilter(SCAN_ACTION);
registerReceiver(mScanReceiver, filter);
// 初始化数据库连接
OpenOrCreateDatabase();
// 初始化DAO对象
adao = new AwaitOutStorageDAO();
dao = new OutStorageDAO();
bomdao = new BillOfMaterialDAO();
mdao = new ManufacturerDAO();
skdao = new StoreKeeperDAO();
// 加载主UI面板
LinearLayout mainLinearLayout = findViewById(R.id.OutStorageScanCodeMainLinearLayout);
mainLinearLayout.setVisibility(LinearLayout.VISIBLE);
// 隐藏其他面板
HideDownloadDataChildLinearLayout();
HideSelectDataChildLinearLayout();
HideValidationChildLinearLayout();
}
// 创建或打开数据库
private void OpenOrCreateDatabase() {
sda = new SqliteDBConnection(this);
sda.open();
db = sda.getDb();
}
2. 扫码阶段
// 扫码广播接收器
private BroadcastReceiver mScanReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
// 获取扫码数据
byte[] barocode = intent.getByteArrayExtra("barocode");
int barocodelen = intent.getIntExtra("length", 0);
String barcodeStr = null;
try {
// GBK解码获取条码字符串
barcodeStr = new String(barocode, 0, barocodelen, "GBK");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
// 调用条码解析方法
parseScanCodeData(barcodeStr);
// 停止扫码
sm.stopScan();
}
};
3. 条码解析
// 条码解析
private void parseScanCodeData(String barcodeStr){
if (barcodeStr.length() >= 21) {
// 材料码(≥21位)
strCode = barcodeStr.toString();
// 验证材料码
validationCode(strCode);
} else {
// 货位码(<21位)
strHwh = barcodeStr.toString();
// 验证货位码
validationHwh(strHwh);
}
// 显示验证面板
ShowValidationChildLinearLayout();
}
4. 验证阶段
// 货位码验证
private void validationHwh(String strHwh) {
try {
// 验证货位码是否存在
int validationRes = adao.validationOutDataHwh(db, strHwh);
if (validationRes == 1) {
// 验证成功
textView_Validation_货位码验证结果.setText("✔");
textView_Validation_货位码验证结果.setTextColor(Color.parseColor("#228B22"));
// 查询并显示货位信息
AwaitOutStorage awaitOutStorage = adao.validationOutDataHwhAndGetInfo(db, strHwh);
textView_Validation_货位号A.setText(awaitOutStorage.getStr_货位号());
textView_Validation_生产日期A.setText(awaitOutStorage.getStr_来料日期());
textView_Validation_库存数量A.setText(String.valueOf(awaitOutStorage.getInt_库存数量()));
textView_Validation_应发数量A.setText(String.valueOf(awaitOutStorage.getInt_应发数量()));
textView_Validation_已扫数量A.setText(String.valueOf(awaitOutStorage.getInt_扫码数量()));
textView_Validation_未扫数量A.setText(String.valueOf(awaitOutStorage.getInt_未扫数量()));
// 检查是否已扫描两种码
if (strCode != null) {
CorrelationData(strHwh, strCode);
}
} else {
// 验证失败
textView_Validation_货位码验证结果.setText("✘");
textView_Validation_货位码验证结果.setTextColor(Color.RED);
textView_Validation_Msg.setText("错误:货位码不正确或不存在!");
}
} catch (Exception e) {
e.printStackTrace();
}
}
// 材料码验证
private void validationCode(String strCode) {
try {
// 从材料码中解析信息
String str_材料条码 = strCode.substring(0, 5);
String str_厂家代码 = strCode.substring(5, 7);
String str_生产日期 = ConvertDate(strCode.substring(7, 13));
String str_批号 = strCode.substring(13, 14);
String str_扫码数量 = strCode.substring(14, 20);
// 验证材料信息
int validationRes = adao.validationOutDataCode(db, str_材料条码, str_厂家代码, str_生产日期);
if (validationRes == 1) {
// 验证成功
textView_Validation_材料码验证结果.setText("✔");
textView_Validation_材料码验证结果.setTextColor(Color.parseColor("#228B22"));
// 查询并显示材料信息
AwaitOutStorage awaitOutStorage = adao.validationOutDataCodeAndGetInfo(db, str_材料条码, str_厂家代码, str_生产日期);
textView_Validation_货位号B.setText(awaitOutStorage.getStr_货位号());
textView_Validation_生产日期B.setText(awaitOutStorage.getStr_来料日期());
textView_Validation_库存数量B.setText(String.valueOf(awaitOutStorage.getInt_库存数量()));
textView_Validation_应发数量B.setText(String.valueOf(awaitOutStorage.getInt_应发数量()));
textView_Validation_已扫数量B.setText(String.valueOf(awaitOutStorage.getInt_扫码数量()));
textView_Validation_未扫数量B.setText(String.valueOf(awaitOutStorage.getInt_未扫数量()));
// 检查是否已扫描两种码
if (strHwh != null) {
CorrelationData(strHwh, strCode);
}
} else {
// 验证失败
textView_Validation_材料码验证结果.setText("✘");
textView_Validation_材料码验证结果.setTextColor(Color.RED);
textView_Validation_Msg.setText("错误:材料码不正确或不匹配!");
}
} catch (Exception e) {
e.printStackTrace();
}
}
5. 数据关联
// 数据关联检查
private void CorrelationData(String strHwh, String strCode) {
try {
// 获取两种码的货位号和生产日期
String str_货位号A = textView_Validation_货位号A.getText().toString();
String str_生产日期A = textView_Validation_生产日期A.getText().toString();
String str_货位号B = textView_Validation_货位号B.getText().toString();
String str_生产日期B = textView_Validation_生产日期B.getText().toString();
// 检查一致性
if (str_货位号A.equals(str_货位号B) && str_生产日期A.equals(str_生产日期B)) {
// 关联成功,启用更新按钮
button_Validation_UpdateData.setEnabled(true);
button_Validation_UpdateData.setClickable(true);
} else {
// 关联失败
textView_Validation_Msg.setText("错误:货位号和生产日期不一致!");
textView_Validation_Msg.setTextColor(Color.RED);
}
} catch (Exception e) {
e.printStackTrace();
}
}
6. 数据更新
// 数据更新
private void updateOutData() {
try {
// 获取相关数据
String str_货位号 = textView_Validation_货位号A.getText().toString();
String str_生产日期 = textView_Validation_生产日期A.getText().toString();
String str_材料条码 = strCode.substring(0, 5);
String str_厂家代码 = strCode.substring(5, 7);
String str_扫码数量 = strCode.substring(14, 20);
// 更新待出库表扫码数量
adao.updateScanCodeSumAdd(db, str_货位号, str_生产日期, str_材料条码, str_厂家代码, str_扫码数量);
// 插入出库扫码记录
OutStorage outStorage = OutStorage.newInstance();
outStorage.setStr_货位号(str_货位号);
outStorage.setStr_扫码时间(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
outStorage.setStr_扫码人(userName);
outStorage.setStr_扫码仓库("B库");
// 设置其他出库信息
// ...
// 向出库扫码表中插入数据
Cursor dao_cursor = dao.insertData(db, outStorage);
// 重新查询数据
Cursor cursor = adao.findOutData(db, str_材料条码, str_厂家代码);
} catch (Exception e) {
e.printStackTrace();
}
}
7. UI刷新
// 刷新主界面列表
private void Refresh_ListView(Cursor cursor) {
// 填充SimpleCursorAdapter
SimpleCursorAdapter adapter = new SimpleCursorAdapter(
this,
R.layout.activity_out_storage_scan_code_scan_data_listview,
cursor,
new String[]{"_id", "货位号", "材料名称", "材料规格", "颜色", "库管员", "厂家缩写", "CBW对照号", "单位", "材料条码", "厂家代码", "生产日期", "批号", "数量", "库管编码", "码文", "扫码人", "扫码时间", "扫码仓库", "出库编号"},
new int[]{
R.id.textView_listView_OutStorageScanCode_DataList_ID,
R.id.textView_listView_OutStorageScanCode_DataList_货位号,
// 其他UI控件ID
// ...
}, 0
);
listView_DataList.setAdapter(adapter);
}
// 刷新待出库表列表
private void Refresh_ListView_OutData(Cursor cursor) {
SimpleCursorAdapter adapter = new SimpleCursorAdapter(
this,
R.layout.activity_out_storage_scan_code_out_data_listview,
cursor,
new String[]{"_id", "货位号", "来料日期", "库存数量", "应发数量", "扫码数量", "验证结果"},
new int[]{
R.id.textView_listView_OutStorageScanCode_OutDataList_ID,
R.id.textView_listView_OutStorageScanCode_OutDataList_货位号,
// 其他UI控件ID
// ...
}, 0
);
listView_OutDataList.setAdapter(adapter);
}
// 清空验证面板信息
private void clearValidationInfo() {
// 重置所有验证控件
textView_Validation_货位号A.setText("");
textView_Validation_生产日期A.setText("");
// 其他验证控件
// ...
// 重置扫码状态
strCode = null;
strHwh = null;
}
8. 循环处理
// 数据更新后的循环处理
if (Integer.parseInt(str_未扫数量) != 0) {
// 同一货位仍有未扫数量,继续扫码
textView_Validation_Msg.setText("此货位号还需出库:" + str_未扫数量 + ",请继续扫材料码?");
textView_Validation_Msg.setTextColor(Color.BLUE);
// 重置部分验证信息,保留货位信息
textView_Validation_货位号B.setText("");
textView_Validation_生产日期B.setText("");
// 其他材料码相关控件
// ...
// 重置材料码状态
strCode = null;
} else {
// 扫码完成,重置所有验证信息
clearValidationInfo();
// 隐藏验证面板
HideValidationChildLinearLayout();
}
// 重新启动扫码,等待下一次扫描
if (sm != null) {
sm.openScan();
}
该实现采用了分层架构设计,通过DAO模式访问数据库,使用异步任务处理耗时操作,确保UI响应流畅。同时实现了条码验证、数据关联检查和数据库事务管理,保证了出库操作的准确性和数据一致性。