读取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;
相关推荐
鱼鱼块4 小时前
揭开浏览器底层的秘密:为什么一个 Chrome 能跑这么快又这么稳?
架构·操作系统·浏览器
Keely4028520 小时前
浏览器指纹识别:从原理到防护的完整指南
前端·浏览器
新晨4372 天前
跨域是服务器拒绝请求还是浏览器去拒绝的请求?
前端·浏览器
阿巴~阿巴~2 天前
探秘HTTP与URL:解锁网络通信的密钥
网络·网络协议·http·域名·dns·url·编码与解码
不一样的少年_4 天前
不仅免费,还开源?这个 AI Mock 神器我必须曝光它
前端·javascript·浏览器
闲人编程4 天前
HTTP协议深度解析与RESTful API设计
网络协议·http·restful·url·接口设计·codecapsule
JamesGosling6666 天前
深入理解内容安全策略(CSP):原理、作用与实践指南
前端·浏览器
月下点灯8 天前
🔄记住这张图,脑子跟着浏览器的事件循环(Event Loop)转起来了
前端·javascript·浏览器
用户7617363540111 天前
浏览器渲染原理
前端·浏览器