商米-android-使用NFC读IC卡,身份证云解和IC卡同时兼容

商米介绍地址:https://www.sunmi.com/
商米是一个提供手持PDA的一个很好的解决方案厂商,
也有其他的一些桌面设备。
其中商米提供的软件服务中,比较特别的是 身份证云解功能。

此处重点说明一下,身份证云解功能。

以往市面上的身份证读卡功能,都是找公安申请身份证读卡器硬件模块。比较贵。
商米的身份证读卡,是利用商米的NFC功能,配合身份证云解功能来实现

单独实现身份证读卡,和单独实现NFC刷IC卡,在商米提供的SDK很容易能实现
但是同时实现兼容 读IC卡和身份证,现在的商米SDK 就兼容性做的很差。
这里主要说明一下同时兼容 读IC卡和身份证,

1、引用jar包:implementation ‘com.sunmi:SunmiEID-SDK:1.3.16’

2、主界面上,初始化NFC,NfcUtils

package com.smk.travelpda.common.nfc;
 
import android.app.Activity;
import android.content.Context;
import android.nfc.NfcAdapter;
import android.nfc.Tag;
import android.util.Log;
import android.widget.Toast;

import com.smk.travelpda.common.util.RString;

/**
 * luoyang
 */
 
public class NfcUtils {
     private static final String TAG = "NfcUtils";
 
     private static NfcAdapter mNfcAdapter;
 
    private NfcUtils(){}
 
    private static NfcUtils nfcUtils = null;
 
    private static boolean isOpen = false;
 
        /**
         * 获取NFC的单例
         * @return NfcUtils
         */
    public static NfcUtils getInstance(){
        if (nfcUtils == null){
            synchronized (NfcUtils.class){
                if (nfcUtils == null){
                    nfcUtils = new NfcUtils();
                }
            }
        }
        return nfcUtils;
    }

    private  NfcListener nfcListener;

    public void setNfcListener(NfcListener listener){
        nfcListener = listener;
    }
    /**
     * 在onStart中检测是否支持nfc功能
     * @param context 当前页面上下文
     */
    public void onStartNfcAdapter(Context context){
        //设备的NfcAdapter对象
        mNfcAdapter = NfcAdapter.getDefaultAdapter(context);
    }
 
    /**
     * 在onResume中开启nfc功能
     * @param activity
     */
    public void onResumeNfcAdapter(final Activity activity){
        if(mNfcAdapter==null){//判断设备是否支持NFC功能
            RString.showDia(activity,"提醒","设备不支持NFC功能");
            return;
        }
        if (!mNfcAdapter.isEnabled()){//判断设备NFC功能是否打开
            RString.showDia(activity,"提醒","请到系统设置中打开NFC功能!");
            return;
        }
        if (!isOpen) {
            mNfcAdapter.enableReaderMode(activity, new NfcAdapter.ReaderCallback() {
                        @Override
                        public void onTagDiscovered(final Tag tag) {
                            if (nfcListener != null){
                                (activity).runOnUiThread(new Runnable() {
                                    @Override
                                    public void run() {
                                        nfcListener.nfcReadHander(tag);
                                    }
                                });
                            }
                        }
                    },
                    (NfcAdapter.FLAG_READER_NFC_A |
                            NfcAdapter.FLAG_READER_NFC_B |
                            NfcAdapter.FLAG_READER_NFC_F |
                            NfcAdapter.FLAG_READER_NFC_V |
                            NfcAdapter.FLAG_READER_NFC_BARCODE ),
                    null);
            isOpen = true;
        }
    }
 
    /**
     * 在onPause中关闭nfc功能
     * @param activity
     */
    public void onPauseNfcAdapter(Activity activity){
        if(mNfcAdapter!=null && mNfcAdapter.isEnabled()){
            if (isOpen){
                mNfcAdapter.disableReaderMode(activity);
            }
            isOpen = false;
        }
    }

}

NFC监听组件

