扫码签名模块
This commit is contained in:
parent
a9fd1062d4
commit
a75576160f
|
|
@ -144,6 +144,9 @@
|
|||
<activity
|
||||
android:name="com.bonus.gzvis.app.fragment.pay.SecondActivity"
|
||||
android:screenOrientation="portrait" />
|
||||
<activity android:name="com.bonus.gzvis.app.util.CustomScannerActivity"
|
||||
android:screenOrientation="portrait"
|
||||
android:theme="@style/Theme.AppCompat.Light.NoActionBar"/>
|
||||
|
||||
<meta-data
|
||||
android:name="com.baidu.lbsapi.API_KEY"
|
||||
|
|
|
|||
|
|
@ -0,0 +1,264 @@
|
|||
package com.bonus.gzvis.app.fragment.person.attendance;
|
||||
|
||||
import android.Manifest;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.BitmapFactory;
|
||||
import android.os.Bundle;
|
||||
import android.os.Environment;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.widget.Button;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.appcompat.app.AlertDialog;
|
||||
import androidx.core.content.ContextCompat;
|
||||
|
||||
import com.bonus.gzvis.app.base.BaseFragment;
|
||||
import com.bonus.gzvis.app.util.CustomScannerActivity;
|
||||
import com.bonus.gzvis.app.util.DateTimeHelper;
|
||||
import com.bonus.gzvis.app.util.GlideUtil;
|
||||
import com.bonus.gzvis.app.util.SignatureView;
|
||||
import com.bonus.gzvis.app.util.StringHelper;
|
||||
import com.bonus.gzvis.app.util.WorkConfig;
|
||||
import com.bonus.gzvis.app.util.XToastUtils;
|
||||
import com.bumptech.glide.Glide;
|
||||
import com.google.zxing.integration.android.IntentIntegrator;
|
||||
import com.google.zxing.integration.android.IntentResult;
|
||||
import com.xuexiang.xpage.annotation.Page;
|
||||
import com.xuexiang.xpage.enums.CoreAnim;
|
||||
import org.easydarwin.easypusher.R;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
|
||||
import butterknife.BindView;
|
||||
import okhttp3.FormBody;
|
||||
|
||||
/**
|
||||
* 二维码扫描与签名Fragment
|
||||
*/
|
||||
@Page(name = "扫码签名", anim = CoreAnim.none)
|
||||
public class ScanFragment extends BaseFragment {
|
||||
|
||||
private static final int CAMERA_PERMISSION_REQUEST_CODE = 100;
|
||||
|
||||
@BindView(R.id.title)
|
||||
TextView title;
|
||||
@BindView(R.id.back) TextView back;
|
||||
@BindView(R.id.add) TextView add;
|
||||
@BindView(R.id.signature_image) ImageView signatureImage;
|
||||
@BindView(R.id.btn_upload) Button btnUpload;
|
||||
|
||||
private final String signaturePath = Environment.getExternalStorageDirectory().getAbsolutePath() + "/signature/";
|
||||
private final String signatureName = DateTimeHelper.getNowDateHMS() + "_signature.jpg";
|
||||
private boolean hasSignature = false;
|
||||
|
||||
private String key="";
|
||||
|
||||
@Override
|
||||
protected int getLayoutId() {
|
||||
return R.layout.activity_scan;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void initViews() {
|
||||
setupTitle();
|
||||
setupSignatureView();
|
||||
}
|
||||
|
||||
private void setupTitle() {
|
||||
title.setText("扫描");
|
||||
back.setOnClickListener(v -> popToBack());
|
||||
add.setOnClickListener(v -> checkCameraPermission());
|
||||
}
|
||||
|
||||
private void setupSignatureView() {
|
||||
// 初始化签名按钮点击事件
|
||||
signatureImage.setOnClickListener(v -> showSignatureDialog());
|
||||
|
||||
// 初始化上传按钮点击事件
|
||||
btnUpload.setOnClickListener(v -> {
|
||||
if (hasSignature) {
|
||||
uploadSignature();
|
||||
} else {
|
||||
XToastUtils.error("请先完成签名");
|
||||
}
|
||||
});
|
||||
|
||||
// 检查是否有已保存的签名
|
||||
checkExistingSignature();
|
||||
}
|
||||
|
||||
private void checkExistingSignature() {
|
||||
File signatureFile = new File(signaturePath + signatureName);
|
||||
if (signatureFile.exists()) {
|
||||
loadSignatureImage(signatureFile.getAbsolutePath());
|
||||
hasSignature = true;
|
||||
}
|
||||
}
|
||||
|
||||
private void showSignatureDialog() {
|
||||
View view = LayoutInflater.from(getActivity()).inflate(R.layout.activity_sign_aotograp, null);
|
||||
AlertDialog dialog = new AlertDialog.Builder(getActivity()).create();
|
||||
SignatureView signatureView = view.findViewById(R.id.signature);
|
||||
|
||||
// 确保签名目录存在
|
||||
File dir = new File(signaturePath);
|
||||
if (!dir.exists()) {
|
||||
dir.mkdirs();
|
||||
}
|
||||
|
||||
// 自动清除签名板
|
||||
view.post(signatureView::clear);
|
||||
|
||||
// 设置按钮点击事件
|
||||
view.findViewById(R.id.clear).setOnClickListener(v -> signatureView.clear());
|
||||
view.findViewById(R.id.next_btn).setOnClickListener(v -> saveSignature(signatureView, dialog));
|
||||
|
||||
dialog.setView(view);
|
||||
dialog.show();
|
||||
}
|
||||
|
||||
private void saveSignature(SignatureView signatureView, AlertDialog dialog) {
|
||||
if (!signatureView.getSigstatus()) {
|
||||
XToastUtils.error("请在签名区域填写签名!");
|
||||
return;
|
||||
}
|
||||
|
||||
String path = signaturePath + signatureName;
|
||||
try {
|
||||
if (signatureView.save(path)) {
|
||||
signatureView.clear();
|
||||
XToastUtils.success("签名保存成功");
|
||||
loadSignatureImage(path);
|
||||
hasSignature = true;
|
||||
dialog.dismiss();
|
||||
} else {
|
||||
dialog.dismiss();
|
||||
XToastUtils.error("签名保存失败");
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
XToastUtils.error("保存出错: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
private void loadSignatureImage(String path) {
|
||||
if (path.startsWith("http")) {
|
||||
GlideUtil.GlideWithPlaceHolder(getActivity(), path).into(signatureImage);
|
||||
} else {
|
||||
Bitmap bitmap = BitmapFactory.decodeFile(path);
|
||||
if (bitmap != null) {
|
||||
signatureImage.setImageBitmap(bitmap);
|
||||
} else {
|
||||
signatureImage.setImageResource(R.drawable.add_ic);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 上传
|
||||
*/
|
||||
private void uploadSignature() {
|
||||
try {
|
||||
String uploadUrl = WorkConfig.getGzramaUrl() + "personAtt/transferAutograph";
|
||||
if ("".equals(key)){
|
||||
XToastUtils.warning("请先扫描二维码获取信息");
|
||||
return;
|
||||
}
|
||||
if (hasSignature) {
|
||||
File signatureFile = new File(signaturePath + signatureName);
|
||||
if (signatureFile.exists()) {
|
||||
XToastUtils.success("开始上传签名...");
|
||||
// 这里添加实际上传代码
|
||||
String url = uploadFileNew(signaturePath+signatureName,"grap");
|
||||
System.err.println("签名地址:"+url);
|
||||
if (!"".equals(url)){
|
||||
FormBody body = new FormBody.Builder()
|
||||
.add("key",strIsEmty(key,1))
|
||||
.add("value1",strIsEmty(url,1))
|
||||
.build();
|
||||
String result = service.httpPost(uploadUrl,body);
|
||||
System.out.println(result);
|
||||
if(!StringHelper.isEmptyAndNull(result)){
|
||||
org.json.JSONObject jsonObject = new org.json.JSONObject(result);
|
||||
int res = jsonObject.getInt("res");
|
||||
if (res == 1){
|
||||
XToastUtils.success("上传成功");
|
||||
popToBack();
|
||||
} else {
|
||||
XToastUtils.error("上传失败,请重试");
|
||||
}
|
||||
}
|
||||
} else {
|
||||
XToastUtils.error("签名上传失败,请重试");
|
||||
}
|
||||
} else {
|
||||
XToastUtils.error("签名文件不存在");
|
||||
hasSignature = false;
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
XToastUtils.error("上传失败,请重试");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void checkCameraPermission() {
|
||||
if (ContextCompat.checkSelfPermission(
|
||||
requireContext(), Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED) {
|
||||
startQrScanner();
|
||||
} else {
|
||||
requestPermissions(new String[]{Manifest.permission.CAMERA}, CAMERA_PERMISSION_REQUEST_CODE);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
|
||||
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
|
||||
if (requestCode == CAMERA_PERMISSION_REQUEST_CODE) {
|
||||
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
|
||||
startQrScanner();
|
||||
} else {
|
||||
XToastUtils.error("需要相机权限才能扫描二维码");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void startQrScanner() {
|
||||
try {
|
||||
IntentIntegrator integrator = IntentIntegrator.forSupportFragment(this)
|
||||
.setDesiredBarcodeFormats(IntentIntegrator.QR_CODE)
|
||||
.setPrompt("将二维码放入框内扫描")
|
||||
.setCameraId(0)
|
||||
.setBeepEnabled(false)
|
||||
.setBarcodeImageEnabled(false)
|
||||
.setOrientationLocked(true)
|
||||
.setCaptureActivity(CustomScannerActivity.class);
|
||||
integrator.initiateScan();
|
||||
} catch (Exception e) {
|
||||
XToastUtils.error("启动扫描失败: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActivityResult(int requestCode, int resultCode, Intent data) {
|
||||
super.onActivityResult(requestCode, resultCode, data);
|
||||
IntentResult result = IntentIntegrator.parseActivityResult(requestCode, resultCode, data);
|
||||
if (result != null) {
|
||||
if (result.getContents() == null) {
|
||||
key="";
|
||||
XToastUtils.info("扫描已取消");
|
||||
} else {
|
||||
key=result.getContents();
|
||||
System.out.println("二维码内容:"+key);
|
||||
XToastUtils.success("获取成功");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -100,6 +100,7 @@ public class AppPageConfig {
|
|||
FaceComponents.add(new PageInfo("考勤打卡", "", "attendance", CoreAnim.slide, 2));
|
||||
FaceComponents.add(new PageInfo("考勤统计", "", "attendance_statistics", CoreAnim.slide, 2));
|
||||
FaceComponents.add(new PageInfo("上班与休息", "", "rest", CoreAnim.slide, 2));
|
||||
FaceComponents.add(new PageInfo("扫码签名", "", "rest", CoreAnim.slide, 2));
|
||||
} else {
|
||||
//首页
|
||||
mComponents.add(new PageInfo("分包商入场", "", "ein_sub", CoreAnim.slide, 2));
|
||||
|
|
@ -146,6 +147,7 @@ public class AppPageConfig {
|
|||
FaceComponents.add(new PageInfo("考勤打卡", "", "attendance", CoreAnim.slide, 2));
|
||||
FaceComponents.add(new PageInfo("考勤统计", "", "attendance_statistics", CoreAnim.slide, 2));
|
||||
FaceComponents.add(new PageInfo("上班与休息", "", "rest", CoreAnim.slide, 2));
|
||||
FaceComponents.add(new PageInfo("扫码签名", "", "rest", CoreAnim.slide, 2));
|
||||
} else {
|
||||
//首页
|
||||
mComponents.add(new PageInfo("分包商入场", "", "ein_sub", CoreAnim.slide, 2));
|
||||
|
|
|
|||
|
|
@ -0,0 +1,45 @@
|
|||
package com.bonus.gzvis.app.util;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.content.pm.ActivityInfo;
|
||||
import android.os.Bundle;
|
||||
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
|
||||
import com.google.zxing.client.android.Intents;
|
||||
import com.journeyapps.barcodescanner.DecoratedBarcodeView;
|
||||
|
||||
import org.easydarwin.easypusher.R;
|
||||
|
||||
public class CustomScannerActivity extends AppCompatActivity {
|
||||
private DecoratedBarcodeView barcodeView;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_custom_scanner);
|
||||
// 强制竖屏
|
||||
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
|
||||
|
||||
barcodeView = findViewById(R.id.zxing_barcode_scanner);
|
||||
barcodeView.initializeFromIntent(getIntent());
|
||||
barcodeView.decodeSingle(result -> {
|
||||
Intent resultIntent = new Intent();
|
||||
resultIntent.putExtra(Intents.Scan.RESULT, result.getText());
|
||||
setResult(RESULT_OK, resultIntent);
|
||||
finish();
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResume() {
|
||||
super.onResume();
|
||||
barcodeView.resume();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPause() {
|
||||
super.onPause();
|
||||
barcodeView.pause();
|
||||
}
|
||||
}
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 406 B |
|
|
@ -0,0 +1,12 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical">
|
||||
|
||||
<com.journeyapps.barcodescanner.DecoratedBarcodeView
|
||||
android:id="@+id/zxing_barcode_scanner"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent" />
|
||||
|
||||
</LinearLayout>
|
||||
|
|
@ -0,0 +1,102 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="#efefef"
|
||||
android:focusableInTouchMode="true">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical"
|
||||
android:gravity="center_horizontal">
|
||||
|
||||
<!-- 标题栏 -->
|
||||
<RelativeLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="50dp"
|
||||
android:background="@color/colorPrimary">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/back"
|
||||
android:layout_width="40dp"
|
||||
android:layout_height="30dp"
|
||||
android:layout_alignParentLeft="true"
|
||||
android:layout_centerVertical="true"
|
||||
android:layout_marginLeft="10dp"
|
||||
android:background="@drawable/back" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/title"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_centerInParent="true"
|
||||
android:text="扫描"
|
||||
android:textColor="#FFFFFF"
|
||||
android:textSize="20sp" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/add"
|
||||
android:layout_width="25dp"
|
||||
android:layout_height="25dp"
|
||||
android:layout_alignParentRight="true"
|
||||
android:layout_centerVertical="true"
|
||||
android:layout_marginRight="10dp"
|
||||
android:background="@drawable/scan" />
|
||||
</RelativeLayout>
|
||||
|
||||
<!-- 主内容区域(居中显示) -->
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0dp"
|
||||
android:layout_weight="1"
|
||||
android:gravity="center"
|
||||
android:orientation="vertical"
|
||||
android:padding="20dp">
|
||||
|
||||
<!-- 签名区域 -->
|
||||
<LinearLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:orientation="vertical">
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center"
|
||||
android:text="签名:"
|
||||
android:textSize="20sp"/>
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/signature_image"
|
||||
android:layout_width="300dp"
|
||||
android:layout_height="200dp"
|
||||
android:layout_marginTop="10dp"
|
||||
android:src="@drawable/add_ic"
|
||||
android:scaleType="fitCenter"
|
||||
android:contentDescription="签名图片" />
|
||||
</LinearLayout>
|
||||
|
||||
<!-- 操作按钮 -->
|
||||
<LinearLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="30dp"
|
||||
android:orientation="horizontal">
|
||||
|
||||
|
||||
<com.xuexiang.xui.widget.textview.supertextview.SuperButton
|
||||
style="@style/SuperButton.Blue"
|
||||
android:id="@+id/btn_upload"
|
||||
android:layout_width="200dp"
|
||||
android:layout_height="45dp"
|
||||
android:text="上传" />
|
||||
</LinearLayout>
|
||||
<View
|
||||
android:layout_width="1dp"
|
||||
android:layout_height="150dp"/>
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
</FrameLayout>
|
||||
Loading…
Reference in New Issue