读取NFC标签内的网址并打开网页

本示例适配的读卡器:https://item.taobao.com/item.htm?spm=a21dvs.23580594.0.0.52de2c1bOBKs2M&ft=t&id=615391857885

检测读卡器上的NFC标签类型

Delphi 复制代码
Function checkcardtype:integer;   //检测NFC标签类型
var
  status:byte;//存放返回值
  mypiccserial:array[0..7] of byte;//卡序列号
  mypiccseriallen:array[0..1] of byte;
  mypicckey:array[0..5] of byte;  //认证密码
  mypicdata:array[0..47] of byte;  //块内数据
  myctrlword,blockaddr,blocksize:byte;  //控制字,读操作起始块地址,读写块数
  pdevicenumber:array[0..3] of byte;
  i:integer;
begin
  Result:=-1;
  myctrlword:=0;
  status:=pcdgetdevicenumber(@pdevicenumber);
  if status=0 then
  begin
      status := piccreadex_ntag(myctrlword,@mypiccserial,@mypicckey,4,1,@mypicdata); //forumtype2 Ntag2标签
      if status=0 then
          Result:=1
      else
      begin
           status := iso15693readex(myctrlword,0,1,1,@mypiccserial,@mypicdata);//forumtype5 15693标签
           if status=0 then
               Result:=2
           else
           begin
                myctrlword:=23;
                mypicckey[0]:=$FF;mypicckey[1]:=$FF;mypicckey[2]:=$FF;mypicckey[3]:=$FF;mypicckey[4]:=$FF;mypicckey[5]:=$FF;
                status := piccreadex(myctrlword,@mypiccserial,0,1,@mypicckey,@mypicdata); //MifareClassic,以出厂状态密码一认证
                if status=0 then
                    Result:=3
                else
                begin
                    myctrlword:=23;
                    mypicckey[0]:=$A0;mypicckey[1]:=$A1;mypicckey[2]:=$A2;mypicckey[3]:=$A3;mypicckey[4]:=$A4;mypicckey[5]:=$A5;
                    status := piccreadex(myctrlword,@mypiccserial,0,1,@mypicckey,@mypicdata); //MifareClassic ,以出厂状态密码二认证
                    if status=0 then
                        Result:=3
                    else
                    begin
                        myctrlword:=0;
                        status := forumtype4request(myctrlword, @mypiccserial, @mypiccseriallen); //forumtype4 标签
                        if (status=0) or (status=52) then
                            Result:=4
                        else
                        begin
                            Result:=-1;
                        end;
                    end;
                end;
           end;
      end;
   end
   else
      Result:=23;
end;

读取不同类型的标签内NDEF信息,解析获取网址及文本

Delphi 复制代码
function ReadTag(funcname: string):string;   //读取不同类型标签的NDEF信息
var
  cardtyep:integer;
  status:byte;
  afi:byte;
  myctrlword:byte;
  revstrlen: Integer;
  recordnumber: Integer;
  mypiccserial:array[0..7] of byte;
  mypiccseriallen:array[0..0] of byte;
  oldpicckey:array[0..5] of byte;
  newpicckey:array[0..5] of byte;
  mypiccdata: array[0..2048] of Byte;
  ndefstr:string;
  dispinf:string;
  cardno:string;
  uristr:string;
  i:integer;
  uribegin:Integer;
begin
     status:=255;

     cardtyep:=checkcardtype;//判断发卡器上标签类型

     case  cardtyep of
          1:
          begin //读forumtype2 Ntag2标签
              myctrlword:=0;
              status := forumtype2_read_ndeftag(myctrlword, @mypiccserial, @oldpicckey);
          end;
          2:
          begin  //读forumtype5 15693标签
              myctrlword:=0;
              afi:=0;
              status := forumtype5_read_ndeftag(myctrlword, afi, @mypiccserial);
          end;
          3:
          begin  //读MifareClassic标签
              myctrlword:=$80+$10;
              status:= piccread_ndeftag(myctrlword, @mypiccserial, @oldpicckey);
          end;
          4:
          begin  //读forumtype4 标签
              myctrlword:=0;
              status := forumtype4_read_ndeftag(myctrlword, @mypiccserial,@mypiccseriallen, @oldpicckey);
          end;
          else
              Result:=''; // funcname+',ReturnCode:008';
     end;

     if status=0 then
     begin
          tagbuf_read(@mypiccdata, @revstrlen, @recordnumber);
          ndefstr:='';
          for i:=0 to revstrlen-1 do  ndefstr:=ndefstr+chr(mypiccdata[i]);
          uribegin:=Pos('URI field:',ndefstr);
          if uribegin>0 then
          begin
              Result:='';
              for i:=uribegin+9 to revstrlen-1 do
              begin
                   if (mypiccdata[i]=13) and (mypiccdata[i+1]=10 ) then
                   begin
                       ReadTextOrURI:=2;
                       Exit;
                   end
                   else
                       Result:=Result+chr(mypiccdata[i]);
              end;
          end
          else
          begin
              uribegin:=Pos('text:',ndefstr);
              if uribegin>0 then
              begin
                  Result:='';
                  for i:=uribegin+5 to revstrlen-1 do
                  begin
                       if (mypiccdata[i+1]=13) and (mypiccdata[i+2]=10 ) then
                       begin
                           ReadTextOrURI:=1;
                           Exit;
                       end
                       else
                           Result:=Result+chr(mypiccdata[i]);
                  end;
              end;
          end;
     end;