package com.smk.travelpda.common.nfc;

import android.nfc.Tag;

/**
     * 自定义的NFC接口
     */
    public interface NfcListener{
        /**
         * 用于扫到nfc后的后续操作
         */
        void nfcReadHander(Tag tag);
    }

设置商米SDK的回调方法

package com.smk.travelpda.common.yidcard;

import android.util.Log;

import com.smk.travelpda.MainActivity;
import com.smk.travelpda.common.util.RJson;
import com.sunmi.eidlibrary.EidCall;
import com.sunmi.eidlibrary.EidConstants;
import com.sunmi.eidlibrary.EidSDK;

import java.util.Map;


//云解身份证读卡回调方法
public class EidCardReadCall implements EidCall {
    private String TAG = "IdCardHander";

    private EidcardListener eidcardListener;

    private String eventType;

    public  EidCardReadCall(EidcardListener eidcardListener,String eventType){
        this.eidcardListener = eidcardListener;
        this.eventType = eventType;
    }

    @Override
    public void onCallData(int code, String msg) {
        if(this.eventType.endsWith(EidHanderEo.EID_INIT)){
            initEidHanderCall(code, msg);
        }else if(this.eventType.endsWith(EidHanderEo.Eid_READY_NFC)){
            readerForNfc(code, msg);
        } else if (this.eventType.endsWith(EidHanderEo.GETIDCARDINFO)) {
            getIDCardInfo(code, msg);
        }
    }

    public void initEidHanderCall(int i, String s){
        EidHanderEo inttEo = new EidHanderEo(this.eventType);
        inttEo.setEventCode(i);
        switch (i) {
            case EidConstants.EID_INIT_SUCCESS:
                inttEo.setSucces(true);
                break;
            default:
                inttEo.setSucces(false);
                inttEo.setMsg(s);
                break;
        }
        eidcardListener.handEidEvent(inttEo);
    }


    public void getIDCardInfo(int i, String s) {
        EidHanderEo eo = new EidHanderEo(this.eventType);
        eo.setEventCode(i);
        if (i == EidConstants.DECODE_SUCCESS) {
            eo.setSucces(true);
            eo.setCardType("sfz");
            try{
                Map<String,Object> sfzMap = RJson.parseJson2Map(s);
                String idnum = (String)((Map<String,Object>)sfzMap.get("base_info")).get("idnum");
                eo.setCardId(idnum);
            }
            catch (Exception e){
                eo.setSucces(false);
                eo.setMsg("身份证解析失败,请重试");
            }
        } else {
            //解码失败,code 为错误吗,data为错误原因
            // typetext.setText("解析失敗:code:"+i);
            //typetext.setText("解析失敗:data:"+s);
            eo.setSucces(false);
            eo.setMsg(s);
        }
        eidcardListener.handEidEvent(eo);
    }

