I recently tried to port my application that requires receiving (udp) broadcast messages. My udp receiving code works on pc (windows/linux), but with android there seems to be some problem receiving broadcast messages, however, i seem to be able to send broadcast messages with android and receive acknowledgment packet from pc version.
Tried to find solution but anything close to the answer is that it MIGHT not work on my device and there was really any info on how i can be sure that this is the case, so felt that there should be thread for making sure it is indeed hardware/firmware problem and not problem in my code, like if there is something android specific that i forgot to enable? Tested with galaxy S (kitkat) and Galaxy s3 mini (kitkat) and both have same problem
(under onCreate)
WifiManager wifi;
wifi = (WifiManager) getSystemService(Context.WIFI_SERVICE);
WifiManager.MulticastLock wifilock = wifi.createMulticastLock("compvter.qft");
Log.i("wifilock", "multicastLock.isHeld() = " +wifilock.isHeld());
Log.i("wifilock", "multicastLock.toString() = " +wifilock.toString());
wifilock.acquire();
Log.i("wifilock", "multicastLock.isHeld() = " + wifilock.isHeld());
Log.i("wifilock", "multicastLock.toString() = " + wifilock.toString());
if (Settings.socket==null)
{
initsocket();
}
UdpServer udpserver = new UdpServer();
udpserver.start();
Under udpserver class
public volatile boolean keepServerRunning=true;
public void run()
{
boolean none=true;
try {
byte[] buffer = new byte[Settings.udppacketsize];
while (keepServerRunning==true)
{
DatagramPacket inpacket = new DatagramPacket(buffer,buffer.length);
Settings.socket.setSoTimeout(1000);
try
{
Settings.socket.receive(inpacket);
none=false;
}
catch (SocketTimeoutException e)
{
none=true;
}
if (none==false)
{
handler handler = new handler(Settings.socket, inpacket);
handler.start();
}
}
Settings.socket.close();
} catch (IOException e)
{
}
}
Logging for wifilock gives:
02-01 16:34:07.516 17365-17365/com.test.oappi.qft I/Wifilock﹕ multicastLock.isHeld() = false
02-01 16:34:07.516 17365-17365/com.test.oappi.qft I/wifilock﹕ multicastLock.toString() = MulticastLock{ 425b3ff8; refcounted: refcount = 0 }
02-01 16:34:07.516 17365-17365/com.test.oappi.qft I/wifilock﹕ multicastLock.isHeld() = true
02-01 16:34:07.516 17365-17365/com.test.oappi.qft I/wifilock﹕ multicastLock.toString() = MulticastLock{ 425b3ff8; held; refcounted: refcount = 1 }
Manifest permissions
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
<uses-permission android:name="android.permission.CHANGE_WIFI_MULTICAST_STATE"/>
Since the wifi state definitely changes, does this mean that i really have two android phones unable to receive broadcast messages or does API version i try to develop matter since i am trying to develop to Api lvl 10. If someone has idea how to check devices broadcast receiving capability please tell it.
Related
So i got my ESP32 and wanted to do some Porjects and I want to control them with an Android App, for example LED Stripes. I already did this with my Raspberry Pi where it runs perfectly.
I already tried some codes and it could connect to the Wifi. And my PC and even Raspberry Pi could connect to it but when i tried with my Smartphone i just didn't worked.
Here' my Android Code:
mainActivity.jre
connectButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (!IPAddress.getText().equals("") || IPAddress.getText() != null || !portNumber.getText().equals("") || portNumber.getText() != null){
return;
}
IPaddresse= IPAddress.getText().toString();
port=Integer.parseInt(portNumber.getText().toString());
try {
client = new Socket(IPaddresse,port);
pw = new PrintWriter(client.getOutputStream());
dataOutputStream= new DataOutputStream(client.getOutputStream());
msg.setText("Verbunden!");
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
});
Permissions:
<uses-permission android:name="android.permission.INTERNET"></uses-permission>
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"></uses-permission>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"></uses-permission>
ESP32 Code:
#include <WiFi.h>
const char* ssid="Name";
const char* password="password";
WiFiServer server(80 );
void setup() {
Serial.begin(115200);
Serial.println("start");
delay(1000);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(1000);
Serial.println("Connecting to WiFi..");
}
Serial.println("Connected to the WiFi network");
Serial.println(WiFi.localIP());
server.begin();
}
void loop() {
WiFiClient client = server.available();
if (client) {
while (client.connected()) {
while (client.available()>0) {
char c = client.read();
client.write(c);
}
Serial.println(client.localIP());
delay(10);
}
}
}
Sorry for my English. And my Code isn't the best im just beginning to Code
Thanks
First on the ESP32 i suggest you add mDNS to your setup, this allows you to give your esp a name on the network like when you give your esp the name pietje then you can find it as pietje.local on your network.
This seems not to work properly with the socket class, but maybe i did something work. It did not finding the ip of it. It was the first time working with sockets. So i learned something new.
I tried your example and it did fault me to. With some short search i found this website:
https://www.tutorialspoint.com/sending-and-receiving-data-with-sockets-in-android
By adding you socket creation inside a thread it did work for me.
I hope this helps you ahead.
I am able to pair devices with the android studio app but I get the tag
"CouldNotConnectToSocket" even though the device is paired.
I am new to android studio so I am really stuck with where to go next.
I also get
getBluetoothService() called with no BluetoothManagerCallback
The UUID I created is:
private final static UUID BTMODULEUUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");
Can anyone please help me?
new Thread() {
#Override
public void run() {
device = BA.getRemoteDevice(address);
try {
BTSocket = device.createRfcommSocketToServiceRecord(BTMODULEUUID);
//BTSocket = createBluetoothSocket(device);
Log.d(TAG, "Device Connected");
BA.cancelDiscovery();
BTSocket.connect();
} catch (IOException ex) {
Log.d(TAG, "CouldNotConnectToSocket");
closeSocket(BTSocket);
}
}
}.start();
The issue I found out was that the devices I was trying to connect to send data back and forth require Bluetooth Low Energy support from the app.
Here is what I am doing:
I register a BroadcastReceiver like this:
mConnectionChangeReceiver = new ConnectionChangeReceiver();
IntentFilter filter = new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION);
filter.addAction(WifiManager.SUPPLICANT_STATE_CHANGED_ACTION);
filter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION);
mContext.registerReceiver(mConnectionChangeReceiver, filter, null, handler);
Then I automatically try connect to a specific WiFi. Something like this:
if (!mWifiManager.isWifiEnabled()) {
mWifiManager.setWifiEnabled(true);
}
mWifiManager.enableNetwork(mCurrentNetworkId, true);
I get the broadcast receiver events as expected. Inside onReceive() I check for the SSID and for SuplicantState. The problem is when I try to get the phone ip address. WifiInfo.getIpAddress returns 0 if the cellular network is enabled on the phone but it works if it is disabled.
Please note that this will work if the device was already connected to SSID in both cases (with/without cellular network). For this to happen wifi must de off or the phone must be connected to another wifi before running the code.
Here's the code:
public void onReceive(Context context, Intent intent) {
WifiInfo wifiInfo = mWifiManager.getConnectionInfo();
//..... Here's the code that compares SSID
if (isConnectedToSSID() && (wifiInfo.getSupplicantState() == SupplicantState.COMPLETED) {
mIpAddress = NetworkHelper.getIpAddress(wifiInfo);
}
}
public static String getIpAddress(WifiInfo pWifiInfo) {
int ipAddress = pWifiInfo.getIpAddress();
if (ByteOrder.nativeOrder().equals(ByteOrder.LITTLE_ENDIAN)) {
ipAddress = Integer.reverseBytes(ipAddress);
}
byte[] ipByteArray = BigInteger.valueOf(ipAddress).toByteArray();
String ipAddressString = null;
try {
ipAddressString = InetAddress.getByAddress(ipByteArray).getHostAddress();
} catch (UnknownHostException ex) {
ex.printStackTrace();
}
return ipAddressString;
}
Any ideas why this happens?
I'm writing a bluetooth HID server for a small and very simple bluetooth remote. I'm following the documentation here.
My application's permission include:
<uses-permission android:name="android.permission.BLUETOOTH"/>
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
And this is my BluetoothServerSocket reading connection-accepting thread:
private class AcceptThread extends Thread {
public void run() {
BluetoothSocket socket = null;
while(true) {
try {
socket = MyBluetoothServerSocket.accept(); // problematic line
} catch(IOException e) {
Log.i(BLUETOOTH_SERVICE, e.toString());
break;
}
if(socket != null) {
readInput(socket);
try {
MyBluetoothServerSocket.close();
} catch (IOException e) {
Log.i(BLUETOOTH_SERVICE, e.toString());
}
} else {
Log.i(BLUETOOTH_SERVICE, "Could not accept a connection from the socket.\n");
}
break;
}
}
}
MyBluetoothServerSocket is a socket constructed like this:
MyBluetoothAdapter.listenUsingRfcommWithServiceRecord("MyService", UUID.fromString("00001124-0000-1000-8000-00805f9b34fb"));
The UUID I'm using above is the only one my remote control device reports through the following method:
MyBluetoothDevice.getUuids();
And MyBluetoothAdapter is just the default adapter:
BluetoothAdapter.getDefaultAdapter();
The rest of the code involved is minimal (making sure bluetooth is on, selecting the correct device) and working correctly. The remote is bonded to the phone.
The line marked as problematic in the code above (accept()) never returns i.e. it blocks forever. What am I doing wrong?
edit: I've tried MyBluetoothAdapter.listenUsingInsecureRfcommWithServiceRecord without success.
HID is based on the L2CAP bluetooth profile (protocol?), which is not implemented (line 107) in Android as of October 2013.
This makes it currently impossible to connect to a HID device.
I am trying to create a Java Client-Server Program, where the Server is running on a Windows PC, and the Client is running on an Android 2.2 Phone.
The Connection is okay. Sending Data from the Phone to the PC works also fine.
Just receiving Data on the Phone crashes the program.
I am using DataInputStream and DataOutputStream to read/write through the Socket.
//Thread on the Phone
public void run() {
while (RUN) {
if (socket != null && socket.isConnected()) {
try {
//Crash
String text = dis.readUTF();
myTextView.setText(text);
} catch (IOException ex) {
//ErrorHandling
}
}
}
}
I want to receive a String from the server and then show it in a TextView.
Any Ideas? I am already setting this permission:
<uses-permission android:name="android.permission.INTERNET" />
do i need any other permissions? Thanks.
you can't set text on your UI if you're not in the UI thread.
do this...
add:
Runnable showmessage = new Runnable() {
public void run() {
myTextView.setText(membervariabletext);
}
};
and from your thread, after the readUTF(), call "runOnUiThread(showmessage);"
I would ensure that your Data Input Stream is initiated correctly:
Socket s = new Socket(serverAddress, port);
DataInputStream dis = new DataInputStream(s.getInputStream());
Otherwise, here's a link for example code where someone uses InputStreamReader() and OutputStreamWriter() to make a server and client for Android.
https://thinkandroid.wordpress.com/2010/03/27/incorporating-socket-programming-into-your-applications/