Cómo enviar un SMS desde cero ( y III )

Continuando con la serie de posts, a continuación veremos cómo se envía un SMS.
Suponemos que en el Form tenemos:
- Una lista de números telefónicos almacenados en un grid con varias columnas (en la columna 3 está el número de teléfono donde hay que enviar el SMS), 
- Un TButton con el siguiente procedimiento asociado al evento OnClick, su función es ir leyendo fila a fila el grid obteniendo el número de teléfono y el texto a enviar, que en este caso he puesto un texto fijo, pero que si lo que queréis es enviar un texto diferente a cada número de teléfono, se almacenaría en la columna 1 para leerlo de esta forma TEXTO:= grid3.Cells[0, i];

PROCEDURE TForm1.Button6Click(Sender: TObject);
VAR
  texto, CeldaX, Nombre,telefono: ansistring;
  i: integer;
BEGIN
  TRY
    Application.processmessages;
    Label1.caption := 'ENVIANDO SMS...';
    FOR i := 1 TO grid3.rowcount - 1 DO
    BEGIN
      grid3.SetFocus;
      grid3.Row := i;
      BEGIN
        TEXTO := 'Este es el texto del SMS';
         Telefono:= grid3.Cells[2, i];
        EnviarSMS(telefono,texto, Rdo, CodigoError);
        IF ansipos(chr(13) + chr(10) + '+CMGS:', Rdo) > 0 THEN
        BEGIN
             // Si el envío es correcto pone en la columna 5 del grid un OK+Fecha
          grid3.cells[4, i] := 'OK: ' + DateTostr(now);
        END
        ELSE grid3.cells[4, i] := '===ERROR==='
      END;
    END;
  FINALLY
    Application.processmessages;
    Label1.caption := 'ENVÍO TERMINADO';
  END;
END;



PROCEDURE tForm1.EnviarSMS(Telefono, texto: ansistring; VAR Rdo: ansistring; VAR CodigoError: Integer);
BEGIN
  enviar('AT+CMGS="' + telefono + '"', Rdo, CodigoError);
  //Después del comando at+cmgs el modem devuelve:   >
  IF ansipos('>', Rdo) > 0 THEN
  BEGIN
    enviar('"' + texto + '"' + ^Z, Rdo, CodigoError);
  END;
END;

El procedimiento "enviar" es el mismo que anteriores posts, pero lo pongo para facilitar la comprensión del procedimiento anterior 


PROCEDURE tform1.enviar(at: ANSISTRING; VAR Rdo: ansistring; VAR CodigoError: integer);
BEGIN
  CodigoError := 0;
  Edit1.TExt := '';
  rdo := '';
  Terminado := False;
  Segundos := 0;
  IF (FStatusTrigger = 0) THEN
  BEGIN
    FStatusTrigger := ApdComPort1.AddStatusTrigger(stLine);
    ApdComPort1.SetStatusTrigger(FStatusTrigger,
      lsOverrun OR lsParity OR lsFraming OR lsBreak,
      True);
  END;
  memo1.Lines.add('>>' + at + chr(13));
  timer1.Enabled := true;
  ApdComPort1.OutPut := at + chr(13);
  REPEAT
    delay(2000)  
  UNTIL Terminado;
END;


Procedimiento del objeto ApdComPort1, que se dispara para recoger los caracteres del buffer

PROCEDURE TForm1.ApdComPort1TriggerAvail(CP: TObject; Count: Word);
  {Event OnTriggerAvail - Example how OnTriggerAvail works}
VAR
  I: Word;
  C: Char;
  S, s1: STRING;
BEGIN
  FOR I := 1 TO Count DO BEGIN
    C := ApdComPort1.GetChar;
    s1 := c;
    Rdo := Rdo + s1;
  END;

  memo1.lines.add(Rdo);
  IF ansipos(chr(13) + chr(10) + 'OK' + chr(13) + chr(10), Rdo) > 0
    THEN
  BEGIN
    application.processmessages;
    edit1.Text := Rdo;
  END;
