我正在开发一个 UDP 聊天应用程序。所有网络处理都在服务的线程内。对于 3.1 和 4.0 操作系统,我仍然收到此错误消息。对于 2.3 及以下版本,它工作正常。问题:我是否应该创建两个应用程序,一个用于 2.3 及以下版本,另一个用于 3.0 及更高版本?根据 LogCat 调用write(byte[] out)方法时会发生错误。
如果我为 ICS 禁用 StrictMode,则应用程序运行正常。
public class ChatService extends Service {
private Binder binder;
private ComThread comThread;
public IBinder onBind(Intent intent) {
return binder;
}
public void onCreate() {
}
public int onStartCommand(Intent intent, int flags, int startId) {
binder = new ChatServiceBinder();
start();
return super.onStartCommand(intent, flags, startId);
}
public synchronized void start() {
comThread = new ComThread();
comThread.start();
}
public void onDestroy() {
stop();
}
public void write(byte[] out) {
comThread.write(out);
}
public synchronized void stop() {
if (comThread != null) {
comThread.cancel();
comThread = null;
}
}
private class ComThread extends Thread {
private static final int BCAST_PORT = 2562;
DatagramSocket mSocket;
InetAddress myBcastIP, myLocalIP;
public ComThread() {
try {
myBcastIP = getBroadcastAddress();
if (D)
Log.d(TAG, "my bcast ip : " + myBcastIP);
myLocalIP = getLocalAddress();
if (D)
Log.d(TAG, "my local ip : " + myLocalIP);
mSocket = new DatagramSocket(BCAST_PORT);
mSocket.setBroadcast(true);
} catch (IOException e) {
Log.e(TAG, "Could not make socket", e);
}
}
public void run() {
try {
byte[] buf = new byte[1024];
if (D)
Log.d(TAG, "run(), com thread startet");
// Listen on socket to receive messages
while (true) {
DatagramPacket packet = new DatagramPacket(buf, buf.length);
mSocket.receive(packet);
InetAddress remoteIP = packet.getAddress();
if (remoteIP.equals(myLocalIP))
continue;
String s = new String(packet.getData(), 0,
packet.getLength());
if (D)
Log.d(TAG, "run(), " + s);
Message msg = new Message();
msg.obj = s;
msg.arg1 = MessageHandler.MSG_IN;
state.getHandler().sendMessage(msg);
}
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* Write broadcast packet.
*/
public void write(byte[] buffer) {
try {
String data = new String(buffer);
DatagramPacket packet = new DatagramPacket(data.getBytes(),
data.length(), myBcastIP, BCAST_PORT);
mSocket.send(packet);
} catch (Exception e) {
Log.e(TAG, "write(), Exception during write", e);
}
}
/**
* Calculate the broadcast IP we need to send the packet along.
*/
private InetAddress getBroadcastAddress() throws IOException {
WifiManager mWifi = (WifiManager) state
.getSystemService(Context.WIFI_SERVICE);
WifiInfo info = mWifi.getConnectionInfo();
if (D)
Log.d(TAG, "\nWiFi Status: " + info.toString());
// DhcpInfo is a simple object for retrieving the results of a DHCP
// request
DhcpInfo dhcp = mWifi.getDhcpInfo();
if (dhcp == null) {
Log.d(TAG, "Could not get dhcp info");
return null;
}
int broadcast = (dhcp.ipAddress & dhcp.netmask) | ~dhcp.netmask;
byte[] quads = new byte[4];
for (int k = 0; k < 4; k++)
quads[k] = (byte) ((broadcast >> k * 8) & 0xFF);
// Returns the InetAddress corresponding to the array of bytes.
return InetAddress.getByAddress(quads); // The high order byte is
// quads[0].
}
private InetAddress getLocalAddress() throws IOException {
try {
for (Enumeration<NetworkInterface> en = NetworkInterface
.getNetworkInterfaces(); en.hasMoreElements();) {
NetworkInterface intf = en.nextElement();
for (Enumeration<InetAddress> enumIpAddr = intf
.getInetAddresses(); enumIpAddr.hasMoreElements();) {
InetAddress inetAddress = enumIpAddr.nextElement();
if (!inetAddress.isLoopbackAddress()) {
return inetAddress;
}
}
}
} catch (SocketException ex) {
Log.e(TAG, ex.toString());
}
return null;
}
public void cancel() {
try {
mSocket.close();
} catch (Exception e) {
Log.e(TAG, "close() of connect socket failed", e);
}
}
}
public class ChatServiceBinder extends Binder {
private ChatService service = ChatService.this;
public ChatService getService() {
return service;
}
}
}
}
谢谢。