Extension: UDP. Send text. WiFi. Source code

In this Community you can find examples with various UDP extensions.

KIO4_UDP.java (deprecated code, see updated code in post #12)

Summary
package com.KIO4_UDP;
// Juan Antonio Villalpando 
// http://kio4.com/appinventor/299K_extension_UDP.htm
//  Diciembre 2022.

import com.google.appinventor.components.annotations.DesignerComponent;
import com.google.appinventor.components.annotations.DesignerProperty;
import com.google.appinventor.components.annotations.PropertyCategory;
import com.google.appinventor.components.annotations.SimpleEvent;
import com.google.appinventor.components.annotations.SimpleFunction;
import com.google.appinventor.components.annotations.SimpleObject;
import com.google.appinventor.components.annotations.SimpleProperty;
import com.google.appinventor.components.annotations.UsesPermissions;
import com.google.appinventor.components.common.ComponentCategory;
import com.google.appinventor.components.common.PropertyTypeConstants;
import com.google.appinventor.components.runtime.util.MediaUtil;
import com.google.appinventor.components.runtime.*;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
// Obtener IP
import java.net.SocketException;
import java.util.Enumeration;
import java.net.NetworkInterface;
import java.net.Inet4Address;

@DesignerComponent(version = 1,
    description = "Send/Receive UDP. WiFi. GotText needs a Clock component." + 
    "Juan Antonio Villalpando - KIO4.COM ",
    category = ComponentCategory.EXTENSION,
    nonVisible = true,
    iconName = "") 
@SimpleObject(external = true)
@UsesPermissions(permissionNames = "android.permission.INTERNET, android.permission.ACCESS_WIFI_STATE")

public class KIO4_UDP extends AndroidNonvisibleComponent implements Component {
    public static final int VERSION = 1;
    private ComponentContainer container;
	public static final String DEFAULT_GOT_TEXT = "";
	private String got_text = "";
	
	InetAddress toAddr;
    int toPort2;
    String text2;
    int fromPort2;
	
	int portToReceive2;
	int sizePacket2;
	DatagramSocket dsocket;

    public KIO4_UDP(ComponentContainer container) {
        super(container.$form());
        this.container = container;
		GotText(DEFAULT_GOT_TEXT);
    }
	
// Obtener el valor.
@SimpleProperty(category = PropertyCategory.BEHAVIOR)
public String GotText() {
	return got_text;
}

// Establecer el valor
@DesignerProperty(editorType = PropertyTypeConstants.PROPERTY_TYPE_STRING, defaultValue = KIO4_UDP.DEFAULT_GOT_TEXT)
@SimpleProperty(description = "This propertie changes with ToReceive block. It needs a Clock component.")
public void GotText(String nuevogotText) {
	this.got_text = nuevogotText;
}

	
////////////////////// ENVIAR PAQUETE  ////////////////////////////////////////////////////////////
@SimpleFunction(description = "Send Packet.")
public void SendPacket(String toIP, int toPort, String text, int fromPort)  { 
toPort2 = toPort;
text2 = text;
fromPort2 = fromPort;
      try {
            toAddr = InetAddress.getByName(toIP);
            } catch (Exception ex) { }

    Thread thread = new Thread(new Runnable(){
     public void run() {
       try {
	DatagramSocket ds = new DatagramSocket(fromPort2);  
    DatagramPacket dp = new DatagramPacket(text2.getBytes(), text2.length(), toAddr, toPort2);  
    ds.send(dp);  
	ds.disconnect();
	ds.close();
	ds = null;
            } catch (IOException e) { }
        }
      });
      thread.start();
}


////////////////////// RECIBIR PAQUETE  ////////////////////////////////////////////////////////////
@SimpleFunction(description = "Text is received in GotText propertie. Use GotText with a Clock component.")	
public void ToReceive(int portToReceive, int sizePacket) {
portToReceive2 = portToReceive;
sizePacket2 = sizePacket;
Thread thread = new Thread(new Runnable(){
       public void run() {
       try {
        dsocket = new DatagramSocket(portToReceive2);
        byte[] buffer = new byte[sizePacket2];
        DatagramPacket packet = new DatagramPacket(buffer, buffer.length);
        while (true) {
            dsocket.receive(packet);
            String aText = new String(buffer, 0, packet.getLength());
			got_text = aText;
       }
            } catch (IOException e) { }
        }
      });  
      thread.start();
}
////////////////////////////////////////////////////////////////////////////////////////
@SimpleFunction(description = "Close to receive.")	
public void CloseToReceive() {
	//dsocket.disconnect();
    dsocket.close();
}
////////////////////////////////////////////////////////////////////////////////////////
@SimpleFunction(description = "Get local IP.")
// http://www.java2s.com/example/java-api/java/net/networkinterface/getnetworkinterfaces-0-1.html
public String GetLocalIp() {
    try {
        for (Enumeration en = NetworkInterface.getNetworkInterfaces(); en.hasMoreElements();) 
		{
            NetworkInterface intf = en.nextElement();
            for (Enumeration enumIpAddr = intf.getInetAddresses(); enumIpAddr.hasMoreElements();) {
                InetAddress inetAddress = enumIpAddr.nextElement();
                if (!inetAddress.isLoopbackAddress() && inetAddress instanceof Inet4Address) {
                    return inetAddress.getHostAddress();
                }
            }
        }
    } catch (SocketException ex) {ex.printStackTrace(); }
    return null;
}

}
  • It is a very simple extension, it can be modified and improved.
  • Let's see several examples...

You can download the extension and the example of...
http://kio4.com/appinventor/299K_extension_UDP.htm

- Designer.

- Blocks.

5 Likes

2.- Send and receive text the same device.

  • To do the first test we run the application (it works in MIT Companion).
    We write IP of the device, in my case 192.168.1.2

  • We establish in "To Port" the port to which it will send, in this case 3333.

  • In "From Port" the port from which it will send, in this case: 3334 (must be different from "To Port").

  • In "This device will...", we write the port where we will receive the information, in this case: 3333.

  • We write a Text to send and we will receive it in the same application.

  • In this example the application sends and receives the text.

extension_udp11

2 Likes

3.- Chat with two mobiles.

  • In each mobile we put the IP and the port of the other mobile ("To IP" and "To Port"), we also establish the port through which we will receive the information.

1 Like

4.- Broadcast.

  • If instead of establishing the IP of a device, we write To IP: 255.255.255.255 the text will be sent to the entire network, and it will "enter" those devices that have port 4444 (in this example) activated with UDP.

2 Likes

5.- Comments.

If we want to send text with accents, tildes,... we will use the Web component with the UriEncode and UriDecode blocks.

  • If in "To Port" we put 0, it will be sent to a random port every time we send a message.

  • If in "To IP" we put 255.255.255.255 it will be sent in Broadcast, that is to say to the entire local network.

1 Like

can we fire an event here? rather than fetch it by a timer?

That was my first intention, to create an event, but I got an error in code execution and took the easy way out: a property.

you need to fire a event on UI thread.

activity.runOnUI Thread (new runnable.....)

Yes, I knew it. In my code I started with "activity.runOnUI Thread (new runnable)" and it gave me an error, so I removed it and put the property.

Pixel 4XL (Android 12)

Can anyone test if Ulrich's extension works with Android >10, please?
p118B_ESP32_UDP.aia (53.7 KB)

https://community.appinventor.mit.edu/t/esp32-with-udp-send-receive-text-chat-mobile-mobile-udp-testing-extension-udp-by-ullis-ulrich-bien/72664/2

I was able to fix the ability to use event.

KIO4_UDP.java

Summary
package com.KIO4_UDP;
//  ?© Juan Antonio Villalpando 
// http://kio4.com/appinventor/299K_extension_UDP.htm
//  Diciembre 2022.

import com.google.appinventor.components.annotations.DesignerComponent;
import com.google.appinventor.components.annotations.DesignerProperty;
import com.google.appinventor.components.annotations.PropertyCategory;
import com.google.appinventor.components.annotations.SimpleEvent;
import com.google.appinventor.components.annotations.SimpleFunction;
import com.google.appinventor.components.annotations.SimpleObject;
import com.google.appinventor.components.annotations.SimpleProperty;
import com.google.appinventor.components.annotations.UsesPermissions;
import com.google.appinventor.components.common.ComponentCategory;
import com.google.appinventor.components.common.PropertyTypeConstants;
import com.google.appinventor.components.runtime.util.MediaUtil;
import com.google.appinventor.components.runtime.*;

import android.app.Activity;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
// Obtener IP
import java.net.SocketException;
import java.util.Enumeration;
import java.net.NetworkInterface;
import java.net.Inet4Address;

@DesignerComponent(version = 1,
    description = "Send/Receive UDP. WiFi. GotText needs a Clock component." + 
    "Juan Antonio Villalpando - KIO4.COM ",
    category = ComponentCategory.EXTENSION,
    nonVisible = true,
    iconName = "") 
@SimpleObject(external = true)
@UsesPermissions(permissionNames = "android.permission.INTERNET, android.permission.ACCESS_WIFI_STATE")

public class KIO4_UDP extends AndroidNonvisibleComponent implements Component {
    public static final int VERSION = 1;
    private ComponentContainer container;
	public static final String DEFAULT_GOT_TEXT = "";
	private String got_text = "-";
    private final Activity activity;
	
	InetAddress toAddr;
    int toPort2;
    String text2;
    int fromPort2;
	
	int portToReceive2;
	int sizePacket2;
	DatagramSocket dsocket;

    public KIO4_UDP(ComponentContainer container) {
        super(container.$form());
        this.container = container;
		GotText(DEFAULT_GOT_TEXT);
        activity = (Activity) container.$context();
    }
	
// Obtener el valor.
@SimpleProperty(category = PropertyCategory.BEHAVIOR)
public String GotText() {
	return got_text;
}

// Establecer el valor
@DesignerProperty(editorType = PropertyTypeConstants.PROPERTY_TYPE_STRING, defaultValue = KIO4_UDP.DEFAULT_GOT_TEXT)
@SimpleProperty(description = "This propertie changes with ToReceive block. It needs a Clock component.")
public void GotText(String nuevogotText) {
	this.got_text = nuevogotText;
}

	
////////////////////// ENVIAR PAQUETE  ////////////////////////////////////////////////////////////
@SimpleFunction(description = "Send Packet.")
public void SendPacket(String toIP, int toPort, String text, int fromPort)  { 
toPort2 = toPort;
text2 = text;
fromPort2 = fromPort;
      try {
            toAddr = InetAddress.getByName(toIP);
            } catch (Exception ex) { }

    Thread thread = new Thread(new Runnable(){
     public void run() {
       try {
	DatagramSocket ds = new DatagramSocket(fromPort2);  
    DatagramPacket dp = new DatagramPacket(text2.getBytes(), text2.length(), toAddr, toPort2);  
    ds.send(dp);  
	ds.disconnect();
	ds.close();
	ds = null;
            } catch (IOException e) { }
        }
      });
      thread.start();
}


////////////////////// RECIBIR PAQUETE  ////////////////////////////////////////////////////////////
@SimpleFunction(description = "Text is received in GotText propertie. Use GotText with a Clock component.")	
public void ToReceive(int portToReceive, int sizePacket) {
portToReceive2 = portToReceive;
sizePacket2 = sizePacket;

Thread thread = new Thread(new Runnable(){
       public void run() {
       try {
        dsocket = new DatagramSocket(portToReceive2);
        byte[] buffer = new byte[sizePacket2];
        DatagramPacket packet = new DatagramPacket(buffer, buffer.length);
        while (true) {
            dsocket.receive(packet);
            String aText = new String(buffer, 0, packet.getLength());
			got_text = aText;	
					    activity.runOnUiThread(new Runnable(){
						public void run() {
						TextReceived(got_text);
						}
						  });  
       }
            } catch (IOException e) { }
        }	
      });  
      thread.start();
}

////////////////////////////////////////////////////////////////////////////////////////
@SimpleFunction(description = "Close to receive.")	
public void CloseToReceive() {
	//dsocket.disconnect();
    dsocket.close();
}
////////////////////////////////////////////////////////////////////////////////////////
@SimpleFunction(description = "Get local IP.")
// http://www.java2s.com/example/java-api/java/net/networkinterface/getnetworkinterfaces-0-1.html
public String GetLocalIp() {
    try {
        for (Enumeration en = NetworkInterface.getNetworkInterfaces(); en.hasMoreElements();) 
		{
            NetworkInterface intf = en.nextElement();
            for (Enumeration enumIpAddr = intf.getInetAddresses(); enumIpAddr.hasMoreElements();) {
                InetAddress inetAddress = enumIpAddr.nextElement();
                if (!inetAddress.isLoopbackAddress() && inetAddress instanceof Inet4Address) {
                    return inetAddress.getHostAddress();
                }
            }
        }
    } catch (SocketException ex) {ex.printStackTrace(); }
    return null;
}

// Bloques de EVENTOS.
    @SimpleEvent(description = "Got text from ToReceive block.")
    public void TextReceived(String text){
        EventDispatcher.dispatchEvent(this, "TextReceived", text);
    }  
	
}

http://kio4.com/appinventor/299K_extension_UDP.htm

  • I've only tested it on Android 5 and Android 9.
1 Like

Where do I get this extension?

Taifun

Thank you! :blush:

@Akeel_ibn_Firdaus Off topic: You seem to have 2 accounts, only 1 is required, your other account is @Umar_bin_Sharif.

I ran into the same problem. We know each other.

Yes

or you both are same person?
If you are having two accounts in community then let us know which one to delete.