    public void readerForNfc(int code, String msg) {
        System.out.println("code:" + code + ":msg:" + msg);
        EidHanderEo eidHanderEo = new EidHanderEo(this.eventType);
        eidHanderEo.setEventCode(code);
        switch (code) {
            case  EidConstants.EID_INIT_SUCCESS:
                eidHanderEo.setSucces(true);
                break;
            case EidConstants.ERR_NFC_NOT_SUPPORT:
                // 该机器不支持NFC功能,无法使用SDK
                eidHanderEo.setSucces(false);
                eidHanderEo.setMsg("机器不支持NFC");
                break;
            case EidConstants.ERR_NETWORK_NOT_CONNECTED:
                eidHanderEo.setSucces(false);
                eidHanderEo.setMsg("网络未连接,请联网后重试");
                // *** 异常处理: 连接网络后,需要重新调用 startCheckCard 方法 (手动触发,非自动)***
                break;
            case EidConstants.ERR_NFC_CLOSED:
                eidHanderEo.setSucces(false);
                eidHanderEo.setMsg("NFC 未打开,打开后重试 ");
                //  *** 异常处理: 打开NFC后,需要重新调用 startCheckCard 方法 (手动触发,非自动)***
                break;
            case EidConstants.READ_CARD_READY:
                //Step 3 读卡准备完成 -> 业务方可以引导用户开始进行刷卡操作
                eidHanderEo.setSucces(true);
                eidHanderEo.setMsg("SDK准备完成,请刷卡");
                break;
            case EidConstants.READ_CARD_START:
                //Step 4 读卡中 -> 业务方可以提醒用户"读卡中,请勿移动卡片"
                eidHanderEo.setSucces(true);
                eidHanderEo.setMsg("开始读卡,请勿移动");
                break;
            case EidConstants.READ_CARD_SUCCESS:
                //Step 5 读卡成功 -> 返回的msg为reqId,通过 reqId 业务方走云对云方案获取身份证信息
                //注:如不需要循环读卡,可在此处调用stopCheckCard方法
                eidHanderEo.setSucces(true);
                eidHanderEo.setMsg("读卡成功");
                eidHanderEo.setCardId(msg);//设置读取的身份证ID
                break;
            case EidConstants.READ_CARD_FAILED:
                //*** 异常处理: 读卡失败,请重新读卡 ***
                eidHanderEo.setSucces(false);
                eidHanderEo.setMsg("读卡失败,请重试"+ msg);
                break;
            case EidConstants.ERR_ACCOUNT_EXCEPTION:
                //*** 异常处理: 读卡失败,请重新读卡 ***
                eidHanderEo.setSucces(false);
                eidHanderEo.setMsg("该设备未开通身份证读卡权限!");
                break;
            default:
                //*** 异常处理: 其他失败 - code为错误码,msg为详细错误原因 需要重新调用 startCheckCard 方法 (手动触发,非自动)***
                eidHanderEo.setSucces(false);
                eidHanderEo.setMsg("读卡异常,请重试code:"+code+ msg);
                break;
        }
        eidcardListener.handEidEvent(eidHanderEo);
    }

}

商米SDK的监听方法

package com.smk.travelpda.common.yidcard;

/**
 * 处理EID的事件
 */
public interface EidcardListener {

    public void handEidEvent(EidHanderEo eidHanderEo);
}

主界面

package com.smk.travelpda;

import android.content.IntentFilter;
import android.nfc.Tag;
import android.nfc.tech.IsoDep;
import android.nfc.tech.MifareClassic;
import android.nfc.tech.NfcA;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.TextView;

import androidx.activity.EdgeToEdge;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.graphics.Insets;
import androidx.core.view.ViewCompat;
import androidx.core.view.WindowInsetsCompat;

import com.smk.travelpda.common.macinfo.MacInfoHander;
import com.smk.travelpda.common.nfc.NfcListener;
import com.smk.travelpda.common.nfc.NfcReadHander;
import com.smk.travelpda.common.nfc.NfcUtils;
import com.smk.travelpda.common.scan.ScanEventEo;
import com.smk.travelpda.common.scan.ScanListener;
import com.smk.travelpda.common.util.BusinessException;
import com.smk.travelpda.common.util.RString;
import com.smk.travelpda.common.util.VersionCheckUtil;
import com.smk.travelpda.common.yidcard.EidCardReadCall;
import com.smk.travelpda.common.yidcard.EidHanderEo;
import com.smk.travelpda.common.scan.ScanMachinReceive;
import com.smk.travelpda.common.yidcard.EidcardListener;
import com.sunmi.eidlibrary.EidCall;
import com.sunmi.eidlibrary.EidConstants;
import com.sunmi.eidlibrary.EidReader;
import com.sunmi.eidlibrary.EidSDK;

/**
 * luoyang 2024-04-17
 */
public class MainActivity extends AppCompatActivity  implements NfcListener, ScanListener, EidcardListener {

    
    public final static String APP_ID = "商米的APPID";
    public final static String APP_KEY = "商米的APPKEY";

