UDP 套接字未在 Android 6 (M) 上接收数据报
UDP socket does not receive datagrams on Android 6 (M)
我下面的代码 运行 在 Android 5.1.1 上运行良好,显示了我的控制台收到的数据报。
byte[] message = new byte[500];
try {
String text;
int server_port = 3421;
DatagramPacket p = new DatagramPacket(message, message.length);
DatagramSocket s = new DatagramSocket(server_port);
s.receive(p);
Log.d("APP", "After received");
final String hexMsg = bytesToHex(message);
Log.d("APP","message:" + hexMsg);
s.close();
} catch (SocketException e) {
e.printStackTrace();
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
}
出于某种未知原因,当我 运行 在 Android 6.0.1 上使用相同的代码时,我没有收到任何数据报。控制台上没有显示错误。
我的 UDP 服务器将数据报直接发送到我的 android 设备(因此,这不是广播)。
完整 class 代码:
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if (Build.VERSION.SDK_INT>Build.VERSION_CODES.LOLLIPOP_MR1) {
String pkg=getPackageName();
PowerManager pm=getSystemService(PowerManager.class);
if (!pm.isIgnoringBatteryOptimizations(pkg)) {
Intent i= new Intent(Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS)
.setData(Uri.parse("package:" + pkg));
startActivity(i);
}
}
new myAsync().execute();
}
final protected static char[] hexArray = "0123456789ABCDEF".toCharArray();
public static String bytesToHex(byte[] bytes) {
char[] hexChars = new char[bytes.length * 2];
for ( int j = 0; j < bytes.length; j++ ) {
int v = bytes[j] & 0xFF;
hexChars[j * 2] = hexArray[v >>> 4];
hexChars[j * 2 + 1] = hexArray[v & 0x0F];
}
return new String(hexChars);
}
class myAsync extends AsyncTask<Void, Void, Void> {
@Override
protected void onPreExecute() {
// TODO Auto-generated method stub
super.onPreExecute();
}
@Override
protected Void doInBackground(Void... params) {
// TODO Auto-generated method stub
byte[] message = new byte[500];
try {
String text;
int server_port = 3421;
DatagramPacket p = new DatagramPacket(message, message.length);
DatagramSocket s = new DatagramSocket(server_port);
s.receive(p);
Log.d("APP", "After received");
final String hexMsg = bytesToHex(message);
Log.d("APP","message:" + hexMsg);
runOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(getApplicationContext(), hexMsg, Toast.LENGTH_LONG).show();
}
});
s.close();
} catch (SocketException e) {
e.printStackTrace();
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
}
return null;
}
@Override
protected void onPostExecute(Void result) {
// TODO Auto-generated method stub
super.onPostExecute(result);
// Handle/Update UI Part
}
}
}
对可能出现的问题有什么想法吗?
我通过进行 2 处更改使其工作:
1st) 通过使用允许重用地址:
DatagramSocket s = new DatagramSocket(null);
s.setReuseAddress(true);
s.bind(new InetSocketAddress(server_port));
而不是
DatagramSocket s = new DatagramSocket(server_port);
2nd) 使用 Runnable Thread 而不是 Async 方法。
我下面的代码 运行 在 Android 5.1.1 上运行良好,显示了我的控制台收到的数据报。
byte[] message = new byte[500];
try {
String text;
int server_port = 3421;
DatagramPacket p = new DatagramPacket(message, message.length);
DatagramSocket s = new DatagramSocket(server_port);
s.receive(p);
Log.d("APP", "After received");
final String hexMsg = bytesToHex(message);
Log.d("APP","message:" + hexMsg);
s.close();
} catch (SocketException e) {
e.printStackTrace();
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
}
出于某种未知原因,当我 运行 在 Android 6.0.1 上使用相同的代码时,我没有收到任何数据报。控制台上没有显示错误。
我的 UDP 服务器将数据报直接发送到我的 android 设备(因此,这不是广播)。
完整 class 代码:
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if (Build.VERSION.SDK_INT>Build.VERSION_CODES.LOLLIPOP_MR1) {
String pkg=getPackageName();
PowerManager pm=getSystemService(PowerManager.class);
if (!pm.isIgnoringBatteryOptimizations(pkg)) {
Intent i= new Intent(Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS)
.setData(Uri.parse("package:" + pkg));
startActivity(i);
}
}
new myAsync().execute();
}
final protected static char[] hexArray = "0123456789ABCDEF".toCharArray();
public static String bytesToHex(byte[] bytes) {
char[] hexChars = new char[bytes.length * 2];
for ( int j = 0; j < bytes.length; j++ ) {
int v = bytes[j] & 0xFF;
hexChars[j * 2] = hexArray[v >>> 4];
hexChars[j * 2 + 1] = hexArray[v & 0x0F];
}
return new String(hexChars);
}
class myAsync extends AsyncTask<Void, Void, Void> {
@Override
protected void onPreExecute() {
// TODO Auto-generated method stub
super.onPreExecute();
}
@Override
protected Void doInBackground(Void... params) {
// TODO Auto-generated method stub
byte[] message = new byte[500];
try {
String text;
int server_port = 3421;
DatagramPacket p = new DatagramPacket(message, message.length);
DatagramSocket s = new DatagramSocket(server_port);
s.receive(p);
Log.d("APP", "After received");
final String hexMsg = bytesToHex(message);
Log.d("APP","message:" + hexMsg);
runOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(getApplicationContext(), hexMsg, Toast.LENGTH_LONG).show();
}
});
s.close();
} catch (SocketException e) {
e.printStackTrace();
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
}
return null;
}
@Override
protected void onPostExecute(Void result) {
// TODO Auto-generated method stub
super.onPostExecute(result);
// Handle/Update UI Part
}
}
}
对可能出现的问题有什么想法吗?
我通过进行 2 处更改使其工作:
1st) 通过使用允许重用地址:
DatagramSocket s = new DatagramSocket(null);
s.setReuseAddress(true);
s.bind(new InetSocketAddress(server_port));
而不是
DatagramSocket s = new DatagramSocket(server_port);
2nd) 使用 Runnable Thread 而不是 Async 方法。