END;


Si queremos leer todos los mensajes almacenados en la SIM y copiarlos en el Grid1  tendremos que utilizar el comando AT+CMGL=all  de la siguiente forma:

PROCEDURE TForm1.Button2Click(Sender: TObject);
VAR
  linea1, linea2: ansistring;
  contador, contadorfila: integer;
  HayParametros: boolean;
BEGIN
  contador := 2; contadorfila := 1; HayParametros := false;
//Lee todos los mensajes de la SIM
  enviar('AT+CMGL=all', Rdo, CodigoError);
  REPEAT
        //captura el token nº “contador” de la cadena RDO, separada por el carácter chr(13))
    linea1 := gettoken(Rdo, chr(13), contador);
    IF ansipos('+CMGL:', linea1) > 0 THEN
    BEGIN
      inc(contadorFila);
      Grid1.Cells[0, contadorFila] := gettoken(linea1, ',', 1);
      Grid1.Cells[1, contadorFila] := gettoken(linea1, ',', 2);
      Grid1.Cells[2, contadorFila] := gettoken(linea1, ',', 3);
      Grid1.Cells[4, contadorFila] := gettoken(linea1, ',', 4);
      Grid1.Cells[5, contadorFila] := gettoken(linea1, ',', 5);
      Grid1.Cells[6, contadorFila] := gettoken(linea1, ',', 6);
      Grid1.Cells[7, contadorFila] := gettoken(linea1, ',', 7);
      Grid1.Cells[8, contadorFila] := gettoken(linea1, ',', 8);
      HayParametros := true;
    END
    ELSE
    BEGIN
      IF HayParametros THEN
      BEGIN
        Grid1.Cells[9, contadorFila] := linea1;
      END;
      HayParametros := false;
    END;
    inc(contador);
  UNTIL (ansipos('OK', LINEA1) > 0) OR (ansipos('OK', LINEA2) > 0) OR (contador > 100);
END;


Para borrar todos los mensajes de la SIM tendremos que usar el comando AT+CMGD=numero del mensaje

PROCEDURE TForm1.Button1Click(Sender: TObject);
VAR
  I: INTEGER;
BEGIN
  FOR I := 0 TO Grid1.rowcount - 1 DO
  BEGIN
    application.processmessages;
    label7.caption := 'Borrando mensaje: ' + inttostr(i);
    application.processmessages;
    enviar('AT+CMGD=' + inttoStr(i), Rdo, CodigoError);
  END;
END;

Una vez que se muestran todos los mensajes en la rejilla podremos borrar un mensaje cualquiera haciendo doble clic sobre una fila , utilizando el siguiente procedimiento:

PROCEDURE TForm1.Grid1DblClick(Sender: TObject);
VAR
  NumeroDeMensaje: ansistring;
  i: integer;
BEGIN
  IF MessageDlg('Eliminar mensaje ?' + grid1.Cells[0, FilaSeleccionada],
    mtConfirmation, [mbYes, mbNo], 0) = mryes THEN
  BEGIN
    NumeroDeMensaje := gettoken(grid1.Cells[0, FilaSeleccionada], ':', 2);
    enviar('AT+CMGD=' + NumeroDeMensaje, Rdo, CodigoError);
    IF CodigoError = 0 THEN
    BEGIN
      FOR i := 0 TO grid1.ColCount - 1 DO grid1.Cells[i, FilaSeleccionada] := '';
    END;
  END;
END;


Relacionados: 


Cómo enviar un SMS desde cero  ( I )
Cómo enviar un SMS desde cero  ( II )

2 comentarios:

  1. Muy buenas las entradas, ¡¡ estoy esperando las próximas !!

    ResponderEliminar
  2. Genial, me ha ayudado mucho...

    ResponderEliminar