    private   TextView datatext;


    //绑定的归属方,景区名称
    private   TextView tourname;
    private   TextView sntext;
    private TextView visionnum;

    private NfcUtils nfcUtils = NfcUtils.getInstance();

    private EidReader eid;

    private ScanMachinReceive myReceiver ;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        EdgeToEdge.enable(this);
        setContentView(R.layout.activity_main);
        ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main), (v, insets) -> {
            Insets systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars());
            v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom);
            return insets;
        });

        datatext = findViewById(R.id.data);
        tourname = findViewById(R.id.tourname);
        sntext = findViewById(R.id.sntext);
        visionnum = findViewById(R.id.visionnum);

        sntext.setText("序列号:"+MacInfoHander.getSN());
        visionnum.setText("V1.0.0");
        tourname.setText("景区");

        //初始化NFC读卡器
        nfcUtils.setNfcListener(this);
			//商米的扫码监听
        initScanReceiveLislen();//初始话监听
        //初始化身份证读卡
        initCardEidSdk();
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        // 注销扫码接收广播
        unregisterReceiver(myReceiver);
        //注销读卡服务
        EidSDK.destroy();
    }

    @Override
    protected void onStart() {
        super.onStart();
        System.out.println("onStart................................");
        nfcUtils.onStartNfcAdapter(this);       //初始化Nfc对象
    }

    @Override
    protected void onResume() {
        super.onResume();
        System.out.println("onResume................................");
        nfcUtils.onResumeNfcAdapter(this);      //activity激活的时候开始扫描
        datatext.append("NFC初始化成功\n");
    }

    @Override
    protected void onPause() {
        super.onPause();
        System.out.println("onPause................................");
        nfcUtils.onPauseNfcAdapter(this);       //activity切换到后台的时候停止扫描
    }

    //读NFC卡后的返回事件
    @Override
    public void nfcReadHander(Tag tag) {
        datatext.setText("start new card");
        String tl[] = tag.getTechList();
        //POS机器,只支持2代和3代卡,身份证,其他证件不支持
        try {
            boolean isHandCard = false;
            for (String s:tl) {
                if(s.equals("android.nfc.tech.MifareClassic")){
                 //String data = NfcReadHander.readMifareTag(tag,MifareClassic.get(tag));
                 datatext.setText(RString.byteToString(tag.getId()));
                 isHandCard = true;
                 break;
                 //旅游卡PDA 无需支持M1卡类型
                 }else if(s.equals("android.nfc.tech.IsoDep")){
                    String cardType = "smk";
                    //读取IC卡
                    String cardId = NfcReadHander.readIsoDepTag(tag, IsoDep.get(tag));
                    System.out.println("cardId"+cardId);
                    datatext.setText(cardId);
                    isHandCard = true;
                    break;
                }else  if(s.equals("android.nfc.tech.NfcB")){
                    //跳转到身份证云解读取,NFCB为身份证模块,此处调用身份证云解,其他的为IC卡读取
                    eid.nfcReadCard(tag);
                    isHandCard = true;
                    break;
                }
            }
            if(!isHandCard){
                throw new BusinessException("请刷IC卡或身份证");
            }
        }catch (BusinessException e){
            //捕获自定义异常
            datatext.setText(e.getMessage());
        }


    }

    /**
     * 实现扫码事件
     * @return
     */
    @Override
    public void scanEventHander(ScanEventEo eventEo) {
        String  eventType = eventEo.getEventType();
        if(eventType.equals(ScanEventEo.SCAN_START)){
            //typetext.setText("开始扫码");
            datatext.setText("开始扫码");
        } else if (eventType.equals(ScanEventEo.SCAN_RECEVIE)) {
            //typetext.setText("扫码成功");
            datatext.setText("");
            datatext.append(eventEo.isAllow()+":"+ eventEo.getQrData());
        } else if (eventType.equals(ScanEventEo.SCAN_END)) {
            datatext.setText("扫码结束");
        }

    }

    //实现云解身份证的事件
    @Override
    public void handEidEvent(EidHanderEo eidHanderEo) {
        String eventType = eidHanderEo.getEventType();
        if(eventType.equals(EidHanderEo.EID_INIT)){
            //typetext.setText("init success");
            //init初始化监听时间
            if(eidHanderEo.isSucces() &&  eidHanderEo.getEventCode() == EidConstants.EID_INIT_SUCCESS){
                eid = EidSDK.getEidReaderForNfc(3, new EidCardReadCall(this,EidHanderEo.Eid_READY_NFC));
            }else {
                //其他都是失败的,
                RString.showDia(this,"身份证模块初始化失败",eidHanderEo.getMsg());
            }
        } else if (eventType.equals(EidHanderEo.Eid_READY_NFC)) {
           // typetext.setText("Eid_READY_NFC");
            //读卡的回调
            if(eidHanderEo.isSucces() &&  eidHanderEo.getEventCode() == EidConstants.READ_CARD_SUCCESS){
                datatext.setText(eidHanderEo.getCardId());
                //读卡成功的回调
                EidSDK.getIDCardInfo(eidHanderEo.getCardId(), MainActivity.APP_KEY, new EidCardReadCall(this,EidHanderEo.GETIDCARDINFO));
            }else if(!eidHanderEo.isSucces()){
               RString.showDia(this,"提醒",eidHanderEo.getMsg());
            }else{
                //有些成功,是否需要干预流程处理,不需要就不做任何事情
                //datatext.setText(eidHanderEo.getMsg());
                datatext.append("身份证模块初始化成功");
            }
        } else if (eventType.equals(EidHanderEo.GETIDCARDINFO)) {
            //typetext.setText("GETIDCARDINFO");
            //调用
            if(eidHanderEo.isSucces() && eidHanderEo.getEventCode() == EidConstants.DECODE_SUCCESS){
                //解析成功
                datatext.setText("");
                datatext.append(eidHanderEo.getCardId());
            }else {
                RString.showDia(this,"提醒",eidHanderEo.getMsg());
            }
        }
    }

    private  void initScanReceiveLislen(){
        myReceiver = new ScanMachinReceive(this);
        IntentFilter intentFilter = new IntentFilter();
        intentFilter.addAction(ScanEventEo.SCAN_RECEVIE); // 监听网络变化广播
        intentFilter.addAction(ScanEventEo.SCAN_START); // 监听网络变化广播
        intentFilter.addAction(ScanEventEo.SCAN_END); // 监听网络变化广播
        // 注册广播  只从原生获取,不从外部APP获取
        registerReceiver(myReceiver, intentFilter);
        datatext.append("扫码初始化成功\n");
    }

    private  void initCardEidSdk(){
        EidSDK.init(this, APP_ID, new EidCardReadCall(this,EidHanderEo.EID_INIT));
       // EidSDK.startCheckCard不要使用这个API
    }

    public  void visionClick(View view){
        //startActivity(VersionCheckUtil.check(false));
    }
}

