[英]Listing of the Network Devices in Android
Similar or the same Question has been answered here 在这里已回答类似或相同的问题
I am creating an Android App, which sends a broadcast message to the network and prepares a list of devices responding back. 我正在创建一个Android应用程序,该应用程序将广播消息发送到网络,并准备响应的设备列表。
Now What I did: 现在我做了什么:
I created an Activity
Class DeviceManagerWindow.java
which calls a thread Sender.java
. 我创建了一个
Activity
类DeviceManagerWindow.java
,它调用了一个线程Sender.java
。 Sender.java
is responsible for sending the broadcast message. Sender.java
负责发送广播消息。
Then the DeviceManagerWindow.java
calls another thread which is responsible for listening to the devices responding back. 然后,
DeviceManagerWindow.java
调用另一个线程,该线程负责侦听响应的设备。 The devices
responding back will be listed in the Activity as soon as the device responds back. devices
回复后,将在活动中列出回复的设备。 For that I have a TableLayout
named deviceList
. 为此,我有一个名为
deviceList
的TableLayout
。
What code I have written: 我写了什么代码:
DeviceManagerWindow.java This method is called when a button for search is pressed
DeviceManagerWindow.java
This method is called when a button for search is pressed
public void searchDevice(View v) throws IOException, InterruptedException
{
//Log.v("TableLayout:",view.toString());
sendMulticastFlyport = new Thread(new FlyportSender(MAC));
sendMulticastFlyport.start();
new Thread()
{
public void run()
{
MulticastSocket socketComputer=null;
try
{
socketComputer = new MulticastSocket(WifiConstants.COMPUTER_RECV_PORT);
socketComputer.joinGroup(InetAddress.getByName(WifiConstants.COMPUTER_NETWORK_ADDR));
socketComputer.setSoTimeout(1*60*1000);
byte[] inBufComputer = new byte[1024];
DatagramPacket inPacketComputer = new DatagramPacket(inBufComputer, inBufComputer.length);
while(true)
{
System.out.println("Listening...");
socketComputer.receive(inPacketComputer);
System.out.println("Received");
String msg = new String(inBufComputer, 0, inPacketComputer.getLength());
DeviceInformation device = new DeviceInformation(1, msg, inPacketComputer.getAddress().toString());
addDevice(device, false, 1);
Log.v("Received:","Received Computer From :" + inPacketComputer.getAddress() + " Msg : " + msg);
//System.out.write(inPacket.getData(),0,inPacket.getLength());
System.out.println();
Thread.sleep(2000);
}
}
catch(Exception e)
{
Log.v("Exception:","During Receiving Computer: "+e.toString());
try
{
addDevice(null, true, 1);
}
catch (IOException e1)
{
Log.v("Exception:", "Computer End Error: " +e1);
}
}
finally
{
socketComputer.close();
}
}
}.start();
The following code creates a list: 以下代码创建一个列表:
public void addDevice(DeviceInformation device, boolean bool, int type) throws IOException
{
TableLayout tb = (TableLayout) findViewById(R.id.DeviceList);
Log.v("addDevice","Called");
if(bool)
{
LayoutParams layout = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
TableRow tr = new TableRow(getApplicationContext());
TextView tv = new TextView(getApplicationContext());
System.out.println(tb);
tv.setLayoutParams(layout);
tr.setLayoutParams(layout);
String message;
Log.v("addDevice","Device Timeout");
switch(type)
{
case 1:
computerEnd=true;
break;
case 2:
raspberryEnd=true;
break;
case 3:
flyportEnd=true;
break;
}
if(computerEnd && raspberryEnd && flyportEnd)
{
if(rowCounter>0)
{
message = "No More Devices";
}
else
{
message = "No Devices Found";
}
tv.setText(message);
tv.setTextColor(Color.WHITE);
if(rowCounter%2==0)
{
tr.setBackgroundColor(Color.DKGRAY);
}
else
{
tr.setBackgroundColor(Color.GRAY);
}
tv.setVisibility(1);
tr.addView(tv);
tb.addView(tr);
}
}
else
{
LayoutParams layout = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
TableRow tr = new TableRow(getApplicationContext());
TextView tv = new TextView(getApplicationContext());
tv.setLayoutParams(layout);
tr.setLayoutParams(layout);
Log.v("addDevice","Received");
String textToDisplay = device.getDeviceTypeString()+"\n"+device.getIPAddress(); //Write the text to display
tv.setText(textToDisplay);
tv.setTextColor(Color.WHITE);
Drawable img;
if(device.getDeviceType()==1)
{
img = getApplicationContext().getResources().getDrawable(R.drawable.pc);
}
else if(device.getDeviceType()==2)
{
img = getApplicationContext().getResources().getDrawable(R.drawable.raspberry);
}
else
{
img = getApplicationContext().getResources().getDrawable(R.drawable.flyport);
}
img.setBounds(0,0,70,45);
tv.setCompoundDrawables(null, null, img, null);
tv.setOnClickListener(new OnClickListener()
{
@Override
public void onClick(View v)
{
}
});
if(rowCounter%2==0)
{
tr.setBackgroundColor(Color.DKGRAY);
}
else
{
tr.setBackgroundColor(Color.GRAY);
}
rowCounter++;
Log.v("Result","Device Added");
}
}
Now it is showing me an error in the logCat as: 现在,它向我显示了logCat中的错误,如下所示:
05-11 22:01:10.165: E/AndroidRuntime(13873): android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
What I have figured out from this is only the UIThread is allowed to access the Views that is created. 我从中得出的结论是,仅允许UIThread访问创建的视图。
Previously I had tried: 以前我曾尝试过:
new Thread()
{
public void run()
{
runOnUiThread(){
MulticastSocket socketComputer=null;
try
{
....
....
....
}
}
And that time I received an error: 那时我收到一个错误:
Main thread cannot access Network 主线程无法访问网络
Before that I had tried to use synchronized
methods which was called from the Receiving.java
Thread File. 在此之前,我曾尝试使用从
Receiving.java
线程文件中调用的synchronized
方法。 but It also gave an error of not creating the list. 但是它也给出了不创建列表的错误。
I have tried all possible ways. 我尝试了所有可能的方法。
Now what whould I do.? 现在我该怎么办?
You figured it out right. 您发现正确。 Now you can learn to either use a Handler to pass information to the UI thread (see http://www.techotopia.com/index.php/A_Basic_Overview_of_Android_Threads_and_Thread_handlers ) or AsyncTask (see http://developer.android.com/reference/android/os/AsyncTask.html ).
现在,您可以学习使用处理程序将信息传递到UI线程(请参阅http://www.techotopia.com/index.php/A_Basic_Overview_of_Android_Threads_and_Thread_handlers )或AsyncTask(请参见http://developer.android.com/reference/ android / os / AsyncTask.html )。
I personally prefer AsyncTask. 我个人更喜欢AsyncTask。 You can paste the code which performs the search into the doInBackground() method (not need to use a separate thread, doInBackground() already does that for you) and paste the UI-related code (the list creation code) into the onPostExecute() method.
您可以将执行搜索的代码粘贴到doInBackground()方法中(不需要使用单独的线程,doInBackground()已经为您完成此操作),并将与UI相关的代码(列表创建代码)粘贴到onPostExecute( ) 方法。 Search for further examples of AsyncTask if it is not sufficiently clear how it works from the link.
如果尚未从链接中充分了解AsyncTask的工作方式,请搜索更多示例。
EDIT: If you intend your device search code to run indefinitely, then you have to resort to Handler, as AsyncTask expects the doInBackground() method to finish before running onPostExecute(). 编辑:如果您希望设备搜索代码无限期运行,则必须诉诸处理程序,因为AsyncTask希望doInBackground()方法在运行onPostExecute()之前完成。 See which option better suits your needs.
查看哪个选项更适合您的需求。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.