关于短信的问题,没有人会 ( 积分: 100 )

  • 主题发起人 主题发起人 whyshui
  • 开始时间 开始时间
W

whyshui

Unregistered / Unconfirmed
GUEST, unregistred user!
在接收短信的时候,字符串为#$D#$A'+CMTI: "SM",15'#$D#$A
+CMTI:代表接收的短信存放到了存储器中,后面的15表示存储器的index
可是现在我不知道要怎么获取这个字符串中的真正的短信内容,怎么从存储器中提取
 
没有人会吗
 
发送 AT+GMGR=index读取,串口将返短息的相关内容,不知你是否设置了UPD格式。
 
function TzfSMS.UnicodeToString(AData:string): string;
var
I: Integer;
begin
Result := '';
I := 1;
while I < Length(AData)do
begin
Result := Result + WideChar(StrToInt('$' + Copy(AData, I, 4)));
I := I + 4;
end;
end;

procedure TzfSMS.DecodeMessage(AData:string);
var
StartP,EndP: Integer;
Phone,Msg,ReceiveTime: string;
begin
StartP := Pos('089168', AData);
EndP := StrToInt('$' + Copy(AData, StartP + 56, 2));
Phone := PhoneShift(Copy(AData, StartP + 26, 12));
Phone := Ifthen
(RightStr(Phone, 1)<>'F', Phone, LeftStr(Phone, Length(Phone) - 1));
ReceiveTime := PhoneShift(Copy(AData, StartP + 42, 12));
ReceiveTime := Copy(ReceiveTime, 1, 2) + '-' + Copy(ReceiveTime, 3, 2) + '-' + Copy(ReceiveTime, 5, 2) + ' ' +
Copy(ReceiveTime, 7, 2) + ':' + Copy(ReceiveTime, 9, 2) + ':' + Copy(ReceiveTime, 11, 2);
ReceiveTime := FormatDateTime('YYYY-MM-DD HH:MM:SS', StrToDateTime(ReceiveTime));
Msg := Copy(AData, StartP + 58, EndP*2);
Msg := UnicodeToString(Msg);
end;
 
我不太明白你的说话,解码的函数有,可是我还是不会用,我们的程序就只判断了
if pos('+CDS:',strlst.Text)>0 then
//是信息报告
else
if pos('+CMT:',strlst.Text)>0 then
//是新短信
可是我不知道包含CMTI:的怎么往下写了
 