end;

将读取到的网址及文本输出,如果是网址使用默认浏览器打开该网址

Delphi 复制代码
procedure TForm1.tmr1Timer(Sender: TObject);
var
    status:byte;//存放返回值
    myareano:byte;//区号
    authmode:byte;//密码类型,用A密码或B密码
    myctrlword:byte;//控制字
	  mypicckey:array[0..5] of byte;//密码
    mypiccserial:array[0..3] of byte;//卡序列号
    mypiccdata:array[0..47] of byte;//卡数据缓冲
    strls:string;
    i:Integer ;
    cardnumber:Longword;
begin
    try

        if Reading= True then
        begin
            ReadTextOrURI:=0;
            tagbuf_forumtype4_clear();            //清空NDEF数据缓冲
            tagbuf_clear();
            strls:=ReadTag('');

            if Length(strls)>0 then
            begin
                picchalt;

                if CheckBox1.Checked =True then
                begin
                   pcdbeep(12);
                end;
                if ((ReadTextOrURI=1) or (CheckBox4.Checked =True))  then  SendKeys(strls);  //模拟键盘输出网址
                if ((ReadTextOrURI=2) and (CheckBox2.Checked =True)) then ShellExecute(Handle, nil, PChar(strls), nil, nil, SW_SHOWNORMAL);  //系统默认浏览器打开网页

                tmr1.Interval :=strtoint(Edit1.Text);
            end
            else
                tmr1.Interval :=100;
        end;
      finally

      end;
end;

模拟键盘输出字符串信息

Delphi 复制代码
procedure SendKeys(sSend:string);
var
    i:integer;
    focushld,windowhld:hwnd;
    threadld:dword;
    ch: byte;
begin
  windowhld:=GetForegroundWindow;           //获得前台应用程序的活动窗口的句柄

  threadld:=GetWindowThreadProcessId(Windowhld,nil);        //获取与指定窗口关联在一起的一个进程和线程标识符

  AttachThreadInput(GetCurrentThreadId,threadld,true);
    //通常,系统内的每个线程都有自己的输入队列。          //
    //AttachThreadInput允许线程和进程共享输入队列。        //
    //连接了线程后,输入焦点、窗口激活、鼠标捕获、键盘状态 //
    //以及输入队列状态都会进入共享状态          //
  Focushld:=getfocus;
    //获得拥有输入焦点的窗口的句柄
  AttachThreadInput(GetCurrentThreadId,threadld,false );
  if focushld = 0 then Exit;
    //如果没有输入焦点则退出发送过程
  i := 1;
  while i <= Length(sSend) do
    //该过程发送指定字符串(中英文皆可以)
  begin  
    ch := byte(sSend[ i ]);
    if Windows.IsDBCSLeadByte(ch) then
    begin
      Inc(i);
      SendMessage(focushld, WM_IME_CHAR, MakeWord(byte(sSend[ i ]), ch), 0);
      //Sleep(1);
    end
    else
      SendMessage(focushld, WM_IME_CHAR, word(ch), 0);
      Inc(i);
    //  Sleep(1);
  end;
  postmessage(focushld,WM_keydown,13,0);  
    //发送一个虚拟Enter按键
end;
相关推荐
亚林瓜子2 天前
nodejs里面的百分号解码之URLSearchParams
开发语言·javascript·ecmascript·node·url·百分号编码
程序员小易3 天前
前端轮子(2)--diy响应数据
前端·javascript·浏览器
八哥程序员7 天前
Chrome DevTools 详解系列之 Elements面板
javascript·浏览器
Bigger8 天前
后端拒写接口?前端硬核自救:纯前端实现静态资源下载全链路解析
前端·浏览器·vite
全马必破三8 天前
浏览器原理知识点总结
前端·浏览器
sg_knight8 天前
模块热替换 (HMR):前端开发的“魔法”与提速秘籍
前端·javascript·vue·浏览器·web·模块化·hmr
1024肥宅9 天前
浏览器存储 API:全面解析与高级实践
前端·数据库·浏览器
1024肥宅10 天前
浏览器相关 API:DOM 操作全解析
前端·浏览器·dom
码农胖大海10 天前
浏览器及标签页关闭时登出的解决方案
前端·浏览器
用户904438163246011 天前
从40亿设备漏洞到AI浏览器:藏在浏览器底层的3个“隐形”原理
前端·javascript·浏览器