这个兼容身份证和IC读卡的关键点在于,不要使用SDK里面 EidSDK.startCheckCard();

1、EidSDK.init方法,
2、在EidSDK.init的成功回调函数中,获取NFC读卡的
EidReader eid = EidSDK.getEidReaderForNfc(3, new EidCardReadCall(this,EidHanderEo.Eid_READY_NFC));
3、初始化成EidReader , 此时刷卡,在NFC读卡器检测到NFCB 的tag类型之后,再使用EidReader 去处理身份证读卡的功能 eid.nfcReadCard(tag); 此处会在第二部的回调函数中 得到读取身份证的结果。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/602624.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

嵌入式RTOS面试题目

用过哪些嵌入式操作系统&#xff1f;使⽤RTOS和裸机代码开发有什么区别&#xff08;优缺点&#xff09;&#xff1f; 之前的⼀个项⽬是采⽤裸机代码开发的&#xff0c;写起来还⾏&#xff0c;通过状态机来管理业务逻辑和各种外设。 但是随着外设的增加&#xff0c;任务之间的…

【WEB前端2024】简单几步制作web3d《萌宠星球》智体节点模板(2)

【WEB前端2024】简单几步制作web3d《萌宠星球》智体节点模板&#xff08;2&#xff09; 使用dtns.network德塔世界&#xff08;开源的智体世界引擎&#xff09;&#xff0c;策划和设计《乔布斯超大型的开源3D纪念馆》的系列教程。dtns.network是一款主要由JavaScript编写的智体…