procedure Thread_Smsg.ManageMsgLst;
var
chd,i,j:integer;
str,tel,stime,fsnr,sqlstr,fszt,msgid:string;
//PDU数据,电话,发送时间,发送内容,SQL语句,发送状态,顺序号
begin
j:=0;
i:=0;
while Msg_Lst.Count>0do
//有待处理的短信
try
strlst.Text:=Msg_Lst[0];
Msg_Lst.Delete(0);
//if pos('+CMGS:',strlst.Text)>0 then
//是发送短信后返回的顺序号
// begin
// msgid:=copy(strlst[1],pos(' ',strlst[1])+1,length(strlst[1])-pos(' ',strlst[1]));
// sqlstr:='select Msgid from SJ_YHLYB '
// end
if pos('+CDS:',strlst.Text)>0 then
//是信息报告
begin
while i<strlst.countdo
begin
if pos('+CDS:',strlst) <> 0 then
begin
j:=i;
i := strlst.count;
end
else
inc(i);
end;
try
chd:=strtoint(copy(strlst[j],pos(' ',strlst[j])+1,length(strlst[j])-pos(' ',strlst[j])));
except
exit;
end;
if chd>0 then
begin
chd:=chd*2;
//str:=copy(strlst[2],length(strlst[2])-chd+1,chd);
str:=copy(strlst[j+1],length(strlst[j+1])-chd+1,chd);
TransMsgReport(str,msgid,tel,stime,fszt);
if fszt='00' then
//发送成功
begin
stime:=copy(stime,1,8);
//发送时间和记入系统的时间有可能有误差,只取天
sqlstr:='update SJ_YHLYB set LYZT=''1'' where LYDX='''+tel+''' and substring(LYSJ,1,8)='''+stime+'''';
//将用户留言(信息发布)表中留言状态改为已接收
executesql(dm_public.qry_tmp,sqlstr,1);
end;
end;
end
else
if pos('+CMT:',strlst.Text)>0 then
//是新短信
begin
try
chd:=strtoint(copy(strlst[1],pos(',',strlst[1])+1,length(strlst[1])-pos(',',strlst[1])));
except
exit;
end;
if chd>0 then
begin
chd:=chd*2+18;
//是否直接截取18位`或者需要先判断短信中心号码的类型和长度?
str:=copy(strlst[2],1,chd);
TransReceiveMsg(str,tel,stime,fsnr);
myMsgReceived(tel,fsnr,stime,dm_public.qry_dx1,dm_public.qry_dx_yw);
//调用短信接收处理过程
end;
// if
end;
// else
else
if pos('+CMTI:',strlst.Text)>0 then
// 把短信存放到存储器中去了
begin

end;
except
end;
end;
这个是程序中的短线线程中的代码,就是判断接收的是什么短信:新短信,信息回报
 
我知道怎么获取index,我也知道这个公式AT+GMGR=index,可是在程序中我不知道怎么继续写下去
 
1 如果串口接收到的数据包含“CMTI”,那么取出Index,然后往串口输入“AT+GMGR=Index”
2 这时,串口就会返回一串数据,假设它赋值给了StrReceive,里面包含了发送过来的号码,时间,内容。
3 用我上面写的函数 DecodeMessage(StrReceive)分解出你需要的信息,电话号码,接收时间,内容等。
 
呵呵,谢谢我比较笨,我不明白怎么往串口输入“AT+GMGR=Index”
 
kukujaky:已经说的详细的不能再详细了!
只是个流程问题!收到信息后,你怎么来控制你的短信的读取
 
那你是怎么发信息的?也是要往串口输入一个发送命令(具体的命令没看程序我不清楚,呵),还是说你的程序只是来接收信息而不发送呢。。。
 
发送的程序是这样的
procedure TFrm_main.MsCommSendMsg(msg,tel:string);
//调用控件执行发送短信操作,在MysendMsg中被调用
var
sMsg,chd:string;
i:integer;
begin
sMsg:=msg;
i:=CheckNumb(tel);
if i=0 then
//移动
TransMsg(tel,CenterNo1,sMsg,chd)
else
//联通
TransMsg(tel,CenterNo2,sMsg,chd);
MSComm1.Output := 'AT'+char(13);
//发送 AT
sleep(100);
//延时0.1秒
MSComm1.Output := 'AT+CMGS='+chd+char(13);//发送 AT+CMGS=消息长度
sleep(1700);
//延时2秒
MSComm1.Output := sMsg+char(26)+char(13);
//这里是发送的消息,char(26是Ctrl+Z)
sleep(3300);
//延时3秒
end;
 
procedure TransReceiveMsg(str:string;var MsgSender,Sendttime,SendMsg:string);
{08 //短信中心长度
91 //短信中心号码类型
683108200205F0 //短信中心号码
24 //TPDU头字节
0D //发送源号码长度
91 //发送源号码类型
683157121468F0 //发送源号码
00 //协议标识 TP—PID
08 //数据编码方案,08:中文编码,00为英文或数字,Bit No.7与Bit No.6
608032719141 //日期时间
00 //时区
02 //用户数据长度
814C //用户短信息数据
}
var
bmlx:string;
i,chd_tel,chd_dx,chd:integer;
begin
chd:=StrToInt('$'+copy(str,1,2));
//短信中心的长度,16转10进制
chd:=chd*2+5;
//号码长度的开始位置
chd_tel:=StrToInt('$'+copy(str,chd,2));
//发送方号码的长度,16转10进制
if odd(chd_tel)=true then
//是奇数
chd_tel:=chd_tel+1;
chd:=chd+4;
//号码的开始位置
MsgSender:=ExchangeStr(copy(str,chd,chd_tel));
if pos('F',MsgSender)>0 then
MsgSender:=copy(MsgSender,1,length(MsgSender)-1);
//去掉F
chd:=chd+chd_tel+2;
//短信编码类型的开始位置
bmlx:=copy(str,chd,2);
chd:=chd+2;
//发送时间的开始位置
Sendttime:='20'+ExchangeStr(copy(str,chd,12));
chd:=chd+14;
//短信长度的开始位置
chd_dx:=StrToInt('$'+copy(str,chd,2));
//短信内容的长度,16转10进制
SendMsg:=copy(str,chd+2,chd_dx*2);
if bmlx='00' then
//7-BIT编码,全英文或数字
SendMsg:=DecodeSMS7Bit(SendMsg)
else
//中文,UNC码
begin
SendMsg:=DecodeUniCode(SendMsg);
SendMsg:=copy(SendMsg,2,length(SendMsg)-1);
//去掉最前面的引号
end;
end;

翻译短信内容 解码
 
“发送的程序是这样的
procedure TFrm_main.MsCommSendMsg(msg,tel:string);
//调用控件执行发送短信操作,在MysendMsg中被调用
var
sMsg,chd:string;
i:integer;
begin
sMsg:=msg;
i:=CheckNumb(tel);
if i=0 then
//移动
TransMsg(tel,CenterNo1,sMsg,chd)
else
//联通
TransMsg(tel,CenterNo2,sMsg,chd);
MSComm1.Output := 'AT'+char(13);
//发送 AT
sleep(100);
//延时0.1秒
MSComm1.Output := 'AT+CMGS='+chd+char(13);//发送 AT+CMGS=消息长度
sleep(1700);
//延时2秒
MSComm1.Output := sMsg+char(26)+char(13);
//这里是发送的消息,char(26是Ctrl+Z)
sleep(3300);
//延时3秒
end;


真有你的。。MSComm这个控件没用过,但是看你的程序就大概清楚了
MSComm1.OutPut := 'AT+GMGR=Index';
应该是这样的吧
原理相同的,你要发送信息也要先发送一个AT命令给GSM Modem的,你怎么发给它的呢,好好想想。
 
hehe
谢谢2位,这个程序是别人做的,同事都走了,现在由我来修改,程序我还没有看懂了
 
后退
顶部