读取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;
相关推荐
津津有味道7 小时前
一键写入启动游戏NDEF复合记录NFC标签vb6源码
游戏·标签·nfc·ndef·复合记录
Nturmoils3 天前
书签真正难的不是收藏,而是找回来:我是怎么做这个 Chrome 插件的
javascript·后端·浏览器
爱学习的程序媛4 天前
浏览器工作原理全景解析
前端·浏览器·web
Jack N4 天前
2026 浏览器原理 常见面试题(附答案)
前端·html·浏览器
哆哆啦004 天前
URL 重写规则和静态资源解析逻辑
前端·浏览器·url
韭菜炒大葱5 天前
讲讲 浏览器的缓存机制
前端·面试·浏览器
xiaoxue..6 天前
讲讲 浏览器的缓存机制
前端·缓存·面试·浏览器
七夜zippoe7 天前
OpenClaw Browser:浏览器控制入门
ai·自动化·浏览器·browser·openclaw
Mac的实验室11 天前
perplexity要验证手机号怎么办?2026年登陆perplexity要验证电话号码的解决办法(附验证方法)
搜索引擎·浏览器
kyriewen11 天前
我开发的 Chrome 扒图浏览器插件又更新了❗
前端·chrome·浏览器