【优选算法】——Leetcode——611. 有效三角形的个数

目录 ​编辑 1.题目 2 .补充知识 3.解法⼀&#xff08;暴⼒求解&#xff09;&#xff08;可能会超时&#xff09;&#xff1a; 算法思路&#xff1a; 算法代码&#xff1a; 4.解法⼆&#xff08;排序双指针&#xff09;&#xff1a; 算法思路&#xff1a; 以输入: nums …

2024年5月12日(星期天)骑行海囗

2024年5月12日 (星期天&#xff09;骑行海口&#xff0c;早8:30到9:00大观公园门口集合&#xff0c;9:30准时出发【因迟到者&#xff0c;骑行速度快者&#xff0c;可自行追赶偶遇。】 偶遇地点:大观公园门口集合 &#xff0c;家住东&#xff0c;西&#xff0c;南&#xff0c;北…

wangEditor富文本编辑器与layui图片上传

记录&#xff1a;js 显示默认的wangEditor富文本编辑器内容和图片 <style>body {background-color: #ffffff;}.layui-form-select dl{z-index:100000;} </style> <div class"layui-form layuimini-form"><div class"layui-form-item"…

MT3034 算术招亲

跟MT3033新的表达式类似&#xff0c;只多了一个括号合法性的判断 #include <bits/stdc.h> using namespace std; const int N 40; bool tag[N]; bool is_op(char c) {return c || c - || c * || c / || c ^; } int priority(char op) { // 优先级排序if (op ||…

数据结构-线性表-应用题-2.2-9

线性表&#xff08;a1,a2,a3,...,an&#xff09;中的元素递增有序且按顺序存储于计算机内。要求设计一个算法&#xff0c;用最少的时间在表中查找数值为x的元素&#xff0c;若找到&#xff0c;则将其与后继元素位置相交换&#xff0c;若找不到&#xff0c;则将其插入表中并使表…

钉钉开放平台创建企业内部H5微应用或者小程序

前言&#xff1a; 在当今企业数字化转型的浪潮中&#xff0c;创建企业内部H5微应用或小程序已成为提升工作效率和促进内部沟通的重要举措。发话不多说本文将介绍如何利用钉钉平台快速创建这些应用&#xff0c;让企业内部的工作更加便捷高效。 步骤 1.在浏览器打开链接…

618好物大放送:5大必买好物,抢购倒计时开始!

嘿&#xff0c;各位购物达人们&#xff0c;年度最燃购物盛宴618已经进入准备阶段&#xff0c;是不是已经开始摩拳擦掌&#xff0c;准备迎接这场消费的狂欢了呢&#xff1f;每年的这个时候&#xff0c;各大电商平台都会推出力度空前的优惠活动&#xff0c;从数码尖货到生活日用品…

Python运维-文本处理、系统和文件信息监控、外部命令

本节主要目录如下&#xff1a; 一、文本处理 1.1、Python编码解码 1.2、文件操作 1.3、读写配置文件 1.4、解析XML文件 二、系统信息监控 2.1、监控CPU信息 2.2、监控内存信息 2.3、监控磁盘信息 2.4、监控网络信息 2.5、获取进程信息 2.6、实例&#xff1a;常见的…

CentOS操作

1.如何修改主机名 方法一&#xff1a; 修改命令&#xff1a;hostnamectl set-hostname 主机名 查看命令&#xff1a;hostname 方法二和方法三都是永久改变主机名&#xff0c;需要密码验证 方法二 修改命令&#xff1a;nmcli general hostname 主机名 查看命令&#xff…

[图解]SysML和EA建模住宅安全系统-02

1 00:00:00,900 --> 00:00:02,690 这个就是一个块定义图了 2 00:00:03,790 --> 00:00:04,780 简称BDD 3 00:00:05,610 --> 00:00:08,070 实际上就是UML里面的类图 4 00:00:08,080 --> 00:00:09,950 和组件图的一个结合体 5 00:00:13,150 --> 00:00:14,690 我…

正点原子i.MX 93开发板,双核A55+M33+NPU,双路RS485FDCAN千兆网,异核/AI/工业开发!

正点原子i.MX 93开发板新品上市&#xff01;双核A55M33NPU&#xff0c;双路RS485&FDCAN&千兆网&#xff0c;异核/AI/工业开发&#xff01; NXP的i.MX系列是一系列面向多媒体和工业应用的ARM架构微处理器。从i.MX6U到i.MX93&#xff0c;这一系列经历了显著的发展&#x…

指代消解类方法梳理

概念&#xff1a; MLM&#xff1a;带遮罩的语言模型 NSP&#xff1a;单句预测&#xff0c;任务包括两个输入序列 SBO&#xff1a;分词边界目标 1.spanBERT&#xff0c;2019 spanBERT是对bert从分词到文本跨度的优化&#xff0c;主要有两方面的优化&#xff1a;&#xff08…

Stable Diffusion Ai绘画模型推荐:二次元Coriander_Mix v1大模型推荐

负tag嵌入式:EasyNegative,badhandv4 此模型经测试是写实偏3D的效果 画质灰暗的话请加&#xff1a;VAE840000 或者负tag&#xff1a;(watermark:2),(blurry:2),fat,paintings,sketches,(worst quality:2),(low quality:2),(normal quality:2),((monochrome)), ((grayscale))…

iOS xib布局

1.多次启动发现启动图和截屏的图片不一致,设置launch storyboard 不能到顶部 https://blog.csdn.net/u011960171/article/details/104053696/ 2.multipiler是比例&#xff0c;需要控制顺序1.视图&#xff0c;2父视图&#xff0c;选择宽度比例&#xff0c;默认是1 3.Aspect R…

python爬虫(二) 之 42号网汽车文章爬虫

python爬虫&#xff08;二&#xff09; 之 42号网汽车文章爬虫 今天在咸鱼上有个买家找我一个42号网汽车文章的爬虫&#xff0c;目前需求已经做完了&#xff0c;现在将这部分代码开源&#xff0c;供大家参考。爬虫能够抓取到网站上所有文章的数据&#xff0c;大概一小时左右就…

超越Scratch的梦 用心打造商业系统图形编程体验

在一个阳光明媚的上午&#xff0c;卧龙和凤雏正在公司会议室激烈地讨论着图形化编程产品在商业系统开发中的应用和改进。会议室里摆放着一些电脑和投影仪&#xff0c;方便他们展示和演示相关的内容。 “你知道图形化编程在商业系统开发中没有被广泛应用的原因吗&#xff1f;”卧…

libcity笔记:libcity/evaluator/traj_loc_pred_evaluator.py

1 构造函数 2 _check_config 检查配置是否符合评估器的要求&#xff0c;确保评估过程能够顺利执行 3 collect 4 evaluate 5 save_result & clear

创建禁止操作区域并且添加水印

css 设置 &#xff1a; 引用换成自己就好 .overlay {z-index: 1000;cursor: none; /*设置为不可点击*/user-select: none; /*设置为不可选择*/contenteditable: false; /*设置为不可编辑*/draggable: false; /*设置为不可拖动*/position: absolute;top: 0;left: 0;width: 100…
最新